public void VerifyMultipleChangesWithTheSameKeyAddedSuccessfully() { var today = DateTime.Today; var expectedChanges = new List <IChange> { new DefaultChange("0.1.0", "Added", "This is a change", today, "REL-1234"), new DefaultChange("0.1.0", "Added", "This is another change", today, "REL-1235") }; var expectedChangeKey = new ChangeCache.ChangeKey(expectedChanges.First()); var changeCache = new ChangeCache(); changeCache.Add(expectedChanges); changeCache.ChangeKeyToChanges.TryGetValue(expectedChangeKey, out var actualChanges); Assert.That(actualChanges, Is.EquivalentTo(expectedChanges)); }
public void VerifyGetAsValueDictionaryVersionOrderingIsDescendingMixedDigits() { var expectedChange1 = new DefaultChange(new ChangeVersion("0.10.0"), "Added", "This is the latest 0.10.0", DateTime.Today, "REL-1231"); var expectedChange2 = new DefaultChange(new ChangeVersion("0.10.0"), "Removed", "This is the middle 0.10.0", DateTime.Today.AddHours(-2), "REL-1232"); var expectedChange3 = new DefaultChange(new ChangeVersion("0.10.0"), "Removed", "This is the earliest 0.10.0", DateTime.Today.AddHours(-3), "REL-1233"); var expectedChange4 = new DefaultChange(new ChangeVersion("0.9.0"), "Added", "This is a change", DateTime.Today.AddDays(-1), "REL-1234"); var expectedChange5 = new DefaultChange(new ChangeVersion("0.9.0"), "Removed", "This is the middle 0.9.0", DateTime.Today.AddDays(-2), "REL-1235"); var expectedChange6 = new DefaultChange(new ChangeVersion("0.9.0"), "Removed", "This is the earliest 0.9.0", DateTime.Today.AddDays(-3), "REL-1236"); var changeCache = new ChangeCache(); changeCache.Add(new List <IChange> { expectedChange1, expectedChange2, expectedChange3, expectedChange4, expectedChange5, expectedChange6 }); var actualValueDictionary = changeCache.GetAsValueDictionary(); var actualVersions = (List <Dictionary <string, object> >)actualValueDictionary["versions"]; Assert.That(actualVersions[0]["version"], Is.EqualTo(expectedChange1.Version)); Assert.That(actualVersions[1]["version"], Is.EqualTo(expectedChange4.Version)); }
public Dictionary <string, string> Generate(ChangeVersion minVersion = null, IEnumerable <string> changeTypesToExclude = null) { var projectToCache = new Dictionary <string, IChangeCache>(); var projectToOutput = new Dictionary <string, string>(); var toExclude = changeTypesToExclude?.ToList() ?? new List <string>(); foreach (var reader in _readers) { var values = reader.Values(); if (minVersion != null || toExclude.Any()) { values = new FilteredChanges <ProjectChange>(values, minVersion, toExclude); } foreach (var lookup in values.ToLookup(change => change.Project)) { if (projectToCache.TryGetValue(lookup.Key, out var cache)) { cache.Add(lookup.ToList()); } else { cache = new ChangeCache(); cache.Add(lookup.ToList()); projectToCache.Add(lookup.Key, cache); } } } foreach (var(project, cache) in projectToCache) { var output = _renderer.Render(_template, cache.GetAsValueDictionary()); projectToOutput.Add(project, output); } return(projectToOutput); }
public void VerifyMultipleChangesWithDifferentKeysAddedSuccessfully() { var today = DateTime.Today; var expectedChange1 = new DefaultChange("0.1.0", "Added", "This is a change", today, "REL-1234"); var expectedChange2 = new DefaultChange("0.1.0", "Removed", "This is a change", today, "REL-1235"); var expectedChangeKey1 = new ChangeCache.ChangeKey(expectedChange1); var expectedChangeKey2 = new ChangeCache.ChangeKey(expectedChange2); var changeCache = new ChangeCache(); changeCache.Add(new List <IChange> { expectedChange1, expectedChange2 }); changeCache.ChangeKeyToChanges.TryGetValue(expectedChangeKey1, out var actualChanges1); CollectionAssert.Contains(actualChanges1, expectedChange1); CollectionAssert.DoesNotContain(actualChanges1, expectedChange2); changeCache.ChangeKeyToChanges.TryGetValue(expectedChangeKey2, out var actualChanges2); CollectionAssert.Contains(actualChanges2, expectedChange2); CollectionAssert.DoesNotContain(actualChanges2, expectedChange1); }
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); } }
private async Task UpdateProject(UpdaterClient updater, string projectRoot) { var targetPath = ""; if (Program.IsUnix) { targetPath = Path.Combine(Directory.GetParent(Assembly.GetEntryAssembly().Location).Parent.Parent.ToString(), projectRoot); } else { targetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), projectRoot); } Application.Invoke((sender, args) => { PlayButton.Sensitive = false; PlayButton.Label = "Updating"; ProgressBar.Text = "Checking for updates"; }); try { var cache = ChangeCache.FromFile(Path.Combine(targetPath, "version.json")); var version = await updater.FindLatestVersion(); Console.WriteLine("Local version: {0}, Latest version: {1}", cache.Version, version); if (cache.Version >= version) { Console.WriteLine("No updates available."); Application.Invoke((sender, args) => { PlayButton.Sensitive = true; PlayButton.Label = "Play"; ProgressBar.Text = "No updates available"; }); return; } Application.Invoke((sender, args) => { ProgressBar.Text = "Getting version " + version + " from server..."; PlayButton.Sensitive = false; PlayButton.Label = "Updating"; }); var changes = await updater.GetChanges(cache.Version, version); Application.Invoke((sender, args) => { ProgressBar.Text = "Preparing to update..."; }); string progressFile = Path.Combine(targetPath, "updateProgress.json"); if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } string curProgress = ""; if (File.Exists(progressFile)) { curProgress = File.ReadAllText(progressFile); } if (curProgress == "") { curProgress = "{}"; } UpdateProgress progress = JsonConvert.DeserializeObject <UpdateProgress>(curProgress); if (progress == null) { progress = new UpdateProgress(); progress.setVersion(version); } if (progress.Downloaded == 0) { progress.setVersion(version); } if (progress.TargetVersion != version) { UpdateLib.Version oldV = progress.TargetVersion; Application.Invoke((sender, args) => { var dialog = new MessageDialog(Window, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, false, "Your previous download progress was for v{0}, but the target version is v{1}. As a result, your download progress was reset.", oldV, version) { Title = "Progress Version Mismatch" }; dialog.Run(); dialog.Destroy(); }); progress.setVersion(version); progress.DownloadedFiles = new List <string>(); } List <KeyValuePair <string, int> > changesLeft = changes.NewSizes.Where(c => !progress.DownloadedFiles.Contains(c.Key)).ToList(); var totalSize = ByteSize.FromBytes(changesLeft.Sum(kvp => kvp.Value)); long currentDownloaded = 0; foreach (var change in changesLeft) { var relativePath = change.Key; if (Program.IsUnix) { relativePath = relativePath.Replace('\\', '/'); } var targetFile = Path.Combine(targetPath, relativePath); if (File.Exists(targetFile)) { File.Delete(targetFile); } await updater.Download(relativePath, targetFile, version); currentDownloaded += change.Value; Application.Invoke((_, args) => { UpdateDownloadProgress(relativePath, ByteSize.FromBytes(currentDownloaded), totalSize); }); progress.DownloadedFiles.Add(change.Key); File.WriteAllText(progressFile, JsonConvert.SerializeObject(progress)); } cache.SetVersion(version); if (File.Exists(progressFile)) { File.Delete(progressFile); } Application.Invoke((sender, args) => { PlayButton.Sensitive = true; PlayButton.Label = "Play"; ProgressBar.Text = "Finished Updating"; }); if (Program.IsUnix) { // Update fix for Mac string executeScript = ""; if (updater.GetProjectName() == _setup.LauncherProject) { executeScript = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "atmolauncher"); } else if (updater.GetProjectName() == _setup.GameProject) { executeScript = Path.Combine(targetPath, "Contents", "MacOS", "Atmosphir"); } Program.macChangePerm(executeScript); } if (updater.GetProjectName() == _setup.LauncherProject) { Program.RebootOrig(); } } catch (Exception e) { if (e is System.Net.WebException || e is System.Net.Http.HttpRequestException || e is System.Net.Sockets.SocketException) { Application.Invoke((sender, args) => { PlayButton.Sensitive = true; PlayButton.Label = "Play"; ProgressBar.Text = "Couldn't connect to update server."; }); } else { Application.Invoke((sender, args) => { Console.WriteLine(e); var dialog = new MessageDialog(Window, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, false, e.GetType() + "An error ocurred, please report this at {0}:\n{1}", _setup.SupportSite, e) { Title = "Update error" }; dialog.Run(); dialog.Destroy(); }); } } }
private async Task UpdateProject(UpdaterClient updater, string projectRoot) { var targetPath = ""; if (Program.IsUnix) { targetPath = Path.Combine(Directory.GetParent(Assembly.GetEntryAssembly().Location).Parent.Parent.ToString(), projectRoot); } else { targetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), projectRoot); } Console.WriteLine("Checking for updates..."); try { var cache = ChangeCache.FromFile(Path.Combine(targetPath, "version.json")); var version = await updater.FindLatestVersion(); Console.WriteLine("Local version: {0}, Latest version: {1}", cache.Version, version); if (cache.Version >= version) { Console.WriteLine("No updates available."); return; } Console.WriteLine("Getting version v{0} from the server...", version); var changes = await updater.GetChanges(cache.Version, version); Console.WriteLine("Preparing to update..."); string progressFile = Path.Combine(targetPath, "updateProgress.json"); if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } string curProgress = ""; if (File.Exists(progressFile)) { curProgress = File.ReadAllText(progressFile); } if (curProgress == "") { curProgress = "{}"; } UpdateProgress progress = JsonConvert.DeserializeObject <UpdateProgress>(curProgress); if (progress == null) { progress = new UpdateProgress(); progress.setVersion(version); } if (progress.Downloaded == 0) { progress.setVersion(version); } if (progress.TargetVersion != version) { UpdateLib.Version oldV = progress.TargetVersion; Console.WriteLine("NOTICE: Your previous download progress was for v{0}, but the target version is v{1}. As a result, your download progress was reset.", oldV, version); progress.setVersion(version); progress.DownloadedFiles = new List <string>(); } List <KeyValuePair <string, int> > changesLeft = changes.NewSizes.Where(c => !progress.DownloadedFiles.Contains(c.Key)).ToList(); var totalSize = ByteSize.FromBytes(changesLeft.Sum(kvp => kvp.Value)); long currentDownloaded = 0; foreach (var change in changesLeft) { var relativePath = change.Key; if (Program.IsUnix) { relativePath = relativePath.Replace('\\', '/'); } var targetFile = Path.Combine(targetPath, relativePath); if (File.Exists(targetFile)) { File.Delete(targetFile); } await updater.Download(relativePath, targetFile, version); currentDownloaded += change.Value; UpdateDownloadProgress(relativePath, ByteSize.FromBytes(currentDownloaded), totalSize); progress.DownloadedFiles.Add(change.Key); File.WriteAllText(progressFile, JsonConvert.SerializeObject(progress)); } cache.SetVersion(version); if (File.Exists(progressFile)) { File.Delete(progressFile); } Console.WriteLine("Finished Updating!"); if (Program.IsUnix) { // Update fix for Mac string executeScript = ""; if (updater.GetProjectName() == _setup.LauncherProject) { executeScript = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "atmolauncher"); } else if (updater.GetProjectName() == _setup.GameProject) { executeScript = Path.Combine(targetPath, _setup.GameExecutable, "Contents", "MacOS", "Atmosphir"); } Program.macChangePerm(executeScript); } if (updater.GetProjectName() == _setup.LauncherProject) { Program.RebootOrig(); } } catch (Exception e) { if (e is System.Net.WebException || e is System.Net.Http.HttpRequestException || e is System.Net.Sockets.SocketException) { Console.WriteLine("ERROR: Couldn't connect to update server. Please check your internet connection or try again later."); errorOcurred = true; } else { Console.WriteLine("An error ocurred, please report this at {0}:\n{1}", _setup.SupportSite, e); errorOcurred = true; } } }
public void VerifyGetAsValueDictionaryIsSuccessful() { var expectedChange1 = new DefaultChange("0.2.0", "Added", "This is the latest 0.2.0", DateTime.Today, "REL-1231"); var expectedChange2 = new DefaultChange("0.2.0", "Removed", "This is the middle 0.2.0", DateTime.Today.AddHours(-2), "REL-1232"); var expectedChange3 = new DefaultChange("0.2.0", "Removed", "This is the earliest 0.2.0", DateTime.Today.AddHours(-3), "REL-1233"); var expectedChange4 = new DefaultChange("0.1.0", "Added", "This is a change", DateTime.Today.AddDays(-1), "REL-1234"); var expectedChange5 = new DefaultChange("0.1.0", "Removed", "This is the middle 0.1.0", DateTime.Today.AddDays(-2), "REL-1235"); var expectedChange6 = new DefaultChange("0.1.0", "Removed", "This is the earliest 0.1.0", DateTime.Today.AddDays(-3), "REL-1236"); var changeCache = new ChangeCache(); changeCache.Add(new List <IChange> { expectedChange1, expectedChange2, expectedChange3, expectedChange4, expectedChange5, expectedChange6 }); var actualValueDictionary = changeCache.GetAsValueDictionary(); var actualVersions = (List <Dictionary <string, object> >)actualValueDictionary["versions"]; var version2 = actualVersions.Find(v => v.ContainsValue("0.2.0")); var version2Tags = (List <Dictionary <string, object> >)version2["tags"]; var version2AddedDictionary = version2Tags.Find(t => t.ContainsValue("Added")); var version2AddedChanges = (List <Dictionary <string, object> >)version2AddedDictionary["changes"]; var version2AddedChangeSummaries = version2AddedChanges.Select(c => c["summary"]); var version2AddedChangeReferences = version2AddedChanges.Select(c => c["reference"]); var version2RemovedDictionary = version2Tags.Find(t => t.ContainsValue("Removed")); var version2RemovedChanges = (List <Dictionary <string, object> >)version2RemovedDictionary["changes"]; var version2RemovedChangeSummaries = version2RemovedChanges.Select(c => c["summary"]); var version2RemovedChangeReferences = version2RemovedChanges.Select(c => c["reference"]); Assert.That(version2["date"], Is.EqualTo(expectedChange1.Date.ToString("yyyy-MM-dd"))); Assert.That(version2AddedChangeSummaries, Is.EquivalentTo(new List <string> { expectedChange1.Summary })); Assert.That(version2AddedChangeReferences, Is.EquivalentTo(new List <string> { expectedChange1.Reference })); Assert.That(version2RemovedChangeSummaries, Is.EquivalentTo(new List <string> { expectedChange2.Summary, expectedChange3.Summary })); Assert.That(version2RemovedChangeReferences, Is.EquivalentTo(new List <string> { expectedChange2.Reference, expectedChange3.Reference })); var version1 = actualVersions.Find(v => v.ContainsValue("0.1.0")); var version1Tags = (List <Dictionary <string, object> >)version1["tags"]; var version1AddedDictionary = version1Tags.Find(t => t.ContainsValue("Added")); var version1AddedChanges = (List <Dictionary <string, object> >)version1AddedDictionary["changes"]; var version1AddedChangeSummaries = version1AddedChanges.Select(c => c["summary"]); var version1AddedChangeReferences = version1AddedChanges.Select(c => c["reference"]); var version1RemovedDictionary = version1Tags.Find(t => t.ContainsValue("Removed")); var version1RemovedChanges = (List <Dictionary <string, object> >)version1RemovedDictionary["changes"]; var version1RemovedChangeSummaries = version1RemovedChanges.Select(c => c["summary"]); var version1RemovedChangeReferences = version1RemovedChanges.Select(c => c["reference"]); Assert.That(version1["date"], Is.EqualTo(expectedChange4.Date.ToString("yyyy-MM-dd"))); Assert.That(version1AddedChangeSummaries, Is.EquivalentTo(new List <string> { expectedChange4.Summary })); Assert.That(version1AddedChangeReferences, Is.EquivalentTo(new List <string> { expectedChange4.Reference })); Assert.That(version1RemovedChangeSummaries, Is.EquivalentTo(new List <string> { expectedChange5.Summary, expectedChange6.Summary })); Assert.That(version1RemovedChangeReferences, Is.EquivalentTo(new List <string> { expectedChange5.Reference, expectedChange6.Reference })); }