예제 #1
0
        private async Task <int> ExecuteAsync()
        {
            if (!TryGetConfiguredUrl(out string?baseUrl))
            {
                Console.Error.WriteLine("error: neither policy.url nor GIT_POLICY_URL is set");
                return(-1);
            }

            var api = new PolicyApi(baseUrl !);

            Console.Error.WriteLine("info: checking for policies...");
            Profile?profile = await api.GetProfileAsync();

            if (profile is not null)
            {
                string policyDir        = GetPolicyFileDirectory();
                string policyConfigPath = Path.Combine(policyDir, ".gitconfig");

                // Get policy information
                var policies = new List <Policy>();
                foreach (string policyId in profile.Policies)
                {
                    Policy?policy = await api.GetPolicyAsync(policyId);

                    if (policy is null)
                    {
                        Console.Error.WriteLine("info: unknown policy '{0}'", policyId);
                        continue;
                    }

                    policies.Add(policy);
                }

                // Remove all old policy files and ensure policy directory is created
                if (_fs.DirectoryExists(policyDir))
                {
                    _fs.DeleteDirectory(policyDir, recurse: true);
                }

                _fs.CreateDirectory(policyDir);

                // Write a new policy config file
                var header = new StringBuilder(AutoGenFileHeader);
                header.AppendLine($"# Last synced: {DateTime.Now:s}");
                header.AppendLine("#");

                _fs.WriteAllText(policyConfigPath, header.ToString());

                // Ensure the global config include is set
                string includePath = PathEx.GetHomeRelativePath(policyConfigPath, useTilde: true);
                IEnumerable <string> existingIncludes = _git.GetAllConfig("include.path", GitConfigurationScope.Global);
                if (!existingIncludes.Any(x => includePath.Equals(x)))
                {
                    try
                    {
                        _git.AddConfig("include.path", includePath, GitConfigurationScope.Global);
                    }
                    catch (GitException ex)
                    {
                        Console.Error.WriteLine("error: failed to add global policy configuration include: {0} (exit={1})",
                                                ex.Message, ex.ExitCode);
                        return(-1);
                    }
                }

                // Read all user policy opt-outs
                ISet <string> optOuts = _git.GetAllConfig("policy.ignore").ToHashSet();

                // Write out new policy files and set includes
                foreach (Policy policy in policies)
                {
                    // Check for user opt-out
                    if (optOuts.Contains(policy.Id))
                    {
                        Console.Error.WriteLine("info: policy '{0}' is opted-out", policy.Id);
                        continue;
                    }

                    // Check Git version
                    if (!IsValidGitVersion(policy))
                    {
                        Console.Error.WriteLine("info: policy '{0}' does not apply to current version of Git", policy.Id);
                        continue;
                    }

                    // Create policy file
                    Console.Error.WriteLine("info: creating policy file '{0}'...", policy.Id);
                    string path = Path.Combine(policyDir, policy.Id);
                    CreatePolicyFile(path, policy);

                    try
                    {
                        // Set new policy include
                        Console.Error.WriteLine("info: adding policy to include file '{0}'...", policy.Id);
                        _git.AddConfigInFile(policyConfigPath, "include.path", policy.Id);
                    }
                    catch (GitException ex)
                    {
                        Console.Error.WriteLine("error: failed to add policy include file '{0}': {1} (exit={2})",
                                                policy.Id, ex.Message, ex.ExitCode);
                    }
                }
            }

            return(0);
        }