Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: imunhatep/gotpl-yaml-linter
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.1.1
Choose a base ref
...
head repository: imunhatep/gotpl-yaml-linter
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 8 commits
  • 13 files changed
  • 2 contributors

Commits on Mar 4, 2024

  1. fix producing artifacts (#3)

    Co-authored-by: Artyom Suharev <asuharevs@evolution.com>
    imunhatep and Artyom Suharev authored Mar 4, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    9d208fa View commit details
  2. update help text for commands (#4)

    Co-authored-by: Artyom Suharev <asuharevs@evolution.com>
    imunhatep and Artyom Suharev authored Mar 4, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    de58cd8 View commit details

Commits on Apr 30, 2024

  1. - update base docker iamges

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    85c47cf View commit details
  2. fixed handling of closing structure without proper opening

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    7dded6c View commit details
  3. add argument to output build version

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    415c261 View commit details
  4. add 'define' as an opening structure

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    e0af862 View commit details
  5. add handling for 'else' control structure

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    77a4e08 View commit details
  6. add handling for 'print' as non-control structure

    Artyom Suharev committed Apr 30, 2024
    Copy the full SHA
    223b285 View commit details
Showing with 117 additions and 584 deletions.
  1. +23 −9 README.md
  2. +5 −5 build/{cli → gotpl-linter}/Dockerfile
  3. +1 −1 build/test/Dockerfile
  4. +15 −16 cmd/gotpl-linter/main.go
  5. +2 −20 go.mod
  6. +1 −470 go.sum
  7. +18 −31 golang.mk
  8. +39 −24 internal/app/yamltpl.go
  9. +8 −4 internal/application.go
  10. +1 −1 internal/commands/format.go
  11. +2 −2 internal/commands/lint.go
  12. +0 −1 resource/test1.yaml
  13. +2 −0 resource/test7.yaml
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# GoTemplate linting for yaml (Helm) files
This tool will list files based on the provided criteria and format them if specified with options.

## How to install
Use go install command, i.e.:
```bash
go install github.com/imunhatep/gotpl-yaml-linter/cmd/gotpl-linter@latest

gotpl-linter --help
```

Project built using go1.22

## How to Run
Linter tool supports to commands:
- lint
@@ -10,22 +20,26 @@ Linter tool supports to commands:
gotpl-yaml-linter help

NAME:
yamltpl_linter - GoLang template for yaml formatting and linting tool
gotpl-linter - GoLang template for yaml formatting and linting tool

USAGE:
bin/yamltpl_linter_{os}-{arch} [command] [subcommand] [command options]
gotpl-linter [command] [subcommand] [command options]

VERSION:
v1.2.0

DESCRIPTION:
https://github.com/imunhatep/gotpl-yaml-linter/README.md

COMMANDS:
fmt yaml tpl format
lint yaml tpl linting
lint yaml gotpl linting
help, h Shows a list of commands or help for one command

GLOBAL OPTIONS:
--verbose value, -v value Log verbosity (default: 3) [$APP_DEBUG]
--help, -h show help
--verbose value, --vv value Log verbosity (default: 3) [$APP_DEBUG]
--help, -h show help
--version, -v print the version
```


@@ -39,7 +53,7 @@ NAME:
yamltpl_linter lint - yaml tpl linting

USAGE:
Example: bin/yamltpl_{os}-{arch} -v 10 lint --path ./templates/ --filter *.yaml
Example: bin/yamltpl_{os}-{arch} -vv 10 lint -p ./templates/ -f *.yaml

OPTIONS:
--path value, -p value path to go tpl files (default: ./)
@@ -53,13 +67,13 @@ OPTIONS:
Executing format command will update file contents in place.

```bash
gotpl-yaml-linter fmt help
gotpl-linter fmt help

NAME:
yamltpl_linter fmt - yaml tpl format
gotpl-linter fmt - yaml tpl format

USAGE:
Example: bin/yamltpl_{os}-{arch} -v 10 fmt --path ./templates/ --filter *.yaml
Example: gotpl-linter -vv 10 fmt -p ./templates/ -f *.yaml

OPTIONS:
--path value, -p value path to go tpl files (default: ./)
10 changes: 5 additions & 5 deletions build/cli/Dockerfile → build/gotpl-linter/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM hub.rms.evolutiongaming.com/hub/golang:1.22.0-alpine3.19 AS builder
FROM golang:1.22.2-alpine3.19 AS builder

ARG TARGETPLATFORM
ARG TARGETOS
@@ -15,21 +15,21 @@ ADD . /project/
WORKDIR /project/

RUN mkdir -p ./bin \
&& env GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o ./bin/yamltpl_linter_${TARGETOS}-${TARGETARCH} -ldflags "-s -w" ./cmd/cli/main.go
&& env GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o ./bin/gotpl_linter_${TARGETOS}-${TARGETARCH} -ldflags "-s -w" ./cmd/gotpl-linter/main.go

FROM hub.rms.evolutiongaming.com/hub/alpine:3.19

RUN apk add --update bash ca-certificates curl

ENV GOMEMLIMIT=256MiB

COPY --from=builder /project/bin/yamltpl_linter_${TARGETOS}-${TARGETARCH} /usr/bin/yamltpl_linter
COPY --from=builder /project/bin/gotpl_linter_${TARGETOS}-${TARGETARCH} /usr/bin/gotpl_linter

RUN chmod +x /usr/bin/yamltpl_lint \
RUN chmod +x /usr/bin/gotpl_lint \
&& adduser -D service

USER service
WORKDIR /home/service

CMD ["yamltpl_linter", "lint"]
CMD ["gotpl_linter", "lint"]
ENTRYPOINT []
2 changes: 1 addition & 1 deletion build/test/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM hub.rms.evolutiongaming.com/hub/golang:1.22.0-alpine3.19
FROM golang:1.22.2-alpine3.19

ARG TARGETPLATFORM
ARG TARGETOS
31 changes: 15 additions & 16 deletions cmd/gotpl-linter/main.go
Original file line number Diff line number Diff line change
@@ -2,30 +2,29 @@ package main

import (
"context"
"github.com/cybozu-go/well"
"github.com/imunhatep/gotpl-yaml-linter/internal"
command "github.com/imunhatep/gotpl-yaml-linter/internal/commands"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
"os"
)

func main() {
well.Go(func(ctx context.Context) error {
app := internal.NewApp()
app.Commands = []*cli.Command{
command.FormatCommand{}.Command(),
command.LintCommand{}.Command(),
}
var (
BuildVersion = "development"

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported

Check failure on line 13 in cmd/gotpl-linter/main.go

GitHub Actions / CI Build

exported var BuildVersion should have comment or be unexported
)

err := app.RunContext(ctx, os.Args)
if err != nil {
log.Error().Err(err).Msg("yaml tpl linting failed")
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

return err
})
app := internal.NewApp(BuildVersion)
app.Commands = []*cli.Command{
command.FormatCommand{}.Command(),
command.LintCommand{}.Command(),
}

well.Stop()
well.Wait()
err := app.RunContext(ctx, os.Args)
if err != nil {
log.Error().Err(err).Msg("yaml tpl linting failed")
}
}
22 changes: 2 additions & 20 deletions go.mod
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ module github.com/imunhatep/gotpl-yaml-linter
go 1.22.0

require (
github.com/cybozu-go/well v1.11.2
github.com/rs/zerolog v1.32.0
github.com/stretchr/testify v1.8.1
github.com/urfave/cli/v2 v2.27.1
@@ -12,30 +11,13 @@ require (

require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cybozu-go/log v1.7.0 // indirect
github.com/cybozu-go/netutil v1.4.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/onsi/gomega v1.25.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
github.com/vishvananda/netns v0.0.3 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)
471 changes: 1 addition & 470 deletions go.sum

Large diffs are not rendered by default.

49 changes: 18 additions & 31 deletions golang.mk
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
# Source: https://github.com/rebuy-de/golang-template

TARGETS?="./cmd/gotpl-linter"
TARGET?="./cmd/gotpl-linter"
PACKAGE=$(shell GOPATH= go list $(TARGET))
NAME=$(notdir $(shell echo $(PACKAGE) | sed 's/\/v2//'))
NAME=$(shell echo $(PACKAGE) | awk -F "/" '{print $$NF}')

BUILD_VERSION=$(shell git describe --always --dirty --tags | tr '-' '.' )
BUILD_DATE=$(shell LC_ALL=C date)
BUILD_HASH=$(shell git rev-parse HEAD)
BUILD_MACHINE=$(shell uname -n)
BUILD_USER=$(shell whoami)
BUILD_ENVIRONMENT=$(BUILD_USER)@$(BUILD_MACHINE)

BUILD_XDST=$(PACKAGE)/cmd
#BUILD_XDST=$(NAME)
BUILD_XDST=main
BUILD_FLAGS=-ldflags "\
$(ADDITIONAL_LDFLAGS) -s -w \
-X '$(BUILD_XDST).BuildVersion=$(BUILD_VERSION)' \
-X '$(BUILD_XDST).BuildDate=$(BUILD_DATE)' \
-X '$(BUILD_XDST).BuildHash=$(BUILD_HASH)' \
-X '$(BUILD_XDST).BuildEnvironment=$(BUILD_ENVIRONMENT)' \
"

GOFILES=$(shell find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./.git/*")
GOPKGS=$(shell go list ./...)
GOPKGS=$(shell go list ./cmd/...)

OUTPUT_FILE=$(NAME)-$(BUILD_VERSION)-$(shell go env GOOS)-$(shell go env GOARCH)$(shell go env GOARM)$(shell go env GOEXE)
OUTPUT_LINK=$(NAME)$(shell go env GOEXE)
@@ -36,58 +31,50 @@ vendor: go.mod go.sum
format:
gofmt -s -w $(GOFILES)

vet: go_generate vendor
vet: vendor
go vet $(GOPKGS)

lint:
$(foreach pkg,$(GOPKGS),golint $(pkg);)

go_generate:
rm -rvf mocks
go generate ./...

test_packages: go_generate vendor
test_packages: vendor
go test $(GOPKGS)

test_format:
gofmt -s -l $(GOFILES)

test: test_format vet lint test_packages

cov: go_generate
cov:
gocov test -v $(GOPKGS) \
| gocov-html > coverage.html

_build: vendor
mkdir -p dist
$(foreach TARGET,$(TARGETS),go build \
$(BUILD_FLAGS) \
-o dist/$(OUTPUT_FILE) \
$(TARGET);\
)
go build $(BUILD_FLAGS) -o dist/$(OUTPUT_FILE) $(TARGET);

build: go_generate _build
build: _build
$(foreach TARGET,$(TARGETS),ln -sf $(OUTPUT_FILE) dist/$(OUTPUT_LINK);)

compress: _build
ifeq ($(GOOS),windows)
zip -j dist/$(WINDOWS_ZIP) dist/$(OUTPUT_FILE)
else
tar czf dist/$(OUTPUT_FILE).tar.gz -C dist $(OUTPUT_FILE)
endif
rm -f dist/$(OUTPUT_FILE)

xc: go_generate
xc:
GOOS=linux GOARCH=amd64 make compress
GOOS=linux GOARCH=arm64 make compress
GOOS=linux GOARCH=arm GOARM=7 make compress
GOOS=darwin GOARCH=amd64 make compress
GOOS=darwin GOARCH=arm64 make compress
GOOS=windows GOARCH=amd64 make compress

install: test
$(foreach TARGET,$(TARGETS),go install \
$(BUILD_FLAGS);)
xb:
GOOS=linux GOARCH=amd64 make build
GOOS=linux GOARCH=arm64 make build
GOOS=linux GOARCH=arm GOARM=7 make build
GOOS=darwin GOARCH=amd64 make build
GOOS=darwin GOARCH=arm64 make build
GOOS=windows GOARCH=amd64 make build

clean:
rm dist/ -rvf
63 changes: 39 additions & 24 deletions internal/app/yamltpl.go
Original file line number Diff line number Diff line change
@@ -8,47 +8,36 @@ import (
"strings"
)

var controlStructureStart = regexp.MustCompile(`^{{-?\s*(if|range|with)\s`)
var controlStructureStart = regexp.MustCompile(`^{{-?\s*(if|range|with|define)\s`)
var controlStructureContinue = regexp.MustCompile(`^{{-?\s*(else)\s`)
var controlStructureEnd = regexp.MustCompile(`^{{-?\s*end\s*-?}}`)
var nonControlStructure = regexp.MustCompile(`^{{-?\s*(include|toYaml|nindent)\s`)

func formatLine(line string, indentLevel int) string {
// Remove leading spaces to reset indentation
trimmedLine := strings.TrimLeft(line, " ")
return strings.Repeat(" ", indentLevel) + trimmedLine
}

func isStartControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return controlStructureStart.MatchString(lineWithoutLeadingSpaces)
}

func isEndControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return controlStructureEnd.MatchString(lineWithoutLeadingSpaces)
}

func isNonControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return nonControlStructure.MatchString(lineWithoutLeadingSpaces)
}
var nonControlStructure = regexp.MustCompile(`^{{-?\s*(include|toYaml|nindent|print)\s`)

// FormatYamlTpl formats a yaml template string
func FormatYamlTpl(yamlTpl string) (string, error) {
lines := strings.Split(yamlTpl, "\n")

indentLevel := 0
var formattedLines []string
for _, line := range lines {
for i, line := range lines {
trimmed := strings.TrimSpace(strings.Replace(line, "\t", "\n", -1))
if isStartControlStructure(trimmed) {
formattedLines = append(formattedLines, formatLine(line, indentLevel))
indentLevel++
} else if isContinueControlStructure(trimmed) {
formattedLines = append(formattedLines, formatLine(line, indentLevel-1))
} else if isNonControlStructure(trimmed) {
// Non-control structures and empty lines are indented according to their current block level
formattedLines = append(formattedLines, formatLine(line, indentLevel))
} else if isEndControlStructure(trimmed) {
// End control structures are indented according to their current block level
indentLevel--

if indentLevel < 0 {
indentLevel = 0
log.Warn().Msgf("Seems closing structure has no opening. Invalid gotpl structure at line ~%d: %s", i, line)
}

formattedLines = append(formattedLines, formatLine(line, indentLevel))
} else {
// Regular lines that are not control structures or non-control structures are treated as text
@@ -97,3 +86,29 @@ func FormatYamlTplFile(file string, format, output bool) (bool, error) {

return true, nil
}

func formatLine(line string, indentLevel int) string {
// Remove leading spaces to reset indentation
trimmedLine := strings.TrimLeft(line, " ")
return strings.Repeat(" ", indentLevel) + trimmedLine
}

func isStartControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return controlStructureStart.MatchString(lineWithoutLeadingSpaces)
}

func isContinueControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return controlStructureContinue.MatchString(lineWithoutLeadingSpaces)
}

func isEndControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return controlStructureEnd.MatchString(lineWithoutLeadingSpaces)
}

func isNonControlStructure(line string) bool {
lineWithoutLeadingSpaces := strings.TrimSpace(line)
return nonControlStructure.MatchString(lineWithoutLeadingSpaces)
}
12 changes: 8 additions & 4 deletions internal/application.go
Original file line number Diff line number Diff line change
@@ -4,15 +4,17 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
"os"
)

// NewApp application entrypoint
func NewApp() *cli.App {
func NewApp(version string) *cli.App {
cmd := cli.NewApp()
cmd.EnableBashCompletion = true
cmd.Name = "yamltpl_linter"
cmd.Version = version
cmd.Name = "gotpl-linter"
cmd.Usage = "GoLang template for yaml formatting and linting tool"
cmd.UsageText = "bin/yamltpl_linter_{os}-{arch} [command] [subcommand] [command options]"
cmd.UsageText = "gotpl-linter [command] [subcommand] [command options]"
cmd.Description = "https://github.com/imunhatep/gotpl-yaml-linter/README.md"
cmd.Before = func(ctx *cli.Context) error {
verbose := ctx.Int("verbose")
@@ -23,7 +25,7 @@ func NewApp() *cli.App {
cmd.Flags = []cli.Flag{
&cli.IntFlag{
Name: "verbose",
Aliases: []string{"v"},
Aliases: []string{"vv"},
EnvVars: []string{"APP_DEBUG"},
Usage: "Log verbosity",
Required: false,
@@ -35,6 +37,8 @@ func NewApp() *cli.App {
}

func setLogLevel(level int) {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})

switch level {
case 0:
zerolog.SetGlobalLevel(zerolog.FatalLevel)
2 changes: 1 addition & 1 deletion internal/commands/format.go
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ func (c FormatCommand) Command() *cli.Command {
return &cli.Command{
Name: "fmt",
Usage: "yaml tpl format ",
UsageText: "Example: bin/yamltpl_{os}-{arch} -v 10 fmt --path ./templates/ --filter *.yaml",
UsageText: "Example: gotpl_linter -v 10 fmt --path ./templates --filter *.yaml",
Flags: []cli.Flag{
&cli.PathFlag{
Name: "path",
4 changes: 2 additions & 2 deletions internal/commands/lint.go
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ type LintCommand struct{}
func (c LintCommand) Command() *cli.Command {
return &cli.Command{
Name: "lint",
Usage: "yaml tpl linting",
UsageText: "Example: bin/yamltpl_{os}-{arch} -v 10 lint --path ./templates/ --filter *.yaml",
Usage: "yaml gotpl linting",
UsageText: "Example: gotpl_linter -v 10 lint --path ./templates --filter *.yaml",
Flags: []cli.Flag{
&cli.PathFlag{
Name: "path",
1 change: 0 additions & 1 deletion resource/test1.yaml
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ metadata:
{{- if .Values.controller.annotations }}
annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
{{- end }}
{{- end }}
spec:
selector:
matchLabels:
2 changes: 2 additions & 0 deletions resource/test7.yaml
Original file line number Diff line number Diff line change
@@ -14,4 +14,6 @@ metadata:
{{- if .Values.controller.annotations }}
annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
{{- end }}
{{- end }}
# end of structure without opening
{{- end }}