From 3fee5b881aa52239328ddfb0204336a1f9c18451 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 7 Jul 2026 07:02:38 -0400 Subject: [PATCH] feat: port git :report subcommand to golang The bash :report implementation for the git plugin is replaced with a compiled golang binary. Property, computed and global keys are collected in parallel, while the sha and last-updated-at keys still shell out to git and stat the deploy branch ref so their values are unchanged. The non-report git helpers such as fn-git-cmd and the computed deploy-branch and keep-git-dir getters remain in place for the build pipeline. --- go.work | 1 + plugins/git/.gitignore | 4 + plugins/git/Makefile | 13 ++ plugins/git/go.mod | 29 ++++ plugins/git/go.sum | 55 ++++++++ plugins/git/internal-functions | 106 -------------- plugins/git/report | 6 - plugins/git/report.go | 154 +++++++++++++++++++++ plugins/git/src/subcommands/subcommands.go | 40 ++++++ plugins/git/src/triggers/triggers.go | 31 +++++ plugins/git/subcommands.go | 29 ++++ plugins/git/subcommands/report | 6 - 12 files changed, 356 insertions(+), 118 deletions(-) create mode 100644 plugins/git/.gitignore create mode 100644 plugins/git/Makefile create mode 100644 plugins/git/go.mod create mode 100644 plugins/git/go.sum mode change 100755 => 100644 plugins/git/internal-functions delete mode 100755 plugins/git/report create mode 100644 plugins/git/report.go create mode 100644 plugins/git/src/subcommands/subcommands.go create mode 100644 plugins/git/src/triggers/triggers.go create mode 100644 plugins/git/subcommands.go delete mode 100755 plugins/git/subcommands/report diff --git a/go.work b/go.work index 2aa88dabc..a5a83cf18 100644 --- a/go.work +++ b/go.work @@ -19,6 +19,7 @@ use ( ./plugins/cron ./plugins/docker-options ./plugins/domains + ./plugins/git ./plugins/haproxy-vhosts ./plugins/logs ./plugins/network diff --git a/plugins/git/.gitignore b/plugins/git/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/git/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/git/Makefile b/plugins/git/Makefile new file mode 100644 index 000000000..4a17c4b2a --- /dev/null +++ b/plugins/git/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = git + +clean-report-subcommand: + rm -rf report-subcommand + +report-subcommand: clean-report-subcommand src/subcommands/subcommands.go + GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go + ln -sf ../report-subcommand subcommands/report + +include ../../common.mk diff --git a/plugins/git/go.mod b/plugins/git/go.mod new file mode 100644 index 000000000..0727b8524 --- /dev/null +++ b/plugins/git/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/git + +go 1.26.2 + +require ( + github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000 + github.com/spf13/pflag v1.0.10 +) + +require ( + github.com/alexellis/go-execute/v2 v2.2.1 // indirect + github.com/fatih/color v1.19.0 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/kr/fs v0.1.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/melbahja/goph v1.5.1 // indirect + github.com/otiai10/copy v1.14.1 // indirect + github.com/otiai10/mint v1.6.3 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/sftp v1.13.10 // indirect + github.com/ryanuber/columnize v2.1.2+incompatible // indirect + golang.org/x/crypto v0.53.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect +) + +replace github.com/dokku/dokku/plugins/common => ../common diff --git a/plugins/git/go.sum b/plugins/git/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/git/go.sum @@ -0,0 +1,55 @@ +github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= +github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/melbahja/goph v1.5.1 h1:gdZyjn5nM6FO6mAZrv7XqE2gArQbb+V6FdIyH3Ru3vA= +github.com/melbahja/goph v1.5.1/go.mod h1:dDwo+44cmvfDLdiVpc6fJxexf5BA5yEDUeE5YgtuDO4= +github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I= +github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg= +github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= +github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I= +github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= +github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU= +github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk= +github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions old mode 100755 new mode 100644 index 11d4f367b..7fcca2bf4 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -328,112 +328,6 @@ cmd-git-public-key() { fn-git-auth-error } -cmd-git-report() { - declare desc="displays a git report for one or more apps" - declare cmd="git:report" - [[ "$1" == "$cmd" ]] && shift 1 - fn-report-parse-args "$@" - set -- "${REPORT_ARGS[@]}" - - declare APP="${1:-}" INFO_FLAG="${2:-}" - - if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then - INFO_FLAG="$APP" - APP="" - fi - - if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then - APP="--global" - fi - - if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then - INFO_FLAG="true" - fi - - if [[ "$APP" == "--global" ]]; then - cmd-git-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-git-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-git-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-git-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - local APP_ROOT="$DOKKU_ROOT/$APP" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--git-computed-archive-max-files: $(fn-archive-computed-max-files)" - "--git-computed-archive-max-size: $(fn-archive-computed-max-size)" - "--git-computed-deploy-branch: $(fn-git-computed-deploy-branch "$APP")" - "--git-computed-keep-git-dir: $(fn-git-computed-keep-git-dir "$APP")" - "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "")" - "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "")" - "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "")" - "--git-global-keep-git-dir: $(fn-plugin-property-get "git" "--global" "keep-git-dir" "")" - ) - else - verify_app_name "$APP" - flag_map=( - "--git-computed-archive-max-files: $(fn-archive-computed-max-files)" - "--git-computed-archive-max-size: $(fn-archive-computed-max-size)" - "--git-computed-deploy-branch: $(fn-git-computed-deploy-branch "$APP")" - "--git-computed-keep-git-dir: $(fn-git-computed-keep-git-dir "$APP")" - "--git-deploy-branch: $(fn-plugin-property-get "git" "$APP" "deploy-branch" "")" - "--git-global-archive-max-files: $(fn-plugin-property-get "git" "--global" "archive-max-files" "")" - "--git-global-archive-max-size: $(fn-plugin-property-get "git" "--global" "archive-max-size" "")" - "--git-global-deploy-branch: $(fn-plugin-property-get "git" "--global" "deploy-branch" "")" - "--git-global-keep-git-dir: $(fn-plugin-property-get "git" "--global" "keep-git-dir" "")" - "--git-keep-git-dir: $(fn-plugin-property-get "git" "$APP" "keep-git-dir" "")" - "--git-rev-env-var: $(fn-plugin-property-get "git" "$APP" "rev-env-var" "GIT_REV")" - "--git-sha: $(fn-git-cmd "$APP_ROOT" rev-parse HEAD 2>/dev/null || false)" - "--git-source-image: $(fn-git-source-image "$APP")" - "--git-last-updated-at: $(fn-git-last-updated-at "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "git" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global git information" - else - dokku_log_info2_quiet "${APP} git information" - fi - for flag in "${flag_map[@]}"; do - key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')" - dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")" - done - else - local match=false - for flag in "${flag_map[@]}"; do - valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)" - if [[ "$flag" == "${INFO_FLAG}:"* ]]; then - value=${flag#*: } - size="${#value}" - if [[ "$size" -ne 0 ]]; then - echo "$value" && match=true - else - match=true - fi - fi - done - [[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}" - fi -} - cmd-git-status() { declare desc="check the git status output for an app" local cmd="git:status" diff --git a/plugins/git/report b/plugins/git/report deleted file mode 100755 index ade453679..000000000 --- a/plugins/git/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/git/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-git-report-single "$@" diff --git a/plugins/git/report.go b/plugins/git/report.go new file mode 100644 index 000000000..1e5d0b255 --- /dev/null +++ b/plugins/git/report.go @@ -0,0 +1,154 @@ +package git + +import ( + "os" + "path/filepath" + "strconv" + + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the git report for one or more apps +func ReportSingleApp(appName string, format string, infoFlag string) error { + if appName != "--global" { + if err := common.VerifyAppName(appName); err != nil { + return err + } + } + + var flags map[string]common.ReportFunc + if appName == "--global" { + flags = map[string]common.ReportFunc{ + "--git-computed-archive-max-files": reportComputedArchiveMaxFiles, + "--git-computed-archive-max-size": reportComputedArchiveMaxSize, + "--git-computed-deploy-branch": reportComputedDeployBranch, + "--git-computed-keep-git-dir": reportComputedKeepGitDir, + "--git-global-archive-max-files": reportGlobalArchiveMaxFiles, + "--git-global-archive-max-size": reportGlobalArchiveMaxSize, + "--git-global-deploy-branch": reportGlobalDeployBranch, + "--git-global-keep-git-dir": reportGlobalKeepGitDir, + } + } else { + flags = map[string]common.ReportFunc{ + "--git-computed-archive-max-files": reportComputedArchiveMaxFiles, + "--git-computed-archive-max-size": reportComputedArchiveMaxSize, + "--git-computed-deploy-branch": reportComputedDeployBranch, + "--git-computed-keep-git-dir": reportComputedKeepGitDir, + "--git-deploy-branch": reportDeployBranch, + "--git-global-archive-max-files": reportGlobalArchiveMaxFiles, + "--git-global-archive-max-size": reportGlobalArchiveMaxSize, + "--git-global-deploy-branch": reportGlobalDeployBranch, + "--git-global-keep-git-dir": reportGlobalKeepGitDir, + "--git-keep-git-dir": reportKeepGitDir, + "--git-last-updated-at": reportLastUpdatedAt, + "--git-rev-env-var": reportRevEnvVar, + "--git-sha": reportSha, + "--git-source-image": reportSourceImage, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "git", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportGlobalArchiveMaxFiles(appName string) string { + return common.PropertyGet("git", "--global", "archive-max-files") +} + +func reportComputedArchiveMaxFiles(appName string) string { + return common.PropertyGetDefault("git", "--global", "archive-max-files", "10000") +} + +func reportGlobalArchiveMaxSize(appName string) string { + return common.PropertyGet("git", "--global", "archive-max-size") +} + +func reportComputedArchiveMaxSize(appName string) string { + return common.PropertyGetDefault("git", "--global", "archive-max-size", "1073741824") +} + +func reportDeployBranch(appName string) string { + return common.PropertyGet("git", appName, "deploy-branch") +} + +func reportGlobalDeployBranch(appName string) string { + return common.PropertyGet("git", "--global", "deploy-branch") +} + +func reportComputedDeployBranch(appName string) string { + if value := common.PropertyGet("git", appName, "deploy-branch"); value != "" { + return value + } + if value := common.PropertyGet("git", "--global", "deploy-branch"); value != "" { + return value + } + + return "master" +} + +func reportKeepGitDir(appName string) string { + return common.PropertyGet("git", appName, "keep-git-dir") +} + +func reportGlobalKeepGitDir(appName string) string { + return common.PropertyGet("git", "--global", "keep-git-dir") +} + +func reportComputedKeepGitDir(appName string) string { + if value := common.PropertyGet("git", appName, "keep-git-dir"); value != "" { + return value + } + if value := common.PropertyGet("git", "--global", "keep-git-dir"); value != "" { + return value + } + + return "false" +} + +func reportRevEnvVar(appName string) string { + return common.PropertyGetDefault("git", appName, "rev-env-var", "GIT_REV") +} + +func reportSourceImage(appName string) string { + return common.PropertyGet("git", appName, "source-image") +} + +func reportSha(appName string) string { + appRoot := filepath.Join(common.MustGetEnv("DOKKU_ROOT"), appName) + result, err := common.CallExecCommand(common.ExecCommandInput{ + Command: "git", + Args: []string{"rev-parse", "HEAD"}, + WorkingDirectory: appRoot, + }) + if err != nil { + return "" + } + + return result.StdoutContents() +} + +func reportLastUpdatedAt(appName string) string { + branch := reportComputedDeployBranch(appName) + headFile := filepath.Join(common.MustGetEnv("DOKKU_ROOT"), appName, "refs", "heads", branch) + info, err := os.Stat(headFile) + if err != nil { + return "" + } + + return strconv.FormatInt(info.ModTime().Unix(), 10) +} diff --git a/plugins/git/src/subcommands/subcommands.go b/plugins/git/src/subcommands/subcommands.go new file mode 100644 index 000000000..1ae4d949b --- /dev/null +++ b/plugins/git/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + git "github.com/dokku/dokku/plugins/git" + + flag "github.com/spf13/pflag" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + + var err error + switch subcommand { + case "report": + args := flag.NewFlagSet("git:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("git", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = git.CommandReport(appName, *format, reportArgs.InfoFlag) + } + default: + err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/git/src/triggers/triggers.go b/plugins/git/src/triggers/triggers.go new file mode 100644 index 000000000..966a9a55b --- /dev/null +++ b/plugins/git/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + git "github.com/dokku/dokku/plugins/git" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + var err error + switch trigger { + case "report": + appName := flag.Arg(0) + err = git.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/git/subcommands.go b/plugins/git/subcommands.go new file mode 100644 index 000000000..5b02536cd --- /dev/null +++ b/plugins/git/subcommands.go @@ -0,0 +1,29 @@ +package git + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a git report for one or more apps +func CommandReport(appName string, format string, infoFlag string) error { + if len(appName) == 0 { + apps, err := common.DokkuApps() + if err != nil { + if errors.Is(err, common.NoAppsExist) { + common.LogWarn(err.Error()) + return nil + } + return err + } + for _, appName := range apps { + if err := ReportSingleApp(appName, format, infoFlag); err != nil { + return err + } + } + return nil + } + + return ReportSingleApp(appName, format, infoFlag) +} diff --git a/plugins/git/subcommands/report b/plugins/git/subcommands/report deleted file mode 100755 index 35fc66a87..000000000 --- a/plugins/git/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/git/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-git-report "$@"