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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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();
                    });
                }
            }
        }
Example #7
0
        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
            }));
        }