mirror of
https://github.com/foomo/squadron.git
synced 2025-10-16 12:35:42 +00:00
Merge pull request #116 from foomo/feature/default-build-args
Some checks failed
Test Branch / test (push) Has been cancelled
Some checks failed
Test Branch / test (push) Has been cancelled
feat: default build args
This commit is contained in:
commit
470cb96905
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@ -9,7 +9,6 @@ on:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
@ -28,9 +27,13 @@ jobs:
|
|||||||
check-latest: true
|
check-latest: true
|
||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
|
|
||||||
- uses: golangci/golangci-lint-action@v8
|
- name: Setup golangci-lint cache
|
||||||
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
install-mode: none
|
path: ~/.cache/golangci-lint
|
||||||
|
key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.mod') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-golangci-lint-
|
||||||
|
|
||||||
- name: Run lint
|
- name: Run lint
|
||||||
run: make lint
|
run: make lint
|
||||||
|
|||||||
241
.golangci.yml
241
.golangci.yml
@ -1,122 +1,59 @@
|
|||||||
|
# https://golangci-lint.run/usage/configuration/
|
||||||
|
# yaml-language-server: $schema=https://golangci-lint.run/jsonschema/golangci.jsonschema.json
|
||||||
version: "2"
|
version: "2"
|
||||||
|
|
||||||
run:
|
run:
|
||||||
build-tags: [safe]
|
build-tags: [ safe ]
|
||||||
modules-download-mode: readonly
|
modules-download-mode: readonly
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
default: none
|
default: all
|
||||||
enable:
|
disable:
|
||||||
## Default linters
|
# Project specific linters
|
||||||
- errcheck # errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]
|
- forbidigo
|
||||||
- govet # (vet, vetshadow) Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes. [fast: false, auto-fix: false]
|
- recvcheck
|
||||||
- ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
|
- paralleltest
|
||||||
- staticcheck # (megacheck) It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint. [fast: false, auto-fix: false]
|
# Discouraged linters
|
||||||
- unused # (megacheck) Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
|
- noinlineerr # Disallows inline error handling (`if err := ...; err != nil {`).
|
||||||
|
- embeddedstructfieldcheck # Embedded types should be at the top of the field list of a struct, and there must be an empty line separating embedded fields from regular fields. [fast]
|
||||||
## Recommended linters
|
- cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
|
||||||
- asasalint # check for pass []any as any in variadic func(...any) [fast: false, auto-fix: false]
|
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
|
||||||
- asciicheck # checks that all code identifiers does not have non-ASCII symbols in the name [fast: true, auto-fix: false]
|
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
|
||||||
- bidichk # Checks for dangerous unicode character sequences [fast: true, auto-fix: false]
|
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
||||||
- bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
|
- dupword # checks for duplicate words in the source code [fast: true, auto-fix: false]
|
||||||
- canonicalheader # checks whether net/http.Header uses canonical header [fast: false, auto-fix: false]
|
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
|
||||||
- containedctx # containedctx is a linter that detects struct contained context.Context field [fast: false, auto-fix: false]
|
- err113 # Go linter to check the errors handling expressions [fast: false, auto-fix: false]
|
||||||
- contextcheck # check whether the function uses a non-inherited context [fast: false, auto-fix: false]
|
- exhaustruct # Checks if all structure fields are initialized [fast: false, auto-fix: false]
|
||||||
- copyloopvar # (go >= 1.22) copyloopvar is a linter detects places where loop variables are copied [fast: true, auto-fix: false]
|
- funlen # Tool for detection of long functions [fast: true, auto-fix: false]
|
||||||
- decorder # check declaration order and count of types, constants, variables and functions [fast: true, auto-fix: false]
|
- ginkgolinter # enforces standards of using ginkgo and gomega [fast: false, auto-fix: false]
|
||||||
- durationcheck # check for two durations multiplied together [fast: false, auto-fix: false]
|
- gochecknoglobals # Check that no global variables exist. [fast: false, auto-fix: false]
|
||||||
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted. [fast: false, auto-fix: false]
|
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
||||||
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]
|
- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
|
||||||
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]
|
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
|
||||||
- exhaustive # check exhaustiveness of enum switch statements [fast: false, auto-fix: false]
|
- godot # Check if comments end in a period [fast: true, auto-fix: true]
|
||||||
- exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions. [auto-fix]
|
- godox # Tool for detection of comment keywords [fast: true, auto-fix: false]
|
||||||
- fatcontext # detects nested contexts in loops and function literals [fast: false, auto-fix: false]
|
- interfacebloat # A linter that checks the number of methods inside an interface. [fast: true, auto-fix: false]
|
||||||
#- forbidigo # Forbids identifiers [fast: false, auto-fix: false]
|
|
||||||
- forcetypeassert # finds forced type assertions [fast: true, auto-fix: false]
|
|
||||||
- gocheckcompilerdirectives # Checks that go compiler directive comments (//go:) are valid. [fast: true, auto-fix: false]
|
|
||||||
- gochecksumtype # Run exhaustiveness checks on Go "sum types" [fast: false, auto-fix: false]
|
|
||||||
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
|
|
||||||
- gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: true]
|
|
||||||
- goheader # Checks is file header matches to pattern [fast: true, auto-fix: true]
|
|
||||||
- gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false]
|
|
||||||
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false]
|
|
||||||
- goprintffuncname # Checks that printf-like functions are named with `f` at the end. [fast: true, auto-fix: false]
|
|
||||||
- gosec # (gas) Inspects source code for security problems [fast: false, auto-fix: false]
|
|
||||||
- gosmopolitan # Report certain i18n/l10n anti-patterns in your Go codebase [fast: false, auto-fix: false]
|
|
||||||
- grouper # Analyze expression groups. [fast: true, auto-fix: false]
|
|
||||||
- iface # Detect the incorrect use of interfaces, helping developers avoid interface pollution. [fast: false, auto-fix: false]
|
|
||||||
- importas # Enforces consistent import aliases [fast: false, auto-fix: false]
|
|
||||||
- inamedparam # reports interfaces with unnamed method parameters [fast: true, auto-fix: false]
|
|
||||||
- intrange # (go >= 1.22) intrange is a linter to find places where for loops could make use of an integer range. [fast: true, auto-fix: false]
|
- intrange # (go >= 1.22) intrange is a linter to find places where for loops could make use of an integer range. [fast: true, auto-fix: false]
|
||||||
- loggercheck # (logrlint) Checks key value pairs for common logger libraries (kitlog,klog,logr,zap). [fast: false, auto-fix: false]
|
- ireturn # Accept Interfaces, Return Concrete Types [fast: false, auto-fix: false]
|
||||||
- makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]
|
- lll # Reports long lines [fast: true, auto-fix: false]
|
||||||
- mirror # reports wrong mirror patterns of bytes/strings usage [fast: false, auto-fix: true]
|
- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]
|
||||||
- misspell # Finds commonly misspelled English words [fast: true, auto-fix: true]
|
- nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
|
||||||
- musttag # enforce field tags in (un)marshaled structs [fast: false, auto-fix: false]
|
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]
|
||||||
- nakedret # Checks that functions with naked returns are not longer than a maximum size (can be zero). [fast: true, auto-fix: false]
|
- mnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
|
||||||
- nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]
|
- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative. [fast: false, auto-fix: false]
|
||||||
- nilnesserr # Reports constructs that checks for err != nil, but returns a different nil value error.
|
- prealloc # Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false]
|
||||||
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false]
|
- protogetter # Reports direct reads from proto message fields when getters should be used [fast: false, auto-fix: true]
|
||||||
- noctx # Finds sending http request without context.Context [fast: false, auto-fix: false]
|
- sloglint # ensure consistent code style when using log/slog [fast: false, auto-fix: false]
|
||||||
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: true]
|
- tagalign # check that struct tags are well aligned [fast: true, auto-fix: true]
|
||||||
- nonamedreturns # Reports all named returns [fast: false, auto-fix: false]
|
- tagliatelle # Checks the struct tags. [fast: true, auto-fix: false]
|
||||||
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false]
|
- unparam # Reports unused function parameters [fast: false, auto-fix: false]
|
||||||
#- paralleltest # Detects missing usage of t.Parallel() method in your Go test [fast: false, auto-fix: false]
|
- varnamelen # checks that the length of a variable's name matches its scope [fast: false, auto-fix: false]
|
||||||
- predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]
|
- wrapcheck # Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]
|
||||||
- promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]
|
- zerologlint # Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg` [fast: false, auto-fix: false]
|
||||||
- reassign # Checks that package variables are not reassigned [fast: false, auto-fix: false]
|
# Deprected linters
|
||||||
#- recvcheck # checks for receiver type consistency [fast: false, auto-fix: false]
|
- wsl
|
||||||
- revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false]
|
|
||||||
- rowserrcheck # checks whether Rows.Err of rows is checked successfully [fast: false, auto-fix: false]
|
|
||||||
- spancheck # Checks for mistakes with OpenTelemetry/Census spans. [fast: false, auto-fix: false]
|
|
||||||
- sqlclosecheck # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed. [fast: false, auto-fix: false]
|
|
||||||
- testableexamples # linter checks if examples are testable (have an expected output) [fast: true, auto-fix: false]
|
|
||||||
- testifylint # Checks usage of github.com/stretchr/testify. [fast: false, auto-fix: false]
|
|
||||||
- testpackage # linter that makes you use a separate _test package [fast: true, auto-fix: false]
|
|
||||||
- thelper # thelper detects tests helpers which is not start with t.Helper() method. [fast: false, auto-fix: false]
|
|
||||||
- tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes. [fast: false, auto-fix: false]
|
|
||||||
- unconvert # Remove unnecessary type conversions [fast: false, auto-fix: false]
|
|
||||||
- usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. [fast: true, auto-fix: false]
|
|
||||||
- usetesting # Reports uses of functions with replacement inside the testing package. [auto-fix]
|
|
||||||
- wastedassign # Finds wasted assignment statements [fast: false, auto-fix: false]
|
|
||||||
- whitespace # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. [fast: true, auto-fix: true]
|
|
||||||
|
|
||||||
## Discouraged linters
|
# https://golangci-lint.run/docs/linters/
|
||||||
#- cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
|
|
||||||
#- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
|
|
||||||
#- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
|
|
||||||
#- dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
|
||||||
#- dupword # checks for duplicate words in the source code [fast: true, auto-fix: false]
|
|
||||||
#- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
|
|
||||||
#- err113 # Go linter to check the errors handling expressions [fast: false, auto-fix: false]
|
|
||||||
#- exhaustruct # Checks if all structure fields are initialized [fast: false, auto-fix: false]
|
|
||||||
#- funlen # Tool for detection of long functions [fast: true, auto-fix: false]
|
|
||||||
#- ginkgolinter # enforces standards of using ginkgo and gomega [fast: false, auto-fix: false]
|
|
||||||
#- gochecknoglobals # Check that no global variables exist. [fast: false, auto-fix: false]
|
|
||||||
#- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
|
||||||
#- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
|
|
||||||
#- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
|
|
||||||
#- godot # Check if comments end in a period [fast: true, auto-fix: true]
|
|
||||||
#- godox # Tool for detection of comment keywords [fast: true, auto-fix: false]
|
|
||||||
#- interfacebloat # A linter that checks the number of methods inside an interface. [fast: true, auto-fix: false]
|
|
||||||
#- intrange # (go >= 1.22) intrange is a linter to find places where for loops could make use of an integer range. [fast: true, auto-fix: false]
|
|
||||||
#- ireturn # Accept Interfaces, Return Concrete Types [fast: false, auto-fix: false]
|
|
||||||
#- lll # Reports long lines [fast: true, auto-fix: false]
|
|
||||||
#- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]
|
|
||||||
#- nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
|
|
||||||
#- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]
|
|
||||||
#- mnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
|
|
||||||
#- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative. [fast: false, auto-fix: false]
|
|
||||||
#- prealloc # Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false]
|
|
||||||
#- protogetter # Reports direct reads from proto message fields when getters should be used [fast: false, auto-fix: true]
|
|
||||||
#- sloglint # ensure consistent code style when using log/slog [fast: false, auto-fix: false]
|
|
||||||
#- tagalign # check that struct tags are well aligned [fast: true, auto-fix: true]
|
|
||||||
#- tagliatelle # Checks the struct tags. [fast: true, auto-fix: false]
|
|
||||||
#- unparam # Reports unused function parameters [fast: false, auto-fix: false]
|
|
||||||
#- varnamelen # checks that the length of a variable's name matches its scope [fast: false, auto-fix: false]
|
|
||||||
#- wrapcheck # Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]
|
|
||||||
#- wsl # add or remove empty lines [fast: true, auto-fix: false]
|
|
||||||
#- zerologlint # Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg` [fast: false, auto-fix: false]
|
|
||||||
settings:
|
settings:
|
||||||
exhaustive:
|
exhaustive:
|
||||||
default-signifies-exhaustive: true
|
default-signifies-exhaustive: true
|
||||||
@ -125,75 +62,19 @@ linters:
|
|||||||
- '!!.+'
|
- '!!.+'
|
||||||
gocritic:
|
gocritic:
|
||||||
disabled-checks:
|
disabled-checks:
|
||||||
|
- assignOp
|
||||||
- ifElseChain
|
- ifElseChain
|
||||||
- commentFormatting
|
|
||||||
gomoddirectives:
|
gomoddirectives:
|
||||||
|
replace-local: true
|
||||||
replace-allow-list:
|
replace-allow-list:
|
||||||
- github.com/miracl/conflate
|
- github.com/miracl/conflate
|
||||||
gosec:
|
gosec:
|
||||||
excludes:
|
severity: medium
|
||||||
- G204
|
|
||||||
confidence: medium
|
confidence: medium
|
||||||
importas:
|
|
||||||
no-unaliased: true
|
|
||||||
misspell:
|
|
||||||
mode: restricted
|
|
||||||
predeclared:
|
|
||||||
ignore:
|
|
||||||
- new
|
|
||||||
- error
|
|
||||||
revive:
|
revive:
|
||||||
enable-all-rules: true
|
|
||||||
rules:
|
rules:
|
||||||
- name: line-length-limit
|
|
||||||
disabled: true
|
|
||||||
- name: cognitive-complexity
|
|
||||||
disabled: true
|
|
||||||
- name: unused-parameter
|
- name: unused-parameter
|
||||||
disabled: true
|
disabled: true
|
||||||
- name: add-constant
|
|
||||||
disabled: true
|
|
||||||
- name: cyclomatic
|
|
||||||
disabled: true
|
|
||||||
- name: function-length
|
|
||||||
disabled: true
|
|
||||||
- name: function-result-limit
|
|
||||||
disabled: true
|
|
||||||
- name: flag-parameter
|
|
||||||
disabled: true
|
|
||||||
- name: unused-receiver
|
|
||||||
disabled: true
|
|
||||||
- name: argument-limit
|
|
||||||
disabled: true
|
|
||||||
- name: max-control-nesting
|
|
||||||
disabled: true
|
|
||||||
- name: comment-spacings
|
|
||||||
disabled: true
|
|
||||||
- name: struct-tag
|
|
||||||
arguments:
|
|
||||||
- json,inline
|
|
||||||
- yaml,squash
|
|
||||||
- name: unhandled-error
|
|
||||||
arguments:
|
|
||||||
- fmt.Printf
|
|
||||||
- fmt.Println
|
|
||||||
- name: deep-exit
|
|
||||||
disabled: true
|
|
||||||
- name: empty-block
|
|
||||||
disabled: true
|
|
||||||
- name: nested-structs
|
|
||||||
disabled: true
|
|
||||||
- name: unhandled-error
|
|
||||||
disabled: true
|
|
||||||
- name: indent-error-flow
|
|
||||||
disabled: true
|
|
||||||
- name: var-naming
|
|
||||||
disabled: true
|
|
||||||
- name: enforce-switch-style
|
|
||||||
disabled: true
|
|
||||||
testifylint:
|
|
||||||
disable:
|
|
||||||
- float-compare
|
|
||||||
exclusions:
|
exclusions:
|
||||||
generated: lax
|
generated: lax
|
||||||
presets:
|
presets:
|
||||||
@ -202,12 +83,14 @@ linters:
|
|||||||
- legacy
|
- legacy
|
||||||
- std-error-handling
|
- std-error-handling
|
||||||
rules:
|
rules:
|
||||||
- linters:
|
- path: _test\.go
|
||||||
- asasalint
|
linters:
|
||||||
path: (.+)_test\.go
|
- forbidigo
|
||||||
|
- unused
|
||||||
|
- gosec
|
||||||
paths:
|
paths:
|
||||||
- bin
|
- bin$
|
||||||
- tmp
|
- tmp$
|
||||||
- third_party$
|
- third_party$
|
||||||
- builtin$
|
- builtin$
|
||||||
- examples$
|
- examples$
|
||||||
@ -215,11 +98,3 @@ formatters:
|
|||||||
enable:
|
enable:
|
||||||
- gofmt
|
- gofmt
|
||||||
- goimports
|
- goimports
|
||||||
exclusions:
|
|
||||||
generated: lax
|
|
||||||
paths:
|
|
||||||
- bin
|
|
||||||
- tmp
|
|
||||||
- third_party$
|
|
||||||
- builtin$
|
|
||||||
- examples$
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
[tools]
|
[tools]
|
||||||
# https://github.com/golangci/golangci-lint/releases
|
# https://github.com/golangci/golangci-lint/releases
|
||||||
golangci-lint = "2.4.0"
|
golangci-lint = "2.5.0"
|
||||||
# https://github.com/go-courier/husky/releases
|
# https://github.com/go-courier/husky/releases
|
||||||
"github:go-courier/husky" = "1.8.1"
|
"github:go-courier/husky" = "1.8.1"
|
||||||
|
|||||||
64
Makefile
64
Makefile
@ -1,6 +1,15 @@
|
|||||||
.DEFAULT_GOAL:=help
|
.DEFAULT_GOAL:=help
|
||||||
-include .makerc
|
-include .makerc
|
||||||
|
|
||||||
|
# --- Config -----------------------------------------------------------------
|
||||||
|
|
||||||
|
GOMODS=$(shell find . -type f -name go.mod)
|
||||||
|
# Newline hack for error output
|
||||||
|
define br
|
||||||
|
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
# --- Targets -----------------------------------------------------------------
|
# --- Targets -----------------------------------------------------------------
|
||||||
|
|
||||||
# This allows us to accept extra arguments
|
# This allows us to accept extra arguments
|
||||||
@ -9,64 +18,77 @@
|
|||||||
|
|
||||||
.PHONY: .mise
|
.PHONY: .mise
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
|
.mise: msg := $(br)$(br)Please ensure you have 'mise' installed and activated!$(br)$(br)$$ brew update$(br)$$ brew install mise$(br)$(br)See the documentation: https://mise.jdx.dev/getting-started.html$(br)$(br)
|
||||||
.mise:
|
.mise:
|
||||||
@command -v mise >/dev/null 2>&1 || { echo >&2 "Error: 'mise' is not installed or not in PATH."; exit 1; }
|
ifeq (, $(shell command -v mise))
|
||||||
@mise install -q
|
$(error ${msg})
|
||||||
|
endif
|
||||||
|
@mise install
|
||||||
|
|
||||||
|
.PHONY: .husky
|
||||||
|
# Configure git hooks for husky
|
||||||
|
.husky:
|
||||||
|
@git config core.hooksPath .husky
|
||||||
|
|
||||||
### Tasks
|
### Tasks
|
||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
## Run tests and linters
|
## Run lint & tests
|
||||||
check: tidy lint test
|
check: tidy lint test
|
||||||
|
|
||||||
.PHONY: doc
|
.PHONY: tidy
|
||||||
## Run tests
|
## Run go mod tidy
|
||||||
doc:
|
tidy:
|
||||||
@open "http://localhost:6060/pkg/github.com/foomo/squadron/"
|
@echo "〉go mod tidy"
|
||||||
@godoc -http=localhost:6060 -play
|
@go mod tidy
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
## Run tests
|
|
||||||
test:
|
|
||||||
@# see https://github.com/pterm/pterm/issues/482
|
|
||||||
@GO_TEST_TAGS=-skip go test -tags=safe -coverprofile=coverage.out
|
|
||||||
@#GO_TEST_TAGS=-skip go test -tags=safe -coverprofile=coverage.out -race
|
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
## Run linter
|
## Run linter
|
||||||
lint:
|
lint:
|
||||||
|
@echo "〉golangci-lint run"
|
||||||
@golangci-lint run
|
@golangci-lint run
|
||||||
|
|
||||||
.PHONY: lint.fix
|
.PHONY: lint.fix
|
||||||
## Fix lint violations
|
## Fix lint violations
|
||||||
lint.fix:
|
lint.fix:
|
||||||
|
@echo "〉golangci-lint run fix"
|
||||||
@golangci-lint run --fix
|
@golangci-lint run --fix
|
||||||
|
|
||||||
.PHONY: tidy
|
.PHONY: test
|
||||||
## Run go mod tidy
|
## Run tests
|
||||||
tidy:
|
test:
|
||||||
@go mod tidy
|
@echo "〉go test"
|
||||||
|
@# see https://github.com/pterm/pterm/issues/482
|
||||||
|
@GO_TEST_TAGS=-skip go test -tags=safe -coverprofile=coverage.out
|
||||||
|
@#GO_TEST_TAGS=-skip go test -tags=safe -coverprofile=coverage.out -race
|
||||||
|
|
||||||
.PHONY: outdated
|
.PHONY: outdated
|
||||||
## Show outdated direct dependencies
|
## Show outdated direct dependencies
|
||||||
outdated:
|
outdated:
|
||||||
|
@echo "〉go mod outdated"
|
||||||
@go list -u -m -json all | go-mod-outdated -update -direct
|
@go list -u -m -json all | go-mod-outdated -update -direct
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
## Install binary
|
## Install binary
|
||||||
install:
|
install:
|
||||||
@echo "installing ${GOPATH}/bin/squadron"
|
@echo "〉installing ${GOPATH}/bin/squadron"
|
||||||
@go build -tags=safe -o ${GOPATH}/bin/squadron cmd/main.go
|
@go build -tags=safe -o ${GOPATH}/bin/squadron cmd/main.go
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
## Build binary
|
## Build binary
|
||||||
build:
|
build:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
@echo "building bin/squadron"
|
@echo "〉building bin/squadron"
|
||||||
@go build -tags=safe -o bin/squadron cmd/main.go
|
@go build -tags=safe -o bin/squadron cmd/main.go
|
||||||
|
|
||||||
### Utils
|
### Utils
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
## Open go docs
|
||||||
|
docs:
|
||||||
|
@echo "〉starting go docs"
|
||||||
|
@go doc -http
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
## Show help text
|
## Show help text
|
||||||
help:
|
help:
|
||||||
|
|||||||
@ -50,6 +50,7 @@ func NewBake(c *viper.Viper) *cobra.Command {
|
|||||||
_ = x.BindPFlag("push", flags.Lookup("push"))
|
_ = x.BindPFlag("push", flags.Lookup("push"))
|
||||||
|
|
||||||
cmd.Flags().Int("parallel", 1, "run command in parallel")
|
cmd.Flags().Int("parallel", 1, "run command in parallel")
|
||||||
|
|
||||||
_ = x.BindPFlag("parallel", flags.Lookup("parallel"))
|
_ = x.BindPFlag("parallel", flags.Lookup("parallel"))
|
||||||
|
|
||||||
flags.StringArray("bake-args", nil, "additional docker bake args")
|
flags.StringArray("bake-args", nil, "additional docker bake args")
|
||||||
|
|||||||
@ -50,6 +50,7 @@ func NewBuild(c *viper.Viper) *cobra.Command {
|
|||||||
_ = x.BindPFlag("push", flags.Lookup("push"))
|
_ = x.BindPFlag("push", flags.Lookup("push"))
|
||||||
|
|
||||||
cmd.Flags().Int("parallel", 1, "run command in parallel")
|
cmd.Flags().Int("parallel", 1, "run command in parallel")
|
||||||
|
|
||||||
_ = x.BindPFlag("parallel", flags.Lookup("parallel"))
|
_ = x.BindPFlag("parallel", flags.Lookup("parallel"))
|
||||||
|
|
||||||
flags.StringArray("build-args", nil, "additional docker buildx build args")
|
flags.StringArray("build-args", nil, "additional docker buildx build args")
|
||||||
|
|||||||
@ -64,6 +64,7 @@ PowerShell:
|
|||||||
case "powershell":
|
case "powershell":
|
||||||
return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
|
return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ func NewConfig(c *viper.Viper) *cobra.Command {
|
|||||||
if err := sq.MergeConfigFiles(cmd.Context()); err != nil {
|
if err := sq.MergeConfigFiles(cmd.Context()); err != nil {
|
||||||
return errors.Wrap(err, "failed to merge config files")
|
return errors.Wrap(err, "failed to merge config files")
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Debug.Println(strings.Join(append([]string{"provided files"}, files...), "\n└ "))
|
pterm.Debug.Println(strings.Join(append([]string{"provided files"}, files...), "\n└ "))
|
||||||
|
|
||||||
squadronName, unitNames := parseSquadronAndUnitNames(args)
|
squadronName, unitNames := parseSquadronAndUnitNames(args)
|
||||||
@ -43,6 +44,7 @@ func NewConfig(c *viper.Viper) *cobra.Command {
|
|||||||
if !x.GetBool("raw") {
|
if !x.GetBool("raw") {
|
||||||
out = util.Highlight(out)
|
out = util.Highlight(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Println(out)
|
pterm.Println(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -46,6 +46,7 @@ func NewDiff(c *viper.Viper) *cobra.Command {
|
|||||||
if !x.GetBool("raw") {
|
if !x.GetBool("raw") {
|
||||||
out = util.Highlight(out)
|
out = util.Highlight(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Println(out)
|
pterm.Println(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -38,17 +38,21 @@ func NewList(c *viper.Viper) *cobra.Command {
|
|||||||
// List squadrons
|
// List squadrons
|
||||||
_ = sq.Config().Squadrons.Iterate(cmd.Context(), func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(cmd.Context(), func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 0, Text: key})
|
list = append(list, pterm.LeveledListItem{Level: 0, Text: key})
|
||||||
|
|
||||||
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 1, Text: k})
|
list = append(list, pterm.LeveledListItem{Level: 1, Text: k})
|
||||||
if x.GetBool("with-tags") && len(v.Tags) > 0 {
|
if x.GetBool("with-tags") && len(v.Tags) > 0 {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 2, Text: "🏷️: " + v.Tags.SortedString()})
|
list = append(list, pterm.LeveledListItem{Level: 2, Text: "🏷️: " + v.Tags.SortedString()})
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.GetBool("with-charts") && len(v.Chart.String()) > 0 {
|
if x.GetBool("with-charts") && len(v.Chart.String()) > 0 {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📑: " + v.Chart.String()})
|
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📑: " + v.Chart.String()})
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.GetBool("with-priority") && len(v.Chart.String()) > 0 {
|
if x.GetBool("with-priority") && len(v.Chart.String()) > 0 {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 2, Text: fmt.Sprintf("☝️: %d", v.Priority)})
|
list = append(list, pterm.LeveledListItem{Level: 2, Text: fmt.Sprintf("☝️: %d", v.Priority)})
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.GetBool("with-bakes") && len(v.Bakes) > 0 {
|
if x.GetBool("with-bakes") && len(v.Bakes) > 0 {
|
||||||
for name, build := range v.Bakes {
|
for name, build := range v.Bakes {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📦: " + name})
|
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📦: " + name})
|
||||||
@ -57,15 +61,18 @@ func NewList(c *viper.Viper) *cobra.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.GetBool("with-builds") && len(v.Builds) > 0 {
|
if x.GetBool("with-builds") && len(v.Builds) > 0 {
|
||||||
for name, build := range v.Builds {
|
for name, build := range v.Builds {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📦: " + name})
|
list = append(list, pterm.LeveledListItem{Level: 2, Text: "📦: " + name})
|
||||||
|
|
||||||
list = append(list, pterm.LeveledListItem{Level: 3, Text: build.Image + ":" + build.Tag})
|
list = append(list, pterm.LeveledListItem{Level: 3, Text: build.Image + ":" + build.Tag})
|
||||||
for _, dependency := range build.Dependencies {
|
for _, dependency := range build.Dependencies {
|
||||||
list = append(list, pterm.LeveledListItem{Level: 3, Text: "🗃️: " + dependency})
|
list = append(list, pterm.LeveledListItem{Level: 3, Text: "🗃️: " + dependency})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -73,6 +80,7 @@ func NewList(c *viper.Viper) *cobra.Command {
|
|||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
root := putils.TreeFromLeveledList(list)
|
root := putils.TreeFromLeveledList(list)
|
||||||
root.Text = "Squadron"
|
root.Text = "Squadron"
|
||||||
|
|
||||||
return pterm.DefaultTree.WithRoot(root).Render()
|
return pterm.DefaultTree.WithRoot(root).Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,9 +29,10 @@ func NewPostRenderer(c *viper.Viper) *cobra.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := exec.CommandContext(cmd.Context(), "kustomize", "build", args[0])
|
c := exec.CommandContext(cmd.Context(), "kustomize", "build", args[0]) //nolint:gosec
|
||||||
c.Stdout = os.Stdout
|
c.Stdout = os.Stdout
|
||||||
c.Stderr = os.Stderr
|
c.Stderr = os.Stderr
|
||||||
|
|
||||||
return c.Run()
|
return c.Run()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,15 +51,18 @@ func NewRoot() *cobra.Command {
|
|||||||
if viper.GetBool("debug") {
|
if viper.GetBool("debug") {
|
||||||
pterm.EnableDebugMessages()
|
pterm.EnableDebugMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.Name() == "help" || cmd.Name() == "init" || cmd.Name() == "version" {
|
if cmd.Name() == "help" || cmd.Name() == "init" || cmd.Name() == "version" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.ValidatePath(".", &cwd)
|
return util.ValidatePath(".", &cwd)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := root.PersistentFlags()
|
flags := root.PersistentFlags()
|
||||||
flags.BoolP("debug", "d", false, "show all output")
|
flags.BoolP("debug", "d", false, "show all output")
|
||||||
|
|
||||||
_ = viper.BindPFlag("debug", root.PersistentFlags().Lookup("debug"))
|
_ = viper.BindPFlag("debug", root.PersistentFlags().Lookup("debug"))
|
||||||
|
|
||||||
flags.StringSliceP("file", "f", []string{"squadron.yaml"}, "specify alternative squadron files")
|
flags.StringSliceP("file", "f", []string{"squadron.yaml"}, "specify alternative squadron files")
|
||||||
@ -70,6 +73,7 @@ func NewRoot() *cobra.Command {
|
|||||||
func NewViper(root *cobra.Command) *viper.Viper {
|
func NewViper(root *cobra.Command) *viper.Viper {
|
||||||
c := viper.New()
|
c := viper.New()
|
||||||
_ = c.BindPFlag("file", root.PersistentFlags().Lookup("file"))
|
_ = c.BindPFlag("file", root.PersistentFlags().Lookup("file"))
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,22 +84,27 @@ func Execute() {
|
|||||||
if say, cerr := cowsay.Say(msg, cowsay.BallonWidth(80)); cerr == nil {
|
if say, cerr := cowsay.Say(msg, cowsay.BallonWidth(80)); cerr == nil {
|
||||||
msg = say
|
msg = say
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
code := 0
|
code := 0
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
l.Error(say("It's time to panic"))
|
l.Error(say("It's time to panic"))
|
||||||
l.Error(fmt.Sprintf("%v", r))
|
l.Error(fmt.Sprintf("%v", r))
|
||||||
l.Error(string(debug.Stack()))
|
l.Error(string(debug.Stack()))
|
||||||
|
|
||||||
code = 1
|
code = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := root.Execute(); err != nil {
|
if err := root.Execute(); err != nil {
|
||||||
l.Error(util.SprintError(err))
|
l.Error(util.SprintError(err))
|
||||||
|
|
||||||
code = 1
|
code = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +118,7 @@ func parseExtraArgs(args []string) (out []string, extraArgs []string) { //nolint
|
|||||||
return nil, args
|
return nil, args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +126,14 @@ func parseSquadronAndUnitNames(args []string) (squadron string, units []string)
|
|||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
squadron = args[0]
|
squadron = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
units = args[1:]
|
units = args[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return squadron, units
|
return squadron, units
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,15 +37,18 @@ func NewSchema(c *viper.Viper) *cobra.Command {
|
|||||||
|
|
||||||
if output := x.GetString("output"); output != "" {
|
if output := x.GetString("output"); output != "" {
|
||||||
pterm.Info.Printfln("Writing JSON schema to %s", output)
|
pterm.Info.Printfln("Writing JSON schema to %s", output)
|
||||||
|
|
||||||
if err := os.WriteFile(output, []byte(out), 0600); err != nil {
|
if err := os.WriteFile(output, []byte(out), 0600); err != nil {
|
||||||
return errors.Wrap(err, "failed to write schema")
|
return errors.Wrap(err, "failed to write schema")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !x.GetBool("raw") {
|
if !x.GetBool("raw") {
|
||||||
out = util.Highlight(out)
|
out = util.Highlight(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Println(out)
|
pterm.Println(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -47,6 +47,7 @@ func NewTemplate(c *viper.Viper) *cobra.Command {
|
|||||||
if !x.GetBool("raw") {
|
if !x.GetBool("raw") {
|
||||||
out = util.Highlight(out)
|
out = util.Highlight(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Println(out)
|
pterm.Println(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -62,23 +62,28 @@ func NewUp(c *viper.Viper) *cobra.Command {
|
|||||||
Squadron: version,
|
Squadron: version,
|
||||||
User: "unknown",
|
User: "unknown",
|
||||||
}
|
}
|
||||||
|
|
||||||
if wd, err := os.Getwd(); err == nil {
|
if wd, err := os.Getwd(); err == nil {
|
||||||
if value := os.Getenv("GIT_DIR"); value != "" {
|
if value := os.Getenv("GIT_DIR"); value != "" {
|
||||||
wd = value
|
wd = value
|
||||||
}
|
}
|
||||||
|
|
||||||
if repo, err := git.PlainOpen(wd); err == nil {
|
if repo, err := git.PlainOpen(wd); err == nil {
|
||||||
if c, err := repo.Config(); err == nil {
|
if c, err := repo.Config(); err == nil {
|
||||||
status.User = c.User.Name
|
status.User = c.User.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if ref, err := repo.Head(); err == nil {
|
if ref, err := repo.Head(); err == nil {
|
||||||
status.Branch = ref.Name().Short()
|
status.Branch = ref.Name().Short()
|
||||||
status.Commit = ref.Hash().String()
|
status.Commit = ref.Hash().String()
|
||||||
|
|
||||||
if tags, err := repo.Tags(); err == nil {
|
if tags, err := repo.Tags(); err == nil {
|
||||||
_ = tags.ForEach(func(r *plumbing.Reference) error {
|
_ = tags.ForEach(func(r *plumbing.Reference) error {
|
||||||
if r.Hash() == ref.Hash() {
|
if r.Hash() == ref.Hash() {
|
||||||
status.Branch = r.Name().Short()
|
status.Branch = r.Name().Short()
|
||||||
return errors.New("found tag")
|
return errors.New("found tag")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,5 +16,6 @@ func NewVersion(c *viper.Viper) *cobra.Command {
|
|||||||
pterm.Println(version)
|
pterm.Println(version)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
13
go.mod
13
go.mod
@ -13,7 +13,7 @@ require (
|
|||||||
github.com/alecthomas/chroma v0.10.0
|
github.com/alecthomas/chroma v0.10.0
|
||||||
github.com/foomo/go v0.0.3
|
github.com/foomo/go v0.0.3
|
||||||
github.com/genelet/determined v1.12.3
|
github.com/genelet/determined v1.12.3
|
||||||
github.com/go-git/go-git/v5 v5.16.2
|
github.com/go-git/go-git/v5 v5.16.3
|
||||||
github.com/invopop/jsonschema v0.13.0
|
github.com/invopop/jsonschema v0.13.0
|
||||||
github.com/miracl/conflate v1.3.4
|
github.com/miracl/conflate v1.3.4
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@ -44,9 +44,10 @@ require (
|
|||||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||||
github.com/buger/jsonparser v1.1.1 // indirect
|
github.com/buger/jsonparser v1.1.1 // indirect
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
|
||||||
github.com/cloudflare/circl v1.6.1 // indirect
|
github.com/cloudflare/circl v1.6.1 // indirect
|
||||||
github.com/containerd/console v1.0.5 // indirect
|
github.com/containerd/console v1.0.5 // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
github.com/cyphar/filepath-securejoin v0.5.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||||
github.com/emirpasic/gods v1.18.1 // indirect
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
@ -73,7 +74,7 @@ require (
|
|||||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
github.com/lithammer/fuzzysearch v1.1.8 // indirect
|
github.com/lithammer/fuzzysearch v1.1.8 // indirect
|
||||||
github.com/mailru/easyjson v0.9.1 // indirect
|
github.com/mailru/easyjson v0.9.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
@ -85,10 +86,10 @@ require (
|
|||||||
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
||||||
github.com/sergi/go-diff v1.4.0 // indirect
|
github.com/sergi/go-diff v1.4.0 // indirect
|
||||||
github.com/shopspring/decimal v1.4.0 // indirect
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
github.com/skeema/knownhosts v1.3.2 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||||
github.com/spf13/afero v1.15.0 // indirect
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
github.com/spf13/cast v1.10.0 // indirect
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
@ -110,7 +111,7 @@ require (
|
|||||||
golang.org/x/crypto v0.42.0 // indirect
|
golang.org/x/crypto v0.42.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||||
golang.org/x/mod v0.27.0 // indirect
|
golang.org/x/mod v0.27.0 // indirect
|
||||||
golang.org/x/net v0.44.0 // indirect
|
golang.org/x/net v0.45.0 // indirect
|
||||||
golang.org/x/sys v0.36.0 // indirect
|
golang.org/x/sys v0.36.0 // indirect
|
||||||
golang.org/x/term v0.35.0 // indirect
|
golang.org/x/term v0.35.0 // indirect
|
||||||
golang.org/x/text v0.29.0 // indirect
|
golang.org/x/text v0.29.0 // indirect
|
||||||
|
|||||||
14
go.sum
14
go.sum
@ -58,6 +58,8 @@ github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQ
|
|||||||
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
|
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
|
||||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
|
||||||
|
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||||
@ -66,6 +68,8 @@ github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
@ -99,6 +103,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
|||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
|
github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8=
|
||||||
|
github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||||
@ -161,6 +167,8 @@ github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
|||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||||
|
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
@ -207,6 +215,8 @@ github.com/runz0rd/conflate v1.2.2-0.20210920145208-fa48576ef06d/go.mod h1:F85f+
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||||
|
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
|
||||||
|
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
|
||||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||||
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
@ -215,6 +225,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D
|
|||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||||
|
github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg=
|
||||||
|
github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow=
|
||||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||||
@ -303,6 +315,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||||
|
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||||
|
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
|||||||
@ -12,6 +12,11 @@ type PTermSlogHandler struct {
|
|||||||
attrs []slog.Attr
|
attrs []slog.Attr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPTermSlogHandler returns a new logging handler that can be intrgrated with log/slog.
|
||||||
|
func NewPTermSlogHandler() *PTermSlogHandler {
|
||||||
|
return &PTermSlogHandler{}
|
||||||
|
}
|
||||||
|
|
||||||
// Enabled returns true if the given level is enabled.
|
// Enabled returns true if the given level is enabled.
|
||||||
func (s *PTermSlogHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
func (s *PTermSlogHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||||
switch level {
|
switch level {
|
||||||
@ -70,6 +75,7 @@ func (s *PTermSlogHandler) Handle(ctx context.Context, record slog.Record) error
|
|||||||
func (s *PTermSlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
func (s *PTermSlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||||
newS := *s
|
newS := *s
|
||||||
newS.attrs = attrs
|
newS.attrs = attrs
|
||||||
|
|
||||||
return &newS
|
return &newS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +84,3 @@ func (s *PTermSlogHandler) WithGroup(name string) slog.Handler {
|
|||||||
// Grouping is not yet supported by pterm.
|
// Grouping is not yet supported by pterm.
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPTermSlogHandler returns a new logging handler that can be intrgrated with log/slog.
|
|
||||||
func NewPTermSlogHandler() *PTermSlogHandler {
|
|
||||||
return &PTermSlogHandler{}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -89,12 +89,14 @@ func (b *Build) Build(ctx context.Context, squadron, unit string, args []string)
|
|||||||
cleanArgs = append(cleanArgs, strings.Split(value, " ")...)
|
cleanArgs = append(cleanArgs, strings.Split(value, " ")...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argOverride := func(name string, vs string, args []string) (string, string) {
|
argOverride := func(name string, vs string, args []string) (string, string) {
|
||||||
if slices.ContainsFunc(args, func(s string) bool {
|
if slices.ContainsFunc(args, func(s string) bool {
|
||||||
return strings.HasPrefix(s, name)
|
return strings.HasPrefix(s, name)
|
||||||
}) {
|
}) {
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return name, vs
|
return name, vs
|
||||||
}
|
}
|
||||||
boolArgOverride := func(name string, vs bool, args []string) (string, bool) {
|
boolArgOverride := func(name string, vs bool, args []string) (string, bool) {
|
||||||
@ -103,10 +105,12 @@ func (b *Build) Build(ctx context.Context, squadron, unit string, args []string)
|
|||||||
}) {
|
}) {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
return name, vs
|
return name, vs
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Debug.Printfln("running docker build for %q", b.Context)
|
pterm.Debug.Printfln("running docker build for %q", b.Context)
|
||||||
|
|
||||||
return util.NewDockerCommand().Build(b.Context).
|
return util.NewDockerCommand().Build(b.Context).
|
||||||
TemplateData(map[string]string{"image": b.Image, "tag": b.Tag}).
|
TemplateData(map[string]string{"image": b.Image, "tag": b.Tag}).
|
||||||
ListArg("--add-host", b.AddHost).
|
ListArg("--add-host", b.AddHost).
|
||||||
@ -114,7 +118,7 @@ func (b *Build) Build(ctx context.Context, squadron, unit string, args []string)
|
|||||||
ListArg("--allow", b.Allow).
|
ListArg("--allow", b.Allow).
|
||||||
ListArg("--attest", b.Attest).
|
ListArg("--attest", b.Attest).
|
||||||
ListArg("--build-arg", b.BuildArg).
|
ListArg("--build-arg", b.BuildArg).
|
||||||
ListArg("--build-contet", b.BuildContext).
|
ListArg("--build-context", b.BuildContext).
|
||||||
Arg(argOverride("--builder", b.Builder, args)).
|
Arg(argOverride("--builder", b.Builder, args)).
|
||||||
Arg(argOverride("--cache-from", b.CacheFrom, args)).
|
Arg(argOverride("--cache-from", b.CacheFrom, args)).
|
||||||
Arg(argOverride("--cache-to", b.CacheTo, args)).
|
Arg(argOverride("--cache-to", b.CacheTo, args)).
|
||||||
@ -152,7 +156,9 @@ func (b *Build) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
if err := value.Decode(&vString); err != nil {
|
if err := value.Decode(&vString); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Context = vString
|
b.Context = vString
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported node tag type for %T: %q", b, value.Tag)
|
return fmt.Errorf("unsupported node tag type for %T: %q", b, value.Tag)
|
||||||
|
|||||||
@ -63,6 +63,7 @@ func (d *Chart) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
if _, err := os.Stat(path.Join(schemaPath, "values.schema.json")); err == nil {
|
if _, err := os.Stat(path.Join(schemaPath, "values.schema.json")); err == nil {
|
||||||
d.Schema = path.Join(schemaPath, "values.schema.json")
|
d.Schema = path.Join(schemaPath, "values.schema.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported node tag type for %T: %q", d, value.Tag)
|
return fmt.Errorf("unsupported node tag type for %T: %q", d, value.Tag)
|
||||||
@ -75,12 +76,15 @@ func (d *Chart) String() string {
|
|||||||
|
|
||||||
func loadChart(name string) (*Chart, error) {
|
func loadChart(name string) (*Chart, error) {
|
||||||
c := Chart{}
|
c := Chart{}
|
||||||
|
|
||||||
file, err := os.ReadFile(name)
|
file, err := os.ReadFile(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error while opening file")
|
return nil, errors.Wrap(err, "error while opening file")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(file, &c); err != nil {
|
if err := yaml.Unmarshal(file, &c); err != nil {
|
||||||
return nil, errors.Wrap(err, "error while unmarshalling template file")
|
return nil, errors.Wrap(err, "error while unmarshalling template file")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ func (Config) JSONSchemaProperty(prop string) any {
|
|||||||
if prop == "squadron" {
|
if prop == "squadron" {
|
||||||
return map[string]map[string]*Unit{}
|
return map[string]map[string]*Unit{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,15 +41,19 @@ func (c *Config) BuildDependencies(ctx context.Context) map[string]Build {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return errors.Errorf("missing build dependency `%s`", dependency)
|
return errors.Errorf("missing build dependency `%s`", dependency)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret[dependency] = b
|
ret[dependency] = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(ret) > 0 {
|
if len(ret) > 0 {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,10 +18,12 @@ func (m Map[T]) Trim() {
|
|||||||
if val.Kind() == reflect.Ptr {
|
if val.Kind() == reflect.Ptr {
|
||||||
val = val.Elem()
|
val = val.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !val.IsValid() {
|
if !val.IsValid() {
|
||||||
delete(m, key)
|
delete(m, key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if val.IsZero() {
|
if val.IsZero() {
|
||||||
delete(m, key)
|
delete(m, key)
|
||||||
continue
|
continue
|
||||||
@ -42,11 +44,14 @@ func (m Map[T]) Keys() []string {
|
|||||||
if reflect.ValueOf(m).IsZero() {
|
if reflect.ValueOf(m).IsZero() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := make([]string, 0, len(m))
|
ret := make([]string, 0, len(m))
|
||||||
for key := range m {
|
for key := range m {
|
||||||
ret = append(ret, key)
|
ret = append(ret, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(ret)
|
sort.Strings(ret)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,11 +60,14 @@ func (m Map[T]) Values() []T {
|
|||||||
if len(m) == 0 {
|
if len(m) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
keys := m.Keys()
|
keys := m.Keys()
|
||||||
|
|
||||||
ret := make([]T, 0, len(keys))
|
ret := make([]T, 0, len(keys))
|
||||||
for i, key := range keys {
|
for i, key := range keys {
|
||||||
ret[i] = m[key]
|
ret[i] = m[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,17 +75,20 @@ func (m Map[T]) Filter(keys ...string) error {
|
|||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
validKeys := m.Keys()
|
validKeys := m.Keys()
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if !slices.Contains(validKeys, key) {
|
if !slices.Contains(validKeys, key) {
|
||||||
return errors.Errorf("key not found: `%s`", key)
|
return errors.Errorf("key not found: `%s`", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for key := range m {
|
for key := range m {
|
||||||
if !slices.Contains(keys, key) {
|
if !slices.Contains(keys, key) {
|
||||||
delete(m, key)
|
delete(m, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +98,7 @@ func (m Map[T]) FilterFn(handler func(key string, value T) bool) error {
|
|||||||
delete(m, key)
|
delete(m, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,13 +106,16 @@ func (m Map[T]) Iterate(ctx context.Context, handler func(ctx context.Context, k
|
|||||||
if len(m) == 0 {
|
if len(m) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, key := range m.Keys() {
|
for _, key := range m.Keys() {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := handler(ctx, key, m[key]); err != nil {
|
if err := handler(ctx, key, m[key]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,13 @@ func (t Tags) Strings() []string {
|
|||||||
for i, tag := range t {
|
for i, tag := range t {
|
||||||
ret[i] = tag.String()
|
ret[i] = tag.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Tags) SortedStrings() []string {
|
func (t Tags) SortedStrings() []string {
|
||||||
ret := t.Strings()
|
ret := t.Strings()
|
||||||
slices.Sort(ret)
|
slices.Sort(ret)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ func (u *Unit) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
if err := value.Decode((*wrapper)(u)); err != nil {
|
if err := value.Decode((*wrapper)(u)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Extends != "" {
|
if u.Extends != "" {
|
||||||
// render filename
|
// render filename
|
||||||
filename, err := template.ExecuteFileTemplate(context.Background(), u.Extends, nil, true)
|
filename, err := template.ExecuteFileTemplate(context.Background(), u.Extends, nil, true)
|
||||||
@ -65,6 +66,7 @@ func (u *Unit) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
if err := yaml.Unmarshal(defaults, &m); err != nil {
|
if err := yaml.Unmarshal(defaults, &m); err != nil {
|
||||||
return errors.Wrap(err, "failed to unmarshal defaults")
|
return errors.Wrap(err, "failed to unmarshal defaults")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := mergo.Merge(&m, u.Values, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithSliceDeepCopy); err != nil {
|
if err := mergo.Merge(&m, u.Values, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithSliceDeepCopy); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -72,6 +74,7 @@ func (u *Unit) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
u.Extends = ""
|
u.Extends = ""
|
||||||
u.Values = m
|
u.Values = m
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +84,7 @@ func (Unit) JSONSchemaProperty(prop string) any {
|
|||||||
if prop == "chart" {
|
if prop == "chart" {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,11 +93,13 @@ func (u *Unit) ValuesYAML(global map[string]any) ([]byte, error) {
|
|||||||
if values == nil {
|
if values == nil {
|
||||||
values = map[string]any{}
|
values = map[string]any{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if global != nil {
|
if global != nil {
|
||||||
if _, ok := values["global"]; !ok {
|
if _, ok := values["global"]; !ok {
|
||||||
values["global"] = global
|
values["global"] = global
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return yamlv2.Marshal(values)
|
return yamlv2.Marshal(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +108,9 @@ func (u *Unit) BakeNames() []string {
|
|||||||
for name := range u.Bakes {
|
for name := range u.Bakes {
|
||||||
ret = append(ret, name)
|
ret = append(ret, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(ret)
|
sort.Strings(ret)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,12 +119,15 @@ func (u *Unit) BuildNames() []string {
|
|||||||
for name := range u.Builds {
|
for name := range u.Builds {
|
||||||
ret = append(ret, name)
|
ret = append(ret, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(ret)
|
sort.Strings(ret)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace string, global map[string]any, helmArgs []string) ([]byte, error) {
|
func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace string, global map[string]any, helmArgs []string) ([]byte, error) {
|
||||||
var ret bytes.Buffer
|
var ret bytes.Buffer
|
||||||
|
|
||||||
valueBytes, err := u.ValuesYAML(global)
|
valueBytes, err := u.ValuesYAML(global)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -138,13 +149,16 @@ func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace str
|
|||||||
cmd.Args(path.Clean(strings.TrimPrefix(u.Chart.Repository, "file://")))
|
cmd.Args(path.Clean(strings.TrimPrefix(u.Chart.Repository, "file://")))
|
||||||
} else {
|
} else {
|
||||||
cmd.Args(u.Chart.Name)
|
cmd.Args(u.Chart.Name)
|
||||||
|
|
||||||
if u.Chart.Repository != "" {
|
if u.Chart.Repository != "" {
|
||||||
cmd.Args("--repo", u.Chart.Repository)
|
cmd.Args("--repo", u.Chart.Repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Chart.Version != "" {
|
if u.Chart.Version != "" {
|
||||||
cmd.Args("--version", u.Chart.Version)
|
cmd.Args("--version", u.Chart.Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if out, err := cmd.Run(ctx); err != nil {
|
if out, err := cmd.Run(ctx); err != nil {
|
||||||
return nil, errors.Wrap(err, out)
|
return nil, errors.Wrap(err, out)
|
||||||
}
|
}
|
||||||
@ -161,5 +175,6 @@ func (u *Unit) PostRendererArgs() []string {
|
|||||||
"--post-renderer-args", u.Kustomize,
|
"--post-renderer-args", u.Kustomize,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,17 +27,21 @@ func (d *Dependency) UnmarshalYAML(value *yaml.Node) error {
|
|||||||
if err := value.Decode(&vString); err != nil {
|
if err := value.Decode(&vString); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vBytes, err := template.ExecuteFileTemplate(context.Background(), vString, nil, true)
|
vBytes, err := template.ExecuteFileTemplate(context.Background(), vString, nil, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to render chart string")
|
return errors.Wrap(err, "failed to render chart string")
|
||||||
}
|
}
|
||||||
|
|
||||||
localChart, err := loadChart(path.Join(string(vBytes), chartFile))
|
localChart, err := loadChart(path.Join(string(vBytes), chartFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to load local chart: " + vString)
|
return errors.New("failed to load local chart: " + vString)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Name = localChart.Name
|
d.Name = localChart.Name
|
||||||
d.Repository = fmt.Sprintf("file://%v", vString)
|
d.Repository = fmt.Sprintf("file://%v", vString)
|
||||||
d.Version = localChart.Version
|
d.Version = localChart.Version
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported node tag type for %T: %q", d, value.Tag)
|
return fmt.Errorf("unsupported node tag type for %T: %q", d, value.Tag)
|
||||||
|
|||||||
@ -16,12 +16,15 @@ const (
|
|||||||
|
|
||||||
func loadChart(path string) (*Chart, error) {
|
func loadChart(path string) (*Chart, error) {
|
||||||
c := Chart{}
|
c := Chart{}
|
||||||
|
|
||||||
file, err := os.ReadFile(path)
|
file, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error while opening file")
|
return nil, errors.Wrap(err, "error while opening file")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(file, &c); err != nil {
|
if err := yaml.Unmarshal(file, &c); err != nil {
|
||||||
return nil, errors.Wrap(err, "error while unmarshalling template file")
|
return nil, errors.Wrap(err, "error while unmarshalling template file")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,12 +24,14 @@ func (js *JSONSchema) LoadBaseSchema(ctx context.Context, url string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
js.baseSchema = baseSchema
|
js.baseSchema = baseSchema
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSquadronUnitSchema overrides the base schema at the given path with another JSON schema from a URL
|
// SetSquadronUnitSchema overrides the base schema at the given path with another JSON schema from a URL
|
||||||
func (js *JSONSchema) SetSquadronUnitSchema(ctx context.Context, squardon, unit, url string) error {
|
func (js *JSONSchema) SetSquadronUnitSchema(ctx context.Context, squadron, unit, url string) error {
|
||||||
var ref string
|
var ref string
|
||||||
if strings.HasPrefix(url, "http") {
|
if strings.HasPrefix(url, "http") {
|
||||||
ref = strings.TrimPrefix(url, "https:")
|
ref = strings.TrimPrefix(url, "https:")
|
||||||
@ -41,6 +43,7 @@ func (js *JSONSchema) SetSquadronUnitSchema(ctx context.Context, squardon, unit,
|
|||||||
ref = strings.TrimPrefix(ref, ".")
|
ref = strings.TrimPrefix(ref, ".")
|
||||||
ref = strings.TrimPrefix(ref, "/")
|
ref = strings.TrimPrefix(ref, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = strings.TrimSuffix(ref, "/")
|
ref = strings.TrimSuffix(ref, "/")
|
||||||
ref = strings.ReplaceAll(ref, "/", "-")
|
ref = strings.ReplaceAll(ref, "/", "-")
|
||||||
ref = strings.ToLower(ref)
|
ref = strings.ToLower(ref)
|
||||||
@ -54,6 +57,7 @@ func (js *JSONSchema) SetSquadronUnitSchema(ctx context.Context, squardon, unit,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to load map: "+url)
|
return errors.Wrap(err, "failed to load map: "+url)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(valuesMap, "$schema")
|
delete(valuesMap, "$schema")
|
||||||
js.ensure(defsMap, ref, valuesMap)
|
js.ensure(defsMap, ref, valuesMap)
|
||||||
}
|
}
|
||||||
@ -63,7 +67,7 @@ func (js *JSONSchema) SetSquadronUnitSchema(ctx context.Context, squardon, unit,
|
|||||||
configPropertiesMap := js.ensure(configMap, "properties", map[string]any{})
|
configPropertiesMap := js.ensure(configMap, "properties", map[string]any{})
|
||||||
squadronsMap := js.ensure(configPropertiesMap, "squadron", map[string]any{})
|
squadronsMap := js.ensure(configPropertiesMap, "squadron", map[string]any{})
|
||||||
squadronsPropertiesMap := js.ensure(squadronsMap, "properties", map[string]any{})
|
squadronsPropertiesMap := js.ensure(squadronsMap, "properties", map[string]any{})
|
||||||
squadronMap := js.ensure(squadronsPropertiesMap, squardon, map[string]any{
|
squadronMap := js.ensure(squadronsPropertiesMap, squadron, map[string]any{
|
||||||
"additionalProperties": map[string]any{
|
"additionalProperties": map[string]any{
|
||||||
"$ref": "#/$defs/Unit",
|
"$ref": "#/$defs/Unit",
|
||||||
},
|
},
|
||||||
@ -95,6 +99,7 @@ func (js *JSONSchema) String() (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +109,7 @@ func (js *JSONSchema) PrettyString() (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,5 +119,6 @@ func (js *JSONSchema) ensure(source map[string]any, name string, initial map[str
|
|||||||
ret = initial
|
ret = initial
|
||||||
source[name] = ret
|
source[name] = ret
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,11 +13,14 @@ import (
|
|||||||
|
|
||||||
// LoadMap fetches the JSON schema from a given URL
|
// LoadMap fetches the JSON schema from a given URL
|
||||||
func LoadMap(ctx context.Context, url string) (map[string]any, error) {
|
func LoadMap(ctx context.Context, url string) (map[string]any, error) {
|
||||||
var err error
|
var (
|
||||||
var body []byte
|
err error
|
||||||
|
body []byte
|
||||||
|
)
|
||||||
|
|
||||||
if strings.HasPrefix(url, "http") {
|
if strings.HasPrefix(url, "http") {
|
||||||
pterm.Debug.Printfln("Loading map from %s", url)
|
pterm.Debug.Printfln("Loading map from %s", url)
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -12,15 +12,20 @@ type MultiPrinter interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MustNewMultiPrinter() MultiPrinter {
|
func MustNewMultiPrinter() MultiPrinter {
|
||||||
var err error
|
var (
|
||||||
var value MultiPrinter
|
err error
|
||||||
|
value MultiPrinter
|
||||||
|
)
|
||||||
|
|
||||||
if _, ok := os.LookupEnv("CI"); ok {
|
if _, ok := os.LookupEnv("CI"); ok {
|
||||||
value, err = NewNoopMultiPrinter()
|
value, err = NewNoopMultiPrinter()
|
||||||
} else {
|
} else {
|
||||||
value, err = NewStandardMultiPrinter()
|
value, err = NewStandardMultiPrinter()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pterm.Fatal.Print(err)
|
pterm.Fatal.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,7 @@ func (s *NoopSpinner) Write(p []byte) (int, error) {
|
|||||||
lines = append(lines, line)
|
lines = append(lines, line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.log = append(s.log, lines...)
|
s.log = append(s.log, lines...)
|
||||||
// pterm.UpdateText.Println(s.message())
|
// pterm.UpdateText.Println(s.message())
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
@ -65,11 +66,14 @@ func (s *NoopSpinner) message(message ...string) string {
|
|||||||
if !s.start.IsZero() && s.stopped {
|
if !s.start.IsZero() && s.stopped {
|
||||||
msg[0] += " ⏱ " + time.Since(s.start).Truncate(time.Second).String()
|
msg[0] += " ⏱ " + time.Since(s.start).Truncate(time.Second).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if value := strings.Join(message, " "); len(value) > 0 {
|
if value := strings.Join(message, " "); len(value) > 0 {
|
||||||
msg = append(msg, value)
|
msg = append(msg, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pterm.PrintDebugMessages {
|
if pterm.PrintDebugMessages {
|
||||||
msg = append(msg, s.log...)
|
msg = append(msg, s.log...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(msg, "\n ")
|
return strings.Join(msg, "\n ")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ func NewStandardMultiPrinter() (*StandardMultiPrinter, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &StandardMultiPrinter{printer: printer}, nil
|
return &StandardMultiPrinter{printer: printer}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -65,7 +65,9 @@ func (s *StandardSpinner) Write(p []byte) (int, error) {
|
|||||||
lines = append(lines, line)
|
lines = append(lines, line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.log = append(s.log, lines...)
|
s.log = append(s.log, lines...)
|
||||||
|
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,17 +76,21 @@ func (s *StandardSpinner) message(message ...string) string {
|
|||||||
if !s.start.IsZero() && s.stopped {
|
if !s.start.IsZero() && s.stopped {
|
||||||
msg[0] += " ⏱ " + time.Since(s.start).Truncate(time.Second).String()
|
msg[0] += " ⏱ " + time.Since(s.start).Truncate(time.Second).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
width := pterm.GetTerminalWidth() - 10
|
width := pterm.GetTerminalWidth() - 10
|
||||||
for i, line := range msg {
|
for i, line := range msg {
|
||||||
if len(line) > width {
|
if len(line) > width {
|
||||||
msg[i] = line[:width] + "…"
|
msg[i] = line[:width] + "…"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if value := strings.Join(message, " "); len(value) > 0 {
|
if value := strings.Join(message, " "); len(value) > 0 {
|
||||||
msg = append(msg, value)
|
msg = append(msg, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pterm.PrintDebugMessages {
|
if pterm.PrintDebugMessages {
|
||||||
msg = append(msg, s.log...)
|
msg = append(msg, s.log...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(msg, "\n ")
|
return strings.Join(msg, "\n ")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,5 +5,6 @@ func defaultIndexValue(v map[string]any, index string, def any) any {
|
|||||||
if _, ok = v[index]; ok {
|
if _, ok = v[index]; ok {
|
||||||
return v[index]
|
return v[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
return def
|
return def
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,18 +41,21 @@ func toYAML(v any) string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSuffix(string(data), "\n")
|
return strings.TrimSuffix(string(data), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func toYAMLPretty(v any) string {
|
func toYAMLPretty(v any) string {
|
||||||
var data bytes.Buffer
|
var data bytes.Buffer
|
||||||
|
|
||||||
encoder := yaml.NewEncoder(&data)
|
encoder := yaml.NewEncoder(&data)
|
||||||
encoder.SetIndent(2)
|
encoder.SetIndent(2)
|
||||||
err := encoder.Encode(v)
|
|
||||||
|
|
||||||
|
err := encoder.Encode(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSuffix(data.String(), "\n")
|
return strings.TrimSuffix(data.String(), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +71,7 @@ func fromYAML(str string) map[string]any {
|
|||||||
if err := yaml.Unmarshal([]byte(str), &m); err != nil {
|
if err := yaml.Unmarshal([]byte(str), &m); err != nil {
|
||||||
m["Error"] = err.Error()
|
m["Error"] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +86,7 @@ func fromYAMLArray(str string) []any {
|
|||||||
if err := yaml.Unmarshal([]byte(str), &a); err != nil {
|
if err := yaml.Unmarshal([]byte(str), &a); err != nil {
|
||||||
a = []any{err.Error()}
|
a = []any{err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,10 +97,12 @@ func fromYAMLArray(str string) []any {
|
|||||||
func toTOML(v any) string {
|
func toTOML(v any) string {
|
||||||
b := bytes.NewBuffer(nil)
|
b := bytes.NewBuffer(nil)
|
||||||
e := toml.NewEncoder(b)
|
e := toml.NewEncoder(b)
|
||||||
|
|
||||||
err := e.Encode(v)
|
err := e.Encode(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +118,7 @@ func fromTOML(str string) map[string]any {
|
|||||||
if err := toml.Unmarshal([]byte(str), &m); err != nil {
|
if err := toml.Unmarshal([]byte(str), &m); err != nil {
|
||||||
m["Error"] = err.Error()
|
m["Error"] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +131,7 @@ func toJSON(v any) string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error()
|
return err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +147,7 @@ func fromJSON(str string) map[string]any {
|
|||||||
if err := json.Unmarshal([]byte(str), &m); err != nil {
|
if err := json.Unmarshal([]byte(str), &m); err != nil {
|
||||||
m["Error"] = err.Error()
|
m["Error"] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,5 +162,6 @@ func fromJSONArray(str string) []any {
|
|||||||
if err := json.Unmarshal([]byte(str), &a); err != nil {
|
if err := json.Unmarshal([]byte(str), &a); err != nil {
|
||||||
a = []any{err.Error()}
|
a = []any{err.Error()}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ func quote(str ...any) string {
|
|||||||
out = append(out, fmt.Sprintf("%v", s))
|
out = append(out, fmt.Sprintf("%v", s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "'" + strings.Join(out, " ") + "'"
|
return "'" + strings.Join(out, " ") + "'"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ func quoteAll(str ...any) string {
|
|||||||
out = append(out, fmt.Sprintf("'%v'", s))
|
out = append(out, fmt.Sprintf("'%v'", s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(out, " ")
|
return strings.Join(out, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ func git(ctx context.Context) func(action string) (string, error) {
|
|||||||
default:
|
default:
|
||||||
cmd.Args = append(cmd.Args, "describe", "--tags", "--always")
|
cmd.Args = append(cmd.Args, "describe", "--tags", "--always")
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cmd.Output()
|
res, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import (
|
|||||||
func kubeseal(ctx context.Context) func(values ...string) (string, error) {
|
func kubeseal(ctx context.Context) func(values ...string) (string, error) {
|
||||||
return func(values ...string) (string, error) {
|
return func(values ...string) (string, error) {
|
||||||
var value string
|
var value string
|
||||||
|
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
return "", errors.Errorf("missing value")
|
return "", errors.Errorf("missing value")
|
||||||
} else if len(values) == 1 {
|
} else if len(values) == 1 {
|
||||||
@ -21,6 +22,7 @@ func kubeseal(ctx context.Context) func(values ...string) (string, error) {
|
|||||||
} else {
|
} else {
|
||||||
value, values = values[len(values)-1], values[:len(values)-1]
|
value, values = values[len(values)-1], values[:len(values)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, "kubeseal", "--raw", "--from-file=/dev/stdin")
|
cmd := exec.CommandContext(ctx, "kubeseal", "--raw", "--from-file=/dev/stdin")
|
||||||
cmd.Args = append(cmd.Args, values...)
|
cmd.Args = append(cmd.Args, values...)
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
@ -29,15 +31,19 @@ func kubeseal(ctx context.Context) func(values ...string) (string, error) {
|
|||||||
if v := os.Getenv("SQUADRON_KUBESEAL_NAME"); v != "" {
|
if v := os.Getenv("SQUADRON_KUBESEAL_NAME"); v != "" {
|
||||||
cmd.Args = append(cmd.Args, "--name", v)
|
cmd.Args = append(cmd.Args, "--name", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := os.Getenv("SQUADRON_KUBESEAL_NAMESPACE"); v != "" {
|
if v := os.Getenv("SQUADRON_KUBESEAL_NAMESPACE"); v != "" {
|
||||||
cmd.Args = append(cmd.Args, "--namespace", v)
|
cmd.Args = append(cmd.Args, "--namespace", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := os.Getenv("SQUADRON_KUBESEAL_CONTROLLER_NAME"); v != "" {
|
if v := os.Getenv("SQUADRON_KUBESEAL_CONTROLLER_NAME"); v != "" {
|
||||||
cmd.Args = append(cmd.Args, "--controller-name", v)
|
cmd.Args = append(cmd.Args, "--controller-name", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := os.Getenv("SQUADRON_KUBESEAL_CONTROLLER_NAMESPACE"); v != "" {
|
if v := os.Getenv("SQUADRON_KUBESEAL_CONTROLLER_NAMESPACE"); v != "" {
|
||||||
cmd.Args = append(cmd.Args, "--controller-namespace", v)
|
cmd.Args = append(cmd.Args, "--controller-namespace", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := os.Getenv("SQUADRON_KUBESEAL_EXTRA_ARGS"); v != "" {
|
if v := os.Getenv("SQUADRON_KUBESEAL_EXTRA_ARGS"); v != "" {
|
||||||
cmd.Args = append(cmd.Args, strings.Split(v, " ")...)
|
cmd.Args = append(cmd.Args, strings.Split(v, " ")...)
|
||||||
}
|
}
|
||||||
@ -46,6 +52,7 @@ func kubeseal(ctx context.Context) func(values ...string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
pterm.Debug.Println(cmd.String())
|
pterm.Debug.Println(cmd.String())
|
||||||
pterm.Error.Println(string(res))
|
pterm.Error.Println(string(res))
|
||||||
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ var ErrOnePasswordNotSignedIn = errors.New("not signed in")
|
|||||||
|
|
||||||
func onePasswordConnectGet(client connect.Client, vaultUUID, itemUUID string) (map[string]string, error) {
|
func onePasswordConnectGet(client connect.Client, vaultUUID, itemUUID string) (map[string]string, error) {
|
||||||
var item *onepassword.Item
|
var item *onepassword.Item
|
||||||
|
|
||||||
if onePasswordUUID.MatchString(itemUUID) {
|
if onePasswordUUID.MatchString(itemUUID) {
|
||||||
if v, err := client.GetItem(itemUUID, vaultUUID); err != nil {
|
if v, err := client.GetItem(itemUUID, vaultUUID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -52,6 +53,7 @@ func onePasswordConnectGet(client connect.Client, vaultUUID, itemUUID string) (m
|
|||||||
|
|
||||||
func onePasswordConnectGetDocument(client connect.Client, vaultUUID, itemUUID string) (string, error) {
|
func onePasswordConnectGetDocument(client connect.Client, vaultUUID, itemUUID string) (string, error) {
|
||||||
var item *onepassword.Item
|
var item *onepassword.Item
|
||||||
|
|
||||||
if onePasswordUUID.MatchString(itemUUID) {
|
if onePasswordUUID.MatchString(itemUUID) {
|
||||||
if v, err := client.GetItem(itemUUID, vaultUUID); err != nil {
|
if v, err := client.GetItem(itemUUID, vaultUUID); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -85,6 +87,7 @@ var onePasswordGetLock sync.Mutex
|
|||||||
func onePasswordGet(ctx context.Context, account, vaultUUID, itemUUID string) (map[string]string, error) {
|
func onePasswordGet(ctx context.Context, account, vaultUUID, itemUUID string) (map[string]string, error) {
|
||||||
onePasswordGetLock.Lock()
|
onePasswordGetLock.Lock()
|
||||||
defer onePasswordGetLock.Unlock()
|
defer onePasswordGetLock.Unlock()
|
||||||
|
|
||||||
var v struct {
|
var v struct {
|
||||||
Vault struct {
|
Vault struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
@ -106,6 +109,7 @@ func onePasswordGet(ctx context.Context, account, vaultUUID, itemUUID string) (m
|
|||||||
return nil, errors.Errorf("wrong vault UUID %s for item %s", vaultUUID, itemUUID)
|
return nil, errors.Errorf("wrong vault UUID %s for item %s", vaultUUID, itemUUID)
|
||||||
} else {
|
} else {
|
||||||
ret := map[string]string{}
|
ret := map[string]string{}
|
||||||
|
|
||||||
aliases := map[string]string{
|
aliases := map[string]string{
|
||||||
"notesPlain": "notes",
|
"notesPlain": "notes",
|
||||||
}
|
}
|
||||||
@ -116,6 +120,7 @@ func onePasswordGet(ctx context.Context, account, vaultUUID, itemUUID string) (m
|
|||||||
ret[field.Label] = fmt.Sprintf("%v", field.Value)
|
ret[field.Label] = fmt.Sprintf("%v", field.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,12 +130,14 @@ var onePasswordGetDocumentLock sync.Mutex
|
|||||||
func onePasswordGetDocument(ctx context.Context, account, vaultUUID, itemUUID string) (string, error) {
|
func onePasswordGetDocument(ctx context.Context, account, vaultUUID, itemUUID string) (string, error) {
|
||||||
onePasswordGetDocumentLock.Lock()
|
onePasswordGetDocumentLock.Lock()
|
||||||
defer onePasswordGetDocumentLock.Unlock()
|
defer onePasswordGetDocumentLock.Unlock()
|
||||||
|
|
||||||
res, err := exec.CommandContext(ctx, "op", "document", "get", itemUUID, "--vault", vaultUUID, "--account", account).CombinedOutput()
|
res, err := exec.CommandContext(ctx, "op", "document", "get", itemUUID, "--vault", vaultUUID, "--account", account).CombinedOutput()
|
||||||
if err != nil && strings.Contains(string(res), "You are not currently signed in") {
|
if err != nil && strings.Contains(string(res), "You are not currently signed in") {
|
||||||
return "", ErrOnePasswordNotSignedIn
|
return "", ErrOnePasswordNotSignedIn
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", errors.Wrap(err, string(res))
|
return "", errors.Wrap(err, string(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Trim(string(res), "\n"), nil
|
return strings.Trim(string(res), "\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +149,7 @@ func onePasswordSignIn(ctx context.Context, account string) error {
|
|||||||
|
|
||||||
// use multi writer to handle password prompt
|
// use multi writer to handle password prompt
|
||||||
var stdoutBuf bytes.Buffer
|
var stdoutBuf bytes.Buffer
|
||||||
|
|
||||||
cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
|
cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
|
|
||||||
@ -155,6 +163,7 @@ func onePasswordSignIn(ctx context.Context, account string) error {
|
|||||||
if token := strings.TrimSuffix(stdoutBuf.String(), "\n"); token == "" {
|
if token := strings.TrimSuffix(stdoutBuf.String(), "\n"); token == "" {
|
||||||
fmt.Printf("Failed to login into your '%s' account! Please refer to the manual:\n", account)
|
fmt.Printf("Failed to login into your '%s' account! Please refer to the manual:\n", account)
|
||||||
fmt.Println("https://support.1password.com/command-line-getting-started/#set-up-the-command-line-tool")
|
fmt.Println("https://support.1password.com/command-line-getting-started/#set-up-the-command-line-tool")
|
||||||
|
|
||||||
return errors.New("failed to retrieve 1password session token")
|
return errors.New("failed to retrieve 1password session token")
|
||||||
} else if err := os.Setenv(fmt.Sprintf("OP_SESSION_%s", account), token); err != nil {
|
} else if err := os.Setenv(fmt.Sprintf("OP_SESSION_%s", account), token); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -162,6 +171,7 @@ func onePasswordSignIn(ctx context.Context, account string) error {
|
|||||||
fmt.Println("NOTE: If you want to skip this step, run:")
|
fmt.Println("NOTE: If you want to skip this step, run:")
|
||||||
fmt.Printf("export OP_SESSION_%s=%s\n", account, token)
|
fmt.Printf("export OP_SESSION_%s=%s\n", account, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +205,7 @@ func onePasswordInit(ctx context.Context, account string) error {
|
|||||||
if _, err := exec.LookPath("op"); err != nil {
|
if _, err := exec.LookPath("op"); err != nil {
|
||||||
pterm.Warning.Println("Your templates includes a call to 1Password, please install it:")
|
pterm.Warning.Println("Your templates includes a call to 1Password, please install it:")
|
||||||
pterm.Warning.Println("https://support.1password.com/command-line-getting-started/#set-up-the-command-line-tool")
|
pterm.Warning.Println("https://support.1password.com/command-line-getting-started/#set-up-the-command-line-tool")
|
||||||
|
|
||||||
return errors.Wrap(err, "failed to lookup op")
|
return errors.Wrap(err, "failed to lookup op")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +236,7 @@ func onePassword(ctx context.Context, templateVars any, errorOnMissing bool) fun
|
|||||||
} else {
|
} else {
|
||||||
itemUUID = value
|
itemUUID = value
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, err := onePasswordRender("op", field, templateVars, errorOnMissing); err != nil {
|
if value, err := onePasswordRender("op", field, templateVars, errorOnMissing); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else {
|
} else {
|
||||||
@ -240,6 +252,7 @@ func onePassword(ctx context.Context, templateVars any, errorOnMissing bool) fun
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res, err := onePasswordConnectGet(client, vaultUUID, itemUUID); err != nil {
|
if res, err := onePasswordConnectGet(client, vaultUUID, itemUUID); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else {
|
} else {
|
||||||
@ -310,11 +323,13 @@ func onePasswordRender(name, text string, data any, errorOnMissing bool) (string
|
|||||||
if !errorOnMissing {
|
if !errorOnMissing {
|
||||||
opts = append(opts, "missingkey=error")
|
opts = append(opts, "missingkey=error")
|
||||||
}
|
}
|
||||||
|
|
||||||
out := bytes.NewBuffer([]byte{})
|
out := bytes.NewBuffer([]byte{})
|
||||||
if uuidTpl, err := template.New(name).Option(opts...).Parse(text); err != nil {
|
if uuidTpl, err := template.New(name).Option(opts...).Parse(text); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else if err := uuidTpl.Execute(out, data); err != nil {
|
} else if err := uuidTpl.Execute(out, data); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.String(), nil
|
return out.String(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,12 +43,16 @@ func ExecuteFileTemplate(ctx context.Context, text string, templateVars any, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out := bytes.NewBuffer([]byte{})
|
out := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
if errorOnMissing {
|
if errorOnMissing {
|
||||||
tpl = tpl.Option("missingkey=error")
|
tpl = tpl.Option("missingkey=error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tpl.Funcs(funcMap).Execute(out, templateVars); err != nil {
|
if err := tpl.Funcs(funcMap).Execute(out, templateVars); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.Bytes(), nil
|
return out.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,10 +12,12 @@ import (
|
|||||||
// Snapshot compares v with its snapshot file
|
// Snapshot compares v with its snapshot file
|
||||||
func Snapshot(t *testing.T, name, yaml string) {
|
func Snapshot(t *testing.T, name, yaml string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
snapshot := readSnapshot(t, name)
|
snapshot := readSnapshot(t, name)
|
||||||
if *UpdateFlag || snapshot == "" {
|
if *UpdateFlag || snapshot == "" {
|
||||||
writeSnapshot(t, name, yaml)
|
writeSnapshot(t, name, yaml)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.YAMLEq(t, snapshot, yaml)
|
assert.YAMLEq(t, snapshot, yaml)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,9 +30,11 @@ func writeSnapshot(t *testing.T, name string, content string) {
|
|||||||
// readSnapshot reads the snapshot file for a given test t.
|
// readSnapshot reads the snapshot file for a given test t.
|
||||||
func readSnapshot(t *testing.T, name string) string {
|
func readSnapshot(t *testing.T, name string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
g, err := os.ReadFile(name)
|
g, err := os.ReadFile(name)
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
require.NoError(t, err, "failed reading file", name)
|
require.NoError(t, err, "failed reading file", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(g)
|
return string(g)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,8 +42,10 @@ func (c *Cmd) Args(args ...string) *Cmd {
|
|||||||
if arg == "" {
|
if arg == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.append(arg)
|
c.append(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +58,9 @@ func (c *Cmd) Arg(name, v string) *Cmd {
|
|||||||
if name == "" || v == "" {
|
if name == "" || v == "" {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
c.append(name, v)
|
c.append(name, v)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +68,9 @@ func (c *Cmd) BoolArg(name string, v bool) *Cmd {
|
|||||||
if name == "" || !v {
|
if name == "" || !v {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
c.append(name)
|
c.append(name)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +78,15 @@ func (c *Cmd) ListArg(name string, vs []string) *Cmd {
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range vs {
|
for _, v := range vs {
|
||||||
if v == "" {
|
if v == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.append(name, v)
|
c.append(name, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +109,9 @@ func (c *Cmd) Stdout(w io.Writer) *Cmd {
|
|||||||
if w == nil {
|
if w == nil {
|
||||||
w, _ = os.Open(os.DevNull)
|
w, _ = os.Open(os.DevNull)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.stdoutWriters = append(c.stdoutWriters, w)
|
c.stdoutWriters = append(c.stdoutWriters, w)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,28 +119,35 @@ func (c *Cmd) Stderr(w io.Writer) *Cmd {
|
|||||||
if w == nil {
|
if w == nil {
|
||||||
w, _ = os.Open(os.DevNull)
|
w, _ = os.Open(os.DevNull)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.stderrWriters = append(c.stderrWriters, w)
|
c.stderrWriters = append(c.stderrWriters, w)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cmd) String() string {
|
func (c *Cmd) String() string {
|
||||||
cmd := exec.Command(c.command[0], c.command[1:]...) //nolint:noctx
|
cmd := exec.Command(c.command[0], c.command[1:]...) //nolint:noctx,gosec
|
||||||
|
|
||||||
cmd.Env = append(os.Environ(), c.env...)
|
cmd.Env = append(os.Environ(), c.env...)
|
||||||
if c.cwd != "" {
|
if c.cwd != "" {
|
||||||
cmd.Dir = c.cwd
|
cmd.Dir = c.cwd
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd.String()
|
return cmd.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cmd) Run(ctx context.Context) (string, error) {
|
func (c *Cmd) Run(ctx context.Context) (string, error) {
|
||||||
cmd := exec.CommandContext(ctx, c.command[0], c.command[1:]...)
|
cmd := exec.CommandContext(ctx, c.command[0], c.command[1:]...) //nolint:gosec
|
||||||
|
|
||||||
cmd.Env = append(os.Environ(), c.env...)
|
cmd.Env = append(os.Environ(), c.env...)
|
||||||
if c.cwd != "" {
|
if c.cwd != "" {
|
||||||
cmd.Dir = c.cwd
|
cmd.Dir = c.cwd
|
||||||
}
|
}
|
||||||
|
|
||||||
var stdout bytes.Buffer
|
var (
|
||||||
var stderr bytes.Buffer
|
stdout bytes.Buffer
|
||||||
|
stderr bytes.Buffer
|
||||||
|
)
|
||||||
|
|
||||||
if c.stdin != nil {
|
if c.stdin != nil {
|
||||||
cmd.Stdin = c.stdin
|
cmd.Stdin = c.stdin
|
||||||
@ -144,10 +162,12 @@ func (c *Cmd) Run(ctx context.Context) (string, error) {
|
|||||||
cmd.Stderr = io.MultiWriter(append(c.stderrWriters, &stderr)...)
|
cmd.Stderr = io.MultiWriter(append(c.stderrWriters, &stderr)...)
|
||||||
|
|
||||||
pterm.Debug.Println("❯ " + cmd.String())
|
pterm.Debug.Println("❯ " + cmd.String())
|
||||||
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "failed to execute: "+cmd.String())
|
err = errors.Wrap(err, "failed to execute: "+cmd.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
return stdout.String() + stderr.String(), err
|
return stdout.String() + stderr.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,5 +185,6 @@ func (c *Cmd) append(v ...string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.command = append(c.command, v...)
|
c.command = append(c.command, v...)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,9 @@ import (
|
|||||||
|
|
||||||
func SprintError(err error) string {
|
func SprintError(err error) string {
|
||||||
var ret string
|
var ret string
|
||||||
|
|
||||||
prefix := "Error: "
|
prefix := "Error: "
|
||||||
|
|
||||||
if pterm.PrintDebugMessages {
|
if pterm.PrintDebugMessages {
|
||||||
return fmt.Sprintf("%+v", err) + "\n"
|
return fmt.Sprintf("%+v", err) + "\n"
|
||||||
}
|
}
|
||||||
@ -21,10 +23,12 @@ func SprintError(err error) string {
|
|||||||
ret += prefix + err.Error() + "\n"
|
ret += prefix + err.Error() + "\n"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if err.Error() != w.Error() {
|
if err.Error() != w.Error() {
|
||||||
ret += prefix + strings.TrimSuffix(err.Error(), ": "+w.Error()) + "\n"
|
ret += prefix + strings.TrimSuffix(err.Error(), ": "+w.Error()) + "\n"
|
||||||
prefix = "↪ "
|
prefix = "↪ "
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w
|
err = w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,9 +21,11 @@ func Highlight(source string) string {
|
|||||||
if l == nil {
|
if l == nil {
|
||||||
l = lexers.Analyse(source)
|
l = lexers.Analyse(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l == nil {
|
if l == nil {
|
||||||
l = lexers.Fallback
|
l = lexers.Fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
l = chroma.Coalesce(l)
|
l = chroma.Coalesce(l)
|
||||||
|
|
||||||
// Determine formatter.
|
// Determine formatter.
|
||||||
@ -60,9 +62,11 @@ func HighlightHCL(source string) string {
|
|||||||
if l == nil {
|
if l == nil {
|
||||||
l = lexers.Analyse(source)
|
l = lexers.Analyse(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l == nil {
|
if l == nil {
|
||||||
l = lexers.Fallback
|
l = lexers.Fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
l = chroma.Coalesce(l)
|
l = chroma.Coalesce(l)
|
||||||
|
|
||||||
// Determine formatter.
|
// Determine formatter.
|
||||||
@ -109,6 +113,7 @@ func (w *numberWriter) Write(p []byte) (int, error) {
|
|||||||
)
|
)
|
||||||
for i, c := range original {
|
for i, c := range original {
|
||||||
tokenLen++
|
tokenLen++
|
||||||
|
|
||||||
if c != '\n' {
|
if c != '\n' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -121,11 +126,13 @@ func (w *numberWriter) Write(p []byte) (int, error) {
|
|||||||
if w.currentLine > 9999 {
|
if w.currentLine > 9999 {
|
||||||
format = "%d |\t%s%s"
|
format = "%d |\t%s%s"
|
||||||
}
|
}
|
||||||
|
|
||||||
format = "\033[34m" + format + "\033[0m"
|
format = "\033[34m" + format + "\033[0m"
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(w.w, format, w.currentLine, string(w.buf), string(token)); err != nil {
|
if _, err := fmt.Fprintf(w.w, format, w.currentLine, string(w.buf), string(token)); err != nil {
|
||||||
return i + 1, err
|
return i + 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.buf = w.buf[:0]
|
w.buf = w.buf[:0]
|
||||||
w.currentLine++
|
w.currentLine++
|
||||||
}
|
}
|
||||||
@ -133,5 +140,6 @@ func (w *numberWriter) Write(p []byte) (int, error) {
|
|||||||
if len(p) > 0 {
|
if len(p) > 0 {
|
||||||
w.buf = append(w.buf, p...)
|
w.buf = append(w.buf, p...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(original), nil
|
return len(original), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ func (c KubeCmd) GetMostRecentPodBySelectors(ctx context.Context, selectors map[
|
|||||||
for k, v := range selectors {
|
for k, v := range selectors {
|
||||||
selector = append(selector, fmt.Sprintf("%v=%v", k, v))
|
selector = append(selector, fmt.Sprintf("%v=%v", k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := c.Args("--selector", strings.Join(selector, ","),
|
out, err := c.Args("--selector", strings.Join(selector, ","),
|
||||||
"get", "pods", "--sort-by=.status.startTime", "-o", "name").Run(ctx)
|
"get", "pods", "--sort-by=.status.startTime", "-o", "name").Run(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -43,9 +44,11 @@ func (c KubeCmd) GetMostRecentPodBySelectors(ctx context.Context, selectors map[
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pods) > 0 {
|
if len(pods) > 0 {
|
||||||
return pods[len(pods)-1], nil
|
return pods[len(pods)-1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.New("no pods found")
|
return "", errors.New("no pods found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +81,7 @@ func (c KubeCmd) ExposePod(pod string, host string, port int) *Cmd {
|
|||||||
if host == "127.0.0.1" {
|
if host == "127.0.0.1" {
|
||||||
host = ""
|
host = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Args("expose", "pod", pod, "--type=LoadBalancer",
|
return c.Args("expose", "pod", pod, "--type=LoadBalancer",
|
||||||
fmt.Sprintf("--port=%v", port), fmt.Sprintf("--external-ip=%v", host))
|
fmt.Sprintf("--port=%v", port), fmt.Sprintf("--external-ip=%v", host))
|
||||||
}
|
}
|
||||||
@ -91,10 +95,12 @@ func (c KubeCmd) GetDeployment(ctx context.Context, deployment string) (*k8s.Dep
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var d k8s.Deployment
|
var d k8s.Deployment
|
||||||
if err := json.Unmarshal([]byte(out), &d); err != nil {
|
if err := json.Unmarshal([]byte(out), &d); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &d, nil
|
return &d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +109,7 @@ func (c KubeCmd) GetNamespaces(ctx context.Context) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseResources(out, "namespace/")
|
return parseResources(out, "namespace/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +118,7 @@ func (c KubeCmd) GetDeployments(ctx context.Context) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseResources(out, "deployment.apps/")
|
return parseResources(out, "deployment.apps/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +127,14 @@ func (c KubeCmd) GetPods(ctx context.Context, selectors map[string]string) ([]st
|
|||||||
for k, v := range selectors {
|
for k, v := range selectors {
|
||||||
selector = append(selector, fmt.Sprintf("%v=%v", k, v))
|
selector = append(selector, fmt.Sprintf("%v=%v", k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
out, err := c.Args("--selector", strings.Join(selector, ","),
|
out, err := c.Args("--selector", strings.Join(selector, ","),
|
||||||
"get", "pods", "--sort-by=.status.startTime",
|
"get", "pods", "--sort-by=.status.startTime",
|
||||||
"-o", "name").Run(ctx)
|
"-o", "name").Run(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseResources(out, "pod/")
|
return parseResources(out, "pod/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +143,7 @@ func (c KubeCmd) GetContainers(deployment k8s.Deployment) []string {
|
|||||||
for i, c := range deployment.Spec.Template.Spec.Containers {
|
for i, c := range deployment.Spec.Template.Spec.Containers {
|
||||||
containers[i] = c.Name
|
containers[i] = c.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
return containers
|
return containers
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +152,7 @@ func (c KubeCmd) GetPodsByLabels(ctx context.Context, labels []string) ([]string
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseResources(out, "pod/")
|
return parseResources(out, "pod/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +166,11 @@ func (c KubeCmd) CreateConfigMapFromFile(ctx context.Context, name, path string)
|
|||||||
|
|
||||||
func (c KubeCmd) CreateConfigMap(ctx context.Context, name string, keyMap map[string]string) (string, error) {
|
func (c KubeCmd) CreateConfigMap(ctx context.Context, name string, keyMap map[string]string) (string, error) {
|
||||||
c.Args("create", "configmap", name)
|
c.Args("create", "configmap", name)
|
||||||
|
|
||||||
for key, value := range keyMap {
|
for key, value := range keyMap {
|
||||||
c.Args(fmt.Sprintf("--from-literal=%v=%v", key, value))
|
c.Args(fmt.Sprintf("--from-literal=%v=%v", key, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Run(ctx)
|
return c.Run(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +186,11 @@ func (c KubeCmd) GetConfigMapKey(ctx context.Context, name, key string) (string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if out == "" {
|
if out == "" {
|
||||||
return out, fmt.Errorf("no key %q found in ConfigMap %q", key, name)
|
return out, fmt.Errorf("no key %q found in ConfigMap %q", key, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,19 +199,24 @@ func parseResources(out, prefix string) ([]string, error) {
|
|||||||
if out == "" {
|
if out == "" {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := strings.Split(out, "\n")
|
lines := strings.Split(out, "\n")
|
||||||
if len(lines) == 1 && lines[0] == "" {
|
if len(lines) == 1 && lines[0] == "" {
|
||||||
return nil, fmt.Errorf("delimiter %q not found in %q", "\n", out)
|
return nil, fmt.Errorf("delimiter %q not found in %q", "\n", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if line == "" {
|
if line == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
unprefixed := strings.TrimPrefix(line, prefix)
|
unprefixed := strings.TrimPrefix(line, prefix)
|
||||||
if unprefixed == line {
|
if unprefixed == line {
|
||||||
return nil, fmt.Errorf("prefix %q not found in %q", prefix, line)
|
return nil, fmt.Errorf("prefix %q not found in %q", prefix, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
res = append(res, strings.TrimPrefix(line, prefix))
|
res = append(res, strings.TrimPrefix(line, prefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,14 +10,18 @@ func ValidatePath(wd string, p *string) error {
|
|||||||
if !filepath.IsAbs(*p) {
|
if !filepath.IsAbs(*p) {
|
||||||
*p = path.Join(wd, *p)
|
*p = path.Join(wd, *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
absPath, err := filepath.Abs(*p)
|
absPath, err := filepath.Abs(*p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = os.Stat(absPath)
|
_, err = os.Stat(absPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = absPath
|
*p = absPath
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,11 @@ func RenderTemplateString(s string, data any) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to parse template")
|
return "", errors.Wrap(err, "failed to parse template")
|
||||||
}
|
}
|
||||||
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
if err := t.Execute(&out, data); err != nil {
|
if err := t.Execute(&out, data); err != nil {
|
||||||
return "", errors.Wrap(err, "failed to execute template")
|
return "", errors.Wrap(err, "failed to execute template")
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.String(), nil
|
return out.String(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,15 +11,19 @@ func GenerateYaml(path string, data any) (err error) {
|
|||||||
if marshalErr != nil {
|
if marshalErr != nil {
|
||||||
return marshalErr
|
return marshalErr
|
||||||
}
|
}
|
||||||
|
|
||||||
file, crateErr := os.Create(path)
|
file, crateErr := os.Create(path)
|
||||||
if crateErr != nil {
|
if crateErr != nil {
|
||||||
return crateErr
|
return crateErr
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if closeErr := file.Close(); err == nil {
|
if closeErr := file.Close(); err == nil {
|
||||||
err = closeErr
|
err = closeErr
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err = file.Write(out)
|
_, err = file.Write(out)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ func TestSchema(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
filename := path.Join(cwd, "squadron.schema.json")
|
filename := path.Join(cwd, "squadron.schema.json")
|
||||||
|
|
||||||
expected, err := os.ReadFile(filename)
|
expected, err := os.ReadFile(filename)
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
210
squadron.go
210
squadron.go
@ -5,6 +5,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
@ -19,6 +21,8 @@ import (
|
|||||||
templatex "github.com/foomo/squadron/internal/template"
|
templatex "github.com/foomo/squadron/internal/template"
|
||||||
"github.com/foomo/squadron/internal/util"
|
"github.com/foomo/squadron/internal/util"
|
||||||
"github.com/genelet/determined/dethcl"
|
"github.com/genelet/determined/dethcl"
|
||||||
|
"github.com/go-git/go-git/v5"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/miracl/conflate"
|
"github.com/miracl/conflate"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/pterm/pterm"
|
"github.com/pterm/pterm"
|
||||||
@ -55,6 +59,7 @@ func New(basePath, namespace string, files []string) *Squadron {
|
|||||||
|
|
||||||
func (sq *Squadron) Namespace(ctx context.Context, squadron, unit string, u *config.Unit) (string, error) {
|
func (sq *Squadron) Namespace(ctx context.Context, squadron, unit string, u *config.Unit) (string, error) {
|
||||||
var tpl string
|
var tpl string
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case u.Namespace != "":
|
case u.Namespace != "":
|
||||||
tpl = u.Namespace
|
tpl = u.Namespace
|
||||||
@ -63,6 +68,7 @@ func (sq *Squadron) Namespace(ctx context.Context, squadron, unit string, u *con
|
|||||||
default:
|
default:
|
||||||
return "default", nil
|
return "default", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.RenderTemplateString(tpl, map[string]string{"Squadron": squadron, "Unit": unit})
|
return util.RenderTemplateString(tpl, map[string]string{"Squadron": squadron, "Unit": unit})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +86,14 @@ func (sq *Squadron) ConfigYAML() string {
|
|||||||
|
|
||||||
func (sq *Squadron) MergeConfigFiles(ctx context.Context) error {
|
func (sq *Squadron) MergeConfigFiles(ctx context.Context) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
pterm.Info.Println("📚 | merging configs")
|
pterm.Info.Println("📚 | merging configs")
|
||||||
|
|
||||||
mergedFiles, err := conflate.FromFiles(sq.files...)
|
mergedFiles, err := conflate.FromFiles(sq.files...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to conflate files")
|
return errors.Wrap(err, "failed to conflate files")
|
||||||
}
|
}
|
||||||
|
|
||||||
fileBytes, err := mergedFiles.MarshalYAML()
|
fileBytes, err := mergedFiles.MarshalYAML()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal yaml")
|
return errors.Wrap(err, "failed to marshal yaml")
|
||||||
@ -95,6 +103,7 @@ func (sq *Squadron) MergeConfigFiles(ctx context.Context) error {
|
|||||||
pterm.Error.Println(string(fileBytes))
|
pterm.Error.Println(string(fileBytes))
|
||||||
return errors.Wrap(err, "failed to unmarshal yaml")
|
return errors.Wrap(err, "failed to unmarshal yaml")
|
||||||
}
|
}
|
||||||
|
|
||||||
if sq.c.Version != config.Version {
|
if sq.c.Version != config.Version {
|
||||||
pterm.Debug.Println(string(fileBytes))
|
pterm.Debug.Println(string(fileBytes))
|
||||||
return errors.New("Please upgrade your YAML definition to from '" + sq.c.Version + "' to '" + config.Version + "'")
|
return errors.New("Please upgrade your YAML definition to from '" + sq.c.Version + "' to '" + config.Version + "'")
|
||||||
@ -111,6 +120,7 @@ func (sq *Squadron) MergeConfigFiles(ctx context.Context) error {
|
|||||||
sq.config = string(value)
|
sq.config = string(value)
|
||||||
|
|
||||||
pterm.Success.Println("📚 | merging configs ⏱ " + time.Since(start).Truncate(time.Second).String())
|
pterm.Success.Println("📚 | merging configs ⏱ " + time.Since(start).Truncate(time.Second).String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,10 +170,14 @@ func (sq *Squadron) FilterConfig(ctx context.Context, squadron string, units, ta
|
|||||||
|
|
||||||
func (sq *Squadron) RenderConfig(ctx context.Context) error {
|
func (sq *Squadron) RenderConfig(ctx context.Context) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
pterm.Info.Println("📗 | rendering config")
|
pterm.Info.Println("📗 | rendering config")
|
||||||
|
|
||||||
var tv templatex.Vars
|
var (
|
||||||
var vars map[string]any
|
tv templatex.Vars
|
||||||
|
vars map[string]any
|
||||||
|
)
|
||||||
|
|
||||||
if err := yaml.Unmarshal([]byte(sq.config), &vars); err != nil {
|
if err := yaml.Unmarshal([]byte(sq.config), &vars); err != nil {
|
||||||
return errors.Wrap(err, "failed to render config")
|
return errors.Wrap(err, "failed to render config")
|
||||||
}
|
}
|
||||||
@ -173,9 +187,11 @@ func (sq *Squadron) RenderConfig(ctx context.Context) error {
|
|||||||
if value, ok := vars["global"]; ok {
|
if value, ok := vars["global"]; ok {
|
||||||
tv.Add("Global", value)
|
tv.Add("Global", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := vars["vars"]; ok {
|
if value, ok := vars["vars"]; ok {
|
||||||
tv.Add("Vars", value)
|
tv.Add("Vars", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := vars["squadron"]; ok {
|
if value, ok := vars["squadron"]; ok {
|
||||||
tv.Add("Squadron", value)
|
tv.Add("Squadron", value)
|
||||||
}
|
}
|
||||||
@ -202,9 +218,11 @@ func (sq *Squadron) RenderConfig(ctx context.Context) error {
|
|||||||
if value, ok := vars["global"]; ok {
|
if value, ok := vars["global"]; ok {
|
||||||
tv.Add("Global", value)
|
tv.Add("Global", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := vars["vars"]; ok {
|
if value, ok := vars["vars"]; ok {
|
||||||
tv.Add("Vars", value)
|
tv.Add("Vars", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := vars["squadron"]; ok {
|
if value, ok := vars["squadron"]; ok {
|
||||||
tv.Add("Squadron", value)
|
tv.Add("Squadron", value)
|
||||||
}
|
}
|
||||||
@ -241,6 +259,7 @@ func (sq *Squadron) Push(ctx context.Context, pushArgs []string, parallel int) e
|
|||||||
item any
|
item any
|
||||||
image string
|
image string
|
||||||
}
|
}
|
||||||
|
|
||||||
var all []one
|
var all []one
|
||||||
|
|
||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
@ -257,6 +276,7 @@ func (sq *Squadron) Push(ctx context.Context, pushArgs []string, parallel int) e
|
|||||||
})
|
})
|
||||||
spinner.Start()
|
spinner.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range v.BakeNames() {
|
for _, name := range v.BakeNames() {
|
||||||
bake := v.Bakes[name]
|
bake := v.Bakes[name]
|
||||||
for _, tag := range bake.Tags {
|
for _, tag := range bake.Tags {
|
||||||
@ -271,6 +291,7 @@ func (sq *Squadron) Push(ctx context.Context, pushArgs []string, parallel int) e
|
|||||||
spinner.Start()
|
spinner.Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -293,13 +314,16 @@ func (sq *Squadron) Push(ctx context.Context, pushArgs []string, parallel int) e
|
|||||||
cleanArgs = append(cleanArgs, strings.Split(value, " ")...)
|
cleanArgs = append(cleanArgs, strings.Split(value, " ")...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Debug.Printfln("running docker push for %s", a.image)
|
pterm.Debug.Printfln("running docker push for %s", a.image)
|
||||||
|
|
||||||
if out, err := util.NewDockerCommand().Push(a.image).Args(cleanArgs...).Run(ctx); err != nil {
|
if out, err := util.NewDockerCommand().Push(a.image).Args(cleanArgs...).Run(ctx); err != nil {
|
||||||
a.spinner.Fail(out)
|
a.spinner.Fail(out)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
a.spinner.Success()
|
a.spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -330,6 +354,7 @@ func (sq *Squadron) BuildDependencies(ctx context.Context, buildArgs []string, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinner.Success()
|
spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,19 +407,30 @@ func (sq *Squadron) Bake(ctx context.Context, buildArgs []string) error {
|
|||||||
Name: "all",
|
Name: "all",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gitInfo, err := sq.getGitInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
pterm.Debug.Println("failed to get git info:", err)
|
||||||
|
}
|
||||||
|
|
||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
_ = value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
_ = value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
for _, name := range v.BakeNames() {
|
for _, name := range v.BakeNames() {
|
||||||
item := v.Bakes[name]
|
item := v.Bakes[name]
|
||||||
item.Name = strings.Join([]string{key, k, name}, "-")
|
item.Name = strings.Join([]string{key, k, name}, "-")
|
||||||
|
item.Args["SQUADRON_NAME"] = key
|
||||||
|
item.Args["SQUADRON_UNIT_NAME"] = k
|
||||||
|
maps.Copy(item.Args, gitInfo)
|
||||||
pterm.Info.Printfln("📦 | %s/%s.%s (%s)", key, k, name, strings.Join(item.Tags, ","))
|
pterm.Info.Printfln("📦 | %s/%s.%s (%s)", key, k, name, strings.Join(item.Tags, ","))
|
||||||
g.Targets = append(g.Targets, item.Name)
|
g.Targets = append(g.Targets, item.Name)
|
||||||
c.Targets = append(c.Targets, &item)
|
c.Targets = append(c.Targets, &item)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
c.Groups = append(c.Groups, g)
|
c.Groups = append(c.Groups, g)
|
||||||
|
|
||||||
b, err := dethcl.Marshal(c)
|
b, err := dethcl.Marshal(c)
|
||||||
@ -402,10 +438,13 @@ func (sq *Squadron) Bake(ctx context.Context, buildArgs []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal bake config")
|
return errors.Wrap(err, "failed to marshal bake config")
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Debug.Println("🔥 | bakefile:\n" + util.HighlightHCL(string(b)))
|
pterm.Debug.Println("🔥 | bakefile:\n" + util.HighlightHCL(string(b)))
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
pterm.Success.Println("🔥 | baking containers")
|
pterm.Success.Println("🔥 | baking containers")
|
||||||
|
|
||||||
out, err := util.NewDockerCommand().
|
out, err := util.NewDockerCommand().
|
||||||
Bake(bytes.NewReader(b)).
|
Bake(bytes.NewReader(b)).
|
||||||
Stderr(ptermx.NewWriter(pterm.Debug)).
|
Stderr(ptermx.NewWriter(pterm.Debug)).
|
||||||
@ -414,6 +453,7 @@ func (sq *Squadron) Bake(ctx context.Context, buildArgs []string) error {
|
|||||||
pterm.Println(util.HighlightHCL(string(b)))
|
pterm.Println(util.HighlightHCL(string(b)))
|
||||||
return errors.Wrap(err, out)
|
return errors.Wrap(err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Success.Println("🔥 | baking containers ⏱︎ " + time.Since(start).Truncate(time.Second).String())
|
pterm.Success.Println("🔥 | baking containers ⏱︎ " + time.Since(start).Truncate(time.Second).String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -436,12 +476,28 @@ func (sq *Squadron) Build(ctx context.Context, buildArgs []string, parallel int)
|
|||||||
unit string
|
unit string
|
||||||
item config.Build
|
item config.Build
|
||||||
}
|
}
|
||||||
|
|
||||||
var all []one
|
var all []one
|
||||||
|
|
||||||
|
gitInfo, err := sq.getGitInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
pterm.Debug.Println("failed to get git info:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var gitInfoArgs []string
|
||||||
|
for s, s2 := range gitInfo {
|
||||||
|
gitInfoArgs = append(gitInfoArgs, fmt.Sprintf("%s=%s", s, s2))
|
||||||
|
}
|
||||||
|
|
||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
for _, name := range v.BuildNames() {
|
for _, name := range v.BuildNames() {
|
||||||
item := v.Builds[name]
|
item := v.Builds[name]
|
||||||
|
item.BuildArg = append(item.BuildArg,
|
||||||
|
"SQUADRON_NAME="+key,
|
||||||
|
"SQUADRON_UNIT_NAME="+k,
|
||||||
|
)
|
||||||
|
item.BuildArg = append(item.BuildArg, gitInfoArgs...)
|
||||||
spinner := printer.NewSpinner(fmt.Sprintf("📦 | %s/%s.%s (%s:%s)", key, k, name, item.Image, item.Tag))
|
spinner := printer.NewSpinner(fmt.Sprintf("📦 | %s/%s.%s (%s:%s)", key, k, name, item.Image, item.Tag))
|
||||||
all = append(all, one{
|
all = append(all, one{
|
||||||
spinner: spinner,
|
spinner: spinner,
|
||||||
@ -451,6 +507,7 @@ func (sq *Squadron) Build(ctx context.Context, buildArgs []string, parallel int)
|
|||||||
})
|
})
|
||||||
spinner.Start()
|
spinner.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -462,17 +519,19 @@ func (sq *Squadron) Build(ctx context.Context, buildArgs []string, parallel int)
|
|||||||
ctx := ptermx.ContextWithSpinner(ctx, a.spinner)
|
ctx := ptermx.ContextWithSpinner(ctx, a.spinner)
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
a.spinner.Warning(err.Error())
|
a.spinner.Warning(err.Error())
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if out, err := a.item.Build(ctx, a.squadron, a.unit, buildArgs); err != nil {
|
if out, err := a.item.Build(ctx, a.squadron, a.unit, buildArgs); errors.Is(ctx.Err(), context.Canceled) {
|
||||||
if !errors.Is(err, context.Canceled) {
|
a.spinner.Warning(ctx.Err().Error())
|
||||||
a.spinner.Fail(out)
|
return nil
|
||||||
}
|
} else if err != nil {
|
||||||
|
a.spinner.Fail(out)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
a.spinner.Success()
|
a.spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -501,6 +560,7 @@ func (sq *Squadron) Down(ctx context.Context, helmArgs []string, parallel int) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := sq.getReleaseName(key, k, v)
|
name := sq.getReleaseName(key, k, v)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, key, k, v)
|
namespace, err := sq.Namespace(ctx, key, k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -519,8 +579,10 @@ func (sq *Squadron) Down(ctx context.Context, helmArgs []string, parallel int) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinner.Success()
|
spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -554,12 +616,17 @@ func (sq *Squadron) RenderSchema(ctx context.Context, baseSchema string) (string
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (string, error) {
|
func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (string, error) {
|
||||||
var m sync.Mutex
|
var (
|
||||||
var ret bytes.Buffer
|
m sync.Mutex
|
||||||
|
ret bytes.Buffer
|
||||||
|
)
|
||||||
|
|
||||||
write := func(b []byte) error {
|
write := func(b []byte) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
_, err := ret.Write(b)
|
_, err := ret.Write(b)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,10 +650,12 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := sq.getReleaseName(key, k, v)
|
name := sq.getReleaseName(key, k, v)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, key, k, v)
|
namespace, err := sq.Namespace(ctx, key, k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
valueBytes, err := v.ValuesYAML(sq.c.Global)
|
valueBytes, err := v.ValuesYAML(sq.c.Global)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -597,6 +666,7 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
spinner.Fail(string(manifest))
|
spinner.Fail(string(manifest))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, "helm", "upgrade", name,
|
cmd := exec.CommandContext(ctx, "helm", "upgrade", name,
|
||||||
"--install",
|
"--install",
|
||||||
"--namespace", namespace,
|
"--namespace", namespace,
|
||||||
@ -616,11 +686,14 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
if v.Chart.Repository != "" {
|
if v.Chart.Repository != "" {
|
||||||
cmd.Args = append(cmd.Args, "--repo", v.Chart.Repository)
|
cmd.Args = append(cmd.Args, "--repo", v.Chart.Repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Chart.Version != "" {
|
if v.Chart.Version != "" {
|
||||||
cmd.Args = append(cmd.Args, "--version", v.Chart.Version)
|
cmd.Args = append(cmd.Args, "--version", v.Chart.Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Args = append(cmd.Args, helmArgs...)
|
cmd.Args = append(cmd.Args, helmArgs...)
|
||||||
|
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
spinner.Fail(string(out))
|
spinner.Fail(string(out))
|
||||||
@ -634,6 +707,7 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
outStr := strings.Split(string(out), "\n")
|
outStr := strings.Split(string(out), "\n")
|
||||||
|
|
||||||
yamls2, err := yamldiff.Load(strings.Join(outStr[10:], "\n"))
|
yamls2, err := yamldiff.Load(strings.Join(outStr[10:], "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
spinner.Fail(string(out))
|
spinner.Fail(string(out))
|
||||||
@ -651,6 +725,7 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinner.Success()
|
spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -667,14 +742,17 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) (
|
|||||||
|
|
||||||
func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int) error {
|
func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int) error {
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
|
|
||||||
tbd := pterm.TableData{
|
tbd := pterm.TableData{
|
||||||
{"Name", "Revision", "Status", "User", "Branch", "Commit", "Squadron", "Last deployed", "Notes"},
|
{"Name", "Revision", "Status", "User", "Branch", "Commit", "Squadron", "Last deployed", "Notes"},
|
||||||
}
|
}
|
||||||
write := func(b []string) {
|
write := func(b []string) {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
tbd = append(tbd, b)
|
tbd = append(tbd, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
type statusType struct {
|
type statusType struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version int `json:"version"`
|
Version int `json:"version"`
|
||||||
@ -686,10 +764,10 @@ func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int)
|
|||||||
LastDeployed string `json:"last_deployed"`
|
LastDeployed string `json:"last_deployed"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
} `json:"info"`
|
} `json:"info"`
|
||||||
user string `json:"-"` //nolint:revive
|
user string `json:"-"`
|
||||||
branch string `json:"-"` //nolint:revive
|
branch string `json:"-"`
|
||||||
commit string `json:"-"` //nolint:revive
|
commit string `json:"-"`
|
||||||
squadron string `json:"-"` //nolint:revive
|
squadron string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
wg, ctx := errgroup.WithContext(ctx)
|
wg, ctx := errgroup.WithContext(ctx)
|
||||||
@ -701,7 +779,9 @@ func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int)
|
|||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
var status statusType
|
var status statusType
|
||||||
|
|
||||||
name := sq.getReleaseName(key, k, v)
|
name := sq.getReleaseName(key, k, v)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, key, k, v)
|
namespace, err := sq.Namespace(ctx, key, k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("failed to retrieve namsspace: %s/%s", key, k)
|
return errors.Errorf("failed to retrieve namsspace: %s/%s", key, k)
|
||||||
@ -739,8 +819,10 @@ func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int)
|
|||||||
return errors.Errorf("failed to retrieve status: %s/%s", key, k)
|
return errors.Errorf("failed to retrieve status: %s/%s", key, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
var notes []string
|
var (
|
||||||
var statusDescription Status
|
notes []string
|
||||||
|
statusDescription Status
|
||||||
|
)
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(status.Info.Description), &statusDescription); err == nil {
|
if err := json.Unmarshal([]byte(status.Info.Description), &statusDescription); err == nil {
|
||||||
status.user = statusDescription.User
|
status.user = statusDescription.User
|
||||||
@ -769,6 +851,7 @@ func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int)
|
|||||||
})
|
})
|
||||||
|
|
||||||
spinner.Success()
|
spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -779,12 +862,14 @@ func (sq *Squadron) Status(ctx context.Context, helmArgs []string, parallel int)
|
|||||||
if err := wg.Wait(); err != nil {
|
if err := wg.Wait(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.Stop()
|
printer.Stop()
|
||||||
|
|
||||||
out, err := pterm.DefaultTable.WithHasHeader().WithData(tbd).Srender()
|
out, err := pterm.DefaultTable.WithHasHeader().WithData(tbd).Srender()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pterm.Println(out)
|
pterm.Println(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -804,6 +889,7 @@ func (sq *Squadron) Rollback(ctx context.Context, revision string, helmArgs []st
|
|||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
name := sq.getReleaseName(key, k, v)
|
name := sq.getReleaseName(key, k, v)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, key, k, v)
|
namespace, err := sq.Namespace(ctx, key, k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -821,6 +907,7 @@ func (sq *Squadron) Rollback(ctx context.Context, revision string, helmArgs []st
|
|||||||
}
|
}
|
||||||
|
|
||||||
stdErr := bytes.NewBuffer([]byte{})
|
stdErr := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
out, err := util.NewHelmCommand().Args("rollback", name).
|
out, err := util.NewHelmCommand().Args("rollback", name).
|
||||||
Stderr(stdErr).
|
Stderr(stdErr).
|
||||||
Args(helmArgs...).
|
Args(helmArgs...).
|
||||||
@ -836,6 +923,7 @@ func (sq *Squadron) Rollback(ctx context.Context, revision string, helmArgs []st
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinner.Success(out)
|
spinner.Success(out)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -851,11 +939,13 @@ func (sq *Squadron) Rollback(ctx context.Context, revision string, helmArgs []st
|
|||||||
func (sq *Squadron) UpdateLocalDependencies(ctx context.Context, parallel int) error {
|
func (sq *Squadron) UpdateLocalDependencies(ctx context.Context, parallel int) error {
|
||||||
// collect unique entrie
|
// collect unique entrie
|
||||||
repositories := map[string]struct{}{}
|
repositories := map[string]struct{}{}
|
||||||
|
|
||||||
err := sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
err := sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
return value.Iterate(ctx, func(ctx context.Context, k string, v *config.Unit) error {
|
||||||
if strings.HasPrefix(v.Chart.Repository, "file:///") {
|
if strings.HasPrefix(v.Chart.Repository, "file:///") {
|
||||||
repositories[v.Chart.Repository] = struct{}{}
|
repositories[v.Chart.Repository] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -869,6 +959,7 @@ func (sq *Squadron) UpdateLocalDependencies(ctx context.Context, parallel int) e
|
|||||||
for repository := range repositories {
|
for repository := range repositories {
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
pterm.Debug.Printfln("running helm dependency update for %s", repository)
|
pterm.Debug.Printfln("running helm dependency update for %s", repository)
|
||||||
|
|
||||||
if out, err := util.NewHelmCommand().
|
if out, err := util.NewHelmCommand().
|
||||||
Cwd(path.Clean(strings.TrimPrefix(repository, "file://"))).
|
Cwd(path.Clean(strings.TrimPrefix(repository, "file://"))).
|
||||||
Args("dependency", "update", "--skip-refresh", "--debug").
|
Args("dependency", "update", "--skip-refresh", "--debug").
|
||||||
@ -877,6 +968,7 @@ func (sq *Squadron) UpdateLocalDependencies(ctx context.Context, parallel int) e
|
|||||||
} else {
|
} else {
|
||||||
pterm.Debug.Println(out)
|
pterm.Debug.Println(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -895,12 +987,14 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
|
|
||||||
printer := ptermx.MustNewMultiPrinter()
|
printer := ptermx.MustNewMultiPrinter()
|
||||||
defer printer.Stop()
|
defer printer.Stop()
|
||||||
|
|
||||||
type one struct {
|
type one struct {
|
||||||
spinner ptermx.Spinner
|
spinner ptermx.Spinner
|
||||||
squadron string
|
squadron string
|
||||||
unit string
|
unit string
|
||||||
item *config.Unit
|
item *config.Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
var all []one
|
var all []one
|
||||||
|
|
||||||
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
_ = sq.Config().Squadrons.Iterate(ctx, func(ctx context.Context, key string, value config.Map[*config.Unit]) error {
|
||||||
@ -909,6 +1003,7 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
if v.Priority != 0 {
|
if v.Priority != 0 {
|
||||||
priority = fmt.Sprintf(" ☝︎ %d", v.Priority)
|
priority = fmt.Sprintf(" ☝︎ %d", v.Priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
spinner := printer.NewSpinner(fmt.Sprintf("🚀 | %s/%s", key, k) + priority)
|
spinner := printer.NewSpinner(fmt.Sprintf("🚀 | %s/%s", key, k) + priority)
|
||||||
all = append(all, one{
|
all = append(all, one{
|
||||||
spinner: spinner,
|
spinner: spinner,
|
||||||
@ -937,11 +1032,13 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := sq.getReleaseName(a.squadron, a.unit, a.item)
|
name := sq.getReleaseName(a.squadron, a.unit, a.item)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, a.squadron, a.unit, a.item)
|
namespace, err := sq.Namespace(ctx, a.squadron, a.unit, a.item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.spinner.Fail(err.Error())
|
a.spinner.Fail(err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
valueBytes, err := a.item.ValuesYAML(sq.c.Global)
|
valueBytes, err := a.item.ValuesYAML(sq.c.Global)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.spinner.Fail(err.Error())
|
a.spinner.Fail(err.Error())
|
||||||
@ -966,9 +1063,11 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
cmd.Args(path.Clean(strings.TrimPrefix(a.item.Chart.Repository, "file://")))
|
cmd.Args(path.Clean(strings.TrimPrefix(a.item.Chart.Repository, "file://")))
|
||||||
} else {
|
} else {
|
||||||
cmd.Args(a.item.Chart.Name)
|
cmd.Args(a.item.Chart.Name)
|
||||||
|
|
||||||
if a.item.Chart.Repository != "" {
|
if a.item.Chart.Repository != "" {
|
||||||
cmd.Args("--repo", a.item.Chart.Repository)
|
cmd.Args("--repo", a.item.Chart.Repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.item.Chart.Version != "" {
|
if a.item.Chart.Version != "" {
|
||||||
cmd.Args("--version", a.item.Chart.Version)
|
cmd.Args("--version", a.item.Chart.Version)
|
||||||
}
|
}
|
||||||
@ -984,6 +1083,7 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
a.spinner.Success()
|
a.spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -992,12 +1092,17 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, status Status, pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel int) (string, error) {
|
func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel int) (string, error) {
|
||||||
var m sync.Mutex
|
var (
|
||||||
var ret bytes.Buffer
|
m sync.Mutex
|
||||||
|
ret bytes.Buffer
|
||||||
|
)
|
||||||
|
|
||||||
write := func(b []byte) error {
|
write := func(b []byte) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
_, err := ret.Write(b)
|
_, err := ret.Write(b)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,6 +1126,7 @@ func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel in
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := sq.getReleaseName(key, k, v)
|
name := sq.getReleaseName(key, k, v)
|
||||||
|
|
||||||
namespace, err := sq.Namespace(ctx, key, k, v)
|
namespace, err := sq.Namespace(ctx, key, k, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
spinner.Fail(err.Error())
|
spinner.Fail(err.Error())
|
||||||
@ -1039,6 +1145,7 @@ func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel in
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinner.Success()
|
spinner.Success()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1057,5 +1164,74 @@ func (sq *Squadron) getReleaseName(squadron, unit string, u *config.Unit) string
|
|||||||
if u.Name != "" {
|
if u.Name != "" {
|
||||||
return u.Name
|
return u.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
return squadron + "-" + unit
|
return squadron + "-" + unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sq *Squadron) getGitInfo(ctx context.Context) (map[string]string, error) {
|
||||||
|
ret := map[string]string{}
|
||||||
|
|
||||||
|
dir := "."
|
||||||
|
|
||||||
|
for _, s := range []string{"GIT_DIR", "PROJECT_ROOT"} {
|
||||||
|
if v := os.Getenv(s); v != "" {
|
||||||
|
dir = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := git.PlainOpen(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get remote "origin" URL
|
||||||
|
remote, err := repo.Remote("origin")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteURLs := remote.Config().URLs
|
||||||
|
if len(remoteURLs) > 0 {
|
||||||
|
url := remoteURLs[0]
|
||||||
|
if strings.HasPrefix(url, "git@") {
|
||||||
|
// Example input: git@github.com:user/repo.git
|
||||||
|
parts := strings.SplitN(url, ":", 2)
|
||||||
|
if len(parts) == 2 {
|
||||||
|
// parts[1] = user/repo.git
|
||||||
|
hostParts := strings.Split(parts[0], "@")
|
||||||
|
if len(hostParts) == 2 {
|
||||||
|
host := hostParts[1]
|
||||||
|
url = "https://" + host + "/" + strings.TrimSuffix(parts[1], ".git")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret["GIT_REPOSITORY_URL"] = url
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get HEAD reference to find the current branch or commit
|
||||||
|
ref, err := repo.Head()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret["GIT_TYPE"] = "branch"
|
||||||
|
ret["GIT_BRANCH"] = ref.Name().Short()
|
||||||
|
ret["GIT_COMMIT_HASH"] = ref.Hash().String()
|
||||||
|
|
||||||
|
if t, err := repo.Tags(); err == nil {
|
||||||
|
_ = t.ForEach(func(reference *plumbing.Reference) error {
|
||||||
|
if ref.Hash() == reference.Hash() {
|
||||||
|
ret["GIT_TAG"] = reference.Name().Short()
|
||||||
|
ret["GIT_TYPE"] = "tag"
|
||||||
|
|
||||||
|
return errors.New("break")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -70,13 +70,16 @@ func TestConfigSimpleSnapshot(t *testing.T) {
|
|||||||
|
|
||||||
func runTestConfig(t *testing.T, name string, files []string, squadronName string, unitNames, tags []string) {
|
func runTestConfig(t *testing.T, name string, files []string, squadronName string, unitNames, tags []string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
var cwd string
|
var cwd string
|
||||||
|
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
require.NoError(t, util.ValidatePath(".", &cwd))
|
require.NoError(t, util.ValidatePath(".", &cwd))
|
||||||
|
|
||||||
for i, file := range files {
|
for i, file := range files {
|
||||||
files[i] = path.Join("testdata", name, file)
|
files[i] = path.Join("testdata", name, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
sq := squadron.New(cwd, "default", files)
|
sq := squadron.New(cwd, "default", files)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user