Exemplo n.º 1
0
        public async Task ExecuteAsync(
            IProgress <double> progress,
            CancellationToken cancellationToken)
        {
            await Program.InitializeAsync(this).ConfigureAwait(false);

            Program.Log.Info("Test");
            Program.Log.Debug("Test");
            Program.Log.Warning("Test");
            Program.Log.Error("Test");

            var(workspace, solution) = await Program
                                       .GetWorkspaceAndSolution("C:/Users/Alexander/Documents/GitHub/ApertureLabs.Selenium/ApertureLabs.Selenium.sln")
                                       .ConfigureAwait(false);

            var originalProject = Program.GetProject(solution,
                                                     "MockServer",
                                                     FrameworkKind.Core);

            var destinationProject = Program.GetProject(solution,
                                                        //"DemoDotNetStandardLib",
                                                        "MockServer.PageObjects",
                                                        FrameworkKind.Standard);

            #region Compiling

            // Get the compiliation of the original project.
            var originalCompiliation    = default(Compilation);
            var destinationCompiliation = default(Compilation);

            try
            {
                originalCompiliation = await originalProject.GetCompilationAsync(cancellationToken)
                                       .ConfigureAwait(false);

                destinationCompiliation = await originalProject.GetCompilationAsync(cancellationToken)
                                          .ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Program.Log.Error("Failed to compile project " + originalProject.Name);
                Program.Log.Error("Failed to compile project " + destinationProject.Name);
                Program.Log.Error(e, true);
            }

            var controllers = originalCompiliation.Assembly.TypeNames.Where(
                t => t.EndsWith(
                    "Controller",
                    StringComparison.Ordinal));

            Program.Log.Info($"Successfully compiled {originalProject.Name}");
            Program.Log.Info($"Successfully compiled {destinationProject.Name}");

            #endregion

            #region Project info.

            originalProjectOutputPath = originalProject.OutputFilePath;

            LogSupportedChanges(workspace);

            Program.Log.Info("Original project info:");
            LogInfoOf(() => originalProject.OutputFilePath);
            LogInfoOf(() => originalProject.SupportsCompilation);

            #endregion

            #region Adding a new project.

            // Try and create a new project.
            //Program.Log.Info("Attempting to create a new project.");
            //var newProjectInfo = ProjectInfo.Create(
            //    ProjectId.CreateNewId(),
            //    VersionStamp.Default,
            //    "MockServer.Tests",
            //    "MockServer.Tests",
            //    LanguageNames.CSharp);

            //var invalidChangesSolution = solution.AddProject(newProjectInfo);
            //LogSupportedChanges(workspace);
            //LogSolutionChanges(invalidChangesSolution, solution);

            //// Try and apply changes.
            //try
            //{
            //    if (!workspace.TryApplyChanges(invalidChangesSolution))
            //        throw new Exception("Failed to modify the solution.");

            //    Program.Log.Info("Successfully added a project.");
            //    solution = invalidChangesSolution;
            //}
            //catch (Exception e)
            //{
            //    Program.Log.Error(e, false);
            //}

            #endregion

            #region Adding a document.

            // Commented this out because I know it works.
            // Try and add a document.
            //var addedDocument = destinationProject.AddDocument(
            //    name: "TestingAddDoc.txt",
            //    text: SourceText.From(
            //        String.Join(Environment.NewLine, new string[]
            //        {
            //            "using System;",
            //            "",
            //            "namespace MockServer.PageObjects",
            //            "{",
            //            "   internal class GeneratedClass",
            //            "   {",
            //            "       public string SomeProperty { get; set; }",
            //            "   }",
            //            "}",
            //        }),
            //        Encoding.UTF8));

            //LogSolutionChanges(addedDocument.Project.Solution, solution);

            //try
            //{
            //    if (!workspace.TryApplyChanges(addedDocument.Project.Solution))
            //        throw new Exception("Failed to add the document");

            //    Program.Log.Info("Successfully added the document.");
            //    solution = addedDocument.Project.Solution;
            //    destinationProject = addedDocument.Project;
            //}
            //catch (Exception e)
            //{
            //    Program.Log.Error(e, false);
            //}

            #endregion

            #region Removing a document.

            // Commented this out because it works.
            // Try and remove the document.
            //var addedDocument = destinationProject.Documents.FirstOrDefault(
            //    d => d.Name.Equals(
            //        "TestingAddDoc.cs",
            //        StringComparison.Ordinal));

            //if (addedDocument == null)
            //    throw new FileNotFoundException();

            //var modifiedSolution = destinationProject.RemoveDocument(addedDocument.Id);

            //LogSolutionChanges(destinationProject.Solution, solution);
            //Program.Log.Info("Attempting to remove the added document.");

            //try
            //{
            //    if (!workspace.TryApplyChanges(destinationProject.Solution))
            //        throw new Exception("Failed to remove the document");

            //    // Need to manually remove the file.
            //    File.Delete(addedDocument.FilePath);

            //    Program.Log.Info("Successfully removed the document.");
            //    solution = destinationProject.Solution;
            //}
            //catch (Exception e)
            //{
            //    Program.Log.Error(e, false);
            //}

            #endregion

            #region Loading the compiled assembly.

            var cancellationTokenSource = new CancellationTokenSource();
            var _progress = new Progress <CodeGenerationProgress>();
            //var loadContext = new PluginLoadContext(destinationProject.OutputFilePath);
            //var assembly = loadContext.LoadFromAssemblyPath(destinationProject.OutputFilePath);

            //var builder = new ContainerBuilder();
            //builder.RegisterAssemblyTypes(assembly);

            //var contianer = builder.Build();
            //var codeGenerators = contianer.Resolve<IEnumerable<ICodeGenerator>>();

            // Because reflection doesn't work that well as of 3/9/2019, need
            // to hard code in the code generators.
            var codeGenerators = new ICodeGenerator[]
            {
                new SeleniumCodeGenerator()
            };

            if (!codeGenerators.Any())
            {
                throw new Exception("No code generators located in the " +
                                    "destination assembly.");
            }

            foreach (var codeGenerator in codeGenerators)
            {
                // Generate the code.
                var modifiedDestProj = await codeGenerator.Generate(
                    originalProject,
                    destinationProject,
                    _progress,
                    cancellationToken)
                                       .ConfigureAwait(false);

                // Get list of changes.
                LogSolutionChanges(
                    modifiedDestProj.Solution,
                    destinationProject.Solution);

                // Prompt for accepting changes.
                Console.Write("Accept changes (Y/N): ");
                var response = Console.ReadLine();

                var isPositiveResponse = response.Equals("y", StringComparison.OrdinalIgnoreCase) ||
                                         response.Equals("yes", StringComparison.OrdinalIgnoreCase);

                if (!isPositiveResponse)
                {
                    // Exit if not applying the changes.
                    Program.Log.Info("Exiting program");
                    return;
                }

                // Apply changes.
                if (workspace.TryApplyChanges(modifiedDestProj.Solution))
                {
                    // Success.
                    Program.Log.Info("Applied changes successfully");
                }
                else
                {
                    // Error.
                    Program.Log.Error("Failed to apply changes.");
                }

                progress.Report(100);
            }

            #endregion
        }
        public async Task ExecuteAsync(
            IProgress <double> progress,
            CancellationToken cancellationToken)
        {
            await Program.InitializeAsync(this).ConfigureAwait(false);

            var(workspace, solution) = await Program
                                       .GetWorkspaceAndSolution(PathToSolution)
                                       .ConfigureAwait(false);

            Program.LogSupportedChanges(workspace);

            if (!Enum.TryParse(typeof(FrameworkKind),
                               OriginalProjectKind,
                               out var originalFrameworkKind))
            {
                throw new InvalidCastException("The argument " +
                                               "original-framework-kind had an invalid value.");
            }

            if (!Enum.TryParse(typeof(FrameworkKind),
                               DestinationProjectKind,
                               out var destinationProjectKind))
            {
                throw new InvalidCastException("The argument " +
                                               "destination-framework-kind had an invalid value");
            }

            // Retrieve original and destination projects.
            var originalProject = Program.GetProject(solution,
                                                     OriginalProjectName,
                                                     (FrameworkKind)originalFrameworkKind);
            var destinationProject = Program.GetProject(
                solution,
                DestinationProjectName,
                (FrameworkKind)destinationProjectKind);

            Program.Log.Info($"Original project: {originalProject.Name}");
            Program.Log.Info($"Destination project: {destinationProject.Name}");

            // Compile original project.
            //var compilation = await originalProject.GetCompilationAsync()
            //    .ConfigureAwait(false);

            // TODO: Allow loading code generators via reflection.
            var codeGenerators = new ICodeGenerator[]
            {
                new SeleniumCodeGenerator()
            };

            if (!codeGenerators.Any())
            {
                throw new Exception("No code generators located in the " +
                                    "destination assembly.");
            }

            var _progress = new Progress <CodeGenerationProgress>();

            foreach (var codeGenerator in codeGenerators)
            {
                // Generate the code.
                var modifiedDestProj = await codeGenerator.Generate(
                    originalProject,
                    destinationProject,
                    _progress,
                    cancellationToken)
                                       .ConfigureAwait(false);

                // Get list of changes.
                Program.LogSolutionChanges(
                    modifiedDestProj.Solution,
                    destinationProject.Solution);

                // Just print out changes if doing a dry run.
                if (DryRun)
                {
                    continue;
                }

                // Prompt for accepting changes.
                Console.Write("Accept changes (Y/N): ");
                var response = Console.ReadLine();

                var isPositiveResponse = response.Equals("y", StringComparison.OrdinalIgnoreCase) ||
                                         response.Equals("yes", StringComparison.OrdinalIgnoreCase);

                if (!isPositiveResponse)
                {
                    // Exit if not applying the changes.
                    Program.Log.Info("Exiting program");
                    return;
                }

                // Apply changes.
                if (workspace.TryApplyChanges(modifiedDestProj.Solution))
                {
                    // Success.
                    Program.Log.Info("Applied changes successfully");
                }
                else
                {
                    // Error.
                    Program.Log.Error("Failed to apply changes.");
                }

                progress.Report(100);
            }
        }