Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate CLI to use cobra #114

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
af0cdb0
chore: comment out the older cli code
1garo Feb 27, 2024
e35c42d
fix: move version cmd to other file
1garo Feb 27, 2024
78ed1ba
feat: add root command
1garo Feb 27, 2024
2918a69
feat: main file to call cmd.Execute()
1garo Feb 27, 2024
bdd67e1
feat: add cobra to the project
1garo Feb 27, 2024
7ad4826
feat: add flags the way cobra uses it
1garo Feb 27, 2024
d1bf455
feat: refactor to cobra style, seems to be working fine
1garo Feb 27, 2024
bc5123d
chore: default is not 0
1garo Feb 27, 2024
0f5f5e5
chore: add some comments to struct and functions
1garo Feb 27, 2024
e7dd29a
fix: refactor some of the functions
1garo Feb 28, 2024
c6cb3d3
feat(WIP): re-add tests
1garo Feb 28, 2024
6de0733
chore: remove old testing file
1garo Feb 29, 2024
36594c5
feat: add version cmd tests
1garo Feb 29, 2024
7550f12
feat: uncomment and fix other tests
1garo Feb 29, 2024
f2b2242
chore: run gofmt and remove comment
1garo Mar 8, 2024
21c4071
Merge branch 'main' into feat/migrate-to-cobra
1garo Apr 3, 2024
58a6988
chore: merge main
1garo Apr 3, 2024
7e1b9c5
chore: add quiet flag
1garo Apr 3, 2024
923d911
Update Dockerfile
1garo Apr 12, 2024
d581599
Update Dockerfile
1garo Apr 12, 2024
a561a84
Merge branch 'main' into feat/migrate-to-cobra
1garo Apr 12, 2024
66b4a3b
fix: do some cleanup after merge
1garo Apr 12, 2024
8a5c705
fix: properly resolve conflicts of last merge
1garo Apr 12, 2024
a9dddfe
chore: change from cmd/validator to main.go target
1garo Apr 12, 2024
08f83f6
chore: go mod tidy to update new deps
1garo Apr 12, 2024
4d73a9f
fix: add search_path as positional argument
1garo Apr 12, 2024
541f6f9
fix: add back quiet flag and update tests
1garo Apr 12, 2024
dad9045
chore: update readme target to main.go instead of cmd/validator.go
1garo Apr 12, 2024
e220a4a
chore: lint
1garo Apr 12, 2024
d78ef64
fix: update usage to cobra format and commands to use `--`
1garo Apr 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
go-version: '1.21'

- name: Download dependencies
run: go mod download
Expand All @@ -34,7 +34,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
go-version: '1.21'

- name: Static Analysis
run: go vet ./...
Expand All @@ -51,7 +51,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
go-version: '1.21'

- name: Build
run: |
Expand All @@ -72,7 +72,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
go-version: '1.21'

- name: Unit test
run: go test -v -cover -coverprofile coverage.out ./...
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
go_version: 1.22
go_version: 1.21
binary_name: "validator"
ldflags: -w -s -extldflags "-static" -X github.com/Boeing/config-file-validator.version=${{ github.event.release.tag_name }}
build_tags: -tags netgo
Expand All @@ -46,7 +46,7 @@ jobs:
strategy:
matrix:
include:
- base: "alpine:3.19"
- base: "alpine:3.18"
postfix: ""
- base: "scratch"
postfix: "-scratch"
Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ We welcome contributions! We want to make contributing to this project as easy a
- Submitting a fix
- Proposing new features

## We Develop with GitHub
We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.
## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull requests.

## We Use [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow)). We actively welcome your pull requests:
## We Use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow)). We actively welcome your pull requests:

1. Fork the repository and create your branch from `main`.
1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. Ensure the test suite passes.
4. Submit that pull request!

## Report bugs using GitHub's [issues](https://github.com/boeing/config-file-validator/issues)
## Report bugs using Github's [issues](https://github.com/boeing/config-file-validator/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/Boeing/config-file-validator/issues/new);
4 changes: 2 additions & 2 deletions Dockerfile
1garo marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG BASE_IMAGE=alpine:3.19
ARG BASE_IMAGE=alpine:3.18
1garo marked this conversation as resolved.
Show resolved Hide resolved

FROM golang:1.22 as go-builder
FROM golang:1.21 as go-builder
1garo marked this conversation as resolved.
Show resolved Hide resolved
ARG VALIDATOR_VERSION=unknown
COPY . /build/
WORKDIR /build
Expand Down
2 changes: 1 addition & 1 deletion PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Maintainer: Clayton Kehoe <118750525+kehoecj@users.noreply.github.com>
# Author : wiz64 <wiz64.com>
pkgname=config-file-validator
pkgver=1.6.0
pkgver=1.5.0
1garo marked this conversation as resolved.
Show resolved Hide resolved
pkgrel=1
pkgdesc="A tool to validate the syntax of configuration files"
arch=('x86_64')
Expand Down
75 changes: 23 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@
</div>

<p align="center">
<img id="cov" src="https://img.shields.io/badge/Coverage-95.2%25-brightgreen" alt="Code Coverage">
<img id="cov" src="https://img.shields.io/badge/Coverage-95.3%25-brightgreen" alt="Code Coverage">

<a href="https://opensource.org/licenses/Apache-2.0">
<img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="Apache 2 License">
</a>

<a href="https://github.com/avelino/awesome-go">
<img src="https://awesome.re/mentioned-badge.svg" alt="Awesome Go">
</a>

<a href="https://pkg.go.dev/github.com/Boeing/config-file-validator">
<img src="https://pkg.go.dev/badge/github.com/Boeing/config-file-validator.svg" alt="Go Reference">
</a>
Expand All @@ -31,9 +27,7 @@
## Supported config files formats:
* Apple PList XML
* CSV
* ENV
* HCL
* HOCON
* INI
* JSON
* Properties
Expand All @@ -50,24 +44,24 @@ There are several ways to install the config file validator tool

### Docker

We offer Alpine, Ubuntu, and Scratch containers
We offer alpine, ubuntu, and scratch containers
1garo marked this conversation as resolved.
Show resolved Hide resolved

#### Alpine

```
docker pull ghcr.io/boeing/config-file-validator:v1.6.0
docker pull ghcr.io/boeing/config-file-validator:v1.5.0
1garo marked this conversation as resolved.
Show resolved Hide resolved
```

#### Ubuntu

```
docker pull ghcr.io/boeing/config-file-validator-ubuntu:v1.6.0
docker pull ghcr.io/boeing/config-file-validator-ubuntu:v1.5.0
1garo marked this conversation as resolved.
Show resolved Hide resolved
```

#### Scratch

```
docker pull ghcr.io/boeing/config-file-validator-scratch:v1.6.0
docker pull ghcr.io/boeing/config-file-validator-scratch:v1.5.0
1garo marked this conversation as resolved.
Show resolved Hide resolved
```

### Binary Releases
Expand All @@ -92,15 +86,15 @@ makepkg -si
If you have a go environment on your desktop you can use [go install](https://go.dev/doc/go-get-install-deprecation) to install the validator executable. The validator executable will be installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set.

```
go install github.com/Boeing/config-file-validator/cmd/validator@v1.6.0
go install github.com/Boeing/config-file-validator/cmd/validator@v1.5.0
1garo marked this conversation as resolved.
Show resolved Hide resolved
```

## Usage
```
Usage: validator [OPTIONS] [<search_path>...]

positional arguments:
search_path: The search path on the filesystem for configuration files. Defaults to the current working directory if no search_path provided
search_path: The search path on the filesystem for configuration files. Defaults to the current working directory if no search_path provided. Multiple search paths can be declared separated by a space.

optional flags:
-depth int
Expand All @@ -109,12 +103,10 @@ optional flags:
Subdirectories to exclude when searching for configuration files
-exclude-file-types string
A comma separated list of file types to ignore
-groupby string
Group output by filetype, directory, pass-fail. Supported for Standard and JSON reports
-output string
Destination to a file to output results
-quiet
1garo marked this conversation as resolved.
Show resolved Hide resolved
If quiet flag is set. It doesn't print any output to stdout.
Destination to a file to output results
-groupby string
Group the output by filetype, pass-fail, or directory. Supported Reporters are Standard and JSON
-reporter string
Format of the printed report. Options are standard and json (default "standard")
-version
Expand All @@ -131,7 +123,7 @@ validator /path/to/search
![Standard Run](./img/standard_run.png)

#### Multiple search paths
Multiple search paths are supported, and the results will be merged into a single report
Multiple search paths are supported and the results will be merged into a single report
```
validator /path/to/search /another/path/to/search
```
Expand All @@ -148,7 +140,7 @@ validator --exclude-dirs=/path/to/search/tests /path/to/search
![Exclude Dirs Run](./img/exclude_dirs.png)

#### Exclude file types
Exclude file types in the search path. Available file types are `csv`, `env`, `hcl`, `hocon`, `ini`, `json`, `plist`, `properties`, `toml`, `xml`, `yaml`, and `yml`
Exclude file types in the search path. Available file types are `csv`, `hcl`, `ini`, `json`, `plist`, `properties`, `toml`, `xml`, `yaml`, and `yml`
1garo marked this conversation as resolved.
Show resolved Hide resolved

```
validator --exclude-file-types=json /path/to/search
Expand All @@ -166,55 +158,39 @@ validator --depth=0 /path/to/search
![Custom Recursion Run](./img/custom_recursion.png)

#### Customize report output
Customize the report output. Available options are `standard`, `junit`, and `json`
Customize the report output. Available options are `standard` and `json`
1garo marked this conversation as resolved.
Show resolved Hide resolved

```
validator --reporter=json /path/to/search
```

![Exclude File Types Run](./img/custom_reporter.png)

### Group report output
Group the report output by file type, directory, or pass-fail. Supports one or more groupings.

```
validator -groupby filetype
```

![Groupby File Type](./img/gb-filetype.png)

#### Multiple groups
```
validator -groupby directory,pass-fail
```

![Groupby File Type and Pass/Fail](./img/gb-filetype-and-pass-fail.png)

### Output results to a file
Output report results to a file (default name is `result.{extension}`). Must provide reporter flag with a supported extension format. Available options are `junit` and `json`. If an existing directory is provided, create a file named default name in the given directory. If a file name is provided, create a file named the given name at the current working directory.

#### Output results to a file
Output report results to a file (default name is `result.{extension}`). Must provide reporter flag with a supported extension format (Available option is `json`). If an existing directory is provided, create a file named default name in the given directory. If a file name is provided, create a file named the given name at the current working directory.
```
validator --reporter=json --output=/path/to/dir
```

### Suppress output
Passing the `--quiet` flag suppresses all output to stdout. If there are invalid config files the validator tool will exit with 1. Any errors in execution such as an invalid path will still be displayed.
### Group report output
Group the report output by file type, directory, or pass-fail. Supports one or more groupings.

```
validator --quiet /path/to/search
validator -groupby filetype
validator -groupby directory,pass-fail
```

#### Container Run
```
docker run -it --rm -v /path/to/config/files:/test config-file-validator:1.6.0 /test
docker run -it --rm -v /path/to/config/files:/test config-file-validator:1.5.0 /test
```

![Docker Standard Run](./img/docker_run.png)

## Build
The project can be downloaded and built from source using an environment with Go 1.21+ installed. After a successful build, the binary can be moved to a location on your operating system PATH.
The project can be downloaded and built from source using an environment with golang 1.21 installed. After a successful build, the binary can be moved to a location on your operating system PATH.

### macOS
### MacOS
#### Build
```
CGO_ENABLED=0 \
Expand Down Expand Up @@ -276,14 +252,9 @@ cp .\validator.exe 'C:\Program Files\validator'
You can also use the provided Dockerfile to build the config file validator tool as a container

```
docker build . -t config-file-validator:v1.6.0
docker build . -t config-file-validator:v1.5.0
```

## Contributors
<a href="https://github.com/Boeing/config-file-validator/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Boeing/config-file-validator" />
</a>

## Contributing
We welcome contributions! Please refer to our [contributing guide](/CONTRIBUTING.md)

Expand Down
26 changes: 26 additions & 0 deletions cmd/validator/commands/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
validator "github.com/Boeing/config-file-validator/cmd/validator"
"github.com/spf13/cobra"
)

func CmdFlags(cmd *cobra.Command) {
cmd.PersistentFlags().
IntVar(&validator.Flags.Depth, "depth", 0, "Depth of recursion for the provided search paths. Set depth to 0 to disable recursive path traversal.")
cmd.PersistentFlags().
StringVar(&validator.Flags.ExcludeDirs, "exclude-dirs", "", "Subdirectories to exclude when searching for configuration files")
cmd.PersistentFlags().
StringVar(&validator.Flags.ExcludeFileTypes, "exclude-file-types", "", "A comma separated list of file types to ignore")
cmd.PersistentFlags().StringVar(&validator.Flags.Output, "output", "", "Destination to a file to output results")
cmd.PersistentFlags().
StringVar(&validator.Flags.ReportType, "reporter", "standard", "Format of the printed report. Options are standard and json")
cmd.PersistentFlags().
StringVar(&validator.Flags.GroupOutput, "groupby", "", "Group output by filetype, directory, pass-fail. Supported for Standard and JSON reports")
cmd.PersistentFlags().
StringVar(&validator.Flags.SearchPath, "search_path", ".", "search_path: The search path on the filesystem for configuration files. Defaults to the current working directory if no search_path provided.")
}

func init() {
CmdFlags(rootCmd)
}
68 changes: 68 additions & 0 deletions cmd/validator/commands/flags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package cmd

import (
"bytes"
"fmt"
"strings"
"testing"

cmd "github.com/Boeing/config-file-validator/cmd/validator"
"github.com/spf13/cobra"
)

func ExecuteTestHelper(t *testing.T, c *cobra.Command, args ...string) (string, error) {
t.Helper()

buf := new(bytes.Buffer)
c.SetOut(buf)
c.SetErr(buf)
c.SetArgs(args)

err := c.Execute()
return strings.TrimSpace(buf.String()), err
}

func Test_flags(t *testing.T) {
// We manipulate the Args to set them up for the testcases
cases := []struct {
Name string
Args []string
ExpectedExit int
}{
{"blank", []string{}, 0},
{"negative depth set", []string{"--depth", "-1", "--reporter", "standard"}, 1},
{"flags set, wrong reporter", []string{"--exclude-dirs", "subdir", "--reporter", "wrong"}, 1},
{"flags set, json reporter", []string{"--exclude-dirs", "subdir", "--reporter", "json"}, 0},
{"flags set, junit reported", []string{"--exclude-dirs", "subdir", "--reporter", "junit"}, 0},
{"bad path", []string{"--search_path", "/path/does/not/exit"}, 1},
//{"exclude file types set", []string{"--exclude-file-types", "json"}, 0},
{"multiple paths", []string{"../../../test/fixtures/subdir/good.json", "../../../test/fixtures/good.json"}, 0},
{"output set", []string{"--output", "../../../test/output", "--reporter", "json"}, 0},
{"empty string output set", []string{"--output", "", "--reporter", "json", "."}, 0},
{"wrong output set", []string{"--output", "/path/not/exist", "--reporter", "json", "."}, 1},
{"incorrect group", []string{"--groupby", "badgroup"}, 1},
{"correct group", []string{"--groupby", "directory"}, 0},
}

var exitStatus int

for _, tc := range cases {
fmt.Printf("Testing args: %v = %v\n", tc.Name, tc.Args)
root := &cobra.Command{
Use: "root",
Run: func(c *cobra.Command, args []string) {
exitStatus = cmd.ExecRoot(c)
},
}
CmdFlags(root)

_, err := ExecuteTestHelper(t, root, tc.Args...)
if err != nil {
t.Error(err)
}

if tc.ExpectedExit != exitStatus {
t.Errorf("Wrong exit code, expected: %v, got: %v", tc.ExpectedExit, exitStatus)
}
}
}
Loading