From d5d2d89705d5089685d4a6af4a74c81f8a780e19 Mon Sep 17 00:00:00 2001 From: Joey Riches Date: Sat, 7 Jan 2023 16:33:23 +0000 Subject: [PATCH] boulder/cli: Implement update command to update version in recipes Updates an existing recipe (stone.yml) with a new version and tarball, provided by the user. Additionally, it recomputes the hash of the new tarball and increments the release. PoC only because dyaml is a shitter and doesn't provide any formatting options when dumping a yaml file to disk making the thing look my left ball and my big toe had a baby. --- source/boulder/cli/package.d | 1 + source/boulder/cli/update_command.d | 102 ++++++++++++++++++++++++++++ source/boulder/main.d | 1 + source/boulder/meson.build | 1 + 4 files changed, 105 insertions(+) create mode 100644 source/boulder/cli/update_command.d diff --git a/source/boulder/cli/package.d b/source/boulder/cli/package.d index eec77dd39d..55a35d91f9 100644 --- a/source/boulder/cli/package.d +++ b/source/boulder/cli/package.d @@ -18,6 +18,7 @@ module boulder.cli; public import moss.core.cli; public import boulder.cli.build_command; public import boulder.cli.new_command; +public import boulder.cli.update_command; public import boulder.cli.version_command; /** diff --git a/source/boulder/cli/update_command.d b/source/boulder/cli/update_command.d new file mode 100644 index 0000000000..e736022834 --- /dev/null +++ b/source/boulder/cli/update_command.d @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: Copyright © 2020-2023 Serpent OS Developers + * + * SPDX-License-Identifier: Zlib + */ + +/** + * boulder.cli.update_command + * + * Implements the `boulder update` subcommand + * + * Authors: Copyright © 2020-2023 Serpent OS Developers + * License: Zlib + */ + +module boulder.cli.update_command; + +public import moss.core.cli; +import boulder.cli : BoulderCLI; +import core.sys.posix.unistd : geteuid; +import drafter; +import dyaml; +import moss.core; +import moss.core.util : computeSHA256; +import moss.fetcher; +import std.algorithm : each; +import std.stdio : File; +import std.file : exists; +import std.format : format; +import std.experimental.logger; + +/** + * The BuildCommand is responsible for handling requests to build stone.yml + * formatted files into useful binary packages. + */ +@CommandName("update") +@CommandHelp("Update the version for an existing recipe") +@CommandUsage("[version] [tarball]") +public struct UpdateCommand +{ + /** Extend BaseCommand with UpdateCommand specific functionality */ + BaseCommand pt; + alias pt this; + + /** + * Manipulation of recipes + */ + @CommandEntry() int run(ref string[] argv) + { + immutable useDebug = this.findAncestor!BoulderCLI.debugMode; + globalLogLevel = useDebug ? LogLevel.trace : LogLevel.info; + + if (argv.length != 2) + { + warning("No arguments specified. For help, run boulder update -h"); + return ExitStatus.Failure; + } + + if (!recipeLocation.exists) + { + error(format!"Unable to find stone.yml in current directory. Use -r to specify location."); + return 1; + } + + immutable ver = argv[0]; + immutable tarball = argv[1]; + + /* Download the tarball */ + auto f = new FetchController(); + auto dlLoc= "/tmp/boulderUpdateTarball"; + auto j = Fetchable(tarball, dlLoc, 0, FetchType.RegularFile, null); + f.enqueue(j); + while (!f.empty()) + { + f.fetch(); + } + info(format!"Wrote tarball to %s"(dlLoc)); + + auto hash = computeSHA256(dlLoc, true); + info(format!"Hash: %s"(hash)); + + /* Overwrite recipe with updated params */ + Node root = Loader.fromFile(recipeLocation).load(); + immutable rel = root["release"].as!int; + // FIXME: This isn't really working as expected + immutable upstreams = format("%s : %s", tarball, hash); + root["release"] = rel + 1; + root["version"] = ver; + root["upstreams"] = upstreams; + /* Purposely write as test.yaml for now as this is still PoC */ + dumper().dump(File("test.yaml", "w").lockingTextWriter, root); + info("Successfully updated recipe"); + + return 0; + } + + /** Where to output the YML file */ + @Option("r", "recipe-location", "Location of existing stone.yml file to update version") + string recipeLocation = "stone.yml"; +} + + diff --git a/source/boulder/main.d b/source/boulder/main.d index 0ebbd8c27a..43b5790a20 100644 --- a/source/boulder/main.d +++ b/source/boulder/main.d @@ -33,6 +33,7 @@ int boulderMain(string[] args) auto clip = cliProcessor!BoulderCLI(args); clip.addCommand!BuildControlCommand; clip.addCommand!NewCommand; + clip.addCommand!UpdateCommand; clip.addCommand!VersionCommand; clip.addCommand!HelpCommand; return clip.process(args); diff --git a/source/boulder/meson.build b/source/boulder/meson.build index 18ba4884f7..04f0dcf1ff 100644 --- a/source/boulder/meson.build +++ b/source/boulder/meson.build @@ -3,6 +3,7 @@ boulder_sources = [ 'cli/package.d', 'cli/new_command.d', + 'cli/update_command.d', 'cli/version_command.d', 'cli/build_command.d', 'buildjob.d',