public void DeletedFileIsProcessed()
        {
            var filesToDelete = new FileSystemInfo[]
            {
                new FileInfo(@"TestFiles\Deletions\a.txt")
            };

            var actualDeletedFiles = new List <FileSystemInfo>();

            //Just simulate deletion so we can just check the list
            void Deletion(FileSystemInfo info) => actualDeletedFiles.Add(info);

            var writer = new ProjectWriter(Deletion, _ => { });

            Assert.IsTrue(writer.TryWrite(
                              new Project
            {
                FilePath  = new FileInfo(@"TestFiles\Deletions\Test1.csproj"),
                Deletions = filesToDelete.ToArray()
            },
                              false
                              ));

            CollectionAssert.AreEqual(filesToDelete, actualDeletedFiles);
        }
        public void DeletedNonEmptyFolderIsNotProcessed()
        {
            var filesToDelete = new FileSystemInfo[]
            {
                new DirectoryInfo(@"TestFiles\Deletions\NonEmptyFolder2")
            };

            var actualDeletedFiles = new List <FileSystemInfo>();

            //Just simulate deletion so we can just check the list
            void Deletion(FileSystemInfo info) => actualDeletedFiles.Add(info);

            var writer = new ProjectWriter(new ProjectWriteOptions {
                DeleteFileOperation = Deletion
            });

            Assert.IsTrue(writer.TryWrite(
                              new Project
            {
                FilePath  = new FileInfo(@"TestFiles\Deletions\Test4.csproj"),
                Deletions = filesToDelete.ToArray()
            }
                              ));

            CollectionAssert.AreEqual(new FileSystemInfo[0], actualDeletedFiles);
        }
        public void DeletedFolderIsProcessed()
        {
            //delete the dummy file we put in to make sure the folder was copied over
            File.Delete(@"TestFiles\Deletions\EmptyFolder\a.txt");

            var filesToDelete = new FileSystemInfo[]
            {
                new DirectoryInfo(@"TestFiles\Deletions\EmptyFolder")
            };

            var actualDeletedFiles = new List <FileSystemInfo>();

            //Just simulate deletion so we can just check the list
            void Deletion(FileSystemInfo info) => actualDeletedFiles.Add(info);

            var writer = new ProjectWriter(new ProjectWriteOptions {
                DeleteFileOperation = Deletion
            });

            Assert.IsTrue(writer.TryWrite(
                              new Project
            {
                FilePath  = new FileInfo(@"TestFiles\Deletions\Test2.csproj"),
                Deletions = filesToDelete.ToArray()
            }
                              ));

            CollectionAssert.AreEqual(filesToDelete, actualDeletedFiles);
        }
        public void DeletedNonEmptyFolderIsProcessedIfCleared()
        {
            var folder = @"TestFiles\Deletions\NonEmptyFolder";
            var file   = @"TestFiles\Deletions\NonEmptyFolder\a.txt";

            var filesToDelete = new FileSystemInfo[]
            {
                new FileInfo(file),
                new DirectoryInfo(folder)
            };

            var actualDeletedFiles = new List <FileSystemInfo>();

            //Just simulate deletion so we can just check the list
            void Deletion(FileSystemInfo info)
            {
                //need to actually delete this one so the folder can be deleted
                info.Delete();
                actualDeletedFiles.Add(info);
            }

            try
            {
                var writer = new ProjectWriter(new ProjectWriteOptions {
                    DeleteFileOperation = Deletion
                });

                Assert.IsTrue(writer.TryWrite(
                                  new Project
                {
                    FilePath  = new FileInfo(@"TestFiles\Deletions\Test3.csproj"),
                    Deletions = filesToDelete.ToArray()
                }
                                  ));

                CollectionAssert.AreEqual(filesToDelete, actualDeletedFiles);
            }
            finally
            {
                //Restore the directory and file back to how it was before test
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }

                if (!File.Exists(file))
                {
                    File.WriteAllBytes(file, new byte[0] {
                    });
                }
            }
        }
