public void GetVersionManaged()
        {
            using var context = GitContext.Create(GetPath(this.ProjectDirectory), writable: false);
            var oracle = new VersionOracle(context, cloudBuild: null);

            this.Version = oracle.Version;
        }
    protected Commit?WriteVersionFile(VersionOptions versionData, string?relativeDirectory = null)
    {
        Requires.NotNull(versionData, nameof(versionData));

        if (relativeDirectory == null)
        {
            relativeDirectory = string.Empty;
        }

        bool localContextCreated = this.Context is null;
        var  context             = this.Context ?? GitContext.Create(this.RepoPath, writable: true);

        try
        {
            string versionFilePath = context.VersionFile.SetVersion(Path.Combine(this.RepoPath, relativeDirectory), versionData);
            return(this.CommitVersionFile(versionFilePath, versionData.Version?.ToString()));
        }
        finally
        {
            if (localContextCreated)
            {
                context.Dispose();
            }
        }
    }
        public static VersionOracle GitVersioningGetVersion(this ICakeContext cakeContext, string projectDirectory = ".")
        {
            var fullProjectDirectory = (new DirectoryInfo(projectDirectory)).FullName;

            string directoryName = Path.GetDirectoryName(Assembly.GetAssembly(typeof(GitVersioningAliases)).Location);

            if (string.IsNullOrWhiteSpace(directoryName))
            {
                throw new InvalidOperationException("Could not locate the Cake.GitVersioning library");
            }

            var gitContext = GitContext.Create(fullProjectDirectory);

            return(new VersionOracle(gitContext, cloudBuild: CloudBuild.Active));
        }
示例#4
0
        private static int OnSetVersionCommand(string project, string version)
        {
            if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver))
            {
                Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec.");
                return((int)ExitCodes.InvalidVersionSpec);
            }

            var defaultOptions = new VersionOptions
            {
                Version = semver,
            };

            string searchPath = GetSpecifiedOrCurrentDirectoryPath(project);

            using var context = GitContext.Create(searchPath, writable: true);
            var    existingOptions = context.VersionFile.GetVersion(out string actualDirectory);
            string versionJsonPath;

            if (existingOptions != null)
            {
                existingOptions.Version = semver;
                versionJsonPath         = context.VersionFile.SetVersion(actualDirectory, existingOptions);
            }
            else if (string.IsNullOrEmpty(project))
            {
                if (!context.IsRepository)
                {
                    Console.Error.WriteLine("No version file and no git repo found at or above: \"{0}\"", searchPath);
                    return((int)ExitCodes.NoGitRepo);
                }

                versionJsonPath = context.VersionFile.SetVersion(context.WorkingTreePath, defaultOptions);
            }
            else
            {
                versionJsonPath = context.VersionFile.SetVersion(project, defaultOptions);
            }

            if (context.IsRepository)
            {
                context.Stage(versionJsonPath);
            }

            return((int)ExitCodes.OK);
        }
示例#5
0
        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);
        }
示例#6
0
 protected override GitContext CreateGitContext(string path, string committish = null) => GitContext.Create(path, committish, writable: true);
示例#7
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);
            }
        }
示例#8
0
        private static int OnCloudCommand(string project, IReadOnlyList <string> metadata, string version, string ciSystem, bool allVars, bool commonVars, IReadOnlyList <string> define)
        {
            string searchPath = GetSpecifiedOrCurrentDirectoryPath(project);

            if (!Directory.Exists(searchPath))
            {
                Console.Error.WriteLine("\"{0}\" is not an existing directory.", searchPath);
                return((int)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((int)ExitCodes.NoCloudBuildProviderMatch);
                }

                activeCloudBuild = CloudBuild.SupportedCloudBuilds[matchingIndex];
            }

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

            if (metadata != 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);
                }
            }

            if (define != null)
            {
                foreach (string def in define)
                {
                    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((int)ExitCodes.BadCloudVariable);
                    }

                    if (variables.ContainsKey(split[0]))
                    {
                        Console.Error.WriteLine($"Cloud build variable \"{split[0]}\" specified more than once.");
                        return((int)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((int)ExitCodes.OK);
            }
            else
            {
                Console.Error.WriteLine("No cloud build detected.");
                return((int)ExitCodes.NoCloudBuildEnvDetected);
            }
        }
示例#9
0
        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);
        }
示例#10
0
        private static int OnGetVersionCommand(string project, IReadOnlyList <string> metadata, string format, string variable, string commitIsh)
        {
            if (string.IsNullOrEmpty(format))
            {
                format = DefaultOutputFormat;
            }

            if (string.IsNullOrEmpty(commitIsh))
            {
                commitIsh = DefaultRef;
            }

            string searchPath = GetSpecifiedOrCurrentDirectoryPath(project);

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

            if (!context.TrySelectCommit(commitIsh))
            {
                Console.Error.WriteLine("rev-parse produced no commit for {0}", commitIsh);
                return((int)ExitCodes.BadGitRef);
            }

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

            if (metadata != null)
            {
                oracle.BuildMetadata.AddRange(metadata);
            }

            // Take the PublicRelease environment variable into account, since the build would as well.
            if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("PublicRelease")) && bool.TryParse(Environment.GetEnvironmentVariable("PublicRelease"), out bool publicRelease))
            {
                oracle.PublicRelease = publicRelease;
            }

            if (string.IsNullOrEmpty(variable))
            {
                switch (format.ToLowerInvariant())
                {
                case "text":
                    Console.WriteLine("Version:                      {0}", oracle.Version);
                    Console.WriteLine("AssemblyVersion:              {0}", oracle.AssemblyVersion);
                    Console.WriteLine("AssemblyInformationalVersion: {0}", oracle.AssemblyInformationalVersion);
                    Console.WriteLine("NuGetPackageVersion:          {0}", oracle.NuGetPackageVersion);
                    Console.WriteLine("NpmPackageVersion:            {0}", oracle.NpmPackageVersion);
                    break;

                case "json":
                    var converters = new JsonConverter[]
                    {
                        new Newtonsoft.Json.Converters.VersionConverter(),
                    };
                    Console.WriteLine(JsonConvert.SerializeObject(oracle, Formatting.Indented, converters));
                    break;

                default:
                    Console.Error.WriteLine("Unsupported format: {0}", format);
                    return((int)ExitCodes.UnsupportedFormat);
                }
            }
            else
            {
                if (format != "text")
                {
                    Console.Error.WriteLine("Format must be \"text\" when querying for an individual variable's value.");
                    return((int)ExitCodes.UnsupportedFormat);
                }

                var property = oracle.GetType().GetProperty(variable, CaseInsensitiveFlags);
                if (property == null)
                {
                    Console.Error.WriteLine("Variable \"{0}\" not a version property.", variable);
                    return((int)ExitCodes.BadVariable);
                }

                Console.WriteLine(property.GetValue(oracle));
            }

            return((int)ExitCodes.OK);
        }
示例#11
0
        private static int OnInstallCommand(string path, string version, IReadOnlyList <string> source)
        {
            if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver))
            {
                Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec.");
                return((int)ExitCodes.InvalidVersionSpec);
            }

            var options = new VersionOptions
            {
                Version = semver,
                PublicReleaseRefSpec = new string[]
                {
                    @"^refs/heads/master$",
                    @"^refs/heads/v\d+(?:\.\d+)?$",
                },
                CloudBuild = new VersionOptions.CloudBuildOptions
                {
                    BuildNumber = new VersionOptions.CloudBuildNumberOptions
                    {
                        Enabled = true,
                    },
                },
            };
            string searchPath = GetSpecifiedOrCurrentDirectoryPath(path);

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

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

            if (string.IsNullOrEmpty(path))
            {
                path = context.WorkingTreePath;
            }

            var existingOptions = context.VersionFile.GetVersion();

            if (existingOptions != null)
            {
                if (!string.IsNullOrEmpty(version))
                {
                    var setVersionExitCode = OnSetVersionCommand(path, version);
                    if (setVersionExitCode != (int)ExitCodes.OK)
                    {
                        return(setVersionExitCode);
                    }
                }
            }
            else
            {
                string versionJsonPath = context.VersionFile.SetVersion(path, options);
                context.Stage(versionJsonPath);
            }

            // Create/update the Directory.Build.props file in the directory of the version.json file to add the NB.GV package.
            string             directoryBuildPropsPath = Path.Combine(path, "Directory.Build.props");
            ProjectRootElement propsFile = File.Exists(directoryBuildPropsPath)
                ? ProjectRootElement.Open(directoryBuildPropsPath)
                : ProjectRootElement.Create(directoryBuildPropsPath);

            const string PackageReferenceItemType = "PackageReference";

            if (!propsFile.Items.Any(i => i.ItemType == PackageReferenceItemType && i.Include == PackageId))
            {
                // Validate given sources
                foreach (var src in source)
                {
                    // TODO: Can declare Option<Uri> to validate argument during parsing.
                    if (!Uri.TryCreate(src, UriKind.Absolute, out var _))
                    {
                        Console.Error.WriteLine($"\"{src}\" is not a valid NuGet package source.");
                        return((int)ExitCodes.InvalidNuGetPackageSource);
                    }
                }

                string packageVersion = GetLatestPackageVersionAsync(PackageId, path, source).GetAwaiter().GetResult();
                if (string.IsNullOrEmpty(packageVersion))
                {
                    string verifyPhrase = source.Any()
                        ? "Please verify the given 'source' option(s)."
                        : "Please verify the package sources in the NuGet.Config files.";
                    Console.Error.WriteLine($"Latest stable version of the {PackageId} package could not be determined. " + verifyPhrase);
                    return((int)ExitCodes.PackageIdNotFound);
                }

                var item = propsFile.AddItem(
                    PackageReferenceItemType,
                    PackageId,
                    new Dictionary <string, string>
                {
                    { "Version", packageVersion },
                    { "PrivateAssets", "all" },
                });
                item.Condition = "!Exists('packages.config')";

                propsFile.Save(directoryBuildPropsPath);
            }

            context.Stage(directoryBuildPropsPath);

            return((int)ExitCodes.OK);
        }
        protected override bool ExecuteInner()
        {
            try
            {
                if (!string.IsNullOrEmpty(this.ProjectPathRelativeToGitRepoRoot))
                {
                    Requires.Argument(!Path.IsPathRooted(this.ProjectPathRelativeToGitRepoRoot), nameof(this.ProjectPathRelativeToGitRepoRoot), "Path must be relative.");
                    Requires.Argument(!(
                                          this.ProjectPathRelativeToGitRepoRoot.Contains(".." + Path.DirectorySeparatorChar) ||
                                          this.ProjectPathRelativeToGitRepoRoot.Contains(".." + Path.AltDirectorySeparatorChar)),
                                      nameof(this.ProjectPathRelativeToGitRepoRoot),
                                      "Path must not use ..\\");
                }

                bool useLibGit2 = false;
                if (!string.IsNullOrWhiteSpace(this.GitEngine))
                {
                    useLibGit2 =
                        this.GitEngine == "Managed" ? false :
                        this.GitEngine == "LibGit2" ? true :
                        throw new ArgumentException("GitEngine property must be set to either \"Managed\" or \"LibGit2\" or left empty.");
                }

                var    cloudBuild = CloudBuild.Active;
                var    overrideBuildNumberOffset = (this.OverrideBuildNumberOffset == int.MaxValue) ? (int?)null : this.OverrideBuildNumberOffset;
                string projectDirectory          = this.ProjectPathRelativeToGitRepoRoot is object && this.GitRepoRoot is object
                                                   ?Path.Combine(this.GitRepoRoot, this.ProjectPathRelativeToGitRepoRoot)
                                                       : this.ProjectDirectory;

                using var context = GitContext.Create(projectDirectory, writable: useLibGit2);
                var oracle = new VersionOracle(context, cloudBuild, overrideBuildNumberOffset);
                if (!string.IsNullOrEmpty(this.DefaultPublicRelease))
                {
                    oracle.PublicRelease = string.Equals(this.DefaultPublicRelease, "true", StringComparison.OrdinalIgnoreCase);
                }

                if (this.BuildMetadata != null)
                {
                    oracle.BuildMetadata.AddRange(this.BuildMetadata.Split(';'));
                }

                if (IsMisconfiguredPrereleaseAndSemVer1(oracle))
                {
                    this.Log.LogWarning("The 'nugetPackageVersion' is explicitly set to 'semVer': 1 but the prerelease version '{0}' is not SemVer1 compliant. Change the 'nugetPackageVersion'.'semVer' value to 2 or change the 'version' member to follow SemVer1 rules (e.g.: '{1}').", oracle.PrereleaseVersion, GetSemVer1WithoutPaddingOrBuildMetadata(oracle));
                }

                this.PublicRelease                = oracle.PublicRelease;
                this.BuildingRef                  = oracle.BuildingRef;
                this.Version                      = oracle.Version.ToString();
                this.AssemblyVersion              = oracle.AssemblyVersion.ToString();
                this.AssemblyFileVersion          = oracle.AssemblyFileVersion.ToString();
                this.AssemblyInformationalVersion = oracle.AssemblyInformationalVersion;
                this.SimpleVersion                = oracle.SimpleVersion.ToString();
                this.MajorMinorVersion            = oracle.MajorMinorVersion.ToString();
                this.BuildNumber                  = oracle.BuildNumber;
                this.PrereleaseVersion            = oracle.PrereleaseVersion;
                this.GitCommitId                  = oracle.GitCommitId;
                this.GitCommitIdShort             = oracle.GitCommitIdShort;
                this.GitCommitDateTicks           = oracle.GitCommitDate != null?oracle.GitCommitDate.Value.UtcTicks.ToString(CultureInfo.InvariantCulture) : null;

                this.GitVersionHeight         = oracle.VersionHeight;
                this.BuildMetadataFragment    = oracle.BuildMetadataFragment;
                this.CloudBuildNumber         = oracle.CloudBuildNumberEnabled ? oracle.CloudBuildNumber : null;
                this.NuGetPackageVersion      = oracle.NuGetPackageVersion;
                this.ChocolateyPackageVersion = oracle.ChocolateyPackageVersion;
                this.NpmPackageVersion        = oracle.NpmPackageVersion;

                IEnumerable <ITaskItem> cloudBuildVersionVars = null;
                if (oracle.CloudBuildVersionVarsEnabled)
                {
                    cloudBuildVersionVars = oracle.CloudBuildVersionVars
                                            .Select(item => new TaskItem(item.Key, new Dictionary <string, string> {
                        { "Value", item.Value }
                    }));
                }

                if (oracle.CloudBuildAllVarsEnabled)
                {
                    var allVariables = oracle.CloudBuildAllVars
                                       .Select(item => new TaskItem(item.Key, new Dictionary <string, string> {
                        { "Value", item.Value }
                    }));

                    if (cloudBuildVersionVars != null)
                    {
                        cloudBuildVersionVars = cloudBuildVersionVars
                                                .Union(allVariables);
                    }
                    else
                    {
                        cloudBuildVersionVars = allVariables;
                    }
                }

                if (cloudBuildVersionVars != null)
                {
                    this.CloudBuildVersionVars = cloudBuildVersionVars.ToArray();
                }

                var outputProperties = new Dictionary <string, PropertySet>(StringComparer.OrdinalIgnoreCase)
                {
                    { "BuildVersion", this.Version },
                    { "AssemblyInformationalVersion", this.AssemblyInformationalVersion },
                    { "AssemblyFileVersion", this.AssemblyFileVersion },
                    { "FileVersion", this.AssemblyFileVersion },
                    { "BuildVersionSimple", this.SimpleVersion },
                    { "PrereleaseVersion", this.PrereleaseVersion },
                    { "MajorMinorVersion", this.MajorMinorVersion },
                    { "AssemblyVersion", this.AssemblyVersion },
                    { "GitCommitId", this.GitCommitId },
                    { "GitCommitIdShort", this.GitCommitIdShort },
                    { "GitCommitDateTicks", this.GitCommitDateTicks },
                    { "GitVersionHeight", this.GitVersionHeight.ToString(CultureInfo.InvariantCulture) },
                    { "BuildNumber", this.BuildNumber.ToString(CultureInfo.InvariantCulture) },
                    { "BuildVersionNumberComponent", this.BuildNumber.ToString(CultureInfo.InvariantCulture) },
                    { "PublicRelease", this.PublicRelease.ToString(CultureInfo.InvariantCulture) },
                    { "BuildingRef", this.BuildingRef },
                    { "CloudBuildNumber", new PropertySet(this.CloudBuildNumber)
                      {
                          HonorPresetValue = true
                      } },
                    { "SemVerBuildSuffix", this.BuildMetadataFragment },
                    { "NuGetPackageVersion", this.NuGetPackageVersion },
                    { "ChocolateyPackageVersion", this.ChocolateyPackageVersion },
                    { "Version", this.NuGetPackageVersion },
                    { "PackageVersion", this.NuGetPackageVersion },
                    { "NPMPackageVersion", this.NpmPackageVersion.ToString(CultureInfo.InvariantCulture) },
                    { "BuildVersion3Components", $"{this.MajorMinorVersion}.{this.BuildNumber}" },
                };
                this.OutputProperties = outputProperties.Select(kv =>
                {
                    var item = new TaskItem(kv.Key);
                    item.SetMetadata("Value", kv.Value.Value);
                    item.SetMetadata("HonorPresetValue", kv.Value.HonorPresetValue ? "true" : "false");
                    return(item);
                }).ToArray();

                return(!this.Log.HasLoggedErrors);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                this.Log.LogErrorFromException(ex);
                return(false);
            }
        }