feat: add concourse pipeline
All checks were successful
concourse-ci/golangci-lint golangci-lint run
concourse-ci/gotestsum gotestsum

This commit is contained in:
Peter 2022-09-27 20:19:27 +00:00 committed by Peter Kurfer
parent a245fd3cbc
commit 59d2d26984
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
18 changed files with 453 additions and 67 deletions

View file

@ -0,0 +1,42 @@
---
resource_types:
- name: git-branches
type: registry-image
source:
repository: aoldershaw/git-branches-resource
resources:
- name: feature-branches
type: git-branches
source:
uri: https://code.icb4dc0.de/prskr/nurse.git
# The "(?P<name>pattern)" syntax defines a named capture group.
# aoldershaw/git-branches-resource emits the value of each named capture
# group under the `groups` key.
#
# e.g. feature/some-feature ==> {"groups": {"feature": "some-feature"}}
branch_regex: '(\d+-|\w+\/|\w+\(\w+\):\s*)(?P<feature>.*)'
- name: nurse.git
type: git
icon: github
source:
uri: https://code.icb4dc0.de/prskr/nurse.git
fetch_tags: true
jobs:
- name: set-feature-pipelines
plan:
- in_parallel:
- get: feature-branches
trigger: true
- get: nurse.git
- load_var: branches
file: feature-branches/branches.json
- across:
- var: branch
values: ((.:branches))
set_pipeline: nurse-dev
file: nurse.git/.concourse/branch-validate.yml
instance_vars: {feature: ((.:branch.groups.feature))}
vars: {branch: ((.:branch.name))}

View file

@ -0,0 +1,17 @@
---
resources:
- name: nurse.git
type: git
icon: github
source:
uri: https://code.icb4dc0.de/prskr/nurse.git
branch: ((branch))
jobs:
- name: lint
plan:
- get: nurse.git
trigger: true
- task: lint
file: nurse.git/.concourse/tasks/lint.yml
input_mapping: {repo: nurse.git}

31
.concourse/cleanup.yml Normal file
View file

@ -0,0 +1,31 @@
---
resources:
- name: daily
type: time
source:
interval: 24h
- name: nurse.git
type: git
icon: github
source:
uri: https://code.icb4dc0.de/prskr/nurse.git
- name: templates.git
type: git
icon: github
source:
uri: https://code.icb4dc0.de/prskr/pipeline-templates.git
jobs:
- name: renovate
plan:
- get: nurse.git
trigger: true
- get: templates.git
trigger: true
- get: daily
trigger: true
- task: renovate
file: templates.git/tasks/renovate.yml
input_mapping: {repo: nurse.git}
vars:
project_path: prskr/nurse

27
.concourse/tasks/lint.yml Normal file
View file

@ -0,0 +1,27 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: docker.io/golang:1.19-bullseye
tag: latest
inputs:
- name: repo
path: .
params:
GO111MODULE: "on"
CGO_ENABLED: "0"
GITEA_TOKEN: ((gitea-credentials.token))
DOCKER_HOST: tcp://127.0.0.1:2375
run:
path: sh
args:
- -ce
- |
apk add -U --no-cache curl
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin
go run github.com/magefile/mage lint

1
.gitignore vendored
View file

@ -16,5 +16,6 @@
dist/
.idea/
.fleet/
cue.mod/
.go/

View file

@ -72,7 +72,7 @@ linters:
- funlen
- gocognit
- goconst
- gocritic
# - gocritic
- gocyclo
- godox
- gofumpt
@ -80,10 +80,11 @@ linters:
- gomoddirectives
- gomnd
- gosec
# - gosimple
- gosimple
- govet
- importas
- ineffassign
# - ireturn - enable later
- lll
- misspell
- nakedret
@ -91,17 +92,15 @@ linters:
- nilnil
- noctx
- nolintlint
- nosprintfhostport
- paralleltest
- prealloc
- predeclared
- promlinter
# - staticcheck
# - stylecheck
- tenv
- staticcheck
- stylecheck
- testpackage
- thelper
- typecheck
# - typecheck
- unconvert
- unparam
- whitespace
@ -118,6 +117,11 @@ issues:
- gocognit
- gomnd
- govet
- path: magefiles/.*\.go
linters:
- typecheck
- unused
- govet
run:
skip-files:

View file

@ -26,5 +26,4 @@ func (c CheckHandler) ServeHTTP(writer http.ResponseWriter, request *http.Reques
}
writer.WriteHeader(http.StatusOK)
return
}

View file

@ -3,7 +3,7 @@ package config
import (
"os"
"path"
. "strings"
"strings"
)
const (
@ -14,16 +14,16 @@ const (
func ServersFromEnv() (map[string]Server, error) {
servers := make(map[string]Server)
for _, kv := range os.Environ() {
key, value, valid := Cut(kv, "=")
key, value, valid := strings.Cut(kv, "=")
if !valid {
continue
}
if !HasPrefix(key, ServerKeyPrefix) {
if !strings.HasPrefix(key, ServerKeyPrefix) {
continue
}
serverName := ToLower(Trim(Replace(key, ServerKeyPrefix, "", -1), "_"))
serverName := strings.ToLower(strings.Trim(strings.Replace(key, ServerKeyPrefix, "", -1), "_"))
srv := Server{}
if err := srv.UnmarshalURL(value); err != nil {
return nil, err
@ -39,16 +39,16 @@ func EndpointsFromEnv() (map[Route]EndpointSpec, error) {
endpoints := make(map[Route]EndpointSpec)
for _, kv := range os.Environ() {
key, value, valid := Cut(kv, "=")
key, value, valid := strings.Cut(kv, "=")
if !valid {
continue
}
if !HasPrefix(key, EndpointKeyPrefix) {
if !strings.HasPrefix(key, EndpointKeyPrefix) {
continue
}
endpointRoute := path.Join(Split(ToLower(Trim(Replace(key, EndpointKeyPrefix, "", -1), "_")), "_")...)
endpointRoute := path.Join(strings.Split(strings.ToLower(strings.Trim(strings.Replace(key, EndpointKeyPrefix, "", -1), "_")), "_")...)
spec := EndpointSpec{}
if err := spec.Parse(value); err != nil {
return nil, err

View file

@ -199,8 +199,8 @@ func (s *Server) UnmarshalJSON(bytes []byte) error {
return s.mergedMarshaledServer(*tmp)
}
func (s *Server) UnmarshalURL(rawUrl string) error {
rawPath, username, password, err := s.extractBaseProperties(rawUrl)
func (s *Server) UnmarshalURL(rawURL string) error {
rawPath, username, password, err := s.extractBaseProperties(rawURL)
if err != nil {
return err
}
@ -215,11 +215,11 @@ func (s *Server) UnmarshalURL(rawUrl string) error {
}
if rawPath != "" {
parsedUrl, err := url.Parse(fmt.Sprintf("%s://%s%s", s.Type.Scheme(), s.Hosts[0], rawPath))
parsedURL, err := url.Parse(fmt.Sprintf("%s://%s%s", s.Type.Scheme(), s.Hosts[0], rawPath))
if err != nil {
return err
}
if err := s.unmarshalPath(parsedUrl); err != nil {
if err := s.unmarshalPath(parsedURL); err != nil {
return err
}
} else {
@ -229,8 +229,8 @@ func (s *Server) UnmarshalURL(rawUrl string) error {
return nil
}
func (s *Server) extractBaseProperties(rawUrl string) (rawPath, username, password string, err error) {
allMatches := hostsRegexp.FindAllStringSubmatch(rawUrl, -1)
func (s *Server) extractBaseProperties(rawURL string) (rawPath, username, password string, err error) {
allMatches := hostsRegexp.FindAllStringSubmatch(rawURL, -1)
if matchLen := len(allMatches); matchLen != 1 {
return "", "", "", fmt.Errorf("ambiguous server match: %d", matchLen)
}

7
go.mod
View file

@ -3,19 +3,21 @@ module code.icb4dc0.de/prskr/nurse
go 1.19
require (
code.gitea.io/sdk/gitea v0.15.1
github.com/PaesslerAG/jsonpath v0.1.1
github.com/alecthomas/participle/v2 v2.0.0-beta.5
github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.6.0
github.com/google/uuid v1.3.0
github.com/jackc/pgx/v5 v5.0.0
github.com/magefile/mage v1.14.0
github.com/maxatome/go-testdeep v1.12.0
github.com/mitchellh/mapstructure v1.5.0
github.com/testcontainers/testcontainers-go v0.14.0
github.com/valyala/bytebufferpool v1.0.0
go.uber.org/multierr v1.8.0
go.uber.org/zap v1.23.0
golang.org/x/exp v0.0.0-20220927162542-c76eaa363f9d
golang.org/x/exp v0.0.0-20221230185412-738e83a70c30
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7
gopkg.in/yaml.v3 v3.0.1
)
@ -38,6 +40,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/magiconair/properties v1.8.6 // indirect
@ -55,7 +58,7 @@ require (
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
google.golang.org/grpc v1.47.0 // indirect

22
go.sum
View file

@ -38,6 +38,9 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
@ -542,6 +545,8 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -606,6 +611,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
@ -988,12 +995,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220907003533-145caa8ea1d0 h1:17k44ji3KFYG94XS5QEFC8pyuOlMh3IoR+vkmTZmJJs=
golang.org/x/exp v0.0.0-20220907003533-145caa8ea1d0/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/exp v0.0.0-20220921164117-439092de6870 h1:j8b6j9gzSigH28O5SjSpQSSh9lFd6f5D/q0aHjNTulc=
golang.org/x/exp v0.0.0-20220921164117-439092de6870/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/exp v0.0.0-20220927162542-c76eaa363f9d h1:3wgmvnqHUJ8SxiNWwea5NCzTwAVfhTtuV+0ClVFlClc=
golang.org/x/exp v0.0.0-20220927162542-c76eaa363f9d/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/exp v0.0.0-20221230185412-738e83a70c30 h1:m9O6OTJ627iFnN2JIWfdqlZCzneRO6EEBsHXI25P8ws=
golang.org/x/exp v0.0.0-20221230185412-738e83a70c30/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1104,8 +1107,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220907140024-f12130a52804 h1:0SH2R3f1b1VmIMG7BXbEZCBUu2dKmHschSmjqGUrW8A=
golang.org/x/sync v0.0.0-20220907140024-f12130a52804/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1212,8 +1213,8 @@ golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -1280,6 +1281,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=

120
magefiles/common.go Normal file
View file

@ -0,0 +1,120 @@
package main
import (
"io/fs"
"os"
"path/filepath"
"strings"
"code.gitea.io/sdk/gitea"
"github.com/magefile/mage/sh"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/exp/slices"
)
const defaultDirPermissions = 0o755
var (
GoSourceFiles []string
GeneratedMockFiles []string
WorkingDir string
OutDir string
GitCommit string
GiteaClient *gitea.Client
dirsToIgnore = []string{
".git",
"magefiles",
".concourse",
".run",
".task",
}
)
func init() {
if currentCommit, err := sh.Output("git", "rev-parse", "HEAD"); err != nil {
panic(err)
} else {
GitCommit = currentCommit
}
if wd, err := os.Getwd(); err != nil {
panic(err)
} else {
WorkingDir = wd
}
OutDir = filepath.Join(WorkingDir, "out")
if err := os.MkdirAll(OutDir, defaultDirPermissions); err != nil {
panic(err)
}
if err := initLogging(); err != nil {
panic(err)
}
if err := initSourceFiles(); err != nil {
panic(err)
}
if giteaToken := os.Getenv("GITEA_TOKEN"); giteaToken != "" {
if client, err := gitea.NewClient("https://code.icb4dc0.de", gitea.SetToken(giteaToken)); err == nil {
GiteaClient = client
}
}
zap.L().Info("Completed initialization", zap.String("commit", GitCommit))
}
func initLogging() error {
cfg := zap.NewDevelopmentConfig()
cfg.Encoding = "console"
cfg.Level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
if logger, err := cfg.Build(); err != nil {
return err
} else {
zap.ReplaceGlobals(logger)
}
return nil
}
func initSourceFiles() error {
return filepath.WalkDir(WorkingDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
if slices.Contains(dirsToIgnore, filepath.Base(path)) {
return fs.SkipDir
}
return nil
}
_, ext, found := strings.Cut(filepath.Base(path), ".")
if !found {
return nil
}
switch ext {
case "mock.go":
GeneratedMockFiles = append(GeneratedMockFiles, path)
case "go":
GoSourceFiles = append(GoSourceFiles, path)
}
return nil
})
}
func commitStatusOption(context, description string) gitea.CreateStatusOption {
return gitea.CreateStatusOption{
Context: context,
Description: description,
State: gitea.StatusPending,
TargetURL: "https://concourse.icb4dc0.de/teams/main/pipelines",
}
}

30
magefiles/format.go Normal file
View file

@ -0,0 +1,30 @@
package main
import (
"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
)
func Format() {
mg.Deps(GoImports, GoFumpt)
}
func GoImports() error {
if err := ensureGoTool("goimports", "golang.org/x/tools/cmd/goimports", "latest"); err != nil {
return err
}
return sh.RunV(
"goimports",
"-local=inetmock.icb4dc0.de/inetmock",
"-w",
WorkingDir,
)
}
func GoFumpt() error {
if err := ensureGoTool("gofumpt", "mvdan.cc/gofumpt", "latest"); err != nil {
return err
}
return sh.RunV("gofumpt", "-l", "-w", WorkingDir)
}

38
magefiles/lint.go Normal file
View file

@ -0,0 +1,38 @@
package main
import (
"context"
"code.gitea.io/sdk/gitea"
"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
"go.uber.org/multierr"
)
func Lint(ctx context.Context) {
mg.CtxDeps(ctx, Format, LintGo)
}
func LintGo(ctx context.Context) (err error) {
status := commitStatusOption("concourse-ci/lint/golangci-lint", "Lint Go files")
if err := setCommitStatus(ctx, status); err != nil {
return err
}
defer func() {
if err == nil {
status.State = gitea.StatusSuccess
} else {
status.State = gitea.StatusFailure
}
err = multierr.Append(err, setCommitStatus(ctx, status))
}()
return sh.RunV(
"golangci-lint",
"run",
"-v",
"--issues-exit-code=1",
)
}

38
magefiles/reporting.go Normal file
View file

@ -0,0 +1,38 @@
package main
import (
"context"
"fmt"
"net/http"
"code.gitea.io/sdk/gitea"
)
type CommitState string
func (s CommitState) String() string {
return string(s)
}
func setCommitStatus(ctx context.Context, notification gitea.CreateStatusOption) error {
if GiteaClient == nil {
return nil
}
GiteaClient.SetContext(ctx)
_, resp, err := GiteaClient.CreateStatus("inetmock", "inetmock", GitCommit, notification)
if err != nil {
return err
}
defer func() {
_ = resp.Close
}()
if resp.StatusCode >= http.StatusMultipleChoices {
return fmt.Errorf("failed to update commit status - %d - %s", resp.StatusCode, resp.Status)
}
return nil
}

34
magefiles/tools.go Normal file
View file

@ -0,0 +1,34 @@
package main
import (
"fmt"
"os/exec"
"github.com/magefile/mage/sh"
"go.uber.org/zap"
)
var (
GoReleaser = sh.RunCmd("goreleaser")
GoInstall = sh.RunCmd("go", "install")
GoBuild = sh.RunCmd("go", "build")
)
func ensureGoTool(toolName, importPath, version string) error {
return checkForTool(toolName, func() error {
logger := zap.L()
toolToInstall := fmt.Sprintf("%s@%s", importPath, version)
logger.Info("Installing Go tool", zap.String("toolToInstall", toolToInstall))
return GoInstall(toolToInstall)
})
}
func checkForTool(toolName string, fallbackAction func() error) error {
logger := zap.L()
if _, err := exec.LookPath(toolName); err != nil {
logger.Warn("tool is missing", zap.String("toolName", toolName))
return fallbackAction()
}
return nil
}

View file

@ -6,7 +6,7 @@ import (
"code.icb4dc0.de/prskr/nurse/validation"
)
type jsonPathValidator_EqualsTestCase[V validation.Value] struct {
type jsonPathValidatorEqualsTestCase[V validation.Value] struct {
testName string
expected V
jsonPath string
@ -14,12 +14,12 @@ type jsonPathValidator_EqualsTestCase[V validation.Value] struct {
wantErr bool
}
func (tt jsonPathValidator_EqualsTestCase[V]) name() string {
func (tt jsonPathValidatorEqualsTestCase[V]) name() string {
return tt.testName
}
//nolint:thelper // is not a helper
func (tt jsonPathValidator_EqualsTestCase[V]) run(t *testing.T) {
func (tt jsonPathValidatorEqualsTestCase[V]) run(t *testing.T) {
t.Parallel()
t.Helper()
validator, err := validation.JSONPathValidatorFor(tt.jsonPath, tt.expected)
@ -37,42 +37,42 @@ func (tt jsonPathValidator_EqualsTestCase[V]) run(t *testing.T) {
func TestJSONPathValidator_Equals(t *testing.T) {
t.Parallel()
tests := []testCase{
jsonPathValidator_EqualsTestCase[string]{
jsonPathValidatorEqualsTestCase[string]{
testName: "Simple object navigation",
expected: "hello",
jsonPath: "$.greeting",
json: `{"greeting": "hello"}`,
wantErr: false,
},
jsonPathValidator_EqualsTestCase[string]{
jsonPathValidatorEqualsTestCase[string]{
testName: "Simple object navigation - number as string",
expected: "42",
jsonPath: "$.number",
json: `{"number": 42}`,
wantErr: false,
},
jsonPathValidator_EqualsTestCase[string]{
jsonPathValidatorEqualsTestCase[string]{
testName: "Simple array navigation",
expected: "world",
jsonPath: "$[1]",
json: `["hello", "world"]`,
wantErr: false,
},
jsonPathValidator_EqualsTestCase[int]{
jsonPathValidatorEqualsTestCase[int]{
testName: "Simple array navigation - string to int",
expected: 37,
jsonPath: "$[1]",
json: `["13", "37"]`,
wantErr: false,
},
jsonPathValidator_EqualsTestCase[int]{
jsonPathValidatorEqualsTestCase[int]{
testName: "Simple array navigation - string to int - wrong value",
expected: 42,
jsonPath: "$[1]",
json: `["13", "37"]`,
wantErr: true,
},
jsonPathValidator_EqualsTestCase[string]{
jsonPathValidatorEqualsTestCase[string]{
testName: "Simple array navigation - int to string",
expected: "37",
jsonPath: "$[1]",

View file

@ -11,7 +11,7 @@ type testCase interface {
name() string
}
type jsonValueComparator_EqualsTestCase[V validation.Value] struct {
type jsonValueComparatorEqualsTestCase[V validation.Value] struct {
testName string
expected V
got any
@ -19,7 +19,7 @@ type jsonValueComparator_EqualsTestCase[V validation.Value] struct {
}
//nolint:thelper // is not a helper
func (tt jsonValueComparator_EqualsTestCase[V]) run(t *testing.T) {
func (tt jsonValueComparatorEqualsTestCase[V]) run(t *testing.T) {
t.Parallel()
t.Helper()
comparator, err := validation.JSONValueComparatorFor(tt.expected)
@ -34,140 +34,140 @@ func (tt jsonValueComparator_EqualsTestCase[V]) run(t *testing.T) {
}
}
func (tt jsonValueComparator_EqualsTestCase[V]) name() string {
func (tt jsonValueComparatorEqualsTestCase[V]) name() string {
return tt.testName
}
func TestJSONValueComparator_Equals(t *testing.T) {
t.Parallel()
tests := []testCase{
jsonValueComparator_EqualsTestCase[int]{
jsonValueComparatorEqualsTestCase[int]{
testName: "Test int equality",
expected: 42,
got: 42,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int]{
jsonValueComparatorEqualsTestCase[int]{
testName: "Test int equality - wrong value",
expected: 42,
got: 43,
wantErr: true,
},
jsonValueComparator_EqualsTestCase[int]{
jsonValueComparatorEqualsTestCase[int]{
testName: "Test int equality - string value",
expected: 42,
got: "42",
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int]{
jsonValueComparatorEqualsTestCase[int]{
testName: "Test int equality - []byte value",
expected: 42,
got: []byte("42"),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int]{
jsonValueComparatorEqualsTestCase[int]{
testName: "Test int equality - float value",
expected: 42,
got: 42.0,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int8]{
jsonValueComparatorEqualsTestCase[int8]{
testName: "Test int8 equality",
expected: 42,
got: 42,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int8]{
jsonValueComparatorEqualsTestCase[int8]{
testName: "Test int8 equality - wrong value",
expected: 42,
got: 43,
wantErr: true,
},
jsonValueComparator_EqualsTestCase[int8]{
jsonValueComparatorEqualsTestCase[int8]{
testName: "Test int8 equality - int16 value",
expected: 42,
got: int16(42),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[int8]{
jsonValueComparatorEqualsTestCase[int8]{
testName: "Test int8 equality - uint16 value",
expected: 42,
got: uint16(42),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float32]{
jsonValueComparatorEqualsTestCase[float32]{
testName: "Test float32 equality - float value",
expected: 42.0,
got: 42.0,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float32]{
jsonValueComparatorEqualsTestCase[float32]{
testName: "Test float32 equality - float value",
expected: 42.0,
got: float64(42.0),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - float value",
expected: 42.0,
got: 42.0,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - int value",
expected: 42.0,
got: 42,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - []byte value",
expected: 42.0,
got: []byte("42"),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - float32 value",
expected: 42.0,
got: float32(42.0),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - string value",
expected: 42.0,
got: "42.0",
wantErr: false,
},
jsonValueComparator_EqualsTestCase[float64]{
jsonValueComparatorEqualsTestCase[float64]{
testName: "Test float64 equality - string value without dot",
expected: 42.0,
got: "42",
wantErr: false,
},
jsonValueComparator_EqualsTestCase[string]{
jsonValueComparatorEqualsTestCase[string]{
testName: "Test string equality",
expected: "hello",
got: "hello",
wantErr: false,
},
jsonValueComparator_EqualsTestCase[string]{
jsonValueComparatorEqualsTestCase[string]{
testName: "Test string equality - []byte value",
expected: "hello",
got: []byte("hello"),
wantErr: false,
},
jsonValueComparator_EqualsTestCase[string]{
jsonValueComparatorEqualsTestCase[string]{
testName: "Test string equality - int value",
expected: "1337",
got: 1337,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[string]{
jsonValueComparatorEqualsTestCase[string]{
testName: "Test string equality - float value",
expected: "13.37",
got: 13.37,
wantErr: false,
},
jsonValueComparator_EqualsTestCase[string]{
jsonValueComparatorEqualsTestCase[string]{
testName: "Test string equality - wrong case",
expected: "hello",
got: "HELLO",