示例#5
0
        private void WizardModernize(IReadOnlyCollection <Project> projects, ITransformationSet transformationSet,
                                     ConversionOptions conversionOptions)
        {
            var transformations = transformationSet.CollectAndOrderTransformations(facility.Logger, conversionOptions);

            var doBackups = AskBinaryChoice("Would you like to create backups?");

            var writer = new ProjectWriter(facility.Logger, new ProjectWriteOptions {
                MakeBackups = doBackups
            });

            foreach (var project in projects)
            {
                using (facility.Logger.BeginScope(project.FilePath))
                {
                    var projectName = Path.GetFileNameWithoutExtension(project.FilePath.Name);
                    Log.Information("Modernizing {ProjectName}...", projectName);

                    if (!project.Valid)
                    {
                        Log.Error("Project {ProjectName} is marked as invalid, skipping...", projectName);
                        continue;
                    }

                    foreach (var transformation in transformations.WhereSuitable(project, conversionOptions))
                    {
                        try
                        {
                            transformation.Transform(project);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "Transformation {Item} has thrown an exception, skipping...",
                                      transformation.GetType().Name);
                        }
                    }

                    if (!writer.TryWrite(project))
                    {
                        continue;
                    }
                    Log.Information("Project {ProjectName} has been modernized", projectName);
                }
            }
        }
        public void ValidatesFileIsWritableProgram()
        {
            var writer = new ProjectWriter();

            var copiedProjectFile = Path.Combine("TestFiles", "OtherTestProjects", $"{nameof(ValidatesFileIsWritableProgram)}.readonly");

            if (File.Exists(copiedProjectFile))
            {
                File.SetAttributes(copiedProjectFile, FileAttributes.Normal);
                File.Delete(copiedProjectFile);
            }

            File.Copy(Path.Combine("TestFiles", "OtherTestProjects", "readonly.testcsproj"), copiedProjectFile);
            File.SetAttributes(copiedProjectFile, FileAttributes.ReadOnly);
            var project = new ProjectReader().Read(copiedProjectFile);

            Assert.IsFalse(writer.TryWrite(project));
        }
示例#7
0
        public void ValidatesFileIsWritableAfterCheckout()
        {
            var logs = new List <string>();

            var projectFile       = Path.Combine("TestFiles", "OtherTestProjects", "readonly.testcsproj");
            var copiedProjectFile = Path.Combine("TestFiles", "OtherTestProjects", $"{nameof(ValidatesFileIsWritableAfterCheckout)}.readonly");

            if (File.Exists(copiedProjectFile))
            {
                File.SetAttributes(copiedProjectFile, FileAttributes.Normal);
                File.Delete(copiedProjectFile);
            }

            try
            {
                File.Copy(projectFile, copiedProjectFile);

                File.SetAttributes(copiedProjectFile, FileAttributes.ReadOnly);

                var project = new ProjectReader().Read(copiedProjectFile);

                var projectWriter = new ProjectWriter(
                    new ProjectWriteOptions
                {
                    CheckoutOperation   = file => File.SetAttributes(file.FullName, FileAttributes.Normal),
                    DeleteFileOperation = _ => { }
                });

                Assert.IsTrue(projectWriter.TryWrite(project));

                Assert.IsFalse(logs.Any(x => x.Contains("Aborting as could not write to project file")));
            }
            finally
            {
                if (File.Exists(copiedProjectFile))
                {
                    File.SetAttributes(copiedProjectFile, FileAttributes.Normal);
                    File.Delete(copiedProjectFile);
                }
            }
        }
        private void WizardModernCleanUp(IReadOnlyList <Project> modern, ITransformationSet transformationSet,
                                         ConversionOptions conversionOptions)
        {
            var transformations = transformationSet.CollectAndOrderTransformations(facility.Logger, conversionOptions);

            var writer = new ProjectWriter(facility.Logger, new ProjectWriteOptions());

            foreach (var project in modern)
            {
                using (facility.Logger.BeginScope(project.FilePath))
                {
                    var projectName = Path.GetFileNameWithoutExtension(project.FilePath.Name);
                    Log.Information("Processing {ProjectName}...", projectName);

                    if (!project.Valid)
                    {
                        Log.Error("Project {ProjectName} is marked as invalid, skipping...", projectName);
                        continue;
                    }

                    foreach (var transformation in transformations.WhereSuitable(project, conversionOptions))
                    {
                        try
                        {
                            transformation.Transform(project);
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "Transformation {Item} has thrown an exception, skipping...",
                                      transformation.GetType().Name);
                        }
                    }

                    if (!writer.TryWrite(project))
                    {
                        continue;
                    }
                    Log.Information("Project {ProjectName} has been processed", projectName);
                }
            }
        }
        public void DeletedFileIsNotCheckedOut()
        {
            var filesToDelete = new FileSystemInfo[]
            {
                new FileInfo(Path.Combine(deletionsPath, "a.txt")),
                new FileInfo(Path.Combine(deletionsPath, "AssemblyInfo.txt"))
            };

            var assemblyInfoFile = new FileInfo(Path.Combine(deletionsPath, "AssemblyInfo.txt"));

            var actualDeletedFiles = new List <FileSystemInfo>();
            var checkedOutFiles    = new List <FileSystemInfo>();

            //Just simulate deletion so we can just check the list
            void Deletion(FileSystemInfo info) => actualDeletedFiles.Add(info);
            void Checkout(FileSystemInfo info) => checkedOutFiles.Add(info);

            var writer = new ProjectWriter(new ProjectWriteOptions {
                DeleteFileOperation = Deletion, CheckoutOperation = Checkout
            });

            Assert.IsTrue(writer.TryWrite(
                              new Project
            {
                FilePath           = new FileInfo(Path.Combine(deletionsPath, "Test1.csproj")),
                AssemblyAttributes = new AssemblyAttributes
                {
                    File    = assemblyInfoFile,
                    Company = "A Company"
                },
                Deletions = filesToDelete.ToArray()
            }
                              ));

            CollectionAssert.AreEqual(filesToDelete, actualDeletedFiles);
            CollectionAssert.DoesNotContain(checkedOutFiles, assemblyInfoFile);
        }
