From f9db9583a187f1be12289dd6201acbed15cfd5cf Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 7 Jul 2026 06:11:13 -0400 Subject: [PATCH] feat: port builder :report subcommands to golang The bash :report implementations for the dockerfile, herokuish, lambda, nixpacks, pack, and railpack builders are replaced with a compiled golang binary that collects report keys in parallel and marshals json directly, avoiding the per-key subshell and jq forks that made the bash reports slow. The subcommands/report and root report trigger become symlinks to the compiled binary, while the non-report bash helpers each plugin still relies on are left in place. --- go.work | 6 ++ plugins/builder-dockerfile/.gitignore | 4 + plugins/builder-dockerfile/Makefile | 13 +++ plugins/builder-dockerfile/go.mod | 29 +++++++ plugins/builder-dockerfile/go.sum | 55 ++++++++++++ plugins/builder-dockerfile/internal-functions | 87 ------------------- plugins/builder-dockerfile/report | 6 -- plugins/builder-dockerfile/report.go | 66 ++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ .../src/triggers/triggers.go | 31 +++++++ plugins/builder-dockerfile/subcommands.go | 29 +++++++ plugins/builder-dockerfile/subcommands/report | 6 -- plugins/builder-herokuish/.gitignore | 4 + plugins/builder-herokuish/Makefile | 13 +++ plugins/builder-herokuish/go.mod | 29 +++++++ plugins/builder-herokuish/go.sum | 55 ++++++++++++ plugins/builder-herokuish/internal-functions | 87 ------------------- plugins/builder-herokuish/report | 6 -- plugins/builder-herokuish/report.go | 83 ++++++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ .../src/triggers/triggers.go | 31 +++++++ plugins/builder-herokuish/subcommands.go | 29 +++++++ plugins/builder-herokuish/subcommands/report | 6 -- plugins/builder-lambda/.gitignore | 4 + plugins/builder-lambda/Makefile | 13 +++ plugins/builder-lambda/go.mod | 29 +++++++ plugins/builder-lambda/go.sum | 55 ++++++++++++ plugins/builder-lambda/internal-functions | 87 ------------------- plugins/builder-lambda/report | 6 -- plugins/builder-lambda/report.go | 66 ++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ .../builder-lambda/src/triggers/triggers.go | 31 +++++++ plugins/builder-lambda/subcommands.go | 29 +++++++ plugins/builder-lambda/subcommands/report | 6 -- plugins/builder-nixpacks/.gitignore | 4 + plugins/builder-nixpacks/Makefile | 13 +++ plugins/builder-nixpacks/go.mod | 29 +++++++ plugins/builder-nixpacks/go.sum | 55 ++++++++++++ plugins/builder-nixpacks/internal-functions | 87 ------------------- plugins/builder-nixpacks/report | 6 -- plugins/builder-nixpacks/report.go | 66 ++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ .../builder-nixpacks/src/triggers/triggers.go | 31 +++++++ plugins/builder-nixpacks/subcommands.go | 29 +++++++ plugins/builder-nixpacks/subcommands/report | 6 -- plugins/builder-pack/.gitignore | 4 + plugins/builder-pack/Makefile | 13 +++ plugins/builder-pack/go.mod | 29 +++++++ plugins/builder-pack/go.sum | 55 ++++++++++++ plugins/builder-pack/internal-functions | 87 ------------------- plugins/builder-pack/report | 6 -- plugins/builder-pack/report.go | 66 ++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ plugins/builder-pack/src/triggers/triggers.go | 31 +++++++ plugins/builder-pack/subcommands.go | 29 +++++++ plugins/builder-pack/subcommands/report | 6 -- plugins/builder-railpack/.gitignore | 4 + plugins/builder-railpack/Makefile | 13 +++ plugins/builder-railpack/go.mod | 29 +++++++ plugins/builder-railpack/go.sum | 55 ++++++++++++ plugins/builder-railpack/internal-functions | 87 ------------------- plugins/builder-railpack/report | 6 -- plugins/builder-railpack/report.go | 66 ++++++++++++++ .../src/subcommands/subcommands.go | 40 +++++++++ .../builder-railpack/src/triggers/triggers.go | 31 +++++++ plugins/builder-railpack/subcommands.go | 29 +++++++ plugins/builder-railpack/subcommands/report | 6 -- 67 files changed, 1625 insertions(+), 594 deletions(-) create mode 100644 plugins/builder-dockerfile/.gitignore create mode 100644 plugins/builder-dockerfile/Makefile create mode 100644 plugins/builder-dockerfile/go.mod create mode 100644 plugins/builder-dockerfile/go.sum delete mode 100755 plugins/builder-dockerfile/report create mode 100644 plugins/builder-dockerfile/report.go create mode 100644 plugins/builder-dockerfile/src/subcommands/subcommands.go create mode 100644 plugins/builder-dockerfile/src/triggers/triggers.go create mode 100644 plugins/builder-dockerfile/subcommands.go delete mode 100755 plugins/builder-dockerfile/subcommands/report create mode 100644 plugins/builder-herokuish/.gitignore create mode 100644 plugins/builder-herokuish/Makefile create mode 100644 plugins/builder-herokuish/go.mod create mode 100644 plugins/builder-herokuish/go.sum mode change 100755 => 100644 plugins/builder-herokuish/internal-functions delete mode 100755 plugins/builder-herokuish/report create mode 100644 plugins/builder-herokuish/report.go create mode 100644 plugins/builder-herokuish/src/subcommands/subcommands.go create mode 100644 plugins/builder-herokuish/src/triggers/triggers.go create mode 100644 plugins/builder-herokuish/subcommands.go delete mode 100755 plugins/builder-herokuish/subcommands/report create mode 100644 plugins/builder-lambda/.gitignore create mode 100644 plugins/builder-lambda/Makefile create mode 100644 plugins/builder-lambda/go.mod create mode 100644 plugins/builder-lambda/go.sum mode change 100755 => 100644 plugins/builder-lambda/internal-functions delete mode 100755 plugins/builder-lambda/report create mode 100644 plugins/builder-lambda/report.go create mode 100644 plugins/builder-lambda/src/subcommands/subcommands.go create mode 100644 plugins/builder-lambda/src/triggers/triggers.go create mode 100644 plugins/builder-lambda/subcommands.go delete mode 100755 plugins/builder-lambda/subcommands/report create mode 100644 plugins/builder-nixpacks/.gitignore create mode 100644 plugins/builder-nixpacks/Makefile create mode 100644 plugins/builder-nixpacks/go.mod create mode 100644 plugins/builder-nixpacks/go.sum mode change 100755 => 100644 plugins/builder-nixpacks/internal-functions delete mode 100755 plugins/builder-nixpacks/report create mode 100644 plugins/builder-nixpacks/report.go create mode 100644 plugins/builder-nixpacks/src/subcommands/subcommands.go create mode 100644 plugins/builder-nixpacks/src/triggers/triggers.go create mode 100644 plugins/builder-nixpacks/subcommands.go delete mode 100755 plugins/builder-nixpacks/subcommands/report create mode 100644 plugins/builder-pack/.gitignore create mode 100644 plugins/builder-pack/Makefile create mode 100644 plugins/builder-pack/go.mod create mode 100644 plugins/builder-pack/go.sum mode change 100755 => 100644 plugins/builder-pack/internal-functions delete mode 100755 plugins/builder-pack/report create mode 100644 plugins/builder-pack/report.go create mode 100644 plugins/builder-pack/src/subcommands/subcommands.go create mode 100644 plugins/builder-pack/src/triggers/triggers.go create mode 100644 plugins/builder-pack/subcommands.go delete mode 100755 plugins/builder-pack/subcommands/report create mode 100644 plugins/builder-railpack/.gitignore create mode 100644 plugins/builder-railpack/Makefile create mode 100644 plugins/builder-railpack/go.mod create mode 100644 plugins/builder-railpack/go.sum mode change 100755 => 100644 plugins/builder-railpack/internal-functions delete mode 100755 plugins/builder-railpack/report create mode 100644 plugins/builder-railpack/report.go create mode 100644 plugins/builder-railpack/src/subcommands/subcommands.go create mode 100644 plugins/builder-railpack/src/triggers/triggers.go create mode 100644 plugins/builder-railpack/subcommands.go delete mode 100755 plugins/builder-railpack/subcommands/report diff --git a/go.work b/go.work index bf66069d0..931e6439d 100644 --- a/go.work +++ b/go.work @@ -4,6 +4,12 @@ use ( ./plugins/app-json ./plugins/apps ./plugins/builder + ./plugins/builder-dockerfile + ./plugins/builder-herokuish + ./plugins/builder-lambda + ./plugins/builder-nixpacks + ./plugins/builder-pack + ./plugins/builder-railpack ./plugins/buildpacks ./plugins/common ./plugins/config diff --git a/plugins/builder-dockerfile/.gitignore b/plugins/builder-dockerfile/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-dockerfile/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-dockerfile/Makefile b/plugins/builder-dockerfile/Makefile new file mode 100644 index 000000000..be9dbcce5 --- /dev/null +++ b/plugins/builder-dockerfile/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-dockerfile + +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/builder-dockerfile/go.mod b/plugins/builder-dockerfile/go.mod new file mode 100644 index 000000000..dd1f20cb8 --- /dev/null +++ b/plugins/builder-dockerfile/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-dockerfile + +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/builder-dockerfile/go.sum b/plugins/builder-dockerfile/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-dockerfile/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/builder-dockerfile/internal-functions b/plugins/builder-dockerfile/internal-functions index a7c6a236a..66ecb200e 100755 --- a/plugins/builder-dockerfile/internal-functions +++ b/plugins/builder-dockerfile/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-dockerfile-report() { - declare desc="displays a builder-dockerfile report for one or more apps" - declare cmd="builder-dockerfile: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-builder-dockerfile-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-dockerfile-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-dockerfile-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")" - "--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")" - "--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")" - "--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-dockerfile" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-dockerfile information" - else - dokku_log_info2_quiet "${APP} builder-dockerfile 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 -} - fn-builder-dockerfile-computed-dockerfile-path() { declare APP="$1" diff --git a/plugins/builder-dockerfile/report b/plugins/builder-dockerfile/report deleted file mode 100755 index 1f809ffca..000000000 --- a/plugins/builder-dockerfile/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-dockerfile-report-single "$@" diff --git a/plugins/builder-dockerfile/report.go b/plugins/builder-dockerfile/report.go new file mode 100644 index 000000000..6e59cd31b --- /dev/null +++ b/plugins/builder-dockerfile/report.go @@ -0,0 +1,66 @@ +package builderdockerfile + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-dockerfile 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{ + "--builder-dockerfile-computed-dockerfile-path": reportComputedDockerfilePath, + "--builder-dockerfile-global-dockerfile-path": reportGlobalDockerfilePath, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-dockerfile-computed-dockerfile-path": reportComputedDockerfilePath, + "--builder-dockerfile-global-dockerfile-path": reportGlobalDockerfilePath, + "--builder-dockerfile-dockerfile-path": reportDockerfilePath, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-dockerfile", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportDockerfilePath(appName string) string { + return common.PropertyGet("builder-dockerfile", appName, "dockerfile-path") +} + +func reportGlobalDockerfilePath(appName string) string { + return common.PropertyGet("builder-dockerfile", "--global", "dockerfile-path") +} + +func reportComputedDockerfilePath(appName string) string { + value := reportDockerfilePath(appName) + if value == "" { + value = reportGlobalDockerfilePath(appName) + } + if value == "" { + value = "Dockerfile" + } + + return value +} diff --git a/plugins/builder-dockerfile/src/subcommands/subcommands.go b/plugins/builder-dockerfile/src/subcommands/subcommands.go new file mode 100644 index 000000000..df2ec7bd0 --- /dev/null +++ b/plugins/builder-dockerfile/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + builderdockerfile "github.com/dokku/dokku/plugins/builder-dockerfile" + "github.com/dokku/dokku/plugins/common" + + 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("builder-dockerfile:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-dockerfile", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = builderdockerfile.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/builder-dockerfile/src/triggers/triggers.go b/plugins/builder-dockerfile/src/triggers/triggers.go new file mode 100644 index 000000000..7e39978b5 --- /dev/null +++ b/plugins/builder-dockerfile/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + builderdockerfile "github.com/dokku/dokku/plugins/builder-dockerfile" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = builderdockerfile.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-dockerfile/subcommands.go b/plugins/builder-dockerfile/subcommands.go new file mode 100644 index 000000000..12e3827d8 --- /dev/null +++ b/plugins/builder-dockerfile/subcommands.go @@ -0,0 +1,29 @@ +package builderdockerfile + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-dockerfile 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/builder-dockerfile/subcommands/report b/plugins/builder-dockerfile/subcommands/report deleted file mode 100755 index 15f0f1769..000000000 --- a/plugins/builder-dockerfile/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-dockerfile-report "$@" diff --git a/plugins/builder-herokuish/.gitignore b/plugins/builder-herokuish/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-herokuish/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-herokuish/Makefile b/plugins/builder-herokuish/Makefile new file mode 100644 index 000000000..716f94f54 --- /dev/null +++ b/plugins/builder-herokuish/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-herokuish + +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/builder-herokuish/go.mod b/plugins/builder-herokuish/go.mod new file mode 100644 index 000000000..526892e6e --- /dev/null +++ b/plugins/builder-herokuish/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-herokuish + +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/builder-herokuish/go.sum b/plugins/builder-herokuish/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-herokuish/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/builder-herokuish/internal-functions b/plugins/builder-herokuish/internal-functions old mode 100755 new mode 100644 index a5cf4182e..395f146fd --- a/plugins/builder-herokuish/internal-functions +++ b/plugins/builder-herokuish/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-herokuish-report() { - declare desc="displays a builder-herokuish report for one or more apps" - declare cmd="builder-herokuish: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-builder-herokuish-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-herokuish-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-herokuish-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-herokuish-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")" - "--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")" - "--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)" - "--builder-herokuish-allowed: $(fn-builder-herokuish-allowed "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-herokuish" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-herokuish information" - else - dokku_log_info2_quiet "${APP} builder-herokuish 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 -} - fn-builder-herokuish-computed-allowed() { declare APP="$1" diff --git a/plugins/builder-herokuish/report b/plugins/builder-herokuish/report deleted file mode 100755 index 785102c30..000000000 --- a/plugins/builder-herokuish/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-herokuish/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-herokuish-report-single "$@" diff --git a/plugins/builder-herokuish/report.go b/plugins/builder-herokuish/report.go new file mode 100644 index 000000000..b5ab0b347 --- /dev/null +++ b/plugins/builder-herokuish/report.go @@ -0,0 +1,83 @@ +package builderherokuish + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-herokuish 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{ + "--builder-herokuish-computed-allowed": reportComputedAllowed, + "--builder-herokuish-global-allowed": reportGlobalAllowed, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-herokuish-computed-allowed": reportComputedAllowed, + "--builder-herokuish-global-allowed": reportGlobalAllowed, + "--builder-herokuish-allowed": reportAllowed, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-herokuish", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportAllowed(appName string) string { + return common.PropertyGet("builder-herokuish", appName, "allowed") +} + +func reportGlobalAllowed(appName string) string { + return common.PropertyGet("builder-herokuish", "--global", "allowed") +} + +func reportComputedAllowed(appName string) string { + allowed := reportAllowed(appName) + if allowed == "" { + allowed = reportGlobalAllowed(appName) + } + if allowed == "" { + allowed = "true" + if hostArchitecture() != "amd64" { + allowed = "false" + } + } + + return allowed +} + +// hostArchitecture returns the dpkg architecture of the host, or an empty string +// when it cannot be determined (matching the bash `dpkg --print-architecture` check) +func hostArchitecture() string { + result, err := common.CallExecCommand(common.ExecCommandInput{ + Command: "dpkg", + Args: []string{"--print-architecture"}, + }) + if err != nil { + return "" + } + + return result.StdoutContents() +} diff --git a/plugins/builder-herokuish/src/subcommands/subcommands.go b/plugins/builder-herokuish/src/subcommands/subcommands.go new file mode 100644 index 000000000..9fb446a78 --- /dev/null +++ b/plugins/builder-herokuish/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + builderherokuish "github.com/dokku/dokku/plugins/builder-herokuish" + "github.com/dokku/dokku/plugins/common" + + 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("builder-herokuish:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-herokuish", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = builderherokuish.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/builder-herokuish/src/triggers/triggers.go b/plugins/builder-herokuish/src/triggers/triggers.go new file mode 100644 index 000000000..54a6929a2 --- /dev/null +++ b/plugins/builder-herokuish/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + builderherokuish "github.com/dokku/dokku/plugins/builder-herokuish" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = builderherokuish.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-herokuish/subcommands.go b/plugins/builder-herokuish/subcommands.go new file mode 100644 index 000000000..5d6971762 --- /dev/null +++ b/plugins/builder-herokuish/subcommands.go @@ -0,0 +1,29 @@ +package builderherokuish + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-herokuish 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/builder-herokuish/subcommands/report b/plugins/builder-herokuish/subcommands/report deleted file mode 100755 index d99bfa2fb..000000000 --- a/plugins/builder-herokuish/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-herokuish/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-herokuish-report "$@" diff --git a/plugins/builder-lambda/.gitignore b/plugins/builder-lambda/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-lambda/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-lambda/Makefile b/plugins/builder-lambda/Makefile new file mode 100644 index 000000000..7c29679a8 --- /dev/null +++ b/plugins/builder-lambda/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-lambda + +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/builder-lambda/go.mod b/plugins/builder-lambda/go.mod new file mode 100644 index 000000000..6568b612a --- /dev/null +++ b/plugins/builder-lambda/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-lambda + +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/builder-lambda/go.sum b/plugins/builder-lambda/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-lambda/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/builder-lambda/internal-functions b/plugins/builder-lambda/internal-functions old mode 100755 new mode 100644 index 98af8d6b7..cb9069a68 --- a/plugins/builder-lambda/internal-functions +++ b/plugins/builder-lambda/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-lambda-report() { - declare desc="displays a builder-lambda report for one or more apps" - declare cmd="builder-lambda: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-builder-lambda-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-lambda-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-lambda-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-lambda-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-lambda-computed-lambdayml-path: $(fn-builder-lambda-computed-lambdayml-path "$APP")" - "--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-lambda-computed-lambdayml-path: $(fn-builder-lambda-computed-lambdayml-path "$APP")" - "--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")" - "--builder-lambda-lambdayml-path: $(fn-builder-lambda-lambdayml-path "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-lambda" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-lambda information" - else - dokku_log_info2_quiet "${APP} builder-lambda 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 -} - fn-builder-lambda-computed-lambdayml-path() { declare APP="$1" diff --git a/plugins/builder-lambda/report b/plugins/builder-lambda/report deleted file mode 100755 index 3271b3684..000000000 --- a/plugins/builder-lambda/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-lambda/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-lambda-report-single "$@" diff --git a/plugins/builder-lambda/report.go b/plugins/builder-lambda/report.go new file mode 100644 index 000000000..e9290a75e --- /dev/null +++ b/plugins/builder-lambda/report.go @@ -0,0 +1,66 @@ +package builderlambda + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-lambda 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{ + "--builder-lambda-computed-lambdayml-path": reportComputedLambdaymlPath, + "--builder-lambda-global-lambdayml-path": reportGlobalLambdaymlPath, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-lambda-computed-lambdayml-path": reportComputedLambdaymlPath, + "--builder-lambda-global-lambdayml-path": reportGlobalLambdaymlPath, + "--builder-lambda-lambdayml-path": reportLambdaymlPath, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-lambda", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportLambdaymlPath(appName string) string { + return common.PropertyGet("builder-lambda", appName, "lambdayml-path") +} + +func reportGlobalLambdaymlPath(appName string) string { + return common.PropertyGet("builder-lambda", "--global", "lambdayml-path") +} + +func reportComputedLambdaymlPath(appName string) string { + value := reportLambdaymlPath(appName) + if value == "" { + value = reportGlobalLambdaymlPath(appName) + } + if value == "" { + value = "lambda.yml" + } + + return value +} diff --git a/plugins/builder-lambda/src/subcommands/subcommands.go b/plugins/builder-lambda/src/subcommands/subcommands.go new file mode 100644 index 000000000..9f8307e5e --- /dev/null +++ b/plugins/builder-lambda/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + builderlambda "github.com/dokku/dokku/plugins/builder-lambda" + "github.com/dokku/dokku/plugins/common" + + 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("builder-lambda:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-lambda", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = builderlambda.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/builder-lambda/src/triggers/triggers.go b/plugins/builder-lambda/src/triggers/triggers.go new file mode 100644 index 000000000..f6832b561 --- /dev/null +++ b/plugins/builder-lambda/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + builderlambda "github.com/dokku/dokku/plugins/builder-lambda" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = builderlambda.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-lambda/subcommands.go b/plugins/builder-lambda/subcommands.go new file mode 100644 index 000000000..c7634558a --- /dev/null +++ b/plugins/builder-lambda/subcommands.go @@ -0,0 +1,29 @@ +package builderlambda + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-lambda 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/builder-lambda/subcommands/report b/plugins/builder-lambda/subcommands/report deleted file mode 100755 index 9f56cd32f..000000000 --- a/plugins/builder-lambda/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-lambda/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-lambda-report "$@" diff --git a/plugins/builder-nixpacks/.gitignore b/plugins/builder-nixpacks/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-nixpacks/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-nixpacks/Makefile b/plugins/builder-nixpacks/Makefile new file mode 100644 index 000000000..79979a35e --- /dev/null +++ b/plugins/builder-nixpacks/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-nixpacks + +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/builder-nixpacks/go.mod b/plugins/builder-nixpacks/go.mod new file mode 100644 index 000000000..3470e287c --- /dev/null +++ b/plugins/builder-nixpacks/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-nixpacks + +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/builder-nixpacks/go.sum b/plugins/builder-nixpacks/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-nixpacks/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/builder-nixpacks/internal-functions b/plugins/builder-nixpacks/internal-functions old mode 100755 new mode 100644 index 2350bd4ea..fab38e0a7 --- a/plugins/builder-nixpacks/internal-functions +++ b/plugins/builder-nixpacks/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-nixpacks-report() { - declare desc="displays a builder-nixpacks report for one or more apps" - declare cmd="builder-nixpacks: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-builder-nixpacks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-nixpacks-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-nixpacks-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-nixpacks-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-nixpacks-computed-nixpackstoml-path: $(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")" - "--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-nixpacks-computed-nixpackstoml-path: $(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")" - "--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")" - "--builder-nixpacks-nixpackstoml-path: $(fn-builder-nixpacks-nixpackstoml-path "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-nixpacks" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-nixpacks information" - else - dokku_log_info2_quiet "${APP} builder-nixpacks 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 -} - fn-builder-nixpacks-computed-nixpackstoml-path() { declare APP="$1" diff --git a/plugins/builder-nixpacks/report b/plugins/builder-nixpacks/report deleted file mode 100755 index 727356552..000000000 --- a/plugins/builder-nixpacks/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-nixpacks/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-nixpacks-report-single "$@" diff --git a/plugins/builder-nixpacks/report.go b/plugins/builder-nixpacks/report.go new file mode 100644 index 000000000..ecd1322cc --- /dev/null +++ b/plugins/builder-nixpacks/report.go @@ -0,0 +1,66 @@ +package buildernixpacks + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-nixpacks 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{ + "--builder-nixpacks-computed-nixpackstoml-path": reportComputedNixpackstomlPath, + "--builder-nixpacks-global-nixpackstoml-path": reportGlobalNixpackstomlPath, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-nixpacks-computed-nixpackstoml-path": reportComputedNixpackstomlPath, + "--builder-nixpacks-global-nixpackstoml-path": reportGlobalNixpackstomlPath, + "--builder-nixpacks-nixpackstoml-path": reportNixpackstomlPath, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-nixpacks", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportNixpackstomlPath(appName string) string { + return common.PropertyGet("builder-nixpacks", appName, "nixpackstoml-path") +} + +func reportGlobalNixpackstomlPath(appName string) string { + return common.PropertyGet("builder-nixpacks", "--global", "nixpackstoml-path") +} + +func reportComputedNixpackstomlPath(appName string) string { + value := reportNixpackstomlPath(appName) + if value == "" { + value = reportGlobalNixpackstomlPath(appName) + } + if value == "" { + value = "nixpacks.toml" + } + + return value +} diff --git a/plugins/builder-nixpacks/src/subcommands/subcommands.go b/plugins/builder-nixpacks/src/subcommands/subcommands.go new file mode 100644 index 000000000..9016333ae --- /dev/null +++ b/plugins/builder-nixpacks/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + buildernixpacks "github.com/dokku/dokku/plugins/builder-nixpacks" + "github.com/dokku/dokku/plugins/common" + + 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("builder-nixpacks:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-nixpacks", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = buildernixpacks.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/builder-nixpacks/src/triggers/triggers.go b/plugins/builder-nixpacks/src/triggers/triggers.go new file mode 100644 index 000000000..57fafcf5e --- /dev/null +++ b/plugins/builder-nixpacks/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + buildernixpacks "github.com/dokku/dokku/plugins/builder-nixpacks" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = buildernixpacks.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-nixpacks/subcommands.go b/plugins/builder-nixpacks/subcommands.go new file mode 100644 index 000000000..ec7b91958 --- /dev/null +++ b/plugins/builder-nixpacks/subcommands.go @@ -0,0 +1,29 @@ +package buildernixpacks + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-nixpacks 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/builder-nixpacks/subcommands/report b/plugins/builder-nixpacks/subcommands/report deleted file mode 100755 index 4ea4b1d13..000000000 --- a/plugins/builder-nixpacks/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-nixpacks/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-nixpacks-report "$@" diff --git a/plugins/builder-pack/.gitignore b/plugins/builder-pack/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-pack/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-pack/Makefile b/plugins/builder-pack/Makefile new file mode 100644 index 000000000..ab09df0e2 --- /dev/null +++ b/plugins/builder-pack/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-pack + +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/builder-pack/go.mod b/plugins/builder-pack/go.mod new file mode 100644 index 000000000..411219c8a --- /dev/null +++ b/plugins/builder-pack/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-pack + +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/builder-pack/go.sum b/plugins/builder-pack/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-pack/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/builder-pack/internal-functions b/plugins/builder-pack/internal-functions old mode 100755 new mode 100644 index f127f77a0..f81f131ea --- a/plugins/builder-pack/internal-functions +++ b/plugins/builder-pack/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-pack-report() { - declare desc="displays a builder-pack report for one or more apps" - declare cmd="builder-pack: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-builder-pack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-pack-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-pack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-pack-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")" - "--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")" - "--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")" - "--builder-pack-projecttoml-path: $(fn-builder-pack-projecttoml-path "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-pack" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-pack information" - else - dokku_log_info2_quiet "${APP} builder-pack 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 -} - fn-builder-pack-computed-projecttoml-path() { declare APP="$1" diff --git a/plugins/builder-pack/report b/plugins/builder-pack/report deleted file mode 100755 index 600703509..000000000 --- a/plugins/builder-pack/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-pack-report-single "$@" diff --git a/plugins/builder-pack/report.go b/plugins/builder-pack/report.go new file mode 100644 index 000000000..c1949c457 --- /dev/null +++ b/plugins/builder-pack/report.go @@ -0,0 +1,66 @@ +package builderpack + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-pack 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{ + "--builder-pack-computed-projecttoml-path": reportComputedProjecttomlPath, + "--builder-pack-global-projecttoml-path": reportGlobalProjecttomlPath, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-pack-computed-projecttoml-path": reportComputedProjecttomlPath, + "--builder-pack-global-projecttoml-path": reportGlobalProjecttomlPath, + "--builder-pack-projecttoml-path": reportProjecttomlPath, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-pack", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportProjecttomlPath(appName string) string { + return common.PropertyGet("builder-pack", appName, "projecttoml-path") +} + +func reportGlobalProjecttomlPath(appName string) string { + return common.PropertyGet("builder-pack", "--global", "projecttoml-path") +} + +func reportComputedProjecttomlPath(appName string) string { + value := reportProjecttomlPath(appName) + if value == "" { + value = reportGlobalProjecttomlPath(appName) + } + if value == "" { + value = "project.toml" + } + + return value +} diff --git a/plugins/builder-pack/src/subcommands/subcommands.go b/plugins/builder-pack/src/subcommands/subcommands.go new file mode 100644 index 000000000..b78f01b91 --- /dev/null +++ b/plugins/builder-pack/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + builderpack "github.com/dokku/dokku/plugins/builder-pack" + "github.com/dokku/dokku/plugins/common" + + 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("builder-pack:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-pack", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = builderpack.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/builder-pack/src/triggers/triggers.go b/plugins/builder-pack/src/triggers/triggers.go new file mode 100644 index 000000000..79a63f32a --- /dev/null +++ b/plugins/builder-pack/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + builderpack "github.com/dokku/dokku/plugins/builder-pack" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = builderpack.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-pack/subcommands.go b/plugins/builder-pack/subcommands.go new file mode 100644 index 000000000..363cd781e --- /dev/null +++ b/plugins/builder-pack/subcommands.go @@ -0,0 +1,29 @@ +package builderpack + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-pack 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/builder-pack/subcommands/report b/plugins/builder-pack/subcommands/report deleted file mode 100755 index 03f6be771..000000000 --- a/plugins/builder-pack/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-pack-report "$@" diff --git a/plugins/builder-railpack/.gitignore b/plugins/builder-railpack/.gitignore new file mode 100644 index 000000000..dac9d7731 --- /dev/null +++ b/plugins/builder-railpack/.gitignore @@ -0,0 +1,4 @@ +/report +/report-subcommand +/triggers +/subcommands/report diff --git a/plugins/builder-railpack/Makefile b/plugins/builder-railpack/Makefile new file mode 100644 index 000000000..73f557fa4 --- /dev/null +++ b/plugins/builder-railpack/Makefile @@ -0,0 +1,13 @@ +GOARCH ?= amd64 +TRIGGERS = triggers/report +BUILD = report-subcommand triggers +PLUGIN_NAME = builder-railpack + +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/builder-railpack/go.mod b/plugins/builder-railpack/go.mod new file mode 100644 index 000000000..f517a86e6 --- /dev/null +++ b/plugins/builder-railpack/go.mod @@ -0,0 +1,29 @@ +module github.com/dokku/dokku/plugins/builder-railpack + +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/builder-railpack/go.sum b/plugins/builder-railpack/go.sum new file mode 100644 index 000000000..5a5292407 --- /dev/null +++ b/plugins/builder-railpack/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/builder-railpack/internal-functions b/plugins/builder-railpack/internal-functions old mode 100755 new mode 100644 index 0dc979e46..8d71c35fc --- a/plugins/builder-railpack/internal-functions +++ b/plugins/builder-railpack/internal-functions @@ -4,93 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -cmd-builder-railpack-report() { - declare desc="displays a builder-railpack report for one or more apps" - declare cmd="builder-railpack: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-builder-railpack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - elif [[ -z "$APP" ]]; then - for app in $(dokku_apps); do - cmd-builder-railpack-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true - done - else - cmd-builder-railpack-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT" - fi -} - -cmd-builder-railpack-report-single() { - declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}" - if [[ "$INFO_FLAG" == "true" ]]; then - INFO_FLAG="" - fi - local flag_map=() - if [[ "$APP" == "--global" ]]; then - flag_map=( - "--builder-railpack-computed-railpackjson-path: $(fn-builder-railpack-computed-railpackjson-path "$APP")" - "--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")" - ) - else - verify_app_name "$APP" - flag_map=( - "--builder-railpack-computed-railpackjson-path: $(fn-builder-railpack-computed-railpackjson-path "$APP")" - "--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")" - "--builder-railpack-railpackjson-path: $(fn-builder-railpack-railpackjson-path "$APP")" - ) - fi - - fn-report-validate-format "$FORMAT" "$INFO_FLAG" - - if [[ "$FORMAT" == "json" ]]; then - fn-report-emit-json flag_map "builder-railpack" - return - fi - - if [[ -z "$INFO_FLAG" ]]; then - if [[ "$APP" == "--global" ]]; then - dokku_log_info2_quiet "global builder-railpack information" - else - dokku_log_info2_quiet "${APP} builder-railpack 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 -} - fn-builder-railpack-computed-railpackjson-path() { declare APP="$1" diff --git a/plugins/builder-railpack/report b/plugins/builder-railpack/report deleted file mode 100755 index 6fbd0d855..000000000 --- a/plugins/builder-railpack/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-railpack-report-single "$@" diff --git a/plugins/builder-railpack/report.go b/plugins/builder-railpack/report.go new file mode 100644 index 000000000..887bb4e65 --- /dev/null +++ b/plugins/builder-railpack/report.go @@ -0,0 +1,66 @@ +package builderrailpack + +import ( + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the builder-railpack 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{ + "--builder-railpack-computed-railpackjson-path": reportComputedRailpackjsonPath, + "--builder-railpack-global-railpackjson-path": reportGlobalRailpackjsonPath, + } + } else { + flags = map[string]common.ReportFunc{ + "--builder-railpack-computed-railpackjson-path": reportComputedRailpackjsonPath, + "--builder-railpack-global-railpackjson-path": reportGlobalRailpackjsonPath, + "--builder-railpack-railpackjson-path": reportRailpackjsonPath, + } + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp(common.ReportSingleAppInput{ + ReportType: "builder-railpack", + AppName: appName, + InfoFlag: infoFlag, + InfoFlags: infoFlags, + InfoFlagKeys: flagKeys, + Format: format, + TrimPrefix: true, + UppercaseFirstCharacter: true, + EmitLegacyPrefix: false, + }) +} + +func reportRailpackjsonPath(appName string) string { + return common.PropertyGet("builder-railpack", appName, "railpackjson-path") +} + +func reportGlobalRailpackjsonPath(appName string) string { + return common.PropertyGet("builder-railpack", "--global", "railpackjson-path") +} + +func reportComputedRailpackjsonPath(appName string) string { + value := reportRailpackjsonPath(appName) + if value == "" { + value = reportGlobalRailpackjsonPath(appName) + } + if value == "" { + value = "railpack.json" + } + + return value +} diff --git a/plugins/builder-railpack/src/subcommands/subcommands.go b/plugins/builder-railpack/src/subcommands/subcommands.go new file mode 100644 index 000000000..12a610b0f --- /dev/null +++ b/plugins/builder-railpack/src/subcommands/subcommands.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "strings" + + builderrailpack "github.com/dokku/dokku/plugins/builder-railpack" + "github.com/dokku/dokku/plugins/common" + + 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("builder-railpack:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + reportArgs, flagErr := common.ParseReportArgs("builder-railpack", os.Args[2:]) + if flagErr == nil { + args.Parse(reportArgs.OSArgs) + appName := args.Arg(0) + if reportArgs.IsGlobal { + appName = "--global" + } + err = builderrailpack.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/builder-railpack/src/triggers/triggers.go b/plugins/builder-railpack/src/triggers/triggers.go new file mode 100644 index 000000000..9e6327592 --- /dev/null +++ b/plugins/builder-railpack/src/triggers/triggers.go @@ -0,0 +1,31 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + builderrailpack "github.com/dokku/dokku/plugins/builder-railpack" + "github.com/dokku/dokku/plugins/common" +) + +// 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 = builderrailpack.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/builder-railpack/subcommands.go b/plugins/builder-railpack/subcommands.go new file mode 100644 index 000000000..f8ac38c3e --- /dev/null +++ b/plugins/builder-railpack/subcommands.go @@ -0,0 +1,29 @@ +package builderrailpack + +import ( + "errors" + + "github.com/dokku/dokku/plugins/common" +) + +// CommandReport displays a builder-railpack 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/builder-railpack/subcommands/report b/plugins/builder-railpack/subcommands/report deleted file mode 100755 index 9801d5f29..000000000 --- a/plugins/builder-railpack/subcommands/report +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions" -set -eo pipefail -[[ $DOKKU_TRACE ]] && set -x - -cmd-builder-railpack-report "$@"