Example #1
0
            public void Provider_must_be_defined_value()
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.Integrations.Provider = (ChangeLogConfiguration.IntegrationProvider)(-1);

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                Assert.Collection(result.Errors,
                                  error => Assert.Contains("'Integration Provider'", error.ErrorMessage)
                                  );
            }
Example #2
0
            public void SourceDirectoryPath_may_be_null_or_whitespace_when_message_overrides_are_disabled_or_another_provider_is_used(bool enabled, ChangeLogConfiguration.MessageOverrideProvider provider, string sourceDirectoryPath)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.MessageOverrides.Enabled             = enabled;
                config.MessageOverrides.Provider            = provider;
                config.MessageOverrides.SourceDirectoryPath = sourceDirectoryPath;

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.True(result.IsValid);
                Assert.Empty(result.Errors);
            }
Example #3
0
                public void AccessToken_must_not_be_whitespace(string accessToken)
                {
                    // ARRANGE
                    var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                    config.Integrations.GitLab.AccessToken = accessToken;

                    var sut = new ConfigurationValidator();

                    // ACT
                    var result = sut.Validate(config);

                    // ASSERT
                    Assert.False(result.IsValid);
                    var error = Assert.Single(result.Errors);

                    Assert.Contains("'GitLab Access Token'", error.ErrorMessage);
                }
Example #4
0
                public void Repository_must_not_be_whitespace(string repository)
                {
                    // ARRANGE
                    var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                    config.Integrations.GitHub.Repository = repository;

                    var sut = new ConfigurationValidator();

                    // ACT
                    var result = sut.Validate(config);

                    // ASSERT
                    Assert.False(result.IsValid);
                    var error = Assert.Single(result.Errors);

                    Assert.Contains("'GitHub Repository Name'", error.ErrorMessage);
                }
Example #5
0
            public void GitNotesNamespace_must_not_be_null_or_whitespace_when_message_overrides_are_enabled(string gitNotesNamespace)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.MessageOverrides.Enabled           = true;
                config.MessageOverrides.GitNotesNamespace = gitNotesNamespace;

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                Assert.Collection(result.Errors,
                                  error => Assert.Contains("'Commit Message Overide Git Notes Namespace'", error.ErrorMessage)
                                  );
            }
Example #6
0
            public void SourceDirectoryPath_must_not_be_null_or_whitespace_when_message_overrides_are_enabled(string sourceDirectoryPath)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.MessageOverrides.Enabled             = true;
                config.MessageOverrides.Provider            = ChangeLogConfiguration.MessageOverrideProvider.FileSystem;
                config.MessageOverrides.SourceDirectoryPath = sourceDirectoryPath;

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                Assert.Collection(result.Errors,
                                  error => Assert.Contains("'Commit Message Override Source Directory'", error.ErrorMessage)
                                  );
            }
Example #7
0
        public void ChangeLog_is_converted_to_expected_Markdown_15()
        {
            // if a display name is configured for a footer,
            // the output must use the display name instead of the footer name

            var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

            config.Footers = new[]
            {
                new ChangeLogConfiguration.FooterConfiguration()
                {
                    Name = "see-also", DisplayName = "See Also"
                },
                new ChangeLogConfiguration.FooterConfiguration()
                {
                    Name = "reviewed-by", DisplayName = "Reviewed by"
                }
            };

            var versionChangeLog = GetSingleVersionChangeLog(
                "1.2.3",
                null,

                GetChangeLogEntry(scope: "scope1", type: "feat", summary: "Some change", footers: new[]
            {
                new ChangeLogEntryFooter(new CommitMessageFooterName("See-Also"), "Issue #5")
            }),

                GetChangeLogEntry(scope: "scope2", type: "fix", summary: "A bug was fixed", footers: new[]
            {
                new ChangeLogEntryFooter(new CommitMessageFooterName("Reviewed-by"), "*****@*****.**")
            })
                );

            var changeLog = new ApplicationChangeLog()
            {
                versionChangeLog
            };

            Approve(changeLog, config);
        }
Example #8
0
        public void Footer_name_must_not_be_null_of_whitespace(string footerName)
        {
            // ARRANGE
            var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

            config.Footers = new[]
            {
                new ChangeLogConfiguration.FooterConfiguration()
                {
                    Name = footerName, DisplayName = "Display Name"
                }
            };

            var sut = new ConfigurationValidator(m_Logger);

            // ACT
            var valid = sut.Validate(config);

            // ASSERT
            Assert.False(valid);
        }
Example #9
0
        public void Entry_type_must_not_be_null_of_whitespace(string entryType)
        {
            // ARRANGE
            var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

            config.EntryTypes = new[]
            {
                new ChangeLogConfiguration.EntryTypeConfiguration()
                {
                    Type = entryType, DisplayName = "Display Name"
                }
            };

            var sut = new ConfigurationValidator(m_Logger);

            // ACT
            var valid = sut.Validate(config);

            // ASSERT
            Assert.False(valid);
        }
Example #10
0
        public async Task Run_does_nothing_if_remote_url_cannot_be_parsed(string remoteName, string url)
        {
            // ARRANGE
            var configuration = ChangeLogConfigurationLoader.GetDefaultConfiguration();

            configuration.Integrations.GitHub.RemoteName = remoteName;

            var repoMock = new Mock <IGitRepository>(MockBehavior.Strict);

            repoMock.SetupRemotes(remoteName, url);

            var sut       = new GitHubLinkTask(m_Logger, configuration, repoMock.Object, m_GitHubClientFactoryMock.Object);
            var changeLog = new ApplicationChangeLog();

            // ACT
            var result = await sut.RunAsync(changeLog);

            // ASSERT
            Assert.Equal(ChangeLogTaskResult.Skipped, result);
            m_GitHubClientFactoryMock.Verify(x => x.CreateClient(It.IsAny <string>()), Times.Never);
        }
Example #11
0
            public void Custom_directory_can_be_null_or_empty(
                ChangeLogConfiguration.TemplateName template,
                [CombinatorialValues(null, "")] string customDirectory)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                var customDirectoryProperty = config.Template.GetType().GetProperty(template.ToString());
                var templateSettings        = (ChangeLogConfiguration.TemplateSettings)customDirectoryProperty !.GetValue(config.Template) !;

                templateSettings.CustomDirectory = customDirectory;

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.True(result.IsValid);
                Assert.Empty(result.Errors);
            }
Example #12
0
            public void Custom_directory_is_valid_when_directory_exists(ChangeLogConfiguration.TemplateName template)
            {
                // ARRANGE
                using var temporaryDirectory = new TemporaryDirectory();

                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                var customDirectoryProperty = config.Template.GetType().GetProperty(template.ToString());
                var templateSettings        = (ChangeLogConfiguration.TemplateSettings)customDirectoryProperty !.GetValue(config.Template) !;

                templateSettings.CustomDirectory = temporaryDirectory;

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.True(result.IsValid);
                Assert.Empty(result.Errors);
            }
Example #13
0
            public void Name_must_be_unique(string scopeName)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.Scopes = new Dictionary <string, ChangeLogConfiguration.ScopeConfiguration>()
                {
                    { scopeName.ToLower(), new ChangeLogConfiguration.ScopeConfiguration() },
                    { scopeName.ToUpper(), new ChangeLogConfiguration.ScopeConfiguration() }
                };

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                var error = Assert.Single(result.Errors);

                Assert.Contains("'Scope Name' must be unique", error.ErrorMessage);
            }
Example #14
0
        public async Task Run_ignores_tags_that_are_not_a_valid_version(string tagName)
        {
            // ARRANGE
            var tags = new GitTag[]
            {
                new GitTag(tagName, new GitId("01")),
            };

            var repoMock = new Mock <IGitRepository>(MockBehavior.Strict);

            repoMock.Setup(x => x.GetTags()).Returns(tags);

            var sut = new LoadVersionsFromTagsTask(m_Logger, ChangeLogConfigurationLoader.GetDefaultConfiguration(), repoMock.Object);

            // ACT
            var changeLog = new ApplicationChangeLog();
            var result    = await sut.RunAsync(changeLog);

            // ASSERT
            Assert.Empty(changeLog.Versions);
            Assert.Equal(ChangeLogTaskResult.Success, result);
        }
Example #15
0
        public async Task Task_succeeds_if_override_directory_does_not_exist(string sourceDirectoryPath)
        {
            // ARRANGE
            using var repositoryDirectory = new TemporaryDirectory();

            var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();
            {
                config.RepositoryPath = repositoryDirectory;
                config.MessageOverrides.SourceDirectoryPath = sourceDirectoryPath;
            }

            var commit1 = GetGitCommit(id: TestGitIds.Id1, commitMessage: "Original Message 1");
            var commit2 = GetGitCommit(id: TestGitIds.Id2, commitMessage: "Original Message 2");

            var repo = new Mock <IGitRepository>(MockBehavior.Strict);

            var versionChangeLog = GetSingleVersionChangeLog("1.2.3", TestGitIds.Id1);
            {
                versionChangeLog.Add(commit1);
                versionChangeLog.Add(commit2);
            }

            var sut = new LoadMessageOverridesFromFileSystemTask(m_Logger, config, repo.Object);

            // ACT
            var result = await sut.RunAsync(new ApplicationChangeLog()
            {
                versionChangeLog
            });

            // ASSERT
            Assert.Equal(ChangeLogTaskResult.Success, result);
            Assert.Collection(
                versionChangeLog.AllCommits,
                c => Assert.Equal(commit1, c),
                c => Assert.Equal(commit2, c)
                );
        }
Example #16
0
            public void Name_must_not_be_empty_or_whitespace(string footerName)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                config.Footers = new Dictionary <string, ChangeLogConfiguration.FooterConfiguration>()
                {
                    { footerName, new ChangeLogConfiguration.FooterConfiguration()
                      {
                          DisplayName = "Display Name"
                      } }
                };

                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                var error = Assert.Single(result.Errors);

                Assert.Contains("'Footer Name'", error.ErrorMessage);
            }
Example #17
0
            public void Custom_directory_must_not_be_whitespace(
                ChangeLogConfiguration.TemplateName template,
                [CombinatorialValues("\t", " ")] string customDirectory)
            {
                // ARRANGE
                var config = ChangeLogConfigurationLoader.GetDefaultConfiguration();

                var customDirectoryProperty = config.Template.GetType().GetProperty(template.ToString());
                var templateSettings        = (ChangeLogConfiguration.TemplateSettings)customDirectoryProperty !.GetValue(config.Template) !;

                templateSettings.CustomDirectory = customDirectory;


                var sut = new ConfigurationValidator();

                // ACT
                var result = sut.Validate(config);

                // ASSERT
                Assert.False(result.IsValid);
                Assert.Collection(result.Errors,
                                  error => Assert.Contains("'Template Custom Directory'", error.ErrorMessage)
                                  );
            }
Example #18
0
        private static async Task <int> RunAsync(CommandLineParameters commandlineParameters)
        {
            var loggerOptions = commandlineParameters.Verbose
                ? new SimpleConsoleLoggerConfiguration(LogLevel.Debug, true, true)
                : new SimpleConsoleLoggerConfiguration(LogLevel.Information, false, true);

            // for validation of command line parameters, directly create a console logger
            // bypassing the DI container because we need to validate the parameters
            // before setting up DI
            var logger = new SimpleConsoleLogger(loggerOptions, "");

            if (!ValidateCommandlineParameters(commandlineParameters, logger))
            {
                return(1);
            }

            var configurationFilePath = !String.IsNullOrEmpty(commandlineParameters.ConfigurationFilePath)
                ? commandlineParameters.ConfigurationFilePath
                : Path.Combine(commandlineParameters.RepositoryPath, s_DefaultConfigurationFileName);

            var configuration = ChangeLogConfigurationLoader.GetConfiguration(configurationFilePath, commandlineParameters);

            using (var gitRepository = new GitRepository(configuration.RepositoryPath))
            {
                var containerBuilder = new ContainerBuilder();

                containerBuilder.RegisterType <ConfigurationValidator>();
                containerBuilder.RegisterInstance(configuration).SingleInstance();
                containerBuilder.RegisterInstance(gitRepository).SingleInstance().As <IGitRepository>();

                containerBuilder.RegisterLogging(loggerOptions);

                containerBuilder.RegisterType <ChangeLogPipeline>();

                containerBuilder.RegisterType <LoadCurrentVersionTask>();
                containerBuilder.RegisterType <LoadVersionsFromTagsTask>();
                containerBuilder.RegisterType <ParseCommitsTask>();
                containerBuilder.RegisterType <FilterVersionsTask>();
                containerBuilder.RegisterType <FilterEntriesTask>();
                containerBuilder.RegisterType <RenderTemplateTask>();

                containerBuilder.RegisterIntegrations();

                try
                {
                    containerBuilder.RegisterTemplate(configuration.Template);
                }
                catch (InvalidTemplateConfigurationException ex)
                {
                    logger.LogCritical($"Failed to load template: {ex.Message}");
                    return(1);
                }

                using (var container = containerBuilder.Build())
                {
                    var configurationValidator = container.Resolve <ConfigurationValidator>();

                    if (!configurationValidator.Validate(configuration))
                    {
                        logger.LogCritical($"Validation of configuration failed");
                        return(1);
                    }

                    // Note: The order of the tasks added here is important.
                    // E.g. In order for commits for versions loaded correctly, ParseCommitsTask needs to run before FilterVersionsTask
                    var pipeline = new ChangeLogPipelineBuilder(container)
                                   .AddTask <LoadCurrentVersionTask>()
                                   .AddTask <LoadVersionsFromTagsTask>()
                                   .AddTask <ParseCommitsTask>()
                                   .AddTask <FilterVersionsTask>()
                                   .AddTask <FilterEntriesTask>()
                                   .AddIntegrationTasks()
                                   .AddTask <RenderTemplateTask>()
                                   .Build();

                    var result = await pipeline.RunAsync();

                    return(result.Success ? 0 : 1);
                }
            }
        }
Example #19
0
 public ParseCommitsTaskTest(ITestOutputHelper testOutputHelper)
 {
     m_Logger = new XunitLogger <ParseCommitsTask>(testOutputHelper);
     m_DefaultConfiguration = ChangeLogConfigurationLoader.GetDefaultConfiguration();
 }
Example #20
0
 public FilterEntriesTaskTest(ITestOutputHelper testOutputHelper)
 {
     m_Logger = new XunitLogger <FilterEntriesTask>(testOutputHelper);
     m_DefaultConfiguration = ChangeLogConfigurationLoader.GetDefaultConfiguration();
 }
Example #21
0
        private static async Task <int> RunAsync(CommandLineParameters commandlineParameters)
        {
            var loggerOptions = commandlineParameters.Verbose
                ? new SimpleConsoleLoggerConfiguration(LogLevel.Debug, true, true)
                : new SimpleConsoleLoggerConfiguration(LogLevel.Information, false, true);

            // for validation of command line parameters, directly create a console logger
            // bypassing the DI container because we need to validate the parameters
            // before setting up DI
            var logger = new SimpleConsoleLogger(loggerOptions, "");

            if (!ValidateCommandlineParameters(commandlineParameters, logger))
            {
                return(1);
            }

            if (!TryGetRepositoryPath(commandlineParameters, logger, out var repositoryPath))
            {
                return(1);
            }

            if (!TryOpenRepository(repositoryPath, logger, out var gitRepository))
            {
                return(1);
            }

            var configurationFilePath = GetConfigurationFilePath(commandlineParameters, repositoryPath);

            if (File.Exists(configurationFilePath))
            {
                logger.LogDebug($"Using configuration file '{configurationFilePath}'");
            }
            else
            {
                logger.LogDebug("Continuing without loading a configuration file, because no configuration file was wound");
            }


            // pass repository path to configuration loader to make it available through the configuration system
            var dynamicSettings = new DynamicallyDeterminedSettings()
            {
                RepositoryPath = repositoryPath
            };

            var configuration = ChangeLogConfigurationLoader.GetConfiguration(configurationFilePath, commandlineParameters, dynamicSettings);

            using (gitRepository)
            {
                var containerBuilder = new ContainerBuilder();

                containerBuilder.RegisterType <ConfigurationValidator>();
                containerBuilder.RegisterInstance(configuration).SingleInstance();
                containerBuilder.RegisterInstance(gitRepository).SingleInstance().As <IGitRepository>();

                containerBuilder.RegisterLogging(loggerOptions);

                containerBuilder.RegisterType <ChangeLogPipeline>();

                containerBuilder.RegisterType <LoadCurrentVersionTask>();
                containerBuilder.RegisterType <LoadVersionsFromTagsTask>();
                containerBuilder.RegisterType <LoadCommitsTask>();
                containerBuilder.RegisterType <LoadMessageOverridesFromGitNotesTask>();
                containerBuilder.RegisterType <LoadMessageOverridesFromFileSystemTask>();
                containerBuilder.RegisterType <ParseCommitsTask>();
                containerBuilder.RegisterType <ParseCommitReferencesTask>();
                containerBuilder.RegisterType <FilterVersionsTask>();
                containerBuilder.RegisterType <FilterEntriesTask>();
                containerBuilder.RegisterType <ResolveEntryReferencesTask>();
                containerBuilder.RegisterType <AddCommitFooterTask>();
                containerBuilder.RegisterType <ParseWebLinksTask>();
                containerBuilder.RegisterType <RenderTemplateTask>();

                containerBuilder.RegisterIntegrations();

                try
                {
                    containerBuilder.RegisterTemplate(configuration.Template);
                }
                catch (InvalidTemplateConfigurationException ex)
                {
                    logger.LogError($"Failed to load template: {ex.Message}");
                    return(1);
                }

                using (var container = containerBuilder.Build())
                {
                    var configurationValidator = container.Resolve <ConfigurationValidator>();
                    var validationResult       = configurationValidator.Validate(configuration);

                    if (!validationResult.IsValid)
                    {
                        foreach (var error in validationResult.Errors)
                        {
                            logger.LogError($"Invalid configuration: {error.ErrorMessage}");
                        }

                        logger.LogError($"Validation of configuration failed");
                        return(1);
                    }

                    var pipeline = new ChangeLogPipelineBuilder(container)
                                   .AddTask <LoadCurrentVersionTask>()
                                   .AddTask <LoadVersionsFromTagsTask>()
                                   .AddTask <LoadCommitsTask>()
                                   .AddTaskIf <LoadMessageOverridesFromGitNotesTask>(
                        configuration.MessageOverrides.Enabled && configuration.MessageOverrides.Provider == ChangeLogConfiguration.MessageOverrideProvider.GitNotes
                        )
                                   .AddTaskIf <LoadMessageOverridesFromFileSystemTask>(
                        configuration.MessageOverrides.Enabled && configuration.MessageOverrides.Provider == ChangeLogConfiguration.MessageOverrideProvider.FileSystem
                        )
                                   .AddTask <ParseCommitsTask>()
                                   .AddTask <ParseCommitReferencesTask>()
                                   .AddTask <ParseWebLinksTask>()
                                   .AddTask <FilterVersionsTask>()
                                   .AddTask <FilterEntriesTask>()
                                   .AddTask <ResolveEntryReferencesTask>()
                                   .AddTask <AddCommitFooterTask>()
                                   .AddIntegrationTasks()
                                   .AddTask <RenderTemplateTask>()
                                   .Build();

                    var result = await pipeline.RunAsync();

                    return(result.Success ? 0 : 1);
                }
            }
        }