From 76b595c5cbe2f1e488580db3e3795a790e2c668d Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Sun, 1 Mar 2020 16:53:05 -0800 Subject: [PATCH] remove duplicated commands --- src/opulence/dotnet-opulence/DeployCommand.cs | 137 ------------- src/opulence/dotnet-opulence/InitCommand.cs | 193 ------------------ src/opulence/dotnet-opulence/Program.cs | 79 +------ src/tye/Program.DeployCommand.cs | 4 +- src/tye/Program.cs | 1 + 5 files changed, 6 insertions(+), 408 deletions(-) delete mode 100644 src/opulence/dotnet-opulence/DeployCommand.cs delete mode 100644 src/opulence/dotnet-opulence/InitCommand.cs diff --git a/src/opulence/dotnet-opulence/DeployCommand.cs b/src/opulence/dotnet-opulence/DeployCommand.cs deleted file mode 100644 index 2ddd398d..00000000 --- a/src/opulence/dotnet-opulence/DeployCommand.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Invocation; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using Tye; - -namespace Opulence -{ - internal static class DeployCommand - { - public static Command Create() - { - var command = new Command("deploy", "Deploy the application to Kubernetes") - { - StandardOptions.Project, - StandardOptions.Verbosity, - StandardOptions.Environment, - }; - - command.Handler = CommandHandler.Create((console, project, environment, verbosity) => - { - return ExecuteAsync(new OutputContext(console, verbosity), project, environment); - }); - - return command; - } - - private static async Task ExecuteAsync(OutputContext output, FileInfo projectFile, string environment) - { - output.WriteBanner(); - - var application = await ApplicationFactory.CreateApplicationAsync(output, projectFile); - if (application.Globals.Registry?.Hostname == null) - { - throw new CommandException("A registry is required for deploy operations. run 'dotnet-opulence init'."); - } - - var steps = new List() - { - new CombineStep() { Environment = environment, }, - new BuildDockerImageStep() { Environment = environment, }, - new PushDockerImageStep() { Environment = environment, }, - }; - - if (application.Globals.DeploymentKind == DeploymentKind.None) - { - // No extra steps - } - else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes) - { - steps.Add(new GenerateKubernetesManifestStep() { Environment = environment, }); - } - else if (application.Globals.DeploymentKind == DeploymentKind.Oam) - { - steps.Add(new GenerateOamComponentStep() { Environment = environment, }); - } - else - { - throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind); - } - - // If this is command is for a project, then deploy the component manifest - // for just the project. We won't run the "application deploy" part. - if (!string.Equals(".sln", projectFile.Extension, StringComparison.Ordinal)) - { - steps.Add(new DeployServiceYamlStep() { Environment = environment, }); - } - - var executor = new ServiceExecutor(output, application, steps); - foreach (var service in application.Services) - { - if (service.IsMatchForProject(application, projectFile)) - { - await executor.ExecuteAsync(service); - } - } - - if (string.Equals(".sln", projectFile.Extension, StringComparison.Ordinal)) - { - await PackageApplicationAsync(output, application, Path.GetFileNameWithoutExtension(projectFile.Name), environment); - } - } - - private static async Task PackageApplicationAsync(OutputContext output, Application application, string applicationName, string environment) - { - using var step = output.BeginStep("Deploying Application Manifests..."); - - using var tempFile = TempFile.Create(); - output.WriteInfoLine($"Writing output to '{tempFile.FilePath}'."); - - { - using var stream = File.OpenWrite(tempFile.FilePath); - using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true); - - if (application.Globals.DeploymentKind == DeploymentKind.None) - { - // No extra steps - } - else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes) - { - await ApplicationYamlWriter.WriteAsync(output, writer, application); - } - else if (application.Globals.DeploymentKind == DeploymentKind.Oam) - { - await OamApplicationGenerator.WriteOamApplicationAsync(writer, output, application, applicationName, environment); - } - else - { - throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind); - } - } - - output.WriteDebugLine("Running 'kubectl apply'."); - output.WriteCommandLine("kubectl", $"apply -f \"{tempFile.FilePath}\""); - var capture = output.Capture(); - var exitCode = await Process.ExecuteAsync( - $"kubectl", - $"apply -f \"{tempFile.FilePath}\"", - System.Environment.CurrentDirectory, - stdOut: capture.StdOut, - stdErr: capture.StdErr); - - output.WriteDebugLine($"Done running 'kubectl apply' exit code: {exitCode}"); - if (exitCode != 0) - { - throw new CommandException("'kubectl apply' failed."); - } - - output.WriteInfoLine($"Deployed application '{applicationName}'."); - - step.MarkComplete(); - } - } -} diff --git a/src/opulence/dotnet-opulence/InitCommand.cs b/src/opulence/dotnet-opulence/InitCommand.cs deleted file mode 100644 index b5174e91..00000000 --- a/src/opulence/dotnet-opulence/InitCommand.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Invocation; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Build.Construction; - -namespace Opulence -{ - internal static class InitCommand - { - public static Command Create() - { - var command = new Command("init", "Initialize repo") - { - StandardOptions.Verbosity, - new Option(new[] { "-d", "--directory", }, "Directory to Initialize") - { - Argument = new Argument(() => - { - return new DirectoryInfo(Environment.CurrentDirectory); - }).ExistingOnly(), - }, - }; - - command.Handler = CommandHandler.Create((console, verbosity, directory) => - { - var output = new OutputContext(console, verbosity); - return ExecuteAsync(output, directory); - }); - - return command; - } - - private static async Task ExecuteAsync(OutputContext output, DirectoryInfo directory) - { - output.WriteBanner(); - - string? solutionFilePath = null; - string? opulenceFilePath = null; - - using (var step = output.BeginStep("Looking For Existing Config...")) - { - opulenceFilePath = DirectorySearch.AscendingSearch(directory.FullName, "Opulence.csx"); - if (opulenceFilePath != null) - { - output.WriteInfoLine($"Found 'Opulence.csx' at '{opulenceFilePath}'"); - step.MarkComplete(); - return; - } - else - { - output.WriteInfoLine("Not Found"); - step.MarkComplete(); - } - } - - using (var step = output.BeginStep("Looking For .sln File...")) - { - solutionFilePath = DirectorySearch.AscendingWildcardSearch(directory.FullName, "*.sln").FirstOrDefault()?.FullName; - if (opulenceFilePath == null && - solutionFilePath != null && - output.Confirm($"Use '{Path.GetDirectoryName(solutionFilePath)}' as Root?")) - { - opulenceFilePath = Path.Combine(Path.GetDirectoryName(solutionFilePath)!, "Opulence.csx"); - step.MarkComplete(); - } - else - { - output.WriteInfoLine("Not Found."); - step.MarkComplete(); - } - } - - if (opulenceFilePath == null && - Path.GetFullPath(directory.FullName) != Path.GetFullPath(Environment.CurrentDirectory)) - { - // User specified a directory other than the current one - using (var step = output.BeginStep("Trying Project Directory...")) - { - if (output.Confirm("Use Project Directory as Root?")) - { - opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx"); - } - - step.MarkComplete(); - } - } - - if (opulenceFilePath == null) - { - using (var step = output.BeginStep("Trying Current Directory...")) - { - if (output.Confirm("Use Current Directory as Root?")) - { - opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx"); - } - - step.MarkComplete(); - } - } - - if (opulenceFilePath == null) - { - throw new CommandException("Cannot Determine Root Directory."); - } - - using (var step = output.BeginStep("Writing Opulence.csx ...")) - { - var hostname = output.Prompt("Enter the Container Registry (ex: 'example.azurecr.io' for Azure or 'example' for dockerhub)"); - - var services = new List<(string, string)>(); - if (solutionFilePath != null && output.Confirm($"Use solution file '{solutionFilePath}' to initialize services?")) - { - services.AddRange(ReadServicesFromSolution(solutionFilePath)); - services.Sort((a, b) => a.Item1.CompareTo(b.Item1)); - } - - using var stream = File.OpenWrite(opulenceFilePath); - using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true); - - await WriteOpulenceConfigAsync(writer, hostname, services); - - output.WriteInfoLine($"Initialized Opulence Config at '{opulenceFilePath}'."); - step.MarkComplete(); - } - } - - private static IEnumerable<(string, string)> ReadServicesFromSolution(string solutionFilePath) - { - SolutionFile solution; - try - { - solution = SolutionFile.Parse(solutionFilePath); - } - catch (Exception ex) - { - throw new CommandException($"Parsing solution file '{solutionFilePath}' failed.", ex); - } - - for (var i = 0; i < solution.ProjectsInOrder.Count; i++) - { - var project = solution.ProjectsInOrder[i]; - if (string.Equals(Path.GetExtension(project.RelativePath), ".csproj", StringComparison.Ordinal)) - { - var fileName = Path.GetFileNameWithoutExtension(project.RelativePath.Replace('\\', Path.DirectorySeparatorChar)); - - yield return (Names.NormalizeToFriendly(fileName), Names.NormalizeToDns(fileName)); - } - } - } - - private static async Task WriteOpulenceConfigAsync(TextWriter writer, string hostname, List<(string, string)> services) - { - await writer.WriteLineAsync("#r \"Opulence\""); - await writer.WriteLineAsync(); - - await writer.WriteLineAsync($"using Opulence;"); - await writer.WriteLineAsync(); - - await writer.WriteLineAsync($"public class Application"); - await writer.WriteLineAsync($"{{"); - await writer.WriteLineAsync($" public ApplicationGlobals Globals {{ get; }} = new ApplicationGlobals()"); - await writer.WriteLineAsync($" {{"); - await writer.WriteLineAsync($" Registry = new ContainerRegistry(\"{hostname}\"),"); - await writer.WriteLineAsync($" }};"); - await writer.WriteLineAsync(); - - await writer.WriteLineAsync($" // Define more services and dependencies here as your application grows."); - for (var i = 0; i < services.Count; i++) - { - await writer.WriteLineAsync($" public Service {services[i].Item1} {{ get; }} = new Service(\"{services[i].Item2}\");"); - - if (i + 1 < services.Count) - { - await writer.WriteLineAsync(); - } - } - - await writer.WriteLineAsync($"}}"); - await writer.WriteLineAsync(); - - await writer.WriteLineAsync($"Pipeline.Configure(app =>"); - await writer.WriteLineAsync($"{{"); - await writer.WriteLineAsync($" // Configure your service bindings here with code."); - await writer.WriteLineAsync($"}});"); - } - } -} diff --git a/src/opulence/dotnet-opulence/Program.cs b/src/opulence/dotnet-opulence/Program.cs index 03dd35f6..c2ad6668 100644 --- a/src/opulence/dotnet-opulence/Program.cs +++ b/src/opulence/dotnet-opulence/Program.cs @@ -1,82 +1,9 @@ -using System; -using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Help; -using System.CommandLine.Invocation; -using System.CommandLine.IO; -using System.CommandLine.Parsing; -using System.CommandLine.Rendering; -using System.Threading.Tasks; - namespace Opulence { - class Program + static class Program { - static async Task Main(string[] args) + public static void Main() { - var command = new RootCommand(); - command.AddCommand(InitCommand.Create()); - command.AddCommand(GenerateCommand.Create()); - command.AddCommand(PackageCommand.Create()); - command.AddCommand(PushCommand.Create()); - command.AddCommand(DeployCommand.Create()); - - command.Description = "White-Glove Service for .NET and Kubernetes"; - command.Handler = CommandHandler.Create(help => - { - help.Write(command); - return 1; - }); - - var builder = new CommandLineBuilder(command); - - // Parsing behavior - builder.UseHelp(); - builder.UseVersionOption(); - builder.UseDebugDirective(); - builder.UseParseErrorReporting(); - builder.ParseResponseFileAs(ResponseFileHandling.ParseArgsAsSpaceSeparated); - builder.UsePrefixes(new[] { "-", "--", }); // disable garbage windows conventions - - builder.CancelOnProcessTermination(); - builder.UseExceptionHandler(HandleException); - - // Allow fancy drawing. - builder.UseAnsiTerminalWhenAvailable(); - - var parser = builder.Build(); - return await parser.InvokeAsync(args); - } - - private static void HandleException(Exception exception, InvocationContext context) - { - context.Console.ResetTerminalForegroundColor(); - context.Console.SetTerminalForegroundColor(ConsoleColor.Red); - - if (exception is OperationCanceledException) - { - context.Console.Error.WriteLine("Oh dear! Operation canceled."); - } - else if (exception is CommandException command) - { - context.Console.Error.WriteLine($"Drats! '{context.ParseResult.CommandResult.Command.Name}' failed:"); - context.Console.Error.WriteLine($"\t{command.Message}"); - - if (command.InnerException != null) - { - context.Console.Error.WriteLine(); - context.Console.Error.WriteLine(command.InnerException.ToString()); - } - } - else - { - context.Console.Error.WriteLine("An unhandled exception has occurred, how unseemly: "); - context.Console.Error.WriteLine(exception.ToString()); - } - - context.Console.ResetTerminalForegroundColor(); - - context.ResultCode = 1; } } -} +} \ No newline at end of file diff --git a/src/tye/Program.DeployCommand.cs b/src/tye/Program.DeployCommand.cs index 7186414a..5525a176 100644 --- a/src/tye/Program.DeployCommand.cs +++ b/src/tye/Program.DeployCommand.cs @@ -99,10 +99,10 @@ namespace Tye await executor.ExecuteAsync(service); } - await PackageApplicationAsync(output, opulenceApplication, application.Source.Directory.Name, environment); + await DeployApplicationManifestAsync(output, opulenceApplication, application.Source.Directory.Name, environment); } - private static async Task PackageApplicationAsync(OutputContext output, Opulence.Application application, string applicationName, string environment) + private static async Task DeployApplicationManifestAsync(OutputContext output, Opulence.Application application, string applicationName, string environment) { using var step = output.BeginStep("Deploying Application Manifests..."); diff --git a/src/tye/Program.cs b/src/tye/Program.cs index d452b9c6..53ccbec4 100644 --- a/src/tye/Program.cs +++ b/src/tye/Program.cs @@ -20,6 +20,7 @@ namespace Tye }; command.AddCommand(CreateInitCommand()); + command.AddCommand(CreateGenerateCommand()); command.AddCommand(CreateRunCommand(args)); command.AddCommand(CreateDeployCommand());