Пример #1
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            settings.SourceControlServerSettings.Scope = ServerScope.Global;

            if (settings.PackageFilters.Includes == null)
            {
                return(ValidationResult.Failure("Global mode must have an include regex"));
            }

            var apiHost = CollaborationFactory.Settings.BaseApiUrl.Host;

            if (apiHost.EndsWith("github.com", StringComparison.OrdinalIgnoreCase))
            {
                return(ValidationResult.Failure("Global mode must not use public github"));
            }

            return(ValidationResult.Success);
        }
        protected override async Task <ValidationResult> PopulateSettings(SettingsContainer settings)
        {
            var baseResult = await base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            const int defaultMaxPackageUpdates = 1;
            var       fileSettings             = FileSettingsCache.GetSettings();

            var maxUpdates = Concat.FirstValue(
                MaxPackageUpdates,
                fileSettings.MaxPackageUpdates,
                defaultMaxPackageUpdates);

            if (maxUpdates < 1)
            {
                return(ValidationResult.Failure($"Max package updates of {maxUpdates} is not valid"));
            }

            settings.PackageFilters.MaxPackageUpdates = maxUpdates;
            return(ValidationResult.Success);
        }
Пример #3
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            settings.ModalSettings.Mode = RunMode.Global;

            if (settings.UserSettings.PackageIncludes == null)
            {
                return(ValidationResult.Failure("Global mode must have an include regex"));
            }

            var apiHost = settings.GithubAuthSettings.ApiBase.Host;

            if (apiHost.EndsWith("github.com"))
            {
                return(ValidationResult.Failure("Global mode must not use public github"));
            }

            return(ValidationResult.Success);
        }
        private ValidationResult PopulateDeleteBranchAfterMerge(
            SettingsContainer settings)
        {
            var fileSettings = FileSettingsCache.GetSettings();

            bool defaultValue;

            // The default value is true, if it is supported for the corresponding platform.
            if (Platform.HasValue && !_platformsSupportingDeleteBranchAfterMerge.Contains(Platform.Value))
            {
                defaultValue = false;
            }
            else
            {
                defaultValue = true;
            }

            settings.BranchSettings.DeleteBranchAfterMerge = Concat.FirstValue(DeleteBranchAfterMerge, fileSettings.DeleteBranchAfterMerge, defaultValue);

            // Ensure that the resulting DeleteBranchAfterMerge value is supported.
            if (settings.BranchSettings.DeleteBranchAfterMerge &&
                Platform.HasValue &&
                !_platformsSupportingDeleteBranchAfterMerge.Contains(Platform.Value))
            {
                return(ValidationResult.Failure("Deletion of source branch after merge is currently only available for Azure DevOps, Gitlab and Bitbucket."));
            }

            return(ValidationResult.Success);
        }
Пример #5
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            var fileSettings = FileSettingsCache.GetSettings();

            var endpoint = Concat.FirstValue(ApiEndpoint, fileSettings.Api, settings.SourceControlServerSettings.Repository?.ApiUri.ToString());
            var forkMode = ForkMode ?? fileSettings.ForkMode;
            var platform = Platform ?? fileSettings.Platform;

            if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var baseUri))
            {
                return(ValidationResult.Failure($"Bad Api Base '{endpoint}'"));
            }

            try
            {
                var collaborationResult = CollaborationFactory.Initialise(
                    baseUri, PersonalAccessToken,
                    forkMode, platform);

                if (!collaborationResult.IsSuccess)
                {
                    return(collaborationResult);
                }
            }
#pragma warning disable CA1031
            catch (Exception ex)
#pragma warning restore CA1031
            {
                return(ValidationResult.Failure(ex.Message));
            }

            if (CollaborationFactory.Settings.Token == null)
            {
                return(ValidationResult.Failure("The required access token was not found"));
            }

            settings.UserSettings.ConsolidateUpdatesInSinglePullRequest =
                Concat.FirstValue(Consolidate, fileSettings.Consolidate, false);

            const int defaultMaxPackageUpdates = 3;
            settings.PackageFilters.MaxPackageUpdates =
                Concat.FirstValue(MaxPackageUpdates, fileSettings.MaxPackageUpdates, defaultMaxPackageUpdates);

            var defaultLabels = new List <string> {
                "nukeeper"
            };

            settings.SourceControlServerSettings.Labels =
                Concat.FirstPopulatedList(Label, fileSettings.Label, defaultLabels);

            return(ValidationResult.Success);
        }
Пример #6
0
        protected override ValidationResult ValidateSettings(SettingsContainer settings)
        {
            if (string.IsNullOrWhiteSpace(GitHubToken))
            {
                return(ValidationResult.Failure("The required GitHub access token was not found"));
            }

            return(base.ValidateSettings(settings));
        }
Пример #7
0
        protected override async Task <ValidationResult> PopulateSettings(SettingsContainer settings)
        {
            if (string.IsNullOrWhiteSpace(RepositoryUri))
            {
                return(ValidationResult.Failure($"Missing repository URI"));
            }

            Uri repoUri;

            try
            {
                repoUri = RepositoryUri.ToUri();
            }
            catch (UriFormatException)
            {
                return(ValidationResult.Failure($"Bad repository URI: '{RepositoryUri}'"));
            }

            var didRead = false;

            foreach (var reader in _settingsReaders)
            {
                if (didRead)
                {
                    continue;
                }

                if (await reader.CanRead(repoUri))
                {
                    didRead = true;
                    settings.SourceControlServerSettings.Repository =
                        await reader.RepositorySettings(repoUri, TargetBranch);
                }
            }

            if (!didRead)
            {
                return(ValidationResult.Failure($"Unable to work out which platform to use {RepositoryUri} could not be matched"));
            }

            var baseResult = await base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            if (settings.SourceControlServerSettings.Repository == null)
            {
                return(ValidationResult.Failure($"Could not read repository URI: '{RepositoryUri}'"));
            }

            settings.SourceControlServerSettings.Scope   = ServerScope.Repository;
            settings.UserSettings.MaxRepositoriesChanged = 1;
            return(ValidationResult.Success);
        }
Пример #8
0
        private ValidationResult PopulateBranchNameTemplate(
            SettingsContainer settings)
        {
            var settingsFromFile = FileSettingsCache.GetSettings();
            var value            = Concat.FirstValue(BranchNameTemplate, settingsFromFile.BranchNameTemplate);

            if (string.IsNullOrWhiteSpace(value))
            {
                settings.BranchSettings.BranchNameTemplate = null;
                return(ValidationResult.Success);
            }

            // Validating git branch names: https://stackoverflow.com/a/12093994/1661209
            // We validate the user defined branch name prefix in combination with a actual branch name that NuKeeper could create.
            // We want to validate the combination since the prefix doesn't need to fully comply with the rules (E.G. 'nukeeper/' is not allowed soley as a branch name).

            var tokenErrors = new StringBuilder();
            var tokenSet    = Regex.Matches(value, @"{(\w+)}").Select(match => match.Groups[1].Value);

            foreach (var token in tokenSet)
            {
                if (!BranchNamer.IsValidTemplateToken(token))
                {
                    tokenErrors.Append($",{token}");
                }
            }

            // Check for valid placeholders
            if (tokenErrors.Length > 0)
            {
                return(ValidationResult.Failure(
                           $"Provided branch template has unknown tokens: '{tokenErrors.ToString().Trim(',')}'."));
            }

            // Test if the generated branchname would be ok.
            // We assume tokens will be generated in valid values, so we use dummy values here
            var tokenValues = new Dictionary <string, string>();

            foreach (var token in BranchNamer.TemplateTokens)
            {
                tokenValues.Add(token, "dummy");
            }

            var validationValue = BranchNamer.MakeName(tokenValues, value);

            if (!Regex.IsMatch(validationValue, @"^(?!@$|build-|/|.*([/.]\.|//|@\{|\\))[^\000-\037\177 ~^:?*[]+/[^\000-\037\177 ~^:?*[]+(?<!\.lock|[/.])$"))
            {
                return(ValidationResult.Failure(
                           $"Provided branch template '{value}' does not comply with branch naming rules."));
            }

            settings.BranchSettings.BranchNameTemplate = value;
            return(ValidationResult.Success);
        }
Пример #9
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            var apiBase = GithubEndpointWithFallback();

            if (string.IsNullOrWhiteSpace(apiBase))
            {
                return(ValidationResult.Failure("No GitHub Api base found"));
            }

            if (!Uri.TryCreate(apiBase, UriKind.Absolute, out var githubUri))
            {
                return(ValidationResult.Failure($"Bad GitHub Api base '{GithubApiEndpoint}'"));
            }

            var token = ReadToken();

            if (string.IsNullOrWhiteSpace(token))
            {
                return(ValidationResult.Failure("The required GitHub access token was not found"));
            }

            var githubUrl = GitSettingsReader.EnsureTrailingSlash(githubUri);

            var fileSettings = FileSettingsCache.Get();

            settings.GithubAuthSettings = new GithubAuthSettings(githubUrl, token);

            settings.UserSettings.ConsolidateUpdatesInSinglePullRequest =
                Concat.FirstValue(Consolidate, fileSettings.Consolidate, false);


            const int defaultMaxPullRequests = 3;

            settings.PackageFilters.MaxPackageUpdates =
                Concat.FirstValue(MaxPullRequestsPerRepository, fileSettings.MaxPr, defaultMaxPullRequests);

            settings.UserSettings.ForkMode   = ForkMode;
            settings.UserSettings.ReportMode = ReportMode;

            var defaultLabels = new[] { "nukeeper" };

            settings.SourceControlServerSettings.Labels =
                Concat.FirstPopulatedList(Label, fileSettings.Label, defaultLabels);

            return(ValidationResult.Success);
        }
Пример #10
0
        protected virtual async Task <ValidationResult> PopulateSettings(SettingsContainer settings)
        {
            var minPackageAge = ReadMinPackageAge();

            if (!minPackageAge.HasValue)
            {
                return(await Task.FromResult(ValidationResult.Failure($"Min package age '{MinimumPackageAge}' could not be parsed")));
            }

            settings.PackageFilters.MinimumAge = minPackageAge.Value;

            var regexIncludeValid = PopulatePackageIncludes(settings);

            if (!regexIncludeValid.IsSuccess)
            {
                return(regexIncludeValid);
            }

            var regexExcludeValid = PopulatePackageExcludes(settings);

            if (!regexExcludeValid.IsSuccess)
            {
                return(regexExcludeValid);
            }

            var settingsFromFile = FileSettingsCache.GetSettings();

            var defaultOutputDestination = string.IsNullOrWhiteSpace(OutputFileName)
                ? Abstractions.Output.OutputDestination.Console
                : Abstractions.Output.OutputDestination.File;

            settings.UserSettings.OutputDestination =
                Concat.FirstValue(OutputDestination, settingsFromFile.OutputDestination,
                                  defaultOutputDestination);

            settings.UserSettings.OutputFormat =
                Concat.FirstValue(OutputFormat, settingsFromFile.OutputFormat,
                                  Abstractions.Output.OutputFormat.Text);

            settings.UserSettings.OutputFileName =
                Concat.FirstValue(OutputFileName, settingsFromFile.OutputFileName,
                                  "nukeeper.out");

            var branchNameTemplateValid = PopulateBranchNameTemplate(settings);

            if (!branchNameTemplateValid.IsSuccess)
            {
                return(branchNameTemplateValid);
            }

            return(await Task.FromResult(ValidationResult.Success));
        }
Пример #11
0
        protected override ValidationResult ValidateSettings(SettingsContainer settings)
        {
            if (settings.UserSettings.PackageIncludes == null)
            {
                return(ValidationResult.Failure("Global mode must have an include regex"));
            }

            var apiHost = settings.GithubAuthSettings.ApiBase.Host;

            if (apiHost.EndsWith("github.com"))
            {
                return(ValidationResult.Failure("Global mode must not use public github"));
            }

            return(base.ValidateSettings(settings));
        }
Пример #12
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            if (!string.IsNullOrWhiteSpace(Path) && !Directory.Exists(Path))
            {
                return(ValidationResult.Failure($"Path '{Path}' was not found"));
            }

            settings.UserSettings.Directory = Path;
            return(ValidationResult.Success);
        }
Пример #13
0
        protected override async Task <ValidationResult> PopulateSettings(SettingsContainer settings)
        {
            if (string.IsNullOrWhiteSpace(RepositoryUri))
            {
                return(ValidationResult.Failure($"Missing repository URI"));
            }

            Uri repoUri;

            try
            {
                repoUri = RepositoryUri.ToUri();
            }
            catch (UriFormatException)
            {
                return(ValidationResult.Failure($"Bad repository URI: '{RepositoryUri}'"));
            }

            ISettingsReader reader = await TryGetSettingsReader(repoUri, Platform);

            if (reader == null)
            {
                return(ValidationResult.Failure($"Unable to work out which platform to use {RepositoryUri} could not be matched"));
            }

            settings.SourceControlServerSettings.Repository = await reader.RepositorySettings(repoUri, SetAutoMerge ?? false, TargetBranch, MergeStrategy ?? GitPullRequestMergeStrategy.NoFastForward);

            var baseResult = await base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            if (settings.SourceControlServerSettings.Repository == null)
            {
                return(ValidationResult.Failure($"Could not read repository URI: '{RepositoryUri}'"));
            }

            settings.SourceControlServerSettings.Scope   = ServerScope.Repository;
            settings.UserSettings.MaxRepositoriesChanged = 1;
            settings.UserSettings.Directory = CheckoutDirectory;

            return(ValidationResult.Success);
        }
Пример #14
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            Uri repoUri;

            try
            {
                repoUri = RepositoryUri.ToUri();
            }
            catch
            {
                return(ValidationResult.Failure($"Bad repository URI: '{RepositoryUri}'"));
            }

            var didRead = false;

            foreach (var reader in _settingsReaders)
            {
                if (reader.CanRead(repoUri))
                {
                    didRead = true;
                    settings.SourceControlServerSettings.Repository = reader.RepositorySettings(repoUri);
                }
            }

            if (!didRead)
            {
                return(ValidationResult.Failure($"Unable to work out which platform to use {RepositoryUri} could not be matched"));
            }

            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            if (settings.SourceControlServerSettings.Repository == null)
            {
                return(ValidationResult.Failure($"Could not read repository URI: '{RepositoryUri}'"));
            }

            settings.SourceControlServerSettings.Scope   = ServerScope.Repository;
            settings.UserSettings.MaxRepositoriesChanged = 1;
            return(ValidationResult.Success);
        }
Пример #15
0
        protected override ValidationResult PopulateSettings(SettingsContainer settings)
        {
            var baseResult = base.PopulateSettings(settings);

            if (!baseResult.IsSuccess)
            {
                return(baseResult);
            }

            if (string.IsNullOrWhiteSpace(GithubApiEndpoint))
            {
                return(ValidationResult.Failure("No GitHub Api base found"));
            }


            Uri githubUri;

            if (!Uri.TryCreate(GithubApiEndpoint, UriKind.Absolute, out githubUri))
            {
                return(ValidationResult.Failure($"Bad GitHub Api base '{GithubApiEndpoint}'"));
            }

            var token = ReadToken();

            if (string.IsNullOrWhiteSpace(token))
            {
                return(ValidationResult.Failure("The required GitHub access token was not found"));
            }

            var githubUrl = GitSettingsReader.EnsureTrailingSlash(githubUri);

            settings.GithubAuthSettings = new GithubAuthSettings(githubUrl, token);

            settings.UserSettings.MaxRepositoriesChanged       = AllowedMaxRepositoriesChangedChange;
            settings.UserSettings.MaxPullRequestsPerRepository = MaxPullRequestsPerRepository;
            settings.UserSettings.ForkMode   = ForkMode;
            settings.UserSettings.ReportMode = ReportMode;

            settings.ModalSettings.Labels = Label;

            return(ValidationResult.Success);
        }
Пример #16
0
        private ValidationResult PopulateExcludeRepos(SettingsContainer settings)
        {
            var settingsFromFile = FileSettingsCache.GetSettings();
            var value            = Concat.FirstValue(ExcludeRepos, settingsFromFile.ExcludeRepos);

            if (string.IsNullOrWhiteSpace(value))
            {
                settings.SourceControlServerSettings.ExcludeRepos = null;
                return(ValidationResult.Success);
            }

            try
            {
                settings.SourceControlServerSettings.ExcludeRepos = new Regex(value);
            }
            catch (Exception ex)
            {
                return(ValidationResult.Failure($"Unable to parse regex '{value}' for ExcludeRepos: {ex.Message}"));
            }

            return(ValidationResult.Success);
        }
Пример #17
0
        private ValidationResult PopulateDeleteBranchAfterMerge(
            SettingsContainer settings)
        {
            var fileSettings = FileSettingsCache.GetSettings();

            if (!Platform.HasValue)
            {
                settings.BranchSettings.DeleteBranchAfterMerge = true;
                return(ValidationResult.Success);
            }

            if (Platform != Abstractions.CollaborationPlatform.Platform.AzureDevOps &&
                Platform != Abstractions.CollaborationPlatform.Platform.GitLab &&
                Platform != Abstractions.CollaborationPlatform.Platform.Bitbucket)
            {
                return(ValidationResult.Failure(
                           $"Deletion of source branch after merge is currently only available for Azure DevOps, Gitlab and Bitbucket."));
            }

            settings.BranchSettings.DeleteBranchAfterMerge = Concat.FirstValue(DeleteBranchAfterMerge, fileSettings.DeleteBranchAfterMerge, true);
            return(ValidationResult.Success);
        }
Пример #18
0
        private static ValidationResult PopulatePackageExcludes(
            SettingsContainer settings, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                settings.UserSettings.PackageExcludes = null;
                return(ValidationResult.Success);
            }

            try
            {
                settings.UserSettings.PackageExcludes = new Regex(value);
            }
            catch (Exception ex)
            {
                {
                    return(ValidationResult.Failure(
                               $"Unable to parse regex '{value}' for Exclude: {ex.Message}"));
                }
            }

            return(ValidationResult.Success);
        }