Exemple #1
0
    public void GetCommitsFromVersion_WithPathFilters()
    {
        string relativeDirectory = "some-sub-dir";

        var commitsAt121 = new List <Commit>();
        var commitsAt122 = new List <Commit>();
        var commitsAt123 = new List <Commit>();

        var versionData = VersionOptions.FromVersion(new Version("1.2"));

        versionData.PathFilters = new[]
        {
            new FilterPath("./", relativeDirectory),
            new FilterPath(":^/some-sub-dir/ignore.txt", relativeDirectory),
            new FilterPath(":^excluded-dir", relativeDirectory)
        };
        commitsAt121.Add(this.WriteVersionFile(versionData, relativeDirectory));

        // Commit touching excluded path does not affect version height
        var ignoredFilePath = Path.Combine(this.RepoPath, relativeDirectory, "ignore.txt");

        File.WriteAllText(ignoredFilePath, "hello");
        Commands.Stage(this.LibGit2Repository, ignoredFilePath);
        commitsAt121.Add(this.LibGit2Repository.Commit("Add excluded file", this.Signer, this.Signer));

        // Commit touching both excluded and included path does affect height
        var includedFilePath = Path.Combine(this.RepoPath, relativeDirectory, "another-file.txt");

        File.WriteAllText(includedFilePath, "hello");
        File.WriteAllText(ignoredFilePath, "changed");
        Commands.Stage(this.LibGit2Repository, includedFilePath);
        Commands.Stage(this.LibGit2Repository, ignoredFilePath);
        commitsAt122.Add(this.LibGit2Repository.Commit("Change both excluded and included file", this.Signer, this.Signer));

        // Commit touching excluded directory does not affect version height
        var fileInExcludedDirPath = Path.Combine(this.RepoPath, relativeDirectory, "excluded-dir", "ignore.txt");

        Directory.CreateDirectory(Path.GetDirectoryName(fileInExcludedDirPath));
        File.WriteAllText(fileInExcludedDirPath, "hello");
        Commands.Stage(this.LibGit2Repository, fileInExcludedDirPath);
        commitsAt122.Add(this.LibGit2Repository.Commit("Add file to excluded dir", this.Signer, this.Signer));

        // Commit touching project directory affects version height
        File.WriteAllText(includedFilePath, "more changes");
        Commands.Stage(this.LibGit2Repository, includedFilePath);
        commitsAt123.Add(this.LibGit2Repository.Commit("Changed included file", this.Signer, this.Signer));

        this.Context.RepoRelativeProjectDirectory = relativeDirectory;
        Assert.Equal(
            commitsAt121.OrderBy(c => c.Sha),
            LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 1)).OrderBy(c => c.Sha));
        Assert.Equal(
            commitsAt122.OrderBy(c => c.Sha),
            LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 2)).OrderBy(c => c.Sha));
        Assert.Equal(
            commitsAt123.OrderBy(c => c.Sha),
            LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 3)).OrderBy(c => c.Sha));
    }
Exemple #2
0
    public void GetCommitsFromVersion_MatchesOnEitherEndian()
    {
        this.InitializeSourceControl();
        Commit commit = this.WriteVersionFile(new VersionOptions {
            Version = SemanticVersion.Parse("1.2"), GitCommitIdShortAutoMinimum = 4
        });

        Version originalVersion      = new VersionOracle(this.Context).Version;
        Version swappedEndian        = new Version(originalVersion.Major, originalVersion.Minor, originalVersion.Build, BinaryPrimitives.ReverseEndianness((ushort)originalVersion.Revision));
        ushort  twoBytesFromCommitId = checked ((ushort)originalVersion.Revision);

        Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, originalVersion));
        Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, swappedEndian));
    }
Exemple #3
0
    public void GetCommitsFromVersion_WithMajorMinorChecks()
    {
        Commit v1_0_50 = this.WriteVersionFile(new VersionOptions {
            Version = SemanticVersion.Parse("1.0.50-preview.{height}")
        });
        Commit v1_1_50 = this.WriteVersionFile(new VersionOptions {
            Version = SemanticVersion.Parse("1.1.50-preview.{height}")
        });

        Assert.Empty(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0)));
        Assert.Empty(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0, 49)));
        Assert.Equal(v1_0_50, Assert.Single(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0, 50))));
        Assert.Equal(v1_1_50, Assert.Single(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 1, 50))));
    }
