Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, ICloudBuild cloudBuild)
        {
            this.cloudBuild     = cloudBuild;
            this.VersionOptions =
                VersionFile.GetVersion(repo, projectDirectory) ??
                VersionFile.GetVersion(projectDirectory);

            var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
            var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot)
                ? projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                : null;

            var commit = repo?.Head.Commits.FirstOrDefault();

            this.GitCommitId   = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null;
            this.VersionHeight = repo?.GetVersionHeight(relativeRepoProjectDirectory) ?? 0;
            this.BuildingRef   = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName;

            // Override the typedVersion with the special build number and revision components, when available.
            this.Version = repo?.GetIdAsVersion(relativeRepoProjectDirectory, this.VersionHeight) ?? this.VersionOptions?.Version.Version;
            this.Version = this.Version ?? new Version(0, 0);

            this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumber ?? new VersionOptions.CloudBuildNumberOptions();

            if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Length > 0)
            {
                this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any(
                    expr => Regex.IsMatch(this.BuildingRef, expr));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, ICloudBuild cloudBuild, int?overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null)
        {
            var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
            var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot)
                ? (!string.IsNullOrEmpty(projectPathRelativeToGitRepoRoot)
                    ? projectPathRelativeToGitRepoRoot
                    : projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
                : null;

            var commit = repo?.Head.Commits.FirstOrDefault();

            var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory);

            var workingVersion = VersionFile.GetVersion(projectDirectory);

            if (overrideBuildNumberOffset.HasValue)
            {
                if (committedVersion != null)
                {
                    committedVersion.BuildNumberOffset = overrideBuildNumberOffset.Value;
                }

                if (workingVersion != null)
                {
                    workingVersion.BuildNumberOffset = overrideBuildNumberOffset.Value;
                }
            }

            this.VersionOptions = committedVersion ?? workingVersion;

            this.GitCommitId   = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null;
            this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion);
            this.BuildingRef   = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName;

            // Override the typedVersion with the special build number and revision components, when available.
            if (repo != null)
            {
                this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight);
            }
            else
            {
                this.Version = this.VersionOptions?.Version.Version ?? Version0;
            }

            this.VersionHeightOffset = this.VersionOptions?.BuildNumberOffsetOrDefault ?? 0;

            this.PrereleaseVersion = ReplaceMacros(this.VersionOptions?.Version.Prerelease ?? string.Empty);

            this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance;

            if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Length > 0)
            {
                this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any(
                    expr => Regex.IsMatch(this.BuildingRef, expr));
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VersionOracle"/> class.
 /// </summary>
 public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, ICloudBuild cloudBuild, int?overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null)
     : this(projectDirectory, repo, null, cloudBuild, overrideBuildNumberOffset, projectPathRelativeToGitRepoRoot)
 {
 }
Exemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        public static VersionOracle Create(string projectDirectory, string gitRepoDirectory = null, ICloudBuild cloudBuild = null, int?overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null)
        {
            Requires.NotNull(projectDirectory, nameof(projectDirectory));
            if (string.IsNullOrEmpty(gitRepoDirectory))
            {
                gitRepoDirectory = projectDirectory;
            }

            using (var git = GitExtensions.OpenGitRepo(gitRepoDirectory))
            {
                return(new VersionOracle(projectDirectory, git, null, cloudBuild, overrideBuildNumberOffset, projectPathRelativeToGitRepoRoot));
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Adds version variables to the the current cloud build environment.
        /// </summary>
        /// <exception cref="CloudCommandException">Thrown when the build environment could not be updated.</exception>
        /// <param name="projectDirectory">
        /// The path to the directory which may (or its ancestors may) define the version file.
        /// </param>
        /// <param name="metadata">
        /// Optionally adds an identifier to the build metadata part of a semantic version.
        /// </param>
        /// <param name="version">
        /// The string to use for the cloud build number. If not specified, the computed version will be used.
        /// </param>
        /// <param name="ciSystem">
        /// The CI system to activate. If not specified, auto-detection will be used.
        /// </param>
        /// <param name="allVars">
        /// Controls whether to define all version variables as cloud build variables.
        /// </param>
        /// <param name="commonVars">
        /// Controls whether to define common version variables as cloud build variables.
        /// </param>
        /// <param name="additionalVariables">
        /// Additional cloud build variables to define.
        /// </param>
        /// <param name="alwaysUseLibGit2">
        /// Force usage of LibGit2 for accessing the git repository.
        /// </param>
        public void SetBuildVariables(string projectDirectory, IEnumerable <string> metadata, string version, string ciSystem, bool allVars, bool commonVars, IEnumerable <KeyValuePair <string, string> > additionalVariables, bool alwaysUseLibGit2)
        {
            Requires.NotNull(projectDirectory, nameof(projectDirectory));
            Requires.NotNull(additionalVariables, nameof(additionalVariables));

            ICloudBuild activeCloudBuild = CloudBuild.Active;

            if (!string.IsNullOrEmpty(ciSystem))
            {
                int matchingIndex = Array.FindIndex(CloudProviderNames, m => string.Equals(m, ciSystem, StringComparison.OrdinalIgnoreCase));
                if (matchingIndex == -1)
                {
                    throw new CloudCommandException(
                              $"No cloud provider found by the name: \"{ciSystem}\"",
                              CloudCommandError.NoCloudBuildProviderMatch);
                }

                activeCloudBuild = CloudBuild.SupportedCloudBuilds[matchingIndex];
            }

            using var context = GitContext.Create(projectDirectory, writable: alwaysUseLibGit2);
            var oracle = new VersionOracle(context, cloudBuild: activeCloudBuild);

            if (metadata is not null)
            {
                oracle.BuildMetadata.AddRange(metadata);
            }

            var variables = new Dictionary <string, string>();

            if (allVars)
            {
                foreach (var pair in oracle.CloudBuildAllVars)
                {
                    variables.Add(pair.Key, pair.Value);
                }
            }

            if (commonVars)
            {
                foreach (var pair in oracle.CloudBuildVersionVars)
                {
                    variables.Add(pair.Key, pair.Value);
                }
            }

            foreach (var kvp in additionalVariables)
            {
                if (variables.ContainsKey(kvp.Key))
                {
                    throw new CloudCommandException(
                              $"Cloud build variable \"{kvp.Key}\" specified more than once.",
                              CloudCommandError.DuplicateCloudVariable);
                }

                variables[kvp.Key] = kvp.Value;
            }

            if (activeCloudBuild is not null)
            {
                if (string.IsNullOrEmpty(version))
                {
                    version = oracle.CloudBuildNumber;
                }

                activeCloudBuild.SetCloudBuildNumber(version, this.stdout, this.stderr);

                foreach (var pair in variables)
                {
                    activeCloudBuild.SetCloudBuildVariable(pair.Key, pair.Value, this.stdout, this.stderr);
                }
            }
            else
            {
                throw new CloudCommandException(
                          "No cloud build detected.",
                          CloudCommandError.NoCloudBuildEnvDetected);
            }
        }
Exemplo n.º 6
0
        private static ExitCodes OnCloudCommand(string projectPath, string version, string cisystem, bool cloudBuildAllVars, bool cloudBuildCommonVars, IReadOnlyList <string> cloudVariables)
        {
            string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath);

            if (!Directory.Exists(searchPath))
            {
                Console.Error.WriteLine("\"{0}\" is not an existing directory.", searchPath);
                return(ExitCodes.NoGitRepo);
            }

            ICloudBuild activeCloudBuild = CloudBuild.Active;

            if (!string.IsNullOrEmpty(cisystem))
            {
                int matchingIndex = Array.FindIndex(CloudProviderNames, m => string.Equals(m, cisystem, StringComparison.OrdinalIgnoreCase));
                if (matchingIndex == -1)
                {
                    Console.Error.WriteLine("No cloud provider found by the name: \"{0}\"", cisystem);
                    return(ExitCodes.NoCloudBuildProviderMatch);
                }

                activeCloudBuild = CloudBuild.SupportedCloudBuilds[matchingIndex];
            }

            var oracle    = VersionOracle.Create(searchPath, cloudBuild: activeCloudBuild);
            var variables = new Dictionary <string, string>();

            if (cloudBuildAllVars)
            {
                foreach (var pair in oracle.CloudBuildAllVars)
                {
                    variables.Add(pair.Key, pair.Value);
                }
            }

            if (cloudBuildCommonVars)
            {
                foreach (var pair in oracle.CloudBuildVersionVars)
                {
                    variables.Add(pair.Key, pair.Value);
                }
            }

            foreach (string def in cloudVariables)
            {
                string[] split = def.Split(new char[] { '=' }, 2);
                if (split.Length < 2)
                {
                    Console.Error.WriteLine($"\"{def}\" is not in the NAME=VALUE syntax required for cloud variables.");
                    return(ExitCodes.BadCloudVariable);
                }

                if (variables.ContainsKey(split[0]))
                {
                    Console.Error.WriteLine($"Cloud build variable \"{split[0]}\" specified more than once.");
                    return(ExitCodes.DuplicateCloudVariable);
                }

                variables[split[0]] = split[1];
            }

            if (activeCloudBuild != null)
            {
                if (string.IsNullOrEmpty(version))
                {
                    version = oracle.CloudBuildNumber;
                }

                activeCloudBuild.SetCloudBuildNumber(version, Console.Out, Console.Error);

                foreach (var pair in variables)
                {
                    activeCloudBuild.SetCloudBuildVariable(pair.Key, pair.Value, Console.Out, Console.Error);
                }

                return(ExitCodes.OK);
            }
            else
            {
                Console.Error.WriteLine("No cloud build detected.");
                return(ExitCodes.NoCloudBuildEnvDetected);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int?overrideVersionHeightOffset = null, string projectPathRelativeToGitRepoRoot = null)
        {
            var relativeRepoProjectDirectory = projectPathRelativeToGitRepoRoot ?? repo?.GetRepoRelativePath(projectDirectory);

            if (repo is object)
            {
                // If we're particularly git focused, normalize/reset projectDirectory to be the path we *actually* want to look at in case we're being redirected.
                projectDirectory = Path.Combine(repo.Info.WorkingDirectory, relativeRepoProjectDirectory);
            }

            var commit = head ?? repo?.Head.Tip;

            var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory);

            var workingVersion = head is object?VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory);

            if (overrideVersionHeightOffset.HasValue)
            {
                if (committedVersion != null)
                {
                    committedVersion.VersionHeightOffset = overrideVersionHeightOffset.Value;
                }

                if (workingVersion != null)
                {
                    workingVersion.VersionHeightOffset = overrideVersionHeightOffset.Value;
                }
            }

            this.VersionOptions = committedVersion ?? workingVersion;

            this.GitCommitId   = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null;
            this.GitCommitDate = commit?.Author.When;
            this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion);
            this.BuildingRef   = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName;

            // Override the typedVersion with the special build number and revision components, when available.
            if (repo != null)
            {
                this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight);
            }
            else
            {
                this.Version = this.VersionOptions?.Version.Version ?? Version0;
            }

            // get the commit id abbreviation only if the commit id is set
            if (!string.IsNullOrEmpty(this.GitCommitId))
            {
                var gitCommitIdShortFixedLength = this.VersionOptions?.GitCommitIdShortFixedLength ?? VersionOptions.DefaultGitCommitIdShortFixedLength;
                var gitCommitIdShortAutoMinimum = this.VersionOptions?.GitCommitIdShortAutoMinimum ?? 0;
                // get it from the git repository if there is a repository present and it is enabled
                if (repo != null && gitCommitIdShortAutoMinimum > 0)
                {
                    this.GitCommitIdShort = repo.ObjectDatabase.ShortenObjectId(commit, gitCommitIdShortAutoMinimum);
                }
                else
                {
                    this.GitCommitIdShort = this.GitCommitId.Substring(0, gitCommitIdShortFixedLength);
                }
            }

            this.VersionHeightOffset = this.VersionOptions?.VersionHeightOffsetOrDefault ?? 0;

            this.PrereleaseVersion = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty);

            this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance;

            if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Count > 0)
            {
                this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any(
                    expr => Regex.IsMatch(this.BuildingRef, expr));
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        /// <param name="projectDirectory"></param>
        /// <param name="gitRepoDirectory"></param>
        /// <param name="cloudBuild"></param>
        /// <returns></returns>
        public static VersionOracle Create(string projectDirectory, string gitRepoDirectory = null, ICloudBuild cloudBuild = null)
        {
            Requires.NotNull(projectDirectory, nameof(projectDirectory));
            if (string.IsNullOrEmpty(gitRepoDirectory))
            {
                gitRepoDirectory = projectDirectory;
            }

            using (var git = OpenGitRepo(gitRepoDirectory))
            {
                return(new VersionOracle(projectDirectory, git, cloudBuild));
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VersionOracle"/> class.
        /// </summary>
        public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int?overrideVersionHeightOffset = null, string projectPathRelativeToGitRepoRoot = null)
        {
            var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
            var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot)
                ? (!string.IsNullOrEmpty(projectPathRelativeToGitRepoRoot)
                    ? projectPathRelativeToGitRepoRoot
                    : projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
                : null;

            var commit = head ?? repo?.Head.Commits.FirstOrDefault();

            var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory);

            var workingVersion = head != null?VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory);

            if (overrideVersionHeightOffset.HasValue)
            {
                if (committedVersion != null)
                {
                    committedVersion.VersionHeightOffset = overrideVersionHeightOffset.Value;
                }

                if (workingVersion != null)
                {
                    workingVersion.VersionHeightOffset = overrideVersionHeightOffset.Value;
                }
            }

            this.VersionOptions = committedVersion ?? workingVersion;

            this.GitCommitId   = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null;
            this.GitCommitDate = commit?.Author.When;
            this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion);
            this.BuildingRef   = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName;

            // Override the typedVersion with the special build number and revision components, when available.
            if (repo != null)
            {
                this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight);
            }
            else
            {
                this.Version = this.VersionOptions?.Version.Version ?? Version0;
            }

            // get the commit id abbreviation only if the commit id is set
            if (!string.IsNullOrEmpty(this.GitCommitId))
            {
                var gitCommitIdShortFixedLength = this.VersionOptions?.GitCommitIdShortFixedLength ?? VersionOptions.DefaultGitCommitIdShortFixedLength;
                var gitCommitIdShortAutoMinimum = this.VersionOptions?.GitCommitIdShortAutoMinimum ?? 0;
                // get it from the git repository if there is a repository present and it is enabled
                if (repo != null && gitCommitIdShortAutoMinimum > 0)
                {
                    this.GitCommitIdShort = repo.ObjectDatabase.ShortenObjectId(commit, gitCommitIdShortAutoMinimum);
                }
                else
                {
                    this.GitCommitIdShort = this.GitCommitId.Substring(0, gitCommitIdShortFixedLength);
                }
            }

            this.VersionHeightOffset = this.VersionOptions?.VersionHeightOffsetOrDefault ?? 0;

            this.PrereleaseVersion = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty);

            this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance;

            if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Length > 0)
            {
                this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any(
                    expr => Regex.IsMatch(this.BuildingRef, expr));
            }
        }