示例#1
0
        Update(NuGitRepository repository)
        {
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }

            var lockDependencies = new List <LockDependency>();

            Traverse(
                repository.Workspace,
                repository.ReadDotNuGit().Dependencies,
                repository,
                new Dictionary <GitRepositoryName, GitCommitName>()
            {
                { repository.Name, new GitCommitName("HEAD") }
            },
                new HashSet <GitRepositoryName>()
            {
                repository.Name
            },
                (d, r) => {
                lockDependencies.Add(new LockDependency(d.Url, d.CommitName, r.GetCommitId()));
            });

            repository.WriteDotNuGitLock(lockDependencies);
        }
示例#2
0
        Restore(NuGitRepository repository, bool exact)
        {
            var workspace        = repository.Workspace;
            var lockDependencies = repository.ReadDotNuGitLock();

            foreach (var d in lockDependencies)
            {
                using (LogicalOperation.Start($"Restoring {d.Url.RepositoryName} to {d.CommitName} ({d.CommitId})"))
                {
                    var name = d.Url.RepositoryName;

                    var r = workspace.FindRepository(name);
                    if (r == null)
                    {
                        Clone(workspace.RootPath, d.Url);
                        r = workspace.GetRepository(name);
                    }

                    var head = r.GetCommitId(new GitCommitName("HEAD"));
                    var isCheckedOutToExact      = head == d.CommitId;
                    var isCheckedOutToDescendent = r.IsAncestor(d.CommitId, head);
                    var hasUncommittedChanges    = r.HasUncommittedChanges();
                    var isCommitNameAtCommitId   = r.GetCommitId(d.CommitName) == d.CommitId;

                    if (!exact && isCheckedOutToExact && hasUncommittedChanges)
                    {
                        Trace.TraceInformation($"Already checked out with uncommitted changes");
                    }
                    else if (!exact && isCheckedOutToExact)
                    {
                        Trace.TraceInformation($"Already checked out");
                    }
                    else if (!exact && isCheckedOutToDescendent && hasUncommittedChanges)
                    {
                        Trace.TraceInformation($"Already checked out to descendent with uncommitted changes");
                    }
                    else if (!exact && isCheckedOutToDescendent)
                    {
                        Trace.TraceInformation($"Already checked out to descendent");
                    }
                    else if (r.HasUncommittedChanges())
                    {
                        Trace.TraceError("Uncommitted changes");
                        throw new UserException($"Uncommitted changes in {name}");
                    }
                    else if (isCheckedOutToExact)
                    {
                        Trace.TraceInformation($"Already checked out");
                    }
                    else if (isCommitNameAtCommitId)
                    {
                        CheckOut(r, d.CommitName);
                    }
                    else
                    {
                        CheckOut(r, d.CommitId);
                    }
                }
            }
        }
示例#3
0
 CheckOut(NuGitRepository repository, GitCommitName commit)
 {
     using (LogicalOperation.Start($"Checking out {commit}"))
     {
         repository.Checkout(commit);
     }
 }
示例#4
0
        Install(NuGitRepository repository, IEnumerable <Dependency> dependencies)
        {
            Guard.NotNull(repository, nameof(repository));
            Guard.NotNull(dependencies, nameof(dependencies));

            var sln = repository.FindVisualStudioSolution();

            if (sln == null)
            {
                throw new UserException("No Visual Studio solution found in repo");
            }

            var oldFolderIds =
                sln.SolutionFolders
                .Where(f => IsNuGitFolder(f.Name))
                .ToDictionary(f => f.Name, f => f.Id);

            DeleteNuGitFolders(sln);

            foreach (var dependency in dependencies)
            {
                var name       = dependency.Url.RepositoryName;
                var folderName = NuGitFolderPrefix + name;
                oldFolderIds.TryGetValue(folderName, out string folderId);
                Install(repository, sln, name, folderName, folderId);
            }

            sln.Save();
        }
示例#5
0
 FindDependencyProjects(NuGitRepository repository, VisualStudioSolution sln)
 {
     Guard.NotNull(repository, nameof(repository));
     Guard.NotNull(sln, nameof(sln));
     return
         (sln.ProjectReferences
          .Where(p =>
                 p.TypeId == VisualStudioProjectTypeIds.CSharp ||
                 p.TypeId == VisualStudioProjectTypeIds.CSharpNew)
          .Where(p => !IsTestProject(p))
          .Where(p => !string.IsNullOrWhiteSpace(p.Location))
          .Where(p => PathExtensions.IsDescendantOf(p.AbsoluteLocation, repository.Path))
          .OrderBy(p => p.Name)
          .ToList());
 }
示例#6
0
        Traverse(
            NuGitWorkspace workspace,
            IEnumerable <Dependency> dependencies,
            NuGitRepository requiredBy,
            IDictionary <GitRepositoryName, GitCommitName> checkedOut,
            ISet <GitRepositoryName> visited,
            Action <Dependency, NuGitRepository> onVisited
            )
        {
            Guard.NotNull(workspace, nameof(workspace));
            Guard.NotNull(dependencies, nameof(dependencies));
            Guard.NotNull(checkedOut, nameof(checkedOut));
            Guard.NotNull(visited, nameof(visited));
            Guard.NotNull(onVisited, nameof(onVisited));

            var unvisited = dependencies.Where(d => !visited.Contains(d.Url.RepositoryName)).ToList().AsReadOnly();

            //
            // Clone any dependency repos that aren't present
            //
            foreach (var d in unvisited)
            {
                if (workspace.FindRepository(d.Url.RepositoryName) != null)
                {
                    continue;
                }
                Clone(workspace.RootPath, d.Url);
            }

            //
            // Visit each dependency
            //
            foreach (var d in dependencies)
            {
                var name   = d.Url.RepositoryName;
                var repo   = workspace.GetRepository(name);
                var commit = d.CommitName;
                checkedOut.TryGetValue(name, out var checkedOutCommit);

                //
                // First visit wins
                //
                if (checkedOutCommit == null)
                {
                    using (LogicalOperation.Start($"Restoring {d.Url.RepositoryName} to {d.CommitName}"))
                    {
                        var commitId              = repo.GetCommitId(commit);
                        var headId                = repo.GetCommitId();
                        var isCheckedOutToCommit  = headId == commitId;
                        var hasUncommittedChanges = repo.HasUncommittedChanges();

                        if (repo.HasUncommittedChanges())
                        {
                            Trace.TraceError("Uncommitted changes");
                            throw new UserException($"Uncommitted changes in {name}");
                        }
                        else if (isCheckedOutToCommit)
                        {
                            Trace.TraceInformation($"Already checked out");
                        }
                        else
                        {
                            CheckOut(repo, commit);
                        }

                        checkedOut.Add(name, commit);
                        visited.Add(name);
                        onVisited(d, repo);
                        continue;
                    }
                }

                //
                // Subsequent visits specifying different commits get a warning
                //
                if (commit != checkedOutCommit)
                {
                    Trace.TraceWarning(
                        StringExtensions.FormatInvariant(
                            "{0} depends on {1}#{2} but #{3} has already been checked out",
                            requiredBy.Name,
                            name,
                            commit,
                            checkedOutCommit));
                    continue;
                }

                //
                // Subsequent visits specifying the same commit do nothing
                //
            }

            //
            // Recurse
            //
            foreach (var d in unvisited)
            {
                var name = d.Url.RepositoryName;
                var repo = workspace.FindRepository(name);

                Traverse(
                    workspace,
                    repo.ReadDotNuGit().Dependencies,
                    repo,
                    checkedOut,
                    visited,
                    onVisited);
            }
        }
示例#7
0
        Install(
            NuGitRepository repository,
            VisualStudioSolution sln,
            GitRepositoryName dependencyName,
            string folderName,
            string folderId
            )
        {
            var workspace = repository.Workspace;

            var slnLocalPath           = PathExtensions.GetPathFromAncestor(sln.Path, repository.Path);
            var slnLocalPathComponents = PathExtensions.Split(slnLocalPath);
            var slnToWorkspacePath     = Path.Combine(Enumerable.Repeat("..", slnLocalPathComponents.Length).ToArray());

            var dependencyRepository = workspace.GetRepository(dependencyName);

            var dependencySln = dependencyRepository.FindVisualStudioSolution();

            if (dependencySln == null)
            {
                return;
            }

            var dependencyProjects = FindDependencyProjects(dependencyRepository, dependencySln);

            if (dependencyProjects.Count == 0)
            {
                return;
            }

            using (LogicalOperation.Start($"Installing projects from {dependencyName}"))
            {
                // TODO Consider configurations in each individual dependency project, not just the solution
                var configurationsInCommon =
                    sln.SolutionConfigurations.Intersect(dependencySln.SolutionConfigurations)
                    .OrderBy(s => s)
                    .ToList();

                var folder =
                    folderId != null
                ? sln.AddSolutionFolder(folderName, folderId)
                : sln.AddSolutionFolder(folderName);

                foreach (var project in dependencyProjects)
                {
                    using (LogicalOperation.Start($"Installing {project.Name}"))
                    {
                        var projectLocalPath =
                            PathExtensions.GetPathFromAncestor(project.AbsoluteLocation, dependencyRepository.Path);

                        //
                        // Add reference to the dependency project
                        //
                        sln.AddProjectReference(
                            project.TypeId,
                            project.Name,
                            Path.Combine(slnToWorkspacePath, dependencyName, projectLocalPath),
                            project.Id);

                        //
                        // Put it in the dependency's solution folder
                        //
                        sln.AddNestedProject(project.Id, folder.Id);

                        //
                        // Add solution -> project configuration mappings
                        //
                        foreach (string configuration in configurationsInCommon)
                        {
                            sln.AddProjectConfiguration(project.Id, configuration, "ActiveCfg", configuration);
                            sln.AddProjectConfiguration(project.Id, configuration, "Build.0", configuration);
                        }
                    }
                }
            }
        }