Exemple #4
0
    [InlineData(50, -2, true)]  // force many build number collisions. generally revision will still make them unique, but it *might* collide on occasion.
    public void GetIdAsVersion_Roundtrip_UnstableOffset(int startingOffset, int offsetStepChange, bool allowCollisions)
    {
        var versionOptions = new VersionOptions
        {
            Version             = SemanticVersion.Parse("1.2"),
            AssemblyVersion     = null,
            VersionHeightOffset = startingOffset,
        };

        this.WriteVersionFile(versionOptions);

        Commit[]  commits  = new Commit[16]; // create enough that statistically we'll likely hit interesting bits as MSB and LSB
        Version[] versions = new Version[commits.Length];
        for (int i = 0; i < commits.Length; i += 2)
        {
            versionOptions.VersionHeightOffset += offsetStepChange;
            commits[i]  = this.WriteVersionFile(versionOptions);
            versions[i] = this.GetVersion(committish: commits[i].Sha);

            commits[i + 1] = this.LibGit2Repository.Commit($"Commit {i + 1}", this.Signer, this.Signer, new CommitOptions {
                AllowEmptyCommit = true
            });
            versions[i + 1] = this.GetVersion(committish: commits[i + 1].Sha);

            this.Logger.WriteLine($"Commit {commits[i].Id.Sha.Substring(0, 8)} as version: {versions[i]}");
            this.Logger.WriteLine($"Commit {commits[i + 1].Id.Sha.Substring(0, 8)} as version: {versions[i + 1]}");

            // Find the commits we just wrote while they are still at the tip of the branch.
            var matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i]);
            Assert.Contains(commits[i], matchingCommits);
            matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i + 1]);
            Assert.Contains(commits[i + 1], matchingCommits);
        }

        // Find all commits (again) now that history has been written.
        for (int i = 0; i < commits.Length; i++)
        {
            var matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i]).ToList();
            Assert.Contains(commits[i], matchingCommits);
            if (!allowCollisions)
            {
                Assert.Single(matchingCommits);
            }
        }
    }
        private static int OnGetCommitsCommand(string project, bool quiet, string version)
        {
            if (!Version.TryParse(version, out Version parsedVersion))
            {
                Console.Error.WriteLine($"\"{version}\" is not a simple a.b.c[.d] version spec.");
                return((int)ExitCodes.InvalidVersionSpec);
            }

            string searchPath = GetSpecifiedOrCurrentDirectoryPath(project);

            using var context = (LibGit2Context)GitContext.Create(searchPath, writable: true);
            if (!context.IsRepository)
            {
                Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath);
                return((int)ExitCodes.NoGitRepo);
            }

            var candidateCommits = LibGit2GitExtensions.GetCommitsFromVersion(context, parsedVersion);

            PrintCommits(quiet, context, candidateCommits);

            return((int)ExitCodes.OK);
        }
        private static int OnTagCommand(string project, string versionOrRef)
        {
            if (string.IsNullOrEmpty(versionOrRef))
            {
                versionOrRef = DefaultRef;
            }

            string searchPath = GetSpecifiedOrCurrentDirectoryPath(project);

            using var context = (LibGit2Context)GitContext.Create(searchPath, writable: true);
            if (context is null)
            {
                Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath);
                return((int)ExitCodes.NoGitRepo);
            }

            var repository = context.Repository;

            if (!context.TrySelectCommit(versionOrRef))
            {
                if (!Version.TryParse(versionOrRef, out Version parsedVersion))
                {
                    Console.Error.WriteLine($"\"{versionOrRef}\" is not a simple a.b.c[.d] version spec or git reference.");
                    return((int)ExitCodes.InvalidVersionSpec);
                }

                string repoRelativeProjectDir = GetRepoRelativePath(searchPath, repository);
                var    candidateCommits       = LibGit2GitExtensions.GetCommitsFromVersion(context, parsedVersion).ToList();
                if (candidateCommits.Count == 0)
                {
                    Console.Error.WriteLine("No commit with that version found.");
                    return((int)ExitCodes.NoMatchingVersion);
                }
                else if (candidateCommits.Count > 1)
                {
                    PrintCommits(false, context, candidateCommits, includeOptions: true);
                    int selection;
                    do
                    {
                        Console.Write("Enter selection: ");
                    }while (!int.TryParse(Console.ReadLine(), out selection) || selection > candidateCommits.Count || selection < 1);
                    context.TrySelectCommit(candidateCommits[selection - 1].Sha);
                }
                else
                {
                    context.TrySelectCommit(candidateCommits.Single().Sha);
                }
            }

            var oracle = new VersionOracle(context, CloudBuild.Active);

            if (!oracle.VersionFileFound)
            {
                Console.Error.WriteLine("No version.json file found in or above \"{0}\" in commit {1}.", searchPath, context.GitCommitId);
                return((int)ExitCodes.NoVersionJsonFound);
            }

            oracle.PublicRelease = true; // assume a public release so we don't get a redundant -gCOMMITID in the tag name
            string tagName = $"v{oracle.SemVer2}";

            try
            {
                context.ApplyTag(tagName);
            }
            catch (LibGit2Sharp.NameConflictException)
            {
                var  taggedCommit = repository.Tags[tagName].Target as LibGit2Sharp.Commit;
                bool correctTag   = taggedCommit?.Sha == context.GitCommitId;
                Console.Error.WriteLine("The tag {0} is already defined ({1}).", tagName, correctTag ? "to the right commit" : $"expected {context.GitCommitId} but was on {taggedCommit.Sha}");
                return((int)(correctTag ? ExitCodes.OK : ExitCodes.TagConflict));
            }

            Console.WriteLine("{0} tag created at {1}.", tagName, context.GitCommitId);
            Console.WriteLine("Remember to push to a remote: git push origin {0}", tagName);

            return((int)ExitCodes.OK);
        }