示例#10
0
        public void ValidatesFileIsWritable()
        {
            var projectFile       = Path.Combine("TestFiles", "OtherTestProjects", "readonly.testcsproj");
            var copiedProjectFile = Path.Combine("TestFiles", "OtherTestProjects", $"{nameof(ValidatesFileIsWritable)}.readonly");

            if (File.Exists(copiedProjectFile))
            {
                File.SetAttributes(copiedProjectFile, FileAttributes.Normal);
                File.Delete(copiedProjectFile);
            }

            try
            {
                File.Copy(projectFile, copiedProjectFile);

                File.SetAttributes(copiedProjectFile, FileAttributes.ReadOnly);

                var logger  = new DummyLogger();
                var project = new ProjectReader(logger).Read(copiedProjectFile);

                Assert.IsFalse(logger.LogEntries.Any(x => x.Contains("Aborting as could not write to project file")));

                var writer = new ProjectWriter(logger);

                Assert.IsFalse(writer.TryWrite(project));

                Assert.IsTrue(logger.LogEntries.Any(x => x.Contains("Aborting as could not write to project file")));
            }
            finally
            {
                if (File.Exists(copiedProjectFile))
                {
                    File.SetAttributes(copiedProjectFile, FileAttributes.Normal);
                    File.Delete(copiedProjectFile);
                }
            }
        }
示例#11
0
        /// <summary>
        /// Ports a list of projects
        /// </summary>
        /// <param name="projectPaths">List of projects paths</param>
        /// <param name="solutionPath">Path to solution file</param>
        /// <param name="targetFramework">Target framework to be used when porting</param>
        /// <param name="upgradeVersions">List of key/value pairs where key is package and value is version number</param>
        /// <returns>A PortingProjectFileResult object, representing the result of the porting operation</returns>
        public List <PortingResult> ApplyProjectChanges(
            List <string> projectPaths, string solutionPath, string targetFramework,
            Dictionary <string, string> upgradeVersions)
        {
            _logger.LogInformation("Applying porting changes to {0}", projectPaths);

            var results = new List <PortingResult>();
            var projectFilesNotFound = projectPaths.Where((path) => !File.Exists(path)).ToList();

            projectFilesNotFound.ForEach((path) => results.Add(new PortingResult
            {
                Message     = "File not found.",
                ProjectFile = path,
                ProjectName = Path.GetFileNameWithoutExtension(path),
                Success     = false
            }));

            var conversionOptions = new ConversionOptions
            {
                ForceOnUnsupportedProjects = true,
                ProjectCache     = new DefaultProjectCache(),
                TargetFrameworks = new List <string> {
                    targetFramework
                },
            };

            var(projects, _) = _facility.ParseProjects(new[] { solutionPath }, Vs16TransformationSet.Instance, conversionOptions);

            var selectedProjects = projects.Where(project => projectPaths.Contains(project.FilePath.FullName)).ToList();

            var writer = new ProjectWriter(_logger, writeOptions);

            foreach (var project in selectedProjects)
            {
                try
                {
                    project.PackageReferences = project.PackageReferences.Select(p =>
                                                                                 new PackageReference
                    {
                        Id      = p.Id,
                        Version = upgradeVersions.ContainsKey(p.Id) ? upgradeVersions[p.Id] : p.Version,
                        IsDevelopmentDependency = p.IsDevelopmentDependency,
                        DefinitionElement       = p.DefinitionElement
                    }).ToList();

                    if (writer.TryWrite(project))
                    {
                        results.Add(new PortingResult
                        {
                            Success     = true,
                            ProjectFile = project.FilePath.FullName,
                            ProjectName = project.ProjectName
                        });
                    }
                    else
                    {
                        results.Add(new PortingResult
                        {
                            Success     = false,
                            ProjectFile = project.FilePath.FullName,
                            ProjectName = project.ProjectName
                        });
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Project {Item} analysis has thrown an exception",
                                     project.ProjectName);

                    results.Add(new PortingResult
                    {
                        Success     = false,
                        ProjectFile = project.FilePath.FullName,
                        ProjectName = project.ProjectName,
                        Exception   = ex
                    });
                }
            }

            conversionOptions.ProjectCache?.Purge();

            _logger.LogInformation("Completed porting changes to {0}", projectPaths);

            return(results);
        }