예제 #1
0
        /// <summary>
        /// Visists a project.
        /// </summary>
        /// <param name="directory">The directory of the project.</param>
        /// <param name="config">The <see cref="GitDependFile"/> with project configuration information.</param>
        /// <returns>The return code.</returns>
        public ReturnCode VisitProject(string directory, GitDependFile config)
        {
            if (config == null)
            {
                return(ReturnCode = ReturnCode.Success);
            }

            // If there are specific dependencies specified
            // and this one isn't in the list
            // skip it.
            if (_whitelist.Any() &&
                _whitelist.All(d => !string.Equals(d, config.Name, StringComparison.InvariantCultureIgnoreCase)))
            {
                return(ReturnCode.Success);
            }

            if (string.IsNullOrEmpty(directory) || !_fileSystem.Directory.Exists(directory))
            {
                return(ReturnCode = ReturnCode.DirectoryDoesNotExist);
            }

            StringBuilder commitMessage = new StringBuilder();

            commitMessage.AppendLine("GitDepend: updating dependencies");
            commitMessage.AppendLine();

            var solutions = _fileSystem.Directory.GetFiles(directory, "*.sln", SearchOption.AllDirectories);

            foreach (var solution in solutions)
            {
                _nuget.Restore(solution);
            }

            foreach (var solution in solutions)
            {
                var path = solution.Remove(0, directory.Length + 1);
                commitMessage.AppendLine(path);

                foreach (var dependency in config.Dependencies)
                {
                    // If there are specific dependencies specified
                    // and this one isn't in the list
                    // skip it.
                    if (_whitelist.Any() &&
                        _whitelist.All(d => !string.Equals(d, dependency.Configuration.Name, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        continue;
                    }

                    var dependencyDir = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(directory, dependency.Directory));
                    var dir           = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(dependencyDir, dependency.Configuration.Packages.Directory));

                    foreach (var file in _fileSystem.Directory.GetFiles(dir, "*.nupkg"))
                    {
                        var name = _fileSystem.Path.GetFileNameWithoutExtension(file);


                        if (string.IsNullOrEmpty(name))
                        {
                            continue;
                        }

                        var match = Pattern.Match(name);

                        if (!match.Success)
                        {
                            continue;
                        }

                        var id      = match.Groups["id"].Value;
                        var version = match.Groups["version"].Value;

                        commitMessage.AppendLine($"* {id}.{version}");

                        _nuget.WorkingDirectory = directory;

                        var cacheDir = GetCacheDirectory();

                        if (string.IsNullOrEmpty(cacheDir))
                        {
                            return(ReturnCode = ReturnCode.CouldNotCreateCacheDirectory);
                        }

                        _nuget.Update(solution, id, version, cacheDir);

                        var package = $"{id}.{version}";
                        if (!UpdatedPackages.Contains(package))
                        {
                            UpdatedPackages.Add(package);
                        }
                    }
                }
            }

            _console.WriteLine("================================================================================");
            _console.WriteLine($"Making update commit on {directory}");
            _git.WorkingDirectory = directory;
            _git.Add("*.csproj", @"*\packages.config");
            _console.WriteLine("================================================================================");
            _git.Status();

            _git.Commit(commitMessage.ToString());

            return(ReturnCode = ReturnCode.Success);
        }
        /// <summary>
        /// Visists a project.
        /// </summary>
        /// <param name="directory">The directory of the project.</param>
        /// <param name="config">The <see cref="GitDependFile"/> with project configuration information.</param>
        /// <returns>The return code.</returns>
        public ReturnCode VisitProject(string directory, GitDependFile config)
        {
            if (config == null)
            {
                return(ReturnCode = ReturnCode.Success);
            }

            if (string.IsNullOrEmpty(directory) || !_fileSystem.Directory.Exists(directory))
            {
                return(ReturnCode = ReturnCode.DirectoryDoesNotExist);
            }

            foreach (var dependency in config.Dependencies)
            {
                var dependencyDir = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(directory, dependency.Directory));
                var dir           = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(dependencyDir, dependency.Configuration.Packages.Directory));

                foreach (var file in _fileSystem.Directory.GetFiles(dir, "*.nupkg"))
                {
                    var name = _fileSystem.Path.GetFileNameWithoutExtension(file);


                    if (string.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    var match = Pattern.Match(name);

                    if (!match.Success)
                    {
                        continue;
                    }

                    var id      = match.Groups["id"].Value;
                    var version = match.Groups["version"].Value;

                    _nuget.WorkingDirectory = directory;

                    foreach (var solution in _fileSystem.Directory.GetFiles(directory, "*.sln", SearchOption.AllDirectories))
                    {
                        var cacheDir = GetCacheDirectory();

                        if (string.IsNullOrEmpty(cacheDir))
                        {
                            return(ReturnCode = ReturnCode.CouldNotCreateCacheDirectory);
                        }

                        _nuget.Restore(solution);
                        _nuget.Update(solution, id, version, cacheDir);
                    }
                }
            }

            _console.WriteLine("================================================================================");
            _console.WriteLine($"Making update commit on {directory}");
            _git.WorkingDirectory = directory;
            _git.Add("*.csproj", @"*\packages.config");
            _console.WriteLine("================================================================================");
            _git.Status();
            _git.Commit("GitDepend: updating dependencies");

            return(ReturnCode = ReturnCode.Success);
        }
예제 #3
0
        public void Run()
        {
            _git.EnsureIsClean();

            var(wasFound, oldProjectPath, solutionFolderPath) = findProject();
            if (!wasFound)
            {
                _errors.Handle($"{_configuration.OldProjectName} cannot be found in the solution");
            }

            var oldDir  = Path.GetDirectoryName(oldProjectPath);
            var newBase = _configuration.NewProjectName.Any(CommonExtensions.IsDirectorySeparator)
                ? CurrentDirectoryAbsolute
                : Path.GetDirectoryName(oldDir);
            var newDir         = _configuration.NewProjectName.ToAbsolutePath(newBase);
            var newFileName    = Path.GetFileName(_configuration.NewProjectName);
            var newProjectPath = Path.Combine(newDir, $"{newFileName}{Constants.ProjectFileExtension}");
            var isPaketUsed    = _filesystem.DoesDirectoryExist(".paket");
            var gitVersion     = _git.GetVersion();

            if (!_configuration.DontReviewSettings)
            {
                var lines = new[]
                {
                    "Please review the following settings:",
                    $"Project:                   {_configuration.OldProjectName}",
                    $"found at:                  {oldProjectPath}",
                    $"Rename to:                 {newFileName}",
                    $"at:                        {newProjectPath}",
                    $"VS Solution folder:        {solutionFolderPath ?? "none"}",
                    $"exclude:                   {_configuration.ExcludedDirectory}",
                    $"Paket in use:              {isPaketUsed.AsText()}",
                    $"Run paket install:         {(!_configuration.DontRunPaketInstall).AsText()}",
                    $"Run build after rename:    {_configuration.DoRunBuild.AsText()}",
                    $"Create automatic commit:   {(!_configuration.DontCreateCommit).AsText()}",
                    $"Git version:               {gitVersion}",
                    "-----------------------------------------------",
                    "Do you want to continue with the rename operation?"
                };
                if (!_input.AskUser(string.Join(Environment.NewLine, lines)))
                {
                    _runtime.Abort();
                }
            }

            var(dependents, dependencies) = analyzeReferences();
            removeFromSolution();
            removeOldReferences();
            gitMove();
            updatePaketReference();
            addNewReferences();
            addToSolution();
            updatePaket();
            _git.StageAllChanges();
            build();
            commit();

            void addNewReferences()
            {
                dependents.ForEach(p => _dotnet.AddReference(p, newProjectPath));
                dependencies.ForEach(d => _dotnet.AddReference(newProjectPath, d));
            }

            void removeOldReferences()
            {
                dependents.ForEach(p => _dotnet.RemoveReference(p, oldProjectPath));
                dependencies.ForEach(d => _dotnet.RemoveReference(oldProjectPath, d));
            }

            (string[] dependents, string[] dependencies) analyzeReferences()
            {
                _logger.Info(
                    "Analyzing references in your projects - depending on the number of projects this can take a bit...");

                return(
                    allProjects().Where(doesNotEqualOldProjectPath).Where(hasReferenceToOldProject).ToArray(),
                    getReferencedProjects(oldProjectPath).ToArray());

                bool hasReferenceToOldProject(string p) =>
                getReferencedProjects(p).Any(doesEqualOldProjectPath);
            }

            bool doesNotEqualOldProjectPath(string what) => !doesEqualOldProjectPath(what);
            bool doesEqualOldProjectPath(string what) => arePathsEqual(what, oldProjectPath);

            IEnumerable <string> getReferencedProjects(string project)
            {
                var relativeReferences = _dotnet.GetReferencedProjects(project).Select(p => p = Path.Combine(p.Split('\\')));
                var baseDirectory      = Path.GetFullPath(Path.GetDirectoryName(project));

                return(relativeReferences.Select(r => r.ToAbsolutePath(baseDirectory)));
            }

            bool arePathsEqual(string lhs, string rhs) => Path.GetFullPath(lhs) == Path.GetFullPath(rhs);

            void commit()
            {
                if (!_configuration.DontCreateCommit)
                {
                    var wasMove = _configuration.NewProjectName.Any(CommonExtensions.IsDirectorySeparator);
                    var msg     = wasMove
                        ? $"Moved {oldProjectPath.ToRelativePath(CurrentDirectoryAbsolute)} to {newProjectPath.ToRelativePath(CurrentDirectoryAbsolute)}"
                        : $"Renamed {_configuration.OldProjectName} to {_configuration.NewProjectName}";
                    _git.Commit(msg);
                }
            }

            void build()
            {
                if (_configuration.DoRunBuild)
                {
                    _dotnet.BuildSolution(() =>
                    {
                        if (_input.AskUser(
                                "dotnet build returned an error or warning - do you want to rollback all changes?")
                            )
                        {
                            _git.RollbackAllChanges();
                            _runtime.Abort();
                        }
                    });
                }
            }

            void updatePaket()
            {
                if (isPaketUsed && !_configuration.DontRunPaketInstall)
                {
                    _dotnet.PaketInstall();
                }
            }

            void updatePaketReference()
            {
                if (!isPaketUsed)
                {
                    return;
                }
                const string restoreTargets = @"\.paket\Paket.Restore.targets";
                var          nesting        = Path.GetFullPath(newProjectPath).Count(CommonExtensions.IsDirectorySeparator) -
                                              CurrentDirectoryAbsolute.Count(CommonExtensions.IsDirectorySeparator) - 1;
                var paketPath = @"..\".Repeat(nesting)[..^ 1] + restoreTargets;