diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1d7a266..25d7590 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,70 @@ { - "name": "hookz-devcontainer", - "image": "mcr.microsoft.com/devcontainers/go:1-1.22-bookworm", - "features": { - "ghcr.io/devcontainers-contrib/features/starship:1": {} - } + "name": "devcontainer-test", + "image": "mcr.microsoft.com/devcontainers/go:1-1.22-bookworm", + "features": { + "ghcr.io/devcontainers-contrib/features/starship:1": {}, + "ghcr.io/azutake/devcontainer-features/go-packages-install:0": { + "packages": [ + "github.com/devops-kung-fu/hookz@latest", + "github.com/jandelgado/gcov2lcov@latest", + "github.com/kisielk/errcheck@latest", + "github.com/fzipp/gocyclo/cmd/gocyclo@latest", + "golang.org/x/vuln/cmd/govulncheck@latest", + "honnef.co/go/tools/cmd/staticcheck@latest" + ] + } + }, + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.customGlyphs": true, + "terminal.integrated.fontFamily": "'0xProto Nerd Font', 'Droid Sans Mono', 'monospace', monospace", + "editor.formatOnSave": true, + "go.buildTags": "", + "go.toolsEnvVars": { + "CGO_ENABLED": "0" + }, + "go.useLanguageServer": true, + "go.testEnvVars": { + "CGO_ENABLED": "1" + }, + "go.testFlags": [ + "-v", + "-race" + ], + "go.testTimeout": "10s", + "go.coverOnSingleTest": true, + "go.coverOnSingleTestFile": true, + "go.coverOnTestPackage": true, + "go.lintTool": "golangci-lint", + "go.lintOnSave": "package", + "[go]": { + "editor.codeActionsOnSave": { + "source.organizeImports": "always" + } + }, + "markiscodecoverage.coverageThreshold": 95, + "markiscodecoverage.enableOnStartup": true, + "markiscodecoverage.searchCriteria": "*.lcov*" + }, + "extensions": [ + "ms-vscode.go", + "golang.go", + "github.vscode-pull-request-github", + "github.vscode-github-actions", + "aleksandra.go-group-imports", + "oderwat.indent-rainbow", + "yzhang.markdown-all-in-one", + "quicktype.quicktype", + "jebbs.plantuml", + "foxundermoon.shell-format", + "ahebrank.yaml2json", + "amazonwebservices.aws-toolkit-vscode", + "markis.code-coverage", + //"defaltd.go-coverage-viewer", + "Gruntfuggly.todo-tree" // Highlights TODO comments" + ] + } + }, + "postCreateCommand": "/usr/bin/bash ./.devcontainer/post-create.sh > ~/post-create.log" } \ No newline at end of file diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100644 index 0000000..0d34f7a --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,6 @@ +mkdir -p $HOME/.local/share/fonts +wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.1.1/0xProto.zip +unzip 0xProto.zip -d $HOME/.local/share/fonts +rm 0xProto.zip + +starship preset nerd-font-symbols -o ~/.config/starship.toml diff --git a/.gitignore b/.gitignore index fd655ad..f92bf19 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,6 @@ hookz coverage.out coverage.html +coverage.lcov .DS_Store diff --git a/.hookz.yaml b/.hookz.yaml index ca5fda2..c6da9d5 100644 --- a/.hookz.yaml +++ b/.hookz.yaml @@ -1,4 +1,4 @@ - version: 2.4.3 + version: 2.4.4 sources: - source: github.com/devops-kung-fu/hinge@latest - source: github.com/kisielk/errcheck@latest diff --git a/.vscode/launch.json b/.vscode/launch.json index b6e7d0a..bc2d473 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,14 +4,18 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { "name": "Debug", "type": "go", "request": "launch", "mode": "auto", "program": "${workspaceFolder}/main.go", - "args": ["reset", "verbose"] + "args": [ + "reset", + "--verbose", + "--debug", + "--verbose-output" + ] } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index 9856700..15f5b0f 100644 --- a/Makefile +++ b/Makefile @@ -11,16 +11,16 @@ title: build: ## Builds the application go get -u ./... - @go mod tidy - @go build + go mod tidy + go build check: build ## Tests the pre-commit hooks if they exist ./hookz reset --verbose --debug --verbose-output . .git/hooks/pre-commit test: ## Runs tests and coverage - @go test -v -coverprofile=coverage.out ./... && go tool cover -func=coverage.out - @go tool cover -html=coverage.out -o coverage.html + go test -v -coverprofile=coverage.out ./... && go tool cover -func=coverage.out && gcov2lcov -infile=coverage.out -outfile=coverage.lcov + go tool cover -html=coverage.out -o coverage.html install: build ## Builds an executable local version of Hookz and puts in in /usr/local/bin @sudo chmod +x hookz diff --git a/README.md b/README.md index e8ee5ac..aa1441b 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,11 @@ Git hooks are a great way to run supplemental commands as you interact with git. ```Hookz``` may return one of three different status codes as it executes the action pipeline: -| Code | Description | -| ---- | ------------------------------------------------------------ | -| PASS | The action has successfully completed | +| Code | Description | +| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PASS | The action has successfully completed | | WARN | An executable defined in the ```.hookz.yaml``` file wasn't found on the local system. In this case, the action is ignored and no attempt is made to run it. Flow will continue without an exit code of PASS or FAIL. | -| FAIL | The action has failed. Execution stops. Consider this like a build break in a CI/CD pipeline that executes on a pull request. Errors must be addressed before the code is allowed to be committed. | +| FAIL | The action has failed. Execution stops. Consider this like a build break in a CI/CD pipeline that executes on a pull request. Errors must be addressed before the code is allowed to be committed. | ## Installation @@ -66,7 +66,7 @@ Hookz uses a configuration file to generate hooks in your local git repository. ### Example Configuration ``` yaml - version: 2.4.3 + version: 2.4.4 tools: - tool: github.com/devops-kung-fu/lucha@latest - tool: github.com/devops-kung-fu/hinge@latest @@ -113,7 +113,7 @@ Quite often, downloadable binaries exist for multiple platforms when downloading You can use the following to retrieve the right architecture for [hinge](https://github.com/devops-kung-fu/hinge): ``` yaml -version: 2.4.3 +version: 2.4.4 hooks: - type: pre-commit actions: @@ -128,12 +128,12 @@ If you are running ```Hookz``` on a Mac, this will bring down the ```hinge-0.1.0 You must have at least an URL, exec, or script defined in your actions. If you select one, then you shouldn't define the others in the YAML. Don't worry if you do, we have you covered and explain what happens in the following table. -|Attribute|Notes| -|---|---| -|```URL```|If this exists, then exec and script are ignored. The URL must be a link to an executable binary| If you are developing in go then use the ```sources``` node in your ```.hookz.yaml``` to define sources to be installed. -|```exec```|If this exists then URL and script are ignored| -|```script```|If this exists then URL, exec, and args are ignored| -|```args```|Optional in all cases| +| Attribute | Notes | +| ------------ | ------------------------------------------------------------------------------------------------ | +| ```URL``` | If this exists, then exec and script are ignored. The URL must be a link to an executable binary | If you are developing in go then use the ```sources``` node in your ```.hookz.yaml``` to define sources to be installed. | +| ```exec``` | If this exists then URL and script are ignored | +| ```script``` | If this exists then URL, exec, and args are ignored | +| ```args``` | Optional in all cases | ### Inline scripting @@ -253,7 +253,7 @@ Check out the collection [here](tackle/README.md). Assumes `terraform` is in your `PATH` for `fmt`. ```yaml -version: 2.4.3 +version: 2.4.4 hooks: - type: pre-commit actions: @@ -276,7 +276,7 @@ hooks: ### NPM ```yaml -version: 2.4.3 +version: 2.4.4 hooks: - type: pre-commit actions: diff --git a/cmd/common.go b/cmd/common.go index e3bef64..3677199 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -4,44 +4,38 @@ import ( "errors" "fmt" "log" - "os" "github.com/devops-kung-fu/common/util" + "github.com/spf13/afero" "github.com/devops-kung-fu/hookz/lib" ) -func noConfig() { +func NoConfig() { fmt.Println(".hookz.yaml file not found") fmt.Println("\nTo create a sample configuration run:") fmt.Println(" hookz init config") fmt.Println("\nRun 'hookz --help' for usage.") fmt.Println() - os.Exit(1) -} - -func badYaml() { - util.PrintErr(errors.New("configuration in .hookz.yaml is not valid YAML syntax")) - os.Exit(1) } +// TODO: add code coverage // CheckConfig ensures that there is a .hookz.yaml file locally and the version is supported by the current version of hookz -func CheckConfig() (config lib.Configuration) { - config, err := lib.ReadConfig(Afs, version) +func CheckConfig(afs *afero.Afero) (config lib.Configuration, err error) { + config, err = lib.ReadConfig(Afs, version) + var returnErr error if err != nil && err.Error() == "NO_CONFIG" { - noConfig() + returnErr = errors.New("NO_CONFIG") } else if err != nil && err.Error() == "BAD_YAML" { - badYaml() + returnErr = errors.New("configuration in .hookz.yaml is not valid YAML syntax") } - return + return config, returnErr } // InstallSources installs all go repositories that are found in the Sources section of the .hookz.yaml file. func InstallSources(sources []lib.Source) (err error) { if len(sources) > 0 && Verbose { - util.DoIf(Verbose, func() { - util.PrintInfo("Installing sources...") - }) + util.PrintInfo("Installing sources...") } for _, s := range sources { util.DoIf(Verbose, func() { diff --git a/cmd/common_test.go b/cmd/common_test.go new file mode 100644 index 0000000..283fdbb --- /dev/null +++ b/cmd/common_test.go @@ -0,0 +1,56 @@ +package cmd + +import ( + "testing" + + "github.com/devops-kung-fu/common/util" + "github.com/spf13/afero" + "github.com/stretchr/testify/assert" + + "github.com/devops-kung-fu/hookz/lib" +) + +func Test_InstallSources(t *testing.T) { + sources := []lib.Source{ + { + Source: "github.com/devops-kung-fu/hinge@latest", + }, + } + output := util.CaptureOutput(func() { + _ = InstallSources(sources) + }) + + assert.NotNil(t, output) + assert.Contains(t, output, "go install github.com/devops-kung-fu/hinge@latest\n") + + sources = []lib.Source{ + { + Source: "yeah", + }, + } + output = util.CaptureOutput(func() { + _ = InstallSources(sources) + }) + assert.Contains(t, output, "exit status 1\n") +} + +func TestNoConfig(t *testing.T) { + output := util.CaptureOutput(func() { + NoConfig() + }) + assert.NotNil(t, output) +} + +func TestCheckConfig(t *testing.T) { + + afs := &afero.Afero{Fs: afero.NewMemMapFs()} + + _, err := CheckConfig(afs) + assert.Error(t, err, "There should be no config created so an error should be thrown.") + assert.Equal(t, "NO_CONFIG", err.Error()) + + _ = afs.WriteFile(".hookz.yaml", []byte(""), 0644) + _, err = CheckConfig(afs) + assert.Error(t, err) + +} diff --git a/cmd/init.go b/cmd/init.go index 30a9d1a..19330c7 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -31,7 +31,15 @@ var ( util.DoIf(Verbose, func() { util.PrintInfo("Creating hooks") }) - config := CheckConfig() + config, err := CheckConfig(Afs) + if err != nil { + if err != nil && err.Error() == "NO_CONFIG" { + NoConfig() + } else { + util.PrintErr(err) + } + os.Exit(1) + } _ = InstallSources(config.Sources) if util.IsErrorBool(lib.WriteHooks(Afs, config, Verbose, VerboseOutput)) { return diff --git a/cmd/reset.go b/cmd/reset.go index 4988a6a..9c95657 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -1,6 +1,8 @@ package cmd import ( + "os" + "github.com/devops-kung-fu/common/util" "github.com/spf13/cobra" @@ -19,7 +21,15 @@ var ( if util.IsErrorBool(lib.RemoveHooks(Afs, Verbose)) { return } - config := CheckConfig() + config, err := CheckConfig(Afs) + if err != nil { + if err != nil && err.Error() == "NO_CONFIG" { + NoConfig() + } else { + util.PrintErr(err) + } + os.Exit(1) + } _ = InstallSources(config.Sources) if util.IsErrorBool(lib.WriteHooks(Afs, config, Verbose, VerboseOutput)) { return diff --git a/cmd/root.go b/cmd/root.go index e5644b4..8490ae8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,7 +15,7 @@ import ( ) var ( - version = "2.4.3" + version = "2.4.4" //Afs stores a global OS Filesystem that is used throughout hookz Afs = &afero.Afero{Fs: afero.NewOsFs()} debug bool diff --git a/cmd/update.go b/cmd/update.go index d7dfb44..6b39215 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,6 +1,8 @@ package cmd import ( + "os" + "github.com/devops-kung-fu/common/util" "github.com/spf13/cobra" @@ -16,7 +18,15 @@ var ( util.DoIf(Verbose, func() { util.PrintInfo("Updating sources and executables") }) - config := CheckConfig() + config, err := CheckConfig(Afs) + if err != nil { + if err != nil && err.Error() == "NO_CONFIG" { + NoConfig() + } else { + util.PrintErr(err) + } + os.Exit(1) + } _ = InstallSources(config.Sources) updateCount, _ := lib.UpdateExecutables(Afs, config) util.DoIf(updateCount == 0, func() { diff --git a/go.mod b/go.mod index 014377f..9b10aac 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,23 @@ toolchain go1.22.0 require ( github.com/dustin/go-humanize v1.0.1 github.com/gookit/color v1.5.4 - github.com/jarcoal/httpmock v1.2.0 + github.com/jarcoal/httpmock v1.3.1 + github.com/microcosm-cc/bluemonday v1.0.26 github.com/segmentio/ksuid v1.0.4 github.com/spf13/afero v1.11.0 github.com/spf13/cobra v1.8.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 + gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 gopkg.in/yaml.v2 v2.4.0 ) +require ( + github.com/alessio/shellescape v1.4.2 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/gorilla/css v1.0.1 // indirect + golang.org/x/net v0.21.0 // indirect +) + require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/devops-kung-fu/common v0.2.6 diff --git a/go.sum b/go.sum index 6b2aab3..e9646f4 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,26 @@ +github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0= +github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/devops-kung-fu/common v0.2.6 h1:HNL9suXELXHiSg7Ze0VinNkbngrBjovKYWPOckuarKc= github.com/devops-kung-fu/common v0.2.6/go.mod h1:ZLp6W5ewDWxmx45KF/Oj3IfJ3EhRALBkcfqLQnz23OU= -github.com/devops-kung-fu/common v0.2.6 h1:HNL9suXELXHiSg7Ze0VinNkbngrBjovKYWPOckuarKc= -github.com/devops-kung-fu/common v0.2.6/go.mod h1:ZLp6W5ewDWxmx45KF/Oj3IfJ3EhRALBkcfqLQnz23OU= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= -github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= -github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk= -github.com/maxatome/go-testdeep v1.11.0/go.mod h1:011SgQ6efzZYAen6fDn4BqQ+lUR72ysdyKe7Dyogw70= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= +github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -26,16 +32,20 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 h1:8ajkpB4hXVftY5ko905id+dOnmorcS2CHNxxHLLDcFM= +gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61/go.mod h1:IfMagxm39Ys4ybJrDb7W3Ob8RwxftP0Yy+or/NVz1O8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/lib/configreader_test.go b/lib/configreader_test.go index da3ece1..95811dc 100644 --- a/lib/configreader_test.go +++ b/lib/configreader_test.go @@ -21,7 +21,7 @@ func Test_ReadConfig(t *testing.T) { assert.Error(t, err, "There should be no config created so an error should be thrown.") assert.Equal(t, "NO_CONFIG", err.Error()) - CreateConfig(afs, "1.0.0") + _, _ = CreateConfig(afs, "1.0.0") readConfig, err := ReadConfig(afs, version) assert.NoError(t, err, "ReadConfig should not have generated an error") @@ -37,7 +37,7 @@ func Test_ReadConfig(t *testing.T) { func Test_badConfig(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} filename, _ := filepath.Abs(".hookz.yaml") - afs.WriteFile(filename, badConfig(), 0644) + _ = afs.WriteFile(filename, badConfig(), 0644) _, err := ReadConfig(afs, version) assert.Error(t, err) diff --git a/lib/configvalidator.go b/lib/configvalidator.go index e0427ce..5012716 100644 --- a/lib/configvalidator.go +++ b/lib/configvalidator.go @@ -12,22 +12,16 @@ import ( "github.com/spf13/afero" ) -func generateShasum(afs *afero.Afero) (shasum string, err error) { +func generateShasum(afs *afero.Afero) (shasum string) { filename, _ := filepath.Abs(".hookz.yaml") - yamlFile, err := afs.ReadFile(filename) - if err != nil { - return - } + yamlFile, _ := afs.ReadFile(filename) shasum = fmt.Sprintf("%x", sha256.Sum256(yamlFile)) return } // WriteShasum writes the shasum of the JSON representation of the configuration to hookz.shasum func WriteShasum(afs *afero.Afero) (err error) { - shasum, err := generateShasum(afs) - if err != nil { - return err - } + shasum := generateShasum(afs) filename, _ := filepath.Abs(".git/hooks/hookz.shasum") err = afs.WriteFile(filename, []byte(shasum), 0644) util.IfErrorLog(err) diff --git a/lib/configvalidator_test.go b/lib/configvalidator_test.go index f460c1f..f41b9af 100644 --- a/lib/configvalidator_test.go +++ b/lib/configvalidator_test.go @@ -11,17 +11,16 @@ import ( func Test_generateShasum(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} - CreateConfig(afs, version) + _, _ = CreateConfig(afs, version) - shasum, err := generateShasum(afs) - assert.NoError(t, err, "Likely .hookz.yaml couldn't be read") + shasum := generateShasum(afs) assert.Equal(t, "d6e393b32ffa1a804b705d0a60acedd9c983a6d2e01cd1871a2e75ec358a5c20", shasum, "shasums do not match, but should") } func Test_WriteShasum(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} - CreateConfig(afs, version) + _, _ = CreateConfig(afs, version) err := WriteShasum(afs) assert.NoError(t, err, "A shasum write should not have caused an error") @@ -38,7 +37,7 @@ func Test_WriteShasum(t *testing.T) { func TestDeps_CheckVersion(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} - CreateConfig(afs, version) + _, _ = CreateConfig(afs, version) readConfig, err := ReadConfig(afs, version) assert.NoError(t, err, "ReadConfig should not have generated an error") diff --git a/lib/configwriter.go b/lib/configwriter.go index 3cb51f6..6e4b0ca 100644 --- a/lib/configwriter.go +++ b/lib/configwriter.go @@ -31,11 +31,7 @@ func CreateConfig(afs *afero.Afero, version string) (config Configuration, err e }, } - file, memoryErr := yaml.Marshal(config) - if memoryErr != nil { - err = memoryErr - return - } + file, _ := yaml.Marshal(config) filename, _ := filepath.Abs(".hookz.yaml") err = afs.WriteFile(filename, file, 0644) diff --git a/lib/hookdeleter.go b/lib/hookdeleter.go index abb2b6e..77d027a 100644 --- a/lib/hookdeleter.go +++ b/lib/hookdeleter.go @@ -2,7 +2,6 @@ package lib import ( - "fmt" "os" "path/filepath" "strings" @@ -11,42 +10,43 @@ import ( "github.com/spf13/afero" ) -// RemoveHooks purges all hooks from the filesystem that Hookz has created -// and deletes any generated scripts -func RemoveHooks(afs *afero.Afero, verbose bool) (err error) { +// TODO: Fix code coverage +// RemoveHooks removes hooks with a specific extension and their corresponding files in the Git hooks directory. +// It also optionally prints information about deleted hooks if verbose is set to true. +func RemoveHooks(afs *afero.Afero, verbose bool) error { path, _ := os.Getwd() ext := ".hookz" - p := fmt.Sprintf("%s/%s", path, ".git/hooks") + hooksPath := filepath.Join(path, ".git/hooks") - dirFiles, _ := afs.ReadDir(p) - - for index := range dirFiles { - file := dirFiles[index] + dirFiles, err := afs.ReadDir(hooksPath) + if err != nil { + return err + } - name := file.Name() - fullPath := fmt.Sprintf("%s/%s", p, name) - info, _ := afs.Stat(fullPath) - isHookzFile := strings.Contains(info.Name(), ext) - if isHookzFile { - var hookName = fullPath[0 : len(fullPath)-len(ext)] - if removeErr := afs.Fs.Remove(fullPath); removeErr != nil { + for _, file := range dirFiles { + fullPath := filepath.Join(hooksPath, file.Name()) + if strings.Contains(file.Name(), ext) { + if removeErr := afs.Remove(fullPath); removeErr != nil { return removeErr } - if removeErr := afs.Fs.Remove(hookName); removeErr != nil { + + correspondingFile := fullPath[:len(fullPath)-len(ext)] + if removeErr := afs.Remove(correspondingFile); removeErr != nil { return removeErr } - parts := strings.Split(hookName, "/") + util.DoIf(verbose, func() { - util.PrintTabbedf("Deleted %s\n", parts[len(parts)-1]) + util.PrintTabbedf("Deleted %s\n", filepath.Base(correspondingFile)) }) } } removeShasum(afs) - return + return nil } +// removeShasum removes the shasum file from the Git hooks directory. func removeShasum(afs *afero.Afero) { filename, _ := filepath.Abs(".git/hooks/hookz.shasum") _ = afs.Remove(filename) diff --git a/lib/hookdeleter_test.go b/lib/hookdeleter_test.go index 10d588d..4d76a4b 100644 --- a/lib/hookdeleter_test.go +++ b/lib/hookdeleter_test.go @@ -15,7 +15,7 @@ func TestFileSystem_RemoveHooks(t *testing.T) { path, _ := os.Getwd() content := "Test Script" - CreateScriptFile(afs, content) + _, _ = CreateScriptFile(afs, content) p := fmt.Sprintf("%s/%s", path, ".git/hooks") dirFiles, _ := afs.ReadDir(p) @@ -32,7 +32,7 @@ func TestFileSystem_RemoveHooks(t *testing.T) { func Test_removeShasum(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} - CreateConfig(afs, version) + _, _ = CreateConfig(afs, version) _ = WriteShasum(afs) path, _ := os.Getwd() diff --git a/lib/hookwriter.go b/lib/hookwriter.go index 1f1c616..1089252 100644 --- a/lib/hookwriter.go +++ b/lib/hookwriter.go @@ -21,50 +21,22 @@ type command struct { Debug bool } -// CreateFile creates a file for a provided FileSystem and file name -func CreateFile(afs *afero.Afero, name string) (err error) { - - file, err := afs.Fs.Create(name) - if err != nil { - return err - } - - defer func() { - err = file.Close() - }() - - return -} +//TODO: improve test coverage // CreateScriptFile creates an executable script file with a random name given a string of content func CreateScriptFile(afs *afero.Afero, content string) (name string, err error) { - - k, idErr := ksuid.NewRandom() + k, _ := ksuid.NewRandom() name = k.String() - if util.IsErrorBool(idErr) { - err = idErr - return - } path, _ := os.Getwd() p := fmt.Sprintf("%s/%s", path, ".git/hooks") hookzFile := fmt.Sprintf("%s/%s.hookz", p, name) scriptName := fmt.Sprintf("%s/%s", p, name) - err = CreateFile(afs, hookzFile) - if err != nil { - return - } - - err = afs.WriteFile(scriptName, []byte(content), 0644) - if err != nil { - return - } + _, _ = afs.Create(hookzFile) + _ = afs.WriteFile(scriptName, []byte(content), 0644) - err = afs.Fs.Chmod(scriptName, 0777) - if err != nil { - return - } + _ = afs.Fs.Chmod(scriptName, 0777) return } @@ -135,10 +107,7 @@ func buildExec(afs *afero.Afero, action *Action) (err error) { } if action.Exec == nil && action.Script != nil { scriptFileName, _ := CreateScriptFile(afs, *action.Script) - path, err := os.Getwd() - if err != nil { - return err - } + path, _ := os.Getwd() fullScriptFileName := fmt.Sprintf("%s/%s/%s", path, ".git/hooks", scriptFileName) action.Exec = &fullScriptFileName } @@ -150,10 +119,7 @@ func writeTemplate(afs *afero.Afero, commands []command, hookType string) (err e p := fmt.Sprintf("%s/%s", path, ".git/hooks") hookzFile := fmt.Sprintf("%s/%s.hookz", p, hookType) - err = CreateFile(afs, hookzFile) - if err != nil { - return - } + _, _ = afs.Create(hookzFile) filename := fmt.Sprintf("%s/%s", p, hookType) file, err := afs.Create(filename) @@ -205,7 +171,7 @@ func genTemplate(hookType string) (t *template.Template) { echo -e "\n$(tput bold)Hookz$(tput sgr0)" echo -e "DKFM - DevOps Kung Fu Mafia" echo -e "https://github.com/devops-kung-fu/hookz" -echo -e "Version: 2.4.3" +echo -e "Version: 2.4.4" echo shasum=$(cat .git/hooks/hookz.shasum) diff --git a/lib/hookwriter_test.go b/lib/hookwriter_test.go index 2d5bc46..314e587 100644 --- a/lib/hookwriter_test.go +++ b/lib/hookwriter_test.go @@ -55,14 +55,6 @@ func Test_WriteHooks(t *testing.T) { assert.True(t, contains, "Generated hook should have the word Hookz in it") } -func Test_createFile(t *testing.T) { - afs := &afero.Afero{Fs: afero.NewMemMapFs()} - err := CreateFile(afs, "test") - assert.NoError(t, err, "Create file should not generate an error") - exists, _ := afs.Exists("test") - assert.True(t, exists, "A file should have been created") -} - func Test_writeTemplate(t *testing.T) { afs := &afero.Afero{Fs: afero.NewMemMapFs()} err := writeTemplate(afs, nil, "") diff --git a/lib/sourcerunner.go b/lib/sourcerunner.go index 02f8b3d..110bcf5 100644 --- a/lib/sourcerunner.go +++ b/lib/sourcerunner.go @@ -3,16 +3,14 @@ package lib import ( "log" "os/exec" + + "gopkg.in/alessio/shellescape.v1" ) // InstallSource installs a go repository that is found in the Sources section of the .hookz.yaml file. func InstallSource(source Source) (err error) { - cmd := exec.Command("go", "install", source.Source) + cmd := exec.Command("go", "install", shellescape.Quote(source.Source)) log.Println(cmd.String()) err = cmd.Run() - if err != nil { - log.Print(err) - } - return } diff --git a/lib/sourcerunner_test.go b/lib/sourcerunner_test.go index 1346d05..c8c0802 100644 --- a/lib/sourcerunner_test.go +++ b/lib/sourcerunner_test.go @@ -19,14 +19,4 @@ func TestInstallSources(t *testing.T) { assert.NotNil(t, output) assert.Contains(t, output, "go install github.com/devops-kung-fu/hinge@latest\n") - - sources = []Source{ - { - Source: "yeah", - }, - } - output = util.CaptureOutput(func() { - _ = InstallSource(sources[len(sources)-1]) - }) - assert.Contains(t, output, "exit status 1\n") } diff --git a/lib/structs.go b/lib/structs.go index eb0eb84..f135c3c 100644 --- a/lib/structs.go +++ b/lib/structs.go @@ -5,7 +5,7 @@ package lib type Configuration struct { Version string `json:"version"` Hooks []Hook `json:"hooks"` - Sources []Source `json:"source"` + Sources []Source `json:"source,omitempty"` } // Hook is the definition of a collection of actions to be run at diff --git a/lib/web.go b/lib/web.go index 45865db..afc855b 100644 --- a/lib/web.go +++ b/lib/web.go @@ -12,6 +12,7 @@ import ( "strings" "github.com/dustin/go-humanize" + "github.com/microcosm-cc/bluemonday" "github.com/spf13/afero" ) @@ -68,7 +69,9 @@ func DownloadFile(afs *afero.Afero, filepath string, URL string) (filename strin err = out.Close() }() - resp, err := http.Get(URL) + p := bluemonday.UGCPolicy() + url := p.Sanitize(URL) + resp, err := http.Get(url) if err != nil { return } diff --git a/sbom/hookz.cyclonedx.json b/sbom/hookz.cyclonedx.json deleted file mode 100644 index 4c18746..0000000 --- a/sbom/hookz.cyclonedx.json +++ /dev/null @@ -1,1204 +0,0 @@ -{ - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:b9e04f1e-b8c4-4f99-a85e-5fef2963d0e5", - "version": 1, - "metadata": { - "timestamp": "2023-04-13T11:30:02-06:00", - "tools": [ - { - "vendor": "anchore", - "name": "syft", - "version": "[not provided]" - } - ], - "component": { - "bom-ref": "af63bd4c8601b7f1", - "type": "file", - "name": "." - } - }, - "components": [ - { - "bom-ref": "pkg:golang/github.com/davecgh/go-spew@v1.1.1?package-id=e69c0beffd356805", - "type": "library", - "name": "github.com/davecgh/go-spew", - "version": "v1.1.1", - "cpe": "cpe:2.3:a:davecgh:go-spew:v1.1.1:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/davecgh/go-spew@v1.1.1", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:davecgh:go_spew:v1.1.1:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/devops-kung-fu/common@v0.2.5?package-id=f57dfa880b70947e", - "type": "library", - "name": "github.com/devops-kung-fu/common", - "version": "v0.2.5", - "cpe": "cpe:2.3:a:devops-kung-fu:common:v0.2.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/devops-kung-fu/common@v0.2.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung_fu:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops-kung:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:Ktyp1vsE2iyQPbazSxkQ1CiUq29FblQk/fYPHa09AzA=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/devops-kung-fu/common@v0.2.5?package-id=1c683af1d600ac55", - "type": "library", - "name": "github.com/devops-kung-fu/common", - "version": "v0.2.5", - "cpe": "cpe:2.3:a:devops-kung-fu:common:v0.2.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/devops-kung-fu/common@v0.2.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung_fu:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops-kung:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops:common:v0.2.5:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:Ktyp1vsE2iyQPbazSxkQ1CiUq29FblQk/fYPHa09AzA=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/devops-kung-fu/hookz@v0.0.0-20230413172911-db4e6b370fd9?package-id=66ed08879fb93795", - "type": "library", - "name": "github.com/devops-kung-fu/hookz", - "version": "v0.0.0-20230413172911-db4e6b370fd9", - "cpe": "cpe:2.3:a:devops-kung-fu:hookz:v0.0.0-20230413172911-db4e6b370fd9:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/devops-kung-fu/hookz@v0.0.0-20230413172911-db4e6b370fd9", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung_fu:hookz:v0.0.0-20230413172911-db4e6b370fd9:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops-kung:hookz:v0.0.0-20230413172911-db4e6b370fd9:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops_kung:hookz:v0.0.0-20230413172911-db4e6b370fd9:*:*:*:*:*:*:*" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:devops:hookz:v0.0.0-20230413172911-db4e6b370fd9:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goBuildSettings:-buildmode", - "value": "exe" - }, - { - "name": "syft:metadata:goBuildSettings:-compiler", - "value": "gc" - }, - { - "name": "syft:metadata:goBuildSettings:CGO_ENABLED", - "value": "1" - }, - { - "name": "syft:metadata:goBuildSettings:GOAMD64", - "value": "v1" - }, - { - "name": "syft:metadata:goBuildSettings:GOARCH", - "value": "amd64" - }, - { - "name": "syft:metadata:goBuildSettings:GOOS", - "value": "linux" - }, - { - "name": "syft:metadata:goBuildSettings:vcs", - "value": "git" - }, - { - "name": "syft:metadata:goBuildSettings:vcs.modified", - "value": "false" - }, - { - "name": "syft:metadata:goBuildSettings:vcs.revision", - "value": "db4e6b370fd9f9cefe7d83ab890a5515642b0722" - }, - { - "name": "syft:metadata:goBuildSettings:vcs.time", - "value": "2023-04-13T17:29:11Z" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/dustin/go-humanize@v1.0.1?package-id=b40944867301975c", - "type": "library", - "name": "github.com/dustin/go-humanize", - "version": "v1.0.1", - "cpe": "cpe:2.3:a:dustin:go-humanize:v1.0.1:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/dustin/go-humanize@v1.0.1", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:dustin:go_humanize:v1.0.1:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/dustin/go-humanize@v1.0.1?package-id=7ce9a7c269b368b", - "type": "library", - "name": "github.com/dustin/go-humanize", - "version": "v1.0.1", - "cpe": "cpe:2.3:a:dustin:go-humanize:v1.0.1:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/dustin/go-humanize@v1.0.1", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:dustin:go_humanize:v1.0.1:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/gookit/color@v1.5.3?package-id=cfa1335605ae0b3b", - "type": "library", - "name": "github.com/gookit/color", - "version": "v1.5.3", - "cpe": "cpe:2.3:a:gookit:color:v1.5.3:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/gookit/color@v1.5.3", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/gookit/color@v1.5.3?package-id=62beb3c6e151de03", - "type": "library", - "name": "github.com/gookit/color", - "version": "v1.5.3", - "cpe": "cpe:2.3:a:gookit:color:v1.5.3:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/gookit/color@v1.5.3", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/inconshreveable/mousetrap@v1.1.0?package-id=37c82ad2116f18d1", - "type": "library", - "name": "github.com/inconshreveable/mousetrap", - "version": "v1.1.0", - "cpe": "cpe:2.3:a:inconshreveable:mousetrap:v1.1.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/inconshreveable/mousetrap@v1.1.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/jarcoal/httpmock@v1.2.0?package-id=68d78015643b8ffe", - "type": "library", - "name": "github.com/jarcoal/httpmock", - "version": "v1.2.0", - "cpe": "cpe:2.3:a:jarcoal:httpmock:v1.2.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/jarcoal/httpmock@v1.2.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/pmezard/go-difflib@v1.0.0?package-id=1503003a9cee31be", - "type": "library", - "name": "github.com/pmezard/go-difflib", - "version": "v1.0.0", - "cpe": "cpe:2.3:a:pmezard:go-difflib:v1.0.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/pmezard/go-difflib@v1.0.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:cpe23", - "value": "cpe:2.3:a:pmezard:go_difflib:v1.0.0:*:*:*:*:*:*:*" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/segmentio/ksuid@v1.0.4?package-id=15e10b9ca234272c", - "type": "library", - "name": "github.com/segmentio/ksuid", - "version": "v1.0.4", - "cpe": "cpe:2.3:a:segmentio:ksuid:v1.0.4:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/segmentio/ksuid@v1.0.4", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/segmentio/ksuid@v1.0.4?package-id=e0b32445b6d22836", - "type": "library", - "name": "github.com/segmentio/ksuid", - "version": "v1.0.4", - "cpe": "cpe:2.3:a:segmentio:ksuid:v1.0.4:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/segmentio/ksuid@v1.0.4", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/afero@v1.9.5?package-id=afef4efae4a6c52e", - "type": "library", - "name": "github.com/spf13/afero", - "version": "v1.9.5", - "cpe": "cpe:2.3:a:spf13:afero:v1.9.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/afero@v1.9.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/afero@v1.9.5?package-id=220147941213fef", - "type": "library", - "name": "github.com/spf13/afero", - "version": "v1.9.5", - "cpe": "cpe:2.3:a:spf13:afero:v1.9.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/afero@v1.9.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/cobra@v1.7.0?package-id=2304181945444e71", - "type": "library", - "name": "github.com/spf13/cobra", - "version": "v1.7.0", - "cpe": "cpe:2.3:a:spf13:cobra:v1.7.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/cobra@v1.7.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/cobra@v1.7.0?package-id=ea502180bab47d63", - "type": "library", - "name": "github.com/spf13/cobra", - "version": "v1.7.0", - "cpe": "cpe:2.3:a:spf13:cobra:v1.7.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/cobra@v1.7.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/pflag@v1.0.5?package-id=54d28db4ae4c8937", - "type": "library", - "name": "github.com/spf13/pflag", - "version": "v1.0.5", - "cpe": "cpe:2.3:a:spf13:pflag:v1.0.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/pflag@v1.0.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/spf13/pflag@v1.0.5?package-id=3ef36d3dd8dc69d3", - "type": "library", - "name": "github.com/spf13/pflag", - "version": "v1.0.5", - "cpe": "cpe:2.3:a:spf13:pflag:v1.0.5:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/spf13/pflag@v1.0.5", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/stretchr/testify@v1.8.0?package-id=40e3f1e5064cda76", - "type": "library", - "name": "github.com/stretchr/testify", - "version": "v1.8.0", - "cpe": "cpe:2.3:a:stretchr:testify:v1.8.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/stretchr/testify@v1.8.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/xo/terminfo@v0.0.0-20220910002029-abceb7e1c41e?package-id=d3f5ed2384e5d7e5", - "type": "library", - "name": "github.com/xo/terminfo", - "version": "v0.0.0-20220910002029-abceb7e1c41e", - "cpe": "cpe:2.3:a:xo:terminfo:v0.0.0-20220910002029-abceb7e1c41e:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/xo/terminfo@v0.0.0-20220910002029-abceb7e1c41e", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=" - } - ] - }, - { - "bom-ref": "pkg:golang/github.com/xo/terminfo@v0.0.0-20220910002029-abceb7e1c41e?package-id=8b3eed1f16aca468", - "type": "library", - "name": "github.com/xo/terminfo", - "version": "v0.0.0-20220910002029-abceb7e1c41e", - "cpe": "cpe:2.3:a:xo:terminfo:v0.0.0-20220910002029-abceb7e1c41e:*:*:*:*:*:*:*", - "purl": "pkg:golang/github.com/xo/terminfo@v0.0.0-20220910002029-abceb7e1c41e", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/golang.org/x/sys@v0.7.0?package-id=23392771bed0fd11", - "type": "library", - "name": "golang.org/x/sys", - "version": "v0.7.0", - "cpe": "cpe:2.3:a:golang:x\\/sys:v0.7.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/golang.org/x/sys@v0.7.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=" - } - ] - }, - { - "bom-ref": "pkg:golang/golang.org/x/text@v0.9.0?package-id=1f1345074dcf5536", - "type": "library", - "name": "golang.org/x/text", - "version": "v0.9.0", - "cpe": "cpe:2.3:a:golang:x\\/text:v0.9.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/golang.org/x/text@v0.9.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=" - } - ] - }, - { - "bom-ref": "pkg:golang/golang.org/x/text@v0.9.0?package-id=6feb1b850f03ea26", - "type": "library", - "name": "golang.org/x/text", - "version": "v0.9.0", - "cpe": "cpe:2.3:a:golang:x\\/text:v0.9.0:*:*:*:*:*:*:*", - "purl": "pkg:golang/golang.org/x/text@v0.9.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/gopkg.in/yaml.v2@v2.4.0?package-id=bd73a1dddee3e578", - "type": "library", - "name": "gopkg.in/yaml.v2", - "version": "v2.4.0", - "purl": "pkg:golang/gopkg.in/yaml.v2@v2.4.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=" - } - ] - }, - { - "bom-ref": "pkg:golang/gopkg.in/yaml.v2@v2.4.0?package-id=6239bd5dfe00f44b", - "type": "library", - "name": "gopkg.in/yaml.v2", - "version": "v2.4.0", - "purl": "pkg:golang/gopkg.in/yaml.v2@v2.4.0", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-module-binary-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangBinMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "hookz" - }, - { - "name": "syft:metadata:architecture", - "value": "amd64" - }, - { - "name": "syft:metadata:goCompiledVersion", - "value": "go1.20.2" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=" - }, - { - "name": "syft:metadata:mainModule", - "value": "github.com/devops-kung-fu/hookz" - } - ] - }, - { - "bom-ref": "pkg:golang/gopkg.in/yaml.v3@v3.0.1?package-id=c6e1240d23bf190f", - "type": "library", - "name": "gopkg.in/yaml.v3", - "version": "v3.0.1", - "purl": "pkg:golang/gopkg.in/yaml.v3@v3.0.1", - "properties": [ - { - "name": "syft:package:foundBy", - "value": "go-mod-file-cataloger" - }, - { - "name": "syft:package:language", - "value": "go" - }, - { - "name": "syft:package:metadataType", - "value": "GolangModMetadata" - }, - { - "name": "syft:package:type", - "value": "go-module" - }, - { - "name": "syft:location:0:path", - "value": "go.mod" - }, - { - "name": "syft:metadata:h1Digest", - "value": "h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=" - } - ] - } - ] -}