From f0698658440305ddba89b9e41a38a01b55c8b187 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Thu, 29 Feb 2024 11:48:57 +0300 Subject: [PATCH 1/9] Add the buildtagger tool - buildtagger can be used to generate the desired build tags (constraints) for the official provider families. - Each resource provider's source modules can share a unique build tag so that tag-aware Go tools (including golangci-lint) can load only those source modules. Signed-off-by: Alper Rifat Ulucinar --- Makefile | 2 +- cmd/buildtagger/main.go | 114 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 cmd/buildtagger/main.go diff --git a/Makefile b/Makefile index 3585f1a..9e26710 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ GO_REQUIRED_VERSION = 1.19 # Uncomment below if you need to override the version. # GOLANGCILINT_VERSION ?= 1.54.0 -GO_STATIC_PACKAGES = $(GO_PROJECT)/cmd/uptest $(GO_PROJECT)/cmd/crddiff $(GO_PROJECT)/cmd/updoc $(GO_PROJECT)/cmd/ttr $(GO_PROJECT)/cmd/perf $(GO_PROJECT)/cmd/linter/lint-provider-family +GO_STATIC_PACKAGES = $(GO_PROJECT)/cmd/uptest $(GO_PROJECT)/cmd/crddiff $(GO_PROJECT)/cmd/buildtagger $(GO_PROJECT)/cmd/updoc $(GO_PROJECT)/cmd/ttr $(GO_PROJECT)/cmd/perf $(GO_PROJECT)/cmd/linter/lint-provider-family GO_LDFLAGS += -X $(GO_PROJECT)/internal/version.Version=$(VERSION) GO_SUBDIRS += cmd internal GO111MODULE = on diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go new file mode 100644 index 0000000..c8a36ff --- /dev/null +++ b/cmd/buildtagger/main.go @@ -0,0 +1,114 @@ +// Copyright 2024 Upbound Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// main package for the buildtagger application which is used in the +// official provider repositories to generate build tags for the +// provider families. Each family's source modules can be tagged using +// the buildtagger tool. +package main + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/pkg/errors" + "gopkg.in/alecthomas/kingpin.v2" +) + +var ( + app = kingpin.New("buildtagger", "A tool for generating build tags (constraints) for the source modules of the official provider families.").DefaultEnvars() +) + +var ( + parentDir = app.Flag("parent-dir", "Parent directory which will be recursively walked to find the Go source files whose relative path to this parent matches the specified regular expression. The files found will be tagged using the specified build tag.").Default("./").String() + regex = app.Flag("regex", `The regular expression against which a discovered Go source file's relative path or name will be matched. This expression must contain one and only one group whose value will be substituted in the given tag format string. An example is "(.+)/.+/.+\.go"`).Required().String() + tagFormat = app.Flag("tag-format", `A format string that must contain one and only one "%s" format specifier to construct the build tag. An example is "(%s || all) && !ignore_autogenerated", where the "%s" format specifier can be replaced by a family resource provider group name.`).Default("(%s || all) && !ignore_autogenerated").String() + mode = app.Flag("mode", `If "file", the file name of the discovered Go source is matched against the given regular expression. If "dir", the relative path of the source file is matched.`).Default("dir").Enum("file", "dir") +) + +// addOrUpdateBuildTag traverses directories from the parent, +// updating or adding build tags in Go files. If a build tag already exists, +// it's replaced with the computed tags. +func addOrUpdateBuildTag(parent, regex, tagFormat, mode string) error { + re, err := regexp.Compile(regex) + kingpin.FatalIfError(err, "Failed to compile the given regular expression: %s", regex) + + return filepath.Walk(parent, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() { + var matchString string + switch mode { + case "file": + // regex is matched against the filename + matchString = filepath.Base(path) + case "dir": + // regex is matched against the relative path + matchString, err = filepath.Rel(parent, path) + if err != nil { + return errors.Wrapf(err, "failed to determine the relative path of %s wrt to %s", path, parent) + } + } + + matches := re.FindStringSubmatch(matchString) + if len(matches) == 2 { + tag := fmt.Sprintf("//go:build "+strings.TrimSpace(tagFormat), matches[1]) + err = updateFileWithBuildTag(path, tag) + if err != nil { + return errors.Wrap(err, "failed to update the source file") + } + } + } + return nil + }) +} + +// updateFileWithBuildTag reads a Go file and updates or inserts the specified build tag. +func updateFileWithBuildTag(filePath, buildTag string) error { + content, err := os.ReadFile(filePath) + if err != nil { + return errors.Wrapf(err, "failed to read the source file at path %s", filePath) + } + + lines := strings.Split(string(content), "\n") + updatedLines := make([]string, 0, len(lines)) + found := false + for _, line := range lines { + if strings.HasPrefix(line, "//go:build") { + if !found { + updatedLines = append(updatedLines, buildTag) + found = true + } + continue + } else { + updatedLines = append(updatedLines, line) + } + } + if !found { + // an extra line is needed after the build tag + updatedLines = append([]string{buildTag, ""}, updatedLines...) + } + // Write the updated content back to the file + return errors.Wrapf(os.WriteFile(filePath, []byte(strings.Join(updatedLines, "\n")), 0644), "failed to write the source file at path %s", filePath) +} + +func main() { + kingpin.MustParse(app.Parse(os.Args[1:])) + kingpin.FatalIfError(addOrUpdateBuildTag(*parentDir, *regex, *tagFormat, *mode), "Failed to run the buildtagger...") +} From df38579730944788768b94a7d603d682fd264d7b Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Fri, 1 Mar 2024 11:05:45 +0300 Subject: [PATCH 2/9] Add build tag deletion support Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 51 ++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index c8a36ff..6bbd4b5 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -34,16 +34,17 @@ var ( ) var ( - parentDir = app.Flag("parent-dir", "Parent directory which will be recursively walked to find the Go source files whose relative path to this parent matches the specified regular expression. The files found will be tagged using the specified build tag.").Default("./").String() - regex = app.Flag("regex", `The regular expression against which a discovered Go source file's relative path or name will be matched. This expression must contain one and only one group whose value will be substituted in the given tag format string. An example is "(.+)/.+/.+\.go"`).Required().String() - tagFormat = app.Flag("tag-format", `A format string that must contain one and only one "%s" format specifier to construct the build tag. An example is "(%s || all) && !ignore_autogenerated", where the "%s" format specifier can be replaced by a family resource provider group name.`).Default("(%s || all) && !ignore_autogenerated").String() - mode = app.Flag("mode", `If "file", the file name of the discovered Go source is matched against the given regular expression. If "dir", the relative path of the source file is matched.`).Default("dir").Enum("file", "dir") + parentDir = app.Flag("parent-dir", "Parent directory which will be recursively walked to find the Go source files whose relative path to this parent matches the specified regular expression. The files found will be tagged using the specified build tag.").Default("./").String() + regex = app.Flag("regex", `The regular expression against which a discovered Go source file's relative path or name will be matched. This expression must contain one and only one group whose value will be substituted in the given tag format string. An example is "(.+)/.+/.+\.go"`).Required().String() + tagFormat = app.Flag("tag-format", `A format string that must contain one and only one "%s" format specifier to construct the build tag. An example is "(%s || all) && !ignore_autogenerated", where the "%s" format specifier can be replaced by a family resource provider group name.`).Default("(%s || all) && !ignore_autogenerated").String() + mode = app.Flag("mode", `If "file", the file name of the discovered Go source is matched against the given regular expression. If "dir", the relative path of the source file is matched.`).Default("dir").Enum("file", "dir") + deleteTags = app.Flag("delete", `If set, the build tags are removed from the discovered Go sources, instead of being added.`).Default("false").Bool() ) // addOrUpdateBuildTag traverses directories from the parent, // updating or adding build tags in Go files. If a build tag already exists, // it's replaced with the computed tags. -func addOrUpdateBuildTag(parent, regex, tagFormat, mode string) error { +func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) error { re, err := regexp.Compile(regex) kingpin.FatalIfError(err, "Failed to compile the given regular expression: %s", regex) @@ -69,7 +70,7 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string) error { matches := re.FindStringSubmatch(matchString) if len(matches) == 2 { tag := fmt.Sprintf("//go:build "+strings.TrimSpace(tagFormat), matches[1]) - err = updateFileWithBuildTag(path, tag) + err = updateFileWithBuildTag(path, tag, deleteTags) if err != nil { return errors.Wrap(err, "failed to update the source file") } @@ -80,29 +81,33 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string) error { } // updateFileWithBuildTag reads a Go file and updates or inserts the specified build tag. -func updateFileWithBuildTag(filePath, buildTag string) error { +func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { content, err := os.ReadFile(filePath) if err != nil { return errors.Wrapf(err, "failed to read the source file at path %s", filePath) } lines := strings.Split(string(content), "\n") - updatedLines := make([]string, 0, len(lines)) - found := false - for _, line := range lines { - if strings.HasPrefix(line, "//go:build") { - if !found { - updatedLines = append(updatedLines, buildTag) - found = true - } - continue - } else { - updatedLines = append(updatedLines, line) - } + if len(lines) < 1 { + return nil } - if !found { - // an extra line is needed after the build tag - updatedLines = append([]string{buildTag, ""}, updatedLines...) + var updatedLines []string + index := -1 + if strings.HasPrefix(lines[0], "//go:build") { + index++ + } + emptyLineFollows := len(lines) > 1 && strings.TrimSpace(lines[1]) == "" + if deleteTag && emptyLineFollows { + index++ + } + updatedLines = lines[index+1:] + if !deleteTag { + addedLines := [2]string{buildTag} + trimIndex := 2 + if emptyLineFollows { + trimIndex = 1 + } + updatedLines = append(addedLines[:trimIndex], updatedLines...) } // Write the updated content back to the file return errors.Wrapf(os.WriteFile(filePath, []byte(strings.Join(updatedLines, "\n")), 0644), "failed to write the source file at path %s", filePath) @@ -110,5 +115,5 @@ func updateFileWithBuildTag(filePath, buildTag string) error { func main() { kingpin.MustParse(app.Parse(os.Args[1:])) - kingpin.FatalIfError(addOrUpdateBuildTag(*parentDir, *regex, *tagFormat, *mode), "Failed to run the buildtagger...") + kingpin.FatalIfError(addOrUpdateBuildTag(*parentDir, *regex, *tagFormat, *mode, *deleteTags), "Failed to run the buildtagger...") } From 73dcf55bfc1d44f610b91f26b44494b8a61cc038 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Sun, 3 Mar 2024 18:29:27 +0300 Subject: [PATCH 3/9] Allow an arbitrary number of capturing groups in the "--regex" argument Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index 6bbd4b5..1b50a0e 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -34,9 +34,10 @@ var ( ) var ( - parentDir = app.Flag("parent-dir", "Parent directory which will be recursively walked to find the Go source files whose relative path to this parent matches the specified regular expression. The files found will be tagged using the specified build tag.").Default("./").String() - regex = app.Flag("regex", `The regular expression against which a discovered Go source file's relative path or name will be matched. This expression must contain one and only one group whose value will be substituted in the given tag format string. An example is "(.+)/.+/.+\.go"`).Required().String() - tagFormat = app.Flag("tag-format", `A format string that must contain one and only one "%s" format specifier to construct the build tag. An example is "(%s || all) && !ignore_autogenerated", where the "%s" format specifier can be replaced by a family resource provider group name.`).Default("(%s || all) && !ignore_autogenerated").String() + parentDir = app.Flag("parent-dir", "Parent directory which will be recursively walked to find the Go source files whose relative path to this parent matches the specified regular expression. The files found will be tagged using the specified build tag.").Default("./").String() + regex = app.Flag("regex", `The regular expression against which a discovered Go source file's relative path or name will be matched. This expression must contain one and only one group whose value will be substituted in the given tag format string. An example is "(.+)/.+/.+\.go"`).Default(".*").String() + tagFormat = app.Flag("tag-format", `A Printf format string to construct the build tag. An example is "(%s || all) && !ignore_autogenerated", where the "%s" format specifier can be replaced by a family resource provider group name.`+ + `There should be a string format specifier for each of the capturing groups specified in the "regex".`).Default("!ignore_autogenerated").String() mode = app.Flag("mode", `If "file", the file name of the discovered Go source is matched against the given regular expression. If "dir", the relative path of the source file is matched.`).Default("dir").Enum("file", "dir") deleteTags = app.Flag("delete", `If set, the build tags are removed from the discovered Go sources, instead of being added.`).Default("false").Bool() ) @@ -68,12 +69,17 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) } matches := re.FindStringSubmatch(matchString) - if len(matches) == 2 { - tag := fmt.Sprintf("//go:build "+strings.TrimSpace(tagFormat), matches[1]) - err = updateFileWithBuildTag(path, tag, deleteTags) - if err != nil { - return errors.Wrap(err, "failed to update the source file") - } + if len(matches) == 0 { + return nil + } + args := make([]any, len(matches)-1) + for i, a := range matches[1:] { + args[i] = a + } + tag := fmt.Sprintf("//go:build "+strings.TrimSpace(tagFormat), args...) + err = updateFileWithBuildTag(path, tag, deleteTags) + if err != nil { + return errors.Wrap(err, "failed to update the source file") } } return nil From 032f6629275ccd5fe45af724b64b07f3b9ea3563 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Sun, 3 Mar 2024 18:35:15 +0300 Subject: [PATCH 4/9] If no source files match the given regular expression with "--regex", exit non-zero Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index 1b50a0e..1e2b27c 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -48,8 +48,8 @@ var ( func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) error { re, err := regexp.Compile(regex) kingpin.FatalIfError(err, "Failed to compile the given regular expression: %s", regex) - - return filepath.Walk(parent, func(path string, info os.FileInfo, err error) error { + matched := false + err = filepath.Walk(parent, func(path string, info os.FileInfo, err error) error { if err != nil { return err } @@ -72,6 +72,7 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) if len(matches) == 0 { return nil } + matched = true args := make([]any, len(matches)-1) for i, a := range matches[1:] { args[i] = a @@ -84,6 +85,13 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) } return nil }) + if err != nil { + return err + } + if matched { + return nil + } + return errors.Errorf("no Go source files under %s matched the regular expression %q", parent, regex) } // updateFileWithBuildTag reads a Go file and updates or inserts the specified build tag. From a467b513ac44077e5c0106d7f06281724f68b78b Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Mon, 4 Mar 2024 11:06:57 +0300 Subject: [PATCH 5/9] Bump Go version to 1.21 for the uptest module Signed-off-by: Alper Rifat Ulucinar --- .github/workflows/ci.yml | 2 +- .github/workflows/promote.yaml | 2 +- Makefile | 2 +- go.mod | 2 +- go.sum | 18 ++++++++++++++++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad92b65..9129e8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: env: # Common versions - GO_VERSION: '1.19' + GO_VERSION: '1.21' GOLANGCI_VERSION: 'v1.54.2' DOCKER_BUILDX_VERSION: 'v0.8.2' diff --git a/.github/workflows/promote.yaml b/.github/workflows/promote.yaml index 7c6ca96..9c899cd 100644 --- a/.github/workflows/promote.yaml +++ b/.github/workflows/promote.yaml @@ -13,7 +13,7 @@ on: env: # Common versions - GO_VERSION: '1.19' + GO_VERSION: '1.21' # Common users. We can't run a step 'if secrets.XXX != ""' but we can run # a step 'if env.XXX' != ""', so we copy these to succinctly test whether diff --git a/Makefile b/Makefile index 9e26710..796761c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ S3_BUCKET ?= upbound.official-providers-ci.releases # ==================================================================================== # Setup Go -GO_REQUIRED_VERSION = 1.19 +GO_REQUIRED_VERSION = 1.21 # GOLANGCILINT_VERSION is inherited from build submodule by default. # Uncomment below if you need to override the version. # GOLANGCILINT_VERSION ?= 1.54.0 diff --git a/go.mod b/go.mod index 51583bd..913dc63 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/upbound/uptest -go 1.19 +go 1.21 require ( cloud.google.com/go/storage v1.27.0 diff --git a/go.sum b/go.sum index f14e491..893fddf 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,7 @@ cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1 cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -54,9 +55,11 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/adrg/frontmatter v0.2.0 h1:/DgnNe82o03riBd1S+ZDjd43wAmC6W35q67NHeLkPd4= github.com/adrg/frontmatter v0.2.0/go.mod h1:93rQCj3z3ZlwyxxpQioRKC1wDLto4aXHrbqIsnH9wmE= github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= +github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA= github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4= github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= +github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -85,6 +88,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk= +github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossplane/crossplane v1.10.0 h1:JP6TdhoZuRS27rYd+HCZNEBdf/1/w+rqIShW2qz/Qhk= @@ -141,6 +145,7 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -212,6 +217,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -242,6 +248,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb 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= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= @@ -267,6 +274,7 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -309,7 +317,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= +github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= @@ -353,6 +363,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -384,6 +395,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/tufin/oasdiff v1.2.6 h1:npdeFfs1lvTTcsT5HB/zDJZntl6tG2oMMK0dfFSF+yM= github.com/tufin/oasdiff v1.2.6/go.mod h1:7Ukdw7vE8EFNl8mf7e9rNX/aXptYn0RGtXoPCjjjlBU= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= +github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -407,9 +419,13 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -760,6 +776,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -778,6 +795,7 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 574bdd3a28fd6e965f1f87af25c4cb87178622bc Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Mon, 4 Mar 2024 16:35:55 +0300 Subject: [PATCH 6/9] Fix linter issues Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 33 +++++++++++++++++++-------------- internal/prepare.go | 5 +---- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index 1e2b27c..e822e17 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -55,19 +55,10 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) } if !info.IsDir() { - var matchString string - switch mode { - case "file": - // regex is matched against the filename - matchString = filepath.Base(path) - case "dir": - // regex is matched against the relative path - matchString, err = filepath.Rel(parent, path) - if err != nil { - return errors.Wrapf(err, "failed to determine the relative path of %s wrt to %s", path, parent) - } + matchString, err := getMatchString(parent, path, mode) + if err != nil { + return err } - matches := re.FindStringSubmatch(matchString) if len(matches) == 0 { return nil @@ -94,9 +85,23 @@ func addOrUpdateBuildTag(parent, regex, tagFormat, mode string, deleteTags bool) return errors.Errorf("no Go source files under %s matched the regular expression %q", parent, regex) } +func getMatchString(parent, path, mode string) (string, error) { + switch mode { + case "file": + // regex is matched against the filename + return filepath.Base(path), nil + case "dir": + // regex is matched against the relative path + matchString, err := filepath.Rel(parent, path) + return matchString, errors.Wrapf(err, "failed to determine the relative path of %s wrt to %s", path, parent) + default: + return "", errors.Errorf("unknown match mode %q", mode) + } +} + // updateFileWithBuildTag reads a Go file and updates or inserts the specified build tag. func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { - content, err := os.ReadFile(filePath) + content, err := os.ReadFile(filepath.Clean(filePath)) if err != nil { return errors.Wrapf(err, "failed to read the source file at path %s", filePath) } @@ -124,7 +129,7 @@ func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { updatedLines = append(addedLines[:trimIndex], updatedLines...) } // Write the updated content back to the file - return errors.Wrapf(os.WriteFile(filePath, []byte(strings.Join(updatedLines, "\n")), 0644), "failed to write the source file at path %s", filePath) + return errors.Wrapf(os.WriteFile(filePath, []byte(strings.Join(updatedLines, "\n")), 0600), "failed to write the source file at path %s", filePath) } func main() { diff --git a/internal/prepare.go b/internal/prepare.go index a704fda..c928fb5 100644 --- a/internal/prepare.go +++ b/internal/prepare.go @@ -26,13 +26,11 @@ import ( "path/filepath" "regexp" "strings" - "time" - - "sigs.k8s.io/yaml" "github.com/crossplane/crossplane-runtime/pkg/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" kyaml "k8s.io/apimachinery/pkg/util/yaml" + "sigs.k8s.io/yaml" "github.com/upbound/uptest/internal/config" ) @@ -169,7 +167,6 @@ func (p *preparer) injectValues(manifestData string, dataSourceMap map[string]st } func generateRFC1123SubdomainCompatibleString() string { - rand.Seed(time.Now().UnixNano()) s := make([]rune, 8) for i := range s { s[i] = charset[rand.Intn(len(charset))] //nolint:gosec // no need for crypto/rand here From ed0270fd4c7ec7021815c4aa815d28cbd7621d06 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Wed, 6 Mar 2024 04:45:50 +0300 Subject: [PATCH 7/9] Add a newline after the build constraint Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index e822e17..88c6cb6 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -112,18 +112,20 @@ func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { } var updatedLines []string index := -1 + tagExists := false if strings.HasPrefix(lines[0], "//go:build") { + tagExists = true index++ } emptyLineFollows := len(lines) > 1 && strings.TrimSpace(lines[1]) == "" - if deleteTag && emptyLineFollows { + if deleteTag && emptyLineFollows && tagExists { index++ } updatedLines = lines[index+1:] if !deleteTag { addedLines := [2]string{buildTag} trimIndex := 2 - if emptyLineFollows { + if emptyLineFollows && tagExists { trimIndex = 1 } updatedLines = append(addedLines[:trimIndex], updatedLines...) From 790ea7276dcd0e5ecbbca860ee87b4e3f527c703 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Wed, 6 Mar 2024 06:41:12 +0300 Subject: [PATCH 8/9] Add the "golangci-skip" input parameter for the "Provider CI" workflow to conditionally skip the "lint" job. Signed-off-by: Alper Rifat Ulucinar --- .github/workflows/provider-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/provider-ci.yml b/.github/workflows/provider-ci.yml index df82621..da9715c 100644 --- a/.github/workflows/provider-ci.yml +++ b/.github/workflows/provider-ci.yml @@ -4,6 +4,7 @@ on: workflow_call: inputs: upjet-based-provider: + description: 'Should be set to true if the repo running the workflow is an upjet-based provider repo' required: false type: boolean default: true @@ -22,6 +23,11 @@ on: default: 'v1.55.2' required: false type: string + golangci-skip: + description: 'If set to true, the lint job will be skipped' + default: false + required: false + type: boolean secrets: UPBOUND_MARKETPLACE_PUSH_ROBOT_USR: required: true @@ -80,7 +86,7 @@ jobs: lint: runs-on: Ubuntu-Jumbo-Runner needs: detect-noop - if: needs.detect-noop.outputs.noop != 'true' + if: needs.detect-noop.outputs.noop != 'true' && !inputs.golangci-skip steps: - name: Cleanup Disk From e05c869dbd4ce1a35b90fc85176a2264d65aa062 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Wed, 6 Mar 2024 13:00:43 +0300 Subject: [PATCH 9/9] Refactor main.updateFileWithBuildTag to decrease its cyclomatic complexity Signed-off-by: Alper Rifat Ulucinar --- cmd/buildtagger/main.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/cmd/buildtagger/main.go b/cmd/buildtagger/main.go index 88c6cb6..8515917 100644 --- a/cmd/buildtagger/main.go +++ b/cmd/buildtagger/main.go @@ -111,16 +111,7 @@ func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { return nil } var updatedLines []string - index := -1 - tagExists := false - if strings.HasPrefix(lines[0], "//go:build") { - tagExists = true - index++ - } - emptyLineFollows := len(lines) > 1 && strings.TrimSpace(lines[1]) == "" - if deleteTag && emptyLineFollows && tagExists { - index++ - } + index, tagExists, emptyLineFollows := getLineStartIndex(lines, deleteTag) updatedLines = lines[index+1:] if !deleteTag { addedLines := [2]string{buildTag} @@ -134,6 +125,20 @@ func updateFileWithBuildTag(filePath, buildTag string, deleteTag bool) error { return errors.Wrapf(os.WriteFile(filePath, []byte(strings.Join(updatedLines, "\n")), 0600), "failed to write the source file at path %s", filePath) } +func getLineStartIndex(lines []string, deleteTag bool) (int, bool, bool) { + index := -1 + tagExists := false + if strings.HasPrefix(lines[0], "//go:build") { + tagExists = true + index++ + } + emptyLineFollows := len(lines) > 1 && strings.TrimSpace(lines[1]) == "" + if deleteTag && emptyLineFollows && tagExists { + index++ + } + return index, tagExists, emptyLineFollows +} + func main() { kingpin.MustParse(app.Parse(os.Args[1:])) kingpin.FatalIfError(addOrUpdateBuildTag(*parentDir, *regex, *tagFormat, *mode, *deleteTags), "Failed to run the buildtagger...")