public void VerifyChangelogWithMultipleReadersIsGenerated() { var toExclude = new List <string> { "Removed" }; var now = DateTimeOffset.Now; var yesterday = now.AddDays(-1); var reader1Mock = new Mock <IGenericReader <IChange> >(); var reader2Mock = new Mock <IGenericReader <IChange> >(); var cacheMock = new Mock <IChangeCache>(); var renderer = new StubbleBuilder().Build(); var readers = new List <IGenericReader <IChange> > { reader1Mock.Object, reader2Mock.Object, }; var readerChanges1 = new List <IChange> { new DefaultChange(new ChangeVersion("1.0.0"), "Added", "Added some other change", now), new DefaultChange(new ChangeVersion("0.1.0"), "Added", "Added some change", yesterday), }; var readerChanges2 = new List <IChange> { new DefaultChange(new ChangeVersion("1.0.0"), "Removed", "Removed some other change", now), new DefaultChange(new ChangeVersion("0.1.0"), "Removed", "Removed some change", yesterday) }; var expectedChanges = readerChanges1.Concat(readerChanges2).ToList(); var expectedValueDictionary = ToValueDictionary(expectedChanges); reader1Mock.Setup(r => r.Values()).Returns(readerChanges1); reader2Mock.Setup(r => r.Values()).Returns(readerChanges2); cacheMock.Setup(c => c.Add(It.Is <IEnumerable <IChange> >(changes => changes.SequenceEqual(expectedChanges)))); cacheMock.Setup(c => c.GetAsValueDictionary()).Returns(expectedValueDictionary); var expected = $@" ## [1.0.0] - {now:yyyy-MM-dd} ### Added - Added some other change ### Removed - Removed some other change ## [0.1.0] - {yesterday:yyyy-MM-dd} ### Added - Added some change ### Removed - Removed some change "; var generator = new StringChangelogGenerator(readers, cacheMock.Object, Template, renderer); var actual = generator.Generate(changeTypesToExclude: toExclude); Assert.That(actual, Is.EqualTo(expected)); }
public void VerifyMinVersionChangelogIsGenerated() { var minVersion = new ChangeVersion("1.0.0"); var now = DateTimeOffset.Now; var yesterday = now.AddDays(-1); var readerMock = new Mock <IGenericReader <IChange> >(); var cacheMock = new Mock <IChangeCache>(); var renderer = new StubbleBuilder().Build(); var readers = new List <IGenericReader <IChange> > { readerMock.Object }; var expectedChanges = new List <IChange> { new DefaultChange(new ChangeVersion("1.0.0"), "Added", "Added some other change", now), new DefaultChange(new ChangeVersion("1.0.0"), "Removed", "Removed some other change", now) }; var allChanges = new List <IChange>(expectedChanges) { new DefaultChange(new ChangeVersion("0.1.0"), "Added", "Added some change", yesterday), new DefaultChange(new ChangeVersion("0.1.0"), "Removed", "Removed some change", yesterday) }; var expectedValueDictionary = ToValueDictionary(expectedChanges); readerMock.Setup(r => r.Values()).Returns(allChanges); cacheMock.Setup(c => c.Add(It.Is <IEnumerable <IChange> >(changes => changes.SequenceEqual(expectedChanges)))); cacheMock.Setup(c => c.GetAsValueDictionary()).Returns(expectedValueDictionary); var expected = $@" ## [1.0.0] - {now:yyyy-MM-dd} ### Added - Added some other change ### Removed - Removed some other change "; var generator = new StringChangelogGenerator(readers, cacheMock.Object, Template, renderer); var actual = generator.Generate(minVersion); Assert.That(actual, Is.EqualTo(expected)); }
static void Main(string[] args) { try { var configBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json"); Parser.Default.ParseArguments <Options>(args) .WithParsed(options => { var additionalSettings = new List <KeyValuePair <string, string> >(); if (!string.IsNullOrEmpty(options.CustomSettingsPath)) { configBuilder.AddJsonFile(options.CustomSettingsPath); } if (!string.IsNullOrEmpty(options.CustomTemplatePath)) { additionalSettings.Add(new KeyValuePair <string, string>("Template", options.CustomTemplatePath)); } if (!string.IsNullOrEmpty(options.ChangeTypesToExclude)) { additionalSettings.Add(new KeyValuePair <string, string>("ChangeTypesToExclude", options.ChangeTypesToExclude)); } if (!string.IsNullOrEmpty(options.MinVersion)) { additionalSettings.Add(new KeyValuePair <string, string>("MinVersion", options.MinVersion)); } if (!string.IsNullOrEmpty(options.RepositoryPath)) { additionalSettings.Add(new KeyValuePair <string, string>("Repository:Path", options.RepositoryPath)); } if (!string.IsNullOrEmpty(options.FileSourcePath)) { additionalSettings.Add(new KeyValuePair <string, string>("FileSource", options.FileSourcePath)); } configBuilder.AddInMemoryCollection(additionalSettings); }); var config = TryOrExit(() => configBuilder.Build(), "Failed to build configuration"); var appConfig = config.Get <AppConfig>(); var template = GetTemplate(appConfig.Template); var repo = TryOrExit(() => new Repository(appConfig.Repository.Path), "Failed to initialize repository"); var idToOverrideChange = new Dictionary <string, IChange>(); var changeTypesToExclude = appConfig.ChangeTypesToExclude.Split(","); var renderer = new StubbleBuilder().Build(); var minVersion = string.IsNullOrEmpty(appConfig.MinVersion) ? null : new ChangeVersion(appConfig.MinVersion); if (appConfig.MultiProject) { var readers = new List <IGenericReader <ProjectChange> >(); var idToProjectChange = new Dictionary <string, ProjectChange>(); if (!string.IsNullOrEmpty(appConfig.FileSource)) { var fileReader = new FileReader <ProjectChange>(appConfig.FileSource, new ProjectFileSourceRowParser(Console.Error)); readers.Add(fileReader); } if (!string.IsNullOrEmpty(appConfig.Repository.OverrideSource)) { var overrideFileReader = new FileReader <OverrideProjectChange>(appConfig.Repository.OverrideSource, new OverrideProjectSourceRowParser(Console.Error)); readers.Add(overrideFileReader); idToProjectChange = overrideFileReader.Values().ToDictionary <OverrideProjectChange, string, ProjectChange>(change => change.Id, change => change); } var parser = new ProjectCommitParser(appConfig.Parsing); var gitReader = new GitReader <ProjectChange>(repo, parser, idToProjectChange); readers.Add(gitReader); var generator = new ProjectChangelogGenerator(readers, template, renderer); var projectToOutput = generator.Generate(minVersion, changeTypesToExclude); foreach (var(project, output) in projectToOutput) { File.WriteAllText($@"{project}-changelog.md", output); } } else { var readers = new List <IGenericReader <IChange> >(); if (!string.IsNullOrEmpty(appConfig.FileSource)) { var fileReader = new FileReader <DefaultChange>(appConfig.FileSource, new DefaultFileSourceRowParser(Console.Error)); readers.Add(fileReader); } if (!string.IsNullOrEmpty(appConfig.Repository.OverrideSource)) { var overrideFileReader = new FileReader <OverrideChange>(appConfig.Repository.OverrideSource, new OverrideSourceRowParser(Console.Error)); idToOverrideChange = overrideFileReader.Values().ToDictionary <OverrideChange, string, IChange>(change => change.Id, change => change); } Dictionary <string, string> commitShaToTagName = null; if (UsesTagAsSource(appConfig.Parsing)) { commitShaToTagName = new Dictionary <string, string>(); foreach (var tag in repo.Tags) { commitShaToTagName.Add(tag.Target.Sha, tag.FriendlyName); } } var commitParser = new DefaultCommitParser(appConfig.Parsing, commitShaToTagName); var gitReader = new GitReader <IChange>(repo, commitParser, idToOverrideChange); readers.Add(gitReader); var cache = new ChangeCache(); var generator = new StringChangelogGenerator(readers, cache, template, renderer); var output = generator.Generate(minVersion, changeTypesToExclude); File.WriteAllText(@"changelog.md", output); } } catch (Exception e) { Console.WriteLine($"{e.Message}"); Environment.Exit(-1); } }