feat: add concourse pipeline
This commit is contained in:
parent
a245fd3cbc
commit
59d2d26984
18 changed files with 453 additions and 67 deletions
42
.concourse/branch-tracker.yml
Normal file
42
.concourse/branch-tracker.yml
Normal 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))}
|
17
.concourse/branch-validate.yml
Normal file
17
.concourse/branch-validate.yml
Normal 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
31
.concourse/cleanup.yml
Normal 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
27
.concourse/tasks/lint.yml
Normal 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
1
.gitignore
vendored
|
@ -16,5 +16,6 @@
|
|||
|
||||
dist/
|
||||
.idea/
|
||||
.fleet/
|
||||
cue.mod/
|
||||
.go/
|
|
@ -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:
|
||||
|
|
|
@ -26,5 +26,4 @@ func (c CheckHandler) ServeHTTP(writer http.ResponseWriter, request *http.Reques
|
|||
}
|
||||
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
7
go.mod
|
@ -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
22
go.sum
|
@ -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
120
magefiles/common.go
Normal 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
30
magefiles/format.go
Normal 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
38
magefiles/lint.go
Normal 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
38
magefiles/reporting.go
Normal 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
34
magefiles/tools.go
Normal 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
|
||||
}
|
|
@ -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]",
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue