From 0eef2347c16ec1960017224af9ac2aa23a94052b Mon Sep 17 00:00:00 2001 From: Lewis Cook Date: Sun, 17 Sep 2023 12:42:44 +0100 Subject: [PATCH] feat: Add new `run` command With this new command it adds the ability to run custom commands and/or scripts right from the terminal. Examples have been added to the README and likewise example scripts under the new `examples` directory. As a quick overview, before executing anything, we inherit an array of enviroment variables that contain relevent information of the package update(s), for example portsync run 'echo $PACKAGE_ORIGIN: Update to $PACKAGE_LATEST' Will yield something of the likings: misc/broot: Update to 1.2.0 devel/gh: Update to 1.36.1 --- README.md | 9 +++++++ cmd/run.go | 41 +++++++++++++++++++++++++++++ examples/genjson | 5 ++++ examples/poudriere_qa | 61 +++++++++++++++++++++++++++++++++++++++++++ examples/updates | 5 ++++ 5 files changed, 121 insertions(+) create mode 100644 cmd/run.go create mode 100755 examples/genjson create mode 100755 examples/poudriere_qa create mode 100755 examples/updates diff --git a/README.md b/README.md index 939f8be..9c624c4 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,15 @@ Or even be able to output updates in a particular file format, such as JSON portsync fetch -f '{"origin": "%o", "current": "%v", "latest": "%l"}' ``` +Run arbitrary commands and/or scripts +```sh +portsync run -o misc/broot examples/genjson +{"origin": "misc/broot", "version": "1.25.0", "newversion": "1.25.1"} +portsync run 'if [ $PACKAGE_ORIGIN == "misc/broot" ]; then echo "$PACKAGE_ORIGIN!"; fi' +misc/broot! +``` +See [examples](examples) for example scripts. + Happy hacking! ## License diff --git a/cmd/run.go b/cmd/run.go new file mode 100644 index 0000000..d9748fc --- /dev/null +++ b/cmd/run.go @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) Lewis Cook + * All rights reserved. + */ +package cmd + +import ( + "os" + "os/exec" + "strings" + + . "github.com/lcook/portsync/internal/fetcher" + . "github.com/lcook/portsync/internal/util" + "github.com/spf13/cobra" +) + +var runCmd = &cobra.Command{ + Use: "run", + Short: `Run local script or command`, + Long: `Run local script or command with inherited package enviroment variables.`, + RunE: func(cmd *cobra.Command, args []string) error { + packages, err := GetPackages(Portscout{}) + if err != nil { + return err + } + for _, _package := range *packages { + SetPkgEnv(_package) + c := exec.Command("sh", "-c", strings.Join(args, " ")) + c.Stdout = os.Stdout + c.Stderr = os.Stderr + _ = c.Run() + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(runCmd) +} diff --git a/examples/genjson b/examples/genjson new file mode 100755 index 0000000..ebda306 --- /dev/null +++ b/examples/genjson @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +# +# Generate JSON output of available package updates. +# +echo '{"origin": "'$PACKAGE_ORIGIN'", "version": "'$PACKAGE_VERSION'", "newversion": "'$PACKAGE_LATEST'"}' diff --git a/examples/poudriere_qa b/examples/poudriere_qa new file mode 100755 index 0000000..f9007b5 --- /dev/null +++ b/examples/poudriere_qa @@ -0,0 +1,61 @@ +#!/usr/bin/env sh +# +# In this script we create a differential patch of unstaged changes +# of a port from our local ports repository, and make an attempt +# to apply the patch to a remote server containing a Poudirere +# ports tree. +# +# Assuming the patch applied cleanly, run `testport` for each of +# the jails defined on the particular port we made changes to. +# Report back build status when completed. +# +# Usual workflow may be as follows: +# $ portsync update -o foo/bar +# $ portsync run -o foo/bar examples/poudriere_qa +# $ git add foo/bar/* +# $ git commit -m "foo/bar: Update to latest version" +# +buildhost="host@example.org" # Domain or IP of remote build host. +buildport= # ssh port of remote build host. +jails="your jails" # List of jails. E.g., "12-amd64 13-amd63". +porttree= # Tree name of Poudriere ports tree. +portdir= # Directory to Poudirere ports repository. + +package="$PACKAGE_ORIGIN" + +_port=${buildport:-"22"} +if ! ssh -o BatchMode=yes -o ConnectTimeout=10 -p\ + "$_port" $buildhost "exit"; then + printf "\nCould not connect to build host. Diagnose issue and try again\n" + exit 1 +fi + +_dir=${portdir:-"/usr/local/poudriere/ports/default"} +_tree=${porttree:-"default"} +if ! _diff=$(git -C "$PACKAGE_ROOT" diff "$package"\ + | ssh -o BatchMode=yes -p "$_port" $buildhost "git -C $_dir apply -p0"); then + echo "$_diff" + echo "Unable to apply patch to $package on build host cleanly" + echo "Verify the integrity of the remote ports tree repository and try again" + exit 1 +fi + +_failed= +_built= +for j in $jails; do + if ! ssh -o BatchMode=yes -p "$_port" $buildhost\ + "poudriere testport -j $j -p $_tree $package"; then + _failed="$_failed $j" + continue + _built="$_built $j" + fi +done + +# Restore remote ports tree to a clean state. +ssh -o BatchMode=yes -p "$_port" $buildhost "git -C $_dir restore $package" + +echo =================================================== +printf "===> Poudriere results for %s\n" "$package" + +[ -n "$_built" ] && echo "=>> Built:$_built" +[ -n "$_failed" ] && echo "=>> Failed:$_failed" && exit 1 diff --git a/examples/updates b/examples/updates new file mode 100755 index 0000000..ed126aa --- /dev/null +++ b/examples/updates @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +# +# Basic script printing the latest package version. +# +echo "[$PACKAGE_ORIGIN@$PACKAGE_VERSION] New update to $PACKAGE_LATEST"