Skip to content

Commit

Permalink
Optimizations (#135)
Browse files Browse the repository at this point in the history
* Simplifies hookz deleter
* Sources can be empty
* Fixes error checking, updated devcontainer
* updates components
* Security fixes and test coverage
* version bump
  • Loading branch information
djschleen authored Mar 1, 2024
1 parent 9f569f9 commit 087a185
Show file tree
Hide file tree
Showing 28 changed files with 275 additions and 1,370 deletions.
73 changes: 68 additions & 5 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -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"
}
6 changes: 6 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
hookz
coverage.out
coverage.html
coverage.lcov

.DS_Store
2 changes: 1 addition & 1 deletion .hookz.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
8 changes: 6 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
]
}
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -276,7 +276,7 @@ hooks:
### NPM

```yaml
version: 2.4.3
version: 2.4.4
hooks:
- type: pre-commit
actions:
Expand Down
26 changes: 10 additions & 16 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Check failure on line 14 in cmd/common.go

View workflow job for this annotation

GitHub Actions / tests

exported function NoConfig should have comment or be unexported

Check failure on line 14 in cmd/common.go

View workflow job for this annotation

GitHub Actions / tests

exported function NoConfig should have comment or be unexported
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

Check failure on line 22 in cmd/common.go

View workflow job for this annotation

GitHub Actions / tests

comment on exported function CheckConfig should be of the form "CheckConfig ..."

Check failure on line 22 in cmd/common.go

View workflow job for this annotation

GitHub Actions / tests

comment on exported function CheckConfig should be of the form "CheckConfig ..."
// 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() {
Expand Down
56 changes: 56 additions & 0 deletions cmd/common_test.go
Original file line number Diff line number Diff line change
@@ -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)

}
10 changes: 9 additions & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion cmd/reset.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"os"

"github.com/devops-kung-fu/common/util"
"github.com/spf13/cobra"

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 087a185

Please sign in to comment.