2016-06-17 23:16:09 +00:00
|
|
|
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
|
|
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
|
|
2015-11-17 19:40:07 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
2016-07-21 16:46:12 +00:00
|
|
|
|
using System.IO.Compression;
|
2015-11-17 19:40:07 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
2016-07-21 16:46:12 +00:00
|
|
|
|
using Microsoft.DotNet.Cli.CommandLine;
|
|
|
|
|
using Microsoft.DotNet.Cli.Utils;
|
2016-08-09 18:05:00 +00:00
|
|
|
|
using Microsoft.DotNet.PlatformAbstractions;
|
2015-11-17 19:40:07 +00:00
|
|
|
|
|
2015-12-03 10:16:52 +00:00
|
|
|
|
namespace Microsoft.DotNet.Tools.New
|
2015-11-17 19:40:07 +00:00
|
|
|
|
{
|
2016-01-31 05:47:50 +00:00
|
|
|
|
public class NewCommand
|
2015-11-17 19:40:07 +00:00
|
|
|
|
{
|
|
|
|
|
private static string GetFileNameFromResourceName(string s)
|
|
|
|
|
{
|
|
|
|
|
// A.B.C.D.filename.extension
|
|
|
|
|
string[] parts = s.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
if (parts.Length < 2)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// filename.extension
|
|
|
|
|
return parts[parts.Length - 2] + "." + parts[parts.Length - 1];
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
public int CreateEmptyProject(string languageName, string templateDir, bool isMsBuild)
|
2015-11-17 19:40:07 +00:00
|
|
|
|
{
|
2016-06-14 20:20:29 +00:00
|
|
|
|
// Check if project.json exists in the folder
|
2016-10-14 07:06:35 +00:00
|
|
|
|
if (File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "project.json")) && !isMsBuild)
|
2016-06-14 20:20:29 +00:00
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine($"Creating new {languageName} project failed, project already exists.");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-31 05:47:50 +00:00
|
|
|
|
var thisAssembly = typeof(NewCommand).GetTypeInfo().Assembly;
|
2015-11-17 19:40:07 +00:00
|
|
|
|
var resources = from resourceName in thisAssembly.GetManifestResourceNames()
|
2015-12-26 01:46:33 +00:00
|
|
|
|
where resourceName.Contains(templateDir)
|
2015-11-17 19:40:07 +00:00
|
|
|
|
select resourceName;
|
|
|
|
|
|
2015-11-17 18:22:26 +00:00
|
|
|
|
var resourceNameToFileName = new Dictionary<string, string>();
|
2015-11-17 19:40:07 +00:00
|
|
|
|
bool hasFilesToOverride = false;
|
|
|
|
|
foreach (string resourceName in resources)
|
|
|
|
|
{
|
|
|
|
|
string fileName = GetFileNameFromResourceName(resourceName);
|
|
|
|
|
|
2016-05-27 19:37:17 +00:00
|
|
|
|
using (var resource = thisAssembly.GetManifestResourceStream(resourceName))
|
2015-11-17 19:40:07 +00:00
|
|
|
|
{
|
2016-05-27 19:37:17 +00:00
|
|
|
|
var archive = new ZipArchive(resource);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2016-06-14 20:20:29 +00:00
|
|
|
|
// Check if other files from the template exists already, before extraction
|
|
|
|
|
IEnumerable<string> fileNames = archive.Entries.Select(e => e.FullName);
|
|
|
|
|
foreach (var entry in fileNames)
|
|
|
|
|
{
|
|
|
|
|
if (File.Exists(Path.Combine(Directory.GetCurrentDirectory(), entry)))
|
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine($"Creating new {languageName} project failed, directory already contains {entry}");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-21 16:46:12 +00:00
|
|
|
|
string projectDirectory = Directory.GetCurrentDirectory();
|
2016-05-27 19:37:17 +00:00
|
|
|
|
|
2016-07-21 16:46:12 +00:00
|
|
|
|
archive.ExtractToDirectory(projectDirectory);
|
|
|
|
|
|
2016-07-21 23:17:20 +00:00
|
|
|
|
ReplaceFileTemplateNames(projectDirectory);
|
2016-10-14 07:06:35 +00:00
|
|
|
|
|
|
|
|
|
if (!isMsBuild)
|
|
|
|
|
{
|
|
|
|
|
ReplaceProjectJsonTemplateValues(projectDirectory);
|
|
|
|
|
}
|
2016-05-27 19:37:17 +00:00
|
|
|
|
}
|
|
|
|
|
catch (IOException ex)
|
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine(ex.Message);
|
|
|
|
|
hasFilesToOverride = true;
|
|
|
|
|
}
|
2015-11-17 19:40:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hasFilesToOverride)
|
|
|
|
|
{
|
2015-12-26 01:46:33 +00:00
|
|
|
|
Reporter.Error.WriteLine($"Creating new {languageName} project failed.");
|
2015-11-17 19:40:07 +00:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 01:46:33 +00:00
|
|
|
|
Reporter.Output.WriteLine($"Created new {languageName} project in {Directory.GetCurrentDirectory()}.");
|
2015-11-17 19:40:07 +00:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-21 23:17:20 +00:00
|
|
|
|
private static void ReplaceProjectJsonTemplateValues(string projectDirectory)
|
|
|
|
|
{
|
|
|
|
|
string projectJsonFile = Path.Combine(projectDirectory, "project.json");
|
2016-09-27 23:29:56 +00:00
|
|
|
|
string projectJsonTemplateFile = Path.Combine(projectDirectory, "project.json.template");
|
2016-07-21 23:17:20 +00:00
|
|
|
|
|
2016-09-27 23:29:56 +00:00
|
|
|
|
if(File.Exists(projectJsonTemplateFile))
|
2016-09-27 22:38:59 +00:00
|
|
|
|
{
|
2016-09-27 23:29:56 +00:00
|
|
|
|
File.Move(projectJsonTemplateFile, projectJsonFile);
|
2016-09-27 22:38:59 +00:00
|
|
|
|
}
|
2016-07-21 23:17:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ReplaceFileTemplateNames(string projectDirectory)
|
|
|
|
|
{
|
|
|
|
|
string projectName = new DirectoryInfo(projectDirectory).Name;
|
|
|
|
|
foreach (string file in Directory.GetFiles(projectDirectory, "*", SearchOption.AllDirectories))
|
|
|
|
|
{
|
|
|
|
|
if (Path.GetFileNameWithoutExtension(file) == "$projectName$")
|
|
|
|
|
{
|
|
|
|
|
string extension = Path.GetExtension(file);
|
|
|
|
|
|
|
|
|
|
File.Move(
|
|
|
|
|
file,
|
|
|
|
|
Path.Combine(Path.GetDirectoryName(file), $"{projectName}{extension}"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-31 05:47:50 +00:00
|
|
|
|
public static int Run(string[] args)
|
2015-11-17 19:40:07 +00:00
|
|
|
|
{
|
|
|
|
|
DebugHelper.HandleDebugSwitch(ref args);
|
|
|
|
|
|
|
|
|
|
var app = new CommandLineApplication();
|
2015-12-03 10:16:52 +00:00
|
|
|
|
app.Name = "dotnet new";
|
2015-11-17 19:40:07 +00:00
|
|
|
|
app.FullName = ".NET Initializer";
|
|
|
|
|
app.Description = "Initializes empty project for .NET Platform";
|
|
|
|
|
app.HelpOption("-h|--help");
|
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
var csharp = new { Name = "C#", Alias = new[] { "c#", "cs", "csharp" }, TemplatePrefix = "CSharp",
|
|
|
|
|
Templates = new[]
|
|
|
|
|
{
|
|
|
|
|
new { Name = "Console", isMsBuild = true },
|
|
|
|
|
new { Name = "Web", isMsBuild = false },
|
|
|
|
|
new { Name = "Lib", isMsBuild = true },
|
|
|
|
|
new { Name = "xunittest", isMsBuild = false },
|
|
|
|
|
new { Name = "nunittest", isMsBuild = false }
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var fsharp = new { Name = "F#", Alias = new[] { "f#", "fs", "fsharp" }, TemplatePrefix = "FSharp",
|
|
|
|
|
Templates = new[]
|
|
|
|
|
{
|
|
|
|
|
new { Name = "Console", isMsBuild = false },
|
|
|
|
|
new { Name = "Lib", isMsBuild = false }
|
|
|
|
|
}
|
|
|
|
|
};
|
2016-06-22 22:20:40 +00:00
|
|
|
|
|
|
|
|
|
var languages = new[] { csharp, fsharp };
|
|
|
|
|
|
|
|
|
|
string langValuesString = string.Join(", ", languages.Select(l => l.Name));
|
|
|
|
|
var typeValues =
|
|
|
|
|
from l in languages
|
2016-10-14 07:06:35 +00:00
|
|
|
|
let values = string.Join(", ", l.Templates.Select(t => t.Name))
|
2016-06-22 22:20:40 +00:00
|
|
|
|
select $"Valid values for {l.Name}: {values}.";
|
|
|
|
|
string typeValuesString = string.Join(" ", typeValues);
|
|
|
|
|
|
|
|
|
|
var lang = app.Option("-l|--lang <LANGUAGE>", $"Language of project Valid values: {langValuesString}.", CommandOptionType.SingleValue);
|
|
|
|
|
var type = app.Option("-t|--type <TYPE>", $"Type of project {typeValuesString}", CommandOptionType.SingleValue);
|
2015-12-26 01:46:33 +00:00
|
|
|
|
|
2016-01-31 05:47:50 +00:00
|
|
|
|
var dotnetNew = new NewCommand();
|
2016-06-14 20:20:29 +00:00
|
|
|
|
app.OnExecute(() =>
|
|
|
|
|
{
|
2015-12-26 01:46:33 +00:00
|
|
|
|
string languageValue = lang.Value() ?? csharp.Name;
|
|
|
|
|
|
|
|
|
|
var language = new[] { csharp, fsharp }
|
|
|
|
|
.FirstOrDefault(l => l.Alias.Contains(languageValue, StringComparer.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
if (language == null)
|
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine($"Unrecognized language: {languageValue}".Red());
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
string typeValue = type.Value() ?? language.Templates.First().Name;
|
2015-12-26 01:46:33 +00:00
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
var template = language.Templates.FirstOrDefault(t => StringComparer.OrdinalIgnoreCase.Equals(typeValue, t.Name));
|
|
|
|
|
if (template == null)
|
2015-12-26 01:46:33 +00:00
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine($"Unrecognized type: {typeValue}".Red());
|
2016-07-09 18:10:54 +00:00
|
|
|
|
Reporter.Error.WriteLine($"Available types for {language.Name} :".Red());
|
2015-12-26 01:46:33 +00:00
|
|
|
|
foreach (var t in language.Templates)
|
|
|
|
|
{
|
|
|
|
|
Reporter.Error.WriteLine($"- {t}".Red());
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
string templateDir = $"{language.TemplatePrefix}_{template.Name}";
|
2015-12-26 01:46:33 +00:00
|
|
|
|
|
2016-10-14 07:06:35 +00:00
|
|
|
|
return dotnetNew.CreateEmptyProject(language.Name, templateDir, template.isMsBuild);
|
2015-12-26 01:46:33 +00:00
|
|
|
|
});
|
2015-11-17 19:40:07 +00:00
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return app.Execute(args);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
2015-11-17 20:06:07 +00:00
|
|
|
|
Reporter.Error.WriteLine(ex.ToString());
|
2015-11-17 19:40:07 +00:00
|
|
|
|
#else
|
2015-11-17 20:06:07 +00:00
|
|
|
|
Reporter.Error.WriteLine(ex.Message);
|
2015-11-17 19:40:07 +00:00
|
|
|
|
#endif
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|