Task IConfigurableComponent.ConfigureAsync(
            IEnvironment environment, EnvironmentVariableTarget environmentTarget,
            IGit git, GitConfigurationLevel configurationLevel)
        {
            // NOTE: We currently only update the PATH in Windows installations and leave putting the GCM executable
            //       on the PATH on other platform to their installers.
            if (PlatformUtils.IsWindows())
            {
                string directoryPath = Path.GetDirectoryName(_appPath);
                if (!environment.IsDirectoryOnPath(directoryPath))
                {
                    Context.Trace.WriteLine("Adding application to PATH...");
                    environment.AddDirectoryToPath(directoryPath, environmentTarget);
                }
                else
                {
                    Context.Trace.WriteLine("Application is already on the PATH.");
                }
            }

            string helperKey        = $"{Constants.GitConfiguration.Credential.SectionName}.{Constants.GitConfiguration.Credential.Helper}";
            string gitConfigAppName = GetGitConfigAppName();

            IGitConfiguration targetConfig = git.GetConfiguration(configurationLevel);

            /*
             * We are looking for the following to be considered already set:
             *
             * [credential]
             *     ...                         # any number of helper entries
             *     helper =                    # an empty value to reset/clear any previous entries
             *     helper = {gitConfigAppName} # the expected executable value in the last position & directly following the empty value
             *
             */

            string[] currentValues = targetConfig.GetRegex(helperKey, Constants.RegexPatterns.Any).ToArray();
            if (currentValues.Length < 2 ||
                !string.IsNullOrWhiteSpace(currentValues[currentValues.Length - 2]) ||    // second to last entry is empty
                currentValues[currentValues.Length - 1] != gitConfigAppName)              // last entry is the expected executable
            {
                Context.Trace.WriteLine("Updating Git credential helper configuration...");

                // Clear any existing entries in the configuration.
                targetConfig.UnsetAll(helperKey, Constants.RegexPatterns.Any);

                // Add an empty value for `credential.helper`, which has the effect of clearing any helper value
                // from any lower-level Git configuration, then add a second value which is the actual executable path.
                targetConfig.SetValue(helperKey, string.Empty);
                targetConfig.ReplaceAll(helperKey, Constants.RegexPatterns.None, gitConfigAppName);
            }
            else
            {
                Context.Trace.WriteLine("Credential helper configuration is already set correctly.");
            }


            return(Task.CompletedTask);
        }
        public void GitConfiguration_SetValue_All_ThrowsException()
        {
            string repoPath = CreateRepository(out _);

            string            gitPath = GetGitPath();
            var               trace   = new NullTrace();
            var               git     = new GitProcess(trace, gitPath, repoPath);
            IGitConfiguration config  = git.GetConfiguration(GitConfigurationLevel.All);

            Assert.Throws <InvalidOperationException>(() => config.SetValue("core.foobar", "test123"));
        }
        public void GitConfiguration_SetValue_Local_SetsLocalConfig()
        {
            string repoPath = CreateRepository(out string workDirPath);

            string            gitPath = GetGitPath();
            var               trace   = new NullTrace();
            var               git     = new GitProcess(trace, gitPath, repoPath);
            IGitConfiguration config  = git.GetConfiguration(GitConfigurationLevel.Local);

            config.SetValue("core.foobar", "foo123");

            GitResult localResult = Git(repoPath, workDirPath, "config --local core.foobar");

            Assert.Equal("foo123", localResult.StandardOutput.Trim());
        }
        public Task ConfigureAsync(
            IEnvironment environment, EnvironmentVariableTarget environmentTarget,
            IGit git, GitConfigurationLevel configurationLevel)
        {
            string useHttpPathKey = $"{KnownGitCfg.Credential.SectionName}.https://dev.azure.com.{KnownGitCfg.Credential.UseHttpPath}";

            IGitConfiguration targetConfig = git.GetConfiguration(configurationLevel);

            if (targetConfig.TryGetValue(useHttpPathKey, out string currentValue) && currentValue.IsTruthy())
            {
                Context.Trace.WriteLine("Git configuration 'credential.useHttpPath' is already set to 'true' for https://dev.azure.com.");
            }
            else
            {
                Context.Trace.WriteLine("Setting Git configuration 'credential.useHttpPath' to 'true' for https://dev.azure.com...");
                targetConfig.SetValue(useHttpPathKey, "true");
            }

            return(Task.CompletedTask);
        }
        public Task ConfigureAsync(ConfigurationTarget target)
        {
            string useHttpPathKey = $"{KnownGitCfg.Credential.SectionName}.https://dev.azure.com.{KnownGitCfg.Credential.UseHttpPath}";

            GitConfigurationLevel configurationLevel = target == ConfigurationTarget.System
                ? GitConfigurationLevel.System
                : GitConfigurationLevel.Global;

            IGitConfiguration targetConfig = _context.Git.GetConfiguration(configurationLevel);

            if (targetConfig.TryGetValue(useHttpPathKey, out string currentValue) && currentValue.IsTruthy())
            {
                _context.Trace.WriteLine("Git configuration 'credential.useHttpPath' is already set to 'true' for https://dev.azure.com.");
            }
            else
            {
                _context.Trace.WriteLine("Setting Git configuration 'credential.useHttpPath' to 'true' for https://dev.azure.com...");
                targetConfig.SetValue(useHttpPathKey, "true");
            }

            return(Task.CompletedTask);
        }