From c45345c7f021a3ae9e643419fd9b16d4a64c8e0e Mon Sep 17 00:00:00 2001 From: Mark Stafford Date: Wed, 27 Jul 2016 15:49:51 +0800 Subject: [PATCH] Adds CheckDependencies command --- RESTier.CLI/App.config | 2 +- RESTier.CLI/CommandExecutor.cs | 9 +- RESTier.CLI/Commands/BuildCommand.cs | 2 +- .../Commands/CheckDependenciesCommand.cs | 100 ++++++++++++++++++ RESTier.CLI/Commands/GenerateCommand.cs | 2 - RESTier.CLI/ConsoleHelper.cs | 8 +- RESTier.CLI/Dependency.cs | 13 +++ RESTier.CLI/Program.cs | 25 +++++ RESTier.CLI/RESTier.CLI.csproj | 2 + 9 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 RESTier.CLI/Commands/CheckDependenciesCommand.cs create mode 100644 RESTier.CLI/Dependency.cs diff --git a/RESTier.CLI/App.config b/RESTier.CLI/App.config index b565f2e..83109b0 100644 --- a/RESTier.CLI/App.config +++ b/RESTier.CLI/App.config @@ -3,7 +3,7 @@ - + diff --git a/RESTier.CLI/CommandExecutor.cs b/RESTier.CLI/CommandExecutor.cs index 45c3c15..31b33ee 100644 --- a/RESTier.CLI/CommandExecutor.cs +++ b/RESTier.CLI/CommandExecutor.cs @@ -26,8 +26,12 @@ public static CommandLineApplication Create(ref string[] args) app.Option("-c|--connectionstring", "A connection string to a SQL Server database. Used to reverse engineer a RESTier API.", CommandOptionType.SingleValue); + var downloadOption = app.Option("-d|--download", + "Automatically downloads dependencies and places in child folder.", + CommandOptionType.NoValue); - app.Command("new", c => NewCommand.Configure(c)); + var checkDependenciesCommand = app.Command("dependencies", c => CheckDependenciesCommand.Configure(c)); + var newCommand = app.Command("new", c => NewCommand.Configure(c)); app.Command("generate", c => GenerateCommand.Configure(c)); app.Command("build", c => BuildCommand.Configure(c)); app.Command("run", c => RunCommand.Configure(c)); @@ -54,7 +58,8 @@ public static CommandLineApplication Create(ref string[] args) ConsoleHelper.WriteLine(string.Format("Creating new RESTier API for {0}.", connectionStringBuilder.InitialCatalog + connectionStringBuilder.AttachDBFilename)); - app.Commands.First(c => c.Name == "new").Execute(); + checkDependenciesCommand.Execute(); + newCommand.Execute(); return 0; }); diff --git a/RESTier.CLI/Commands/BuildCommand.cs b/RESTier.CLI/Commands/BuildCommand.cs index a1167ff..3002f7f 100644 --- a/RESTier.CLI/Commands/BuildCommand.cs +++ b/RESTier.CLI/Commands/BuildCommand.cs @@ -71,7 +71,7 @@ private static void CmdMSBuild(string projectName, string buildSetting) p.StartInfo.UseShellExecute = false; - p.StartInfo.Arguments = "/c " + "\"" + Path.Combine(ConfigurationManager.AppSettings["MSBuildPath"], "MSBuild.exe") + "\" " + projectName + + p.StartInfo.Arguments = "/c " + "\"" + ConfigurationManager.AppSettings["msbuild"] + "\" " + projectName + (string.IsNullOrEmpty(buildSetting) ? "" : " " + buildSetting); p.Start(); diff --git a/RESTier.CLI/Commands/CheckDependenciesCommand.cs b/RESTier.CLI/Commands/CheckDependenciesCommand.cs new file mode 100644 index 0000000..e27a2e0 --- /dev/null +++ b/RESTier.CLI/Commands/CheckDependenciesCommand.cs @@ -0,0 +1,100 @@ +using System; +using System.Configuration; +using System.Diagnostics; +using System.IO; +using System.Net; +using Microsoft.Extensions.CommandLineUtils; + +namespace Microsoft.RESTier.Cli.Commands +{ + public class CheckDependenciesCommand + { + public static void Configure(CommandLineApplication command) + { + command.Description = "Determines whether dependencies are accessible to RESTier.exe"; + + command.OnExecute(() => + { + ConsoleHelper.WriteVerbose("Checking dependencies."); + var downloadDependencies = command.Parent.Options.Exists(o => o.LongName == "download"); + var dependencies = new[] + { + new Dependency + { + Name = "msbuild", + Path = ConfigurationManager.AppSettings["msbuild"], + DownloadInstructionsUri = "https://www.microsoft.com/en-us/download/details.aspx?id=40760", + DownloadInstallerUri = + "https://download.microsoft.com/download/9/B/B/9BB1309E-1A8F-4A47-A6C5-ECF76672A3B3/BuildTools_Full.exe", + FileName = "msbuild.exe", + InstallerExe = "BuildTools_Full.exe", + InstallerArgs = "/Q /Layout {dependencypath}" + } + }; + foreach (var dependency in dependencies) + { + if (!DependencyExists(dependency)) + { + if (downloadDependencies) + { + DownloadDependency(dependency); + } + else + { + return -1; + } + } + } + return 0; + }); + } + + private static void DownloadDependency(Dependency dependency) + { + string directoryPath = Path.Combine(Directory.GetCurrentDirectory(), "dependencies", dependency.Name); + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + ConsoleHelper.WriteVerbose("Downloading {0}.", dependency.Name); + try + { + var dependencyPath = Path.Combine(directoryPath, dependency.InstallerExe); + var webClient = new WebClient(); + webClient.DownloadFile(dependency.DownloadInstallerUri, dependencyPath); + dependency.InstallerArgs = dependency.InstallerArgs.Replace("{dependencypath}", + directoryPath); + Process.Start(dependencyPath, dependency.InstallerArgs); + } + catch (Exception ex) + { + ConsoleHelper.WriteError(ex.Message + ex.InnerException.Message); + } + } + + private static bool DependencyExists(Dependency dependency) + { + ConsoleHelper.WriteVerbose("Checking for {0}.", dependency.Name); + + ConsoleHelper.WriteVerbose("Checking for {0} at {1}.", dependency.Name, dependency.Path); + if (File.Exists(dependency.Path)) + { + ConsoleHelper.WriteVerbose("Found {0} at {1}.", dependency.Name, dependency.Path); + return true; + } + + // TODO #5: Place static strings into a centralized place. + var alternatePath = Path.Combine("dependencies", dependency.Name, Path.GetFileName(dependency.Path)); + if (File.Exists(alternatePath)) + { + ConsoleHelper.WriteVerbose("Found {0} at {1}.", dependency.Name, alternatePath); + return true; + } + + ConsoleHelper.WriteError( + "Could not locate {0}. You can manually download and install this dependency by following the instructions here: {1}", + dependency.Name, dependency.DownloadInstructionsUri); + return false; + } + } +} \ No newline at end of file diff --git a/RESTier.CLI/Commands/GenerateCommand.cs b/RESTier.CLI/Commands/GenerateCommand.cs index 905a51f..4cdd2db 100644 --- a/RESTier.CLI/Commands/GenerateCommand.cs +++ b/RESTier.CLI/Commands/GenerateCommand.cs @@ -9,8 +9,6 @@ public static void Configure(CommandLineApplication command) { command.Description = "Reverse engineers a data access layer from a database."; - command.Option("-c|--connection-string", "The connection string to connect to the database.", - CommandOptionType.SingleValue); command.Option("-p|--project", "The name for the RESTier project", CommandOptionType.SingleValue); command.HelpOption("-h|--help"); diff --git a/RESTier.CLI/ConsoleHelper.cs b/RESTier.CLI/ConsoleHelper.cs index ac514c7..0c93753 100644 --- a/RESTier.CLI/ConsoleHelper.cs +++ b/RESTier.CLI/ConsoleHelper.cs @@ -51,19 +51,19 @@ private static void WritePretty(ConsoleColor color, Action action, strin } } - public static void Verbose(string message) + public static void WriteVerbose(string message, params object[] args) { if (IsVerbose) { - WriteLine(message); + WriteLine(ConsoleColor.Yellow, message, args); } } public void WriteTrace(string message) - => Verbose(message); + => WriteVerbose(message); public void WriteDebug(string message) - => Verbose(message); + => WriteVerbose(message); public void WriteInformation(string message) => WriteLine(message); diff --git a/RESTier.CLI/Dependency.cs b/RESTier.CLI/Dependency.cs new file mode 100644 index 0000000..ee78fbd --- /dev/null +++ b/RESTier.CLI/Dependency.cs @@ -0,0 +1,13 @@ +namespace Microsoft.RESTier.Cli +{ + internal class Dependency + { + public string Name { get; set; } + public string Path { get; set; } + public string FileName { get; set; } + public string DownloadInstructionsUri { get; set; } + public string DownloadInstallerUri { get; set; } + public string InstallerExe { get; set; } + public string InstallerArgs { get; set; } + } +} \ No newline at end of file diff --git a/RESTier.CLI/Program.cs b/RESTier.CLI/Program.cs index 0c5dec0..eeaf53a 100644 --- a/RESTier.CLI/Program.cs +++ b/RESTier.CLI/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Reflection; @@ -10,6 +11,8 @@ public static int Main(string[] args) { ConsoleHelper.IsVerbose = HandleVerboseOption(ref args); + HandleDebugSwitch(ref args); + try { return CommandExecutor.Create(ref args).Execute(args); @@ -39,5 +42,27 @@ private static bool HandleVerboseOption(ref string[] args) } return false; } + + + [Conditional("DEBUG")] + private static void HandleDebugSwitch(ref string[] args) + + { + for (var i = 0; i < args.Length; i++) + + { + if (args[i] == "--debug") + + { + args = args.Take(i).Concat(args.Skip(i + 1)).ToArray(); + + Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue"); + + Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); + + Console.ReadLine(); + } + } + } } } \ No newline at end of file diff --git a/RESTier.CLI/RESTier.CLI.csproj b/RESTier.CLI/RESTier.CLI.csproj index e5b6367..bf64c63 100644 --- a/RESTier.CLI/RESTier.CLI.csproj +++ b/RESTier.CLI/RESTier.CLI.csproj @@ -62,7 +62,9 @@ + + True