Bump go and golangci-lint versions, fix lint

This commit is contained in:
Tim Hockin 2025-03-24 12:55:57 -07:00
parent de11885271
commit 913a6be647
16 changed files with 140 additions and 99 deletions

View File

@ -19,7 +19,7 @@ jobs:
- name: Set up go
uses: actions/setup-go@v5
with:
go-version: '1.22.4'
go-version: '1.24.1'
- uses: actions/checkout@v4
with:
@ -36,7 +36,7 @@ jobs:
- name: Set up go
uses: actions/setup-go@v5
with:
go-version: '1.22.4'
go-version: '1.24.1'
- uses: actions/checkout@v4
with:
@ -61,7 +61,7 @@ jobs:
- name: Set up go
uses: actions/setup-go@v5
with:
go-version: '1.22.4'
go-version: '1.24.1'
- uses: actions/checkout@v4
with:
@ -72,10 +72,10 @@ jobs:
# There is a risk of drift between the two, but this is only linting,
# not runtime correctness!
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v7
with:
working-directory: git-sync
version: v1.59.0
version: v2.0.0
- name: make lint
working-directory: git-sync

View File

@ -2,25 +2,55 @@
# pass, in contrast to .golangci.yaml which defines checks that also the
# existing code passes.
version: "2"
run:
timeout: 30m
linters:
disable-all: false
default: all
enable: # please keep this alphabetized
- ginkgolinter
- gocritic
- govet
- ineffassign
# Should we add logcheck, for consistency with kubernetes/kubernetes?
# - logcheck
- staticcheck
- stylecheck
- unused
- gocritic
- asasalint
- copyloopvar
linters-settings: # please keep this alphabetized
gocritic:
staticcheck:
checks:
- "all"
stylecheck:
disable:
- errcheck
- cyclop
- depguard
- dupl
- err113
- exhaustruct
- funlen
- gochecknoglobals
- gochecknoinits
- gocognit
- goconst # TODO: turn this one on
- gocyclo
- gosec # TODO: turn this one on
- lll
- maintidx
- mnd
- musttag
- nestif
- nlreturn
- paralleltest
- perfsprint
- promlinter
- recvcheck
- revive
- tagliatelle
- testpackage
- varnamelen
- wrapcheck
- wsl
settings: # please keep this alphabetized
staticcheck:
checks:
- "all"

View File

@ -51,7 +51,7 @@ IMAGE := $(REGISTRY)/$(BIN)
TAG := $(VERSION)
OS_ARCH_TAG := $(TAG)__$(OS)_$(ARCH)
BUILD_IMAGE ?= golang:1.22
BUILD_IMAGE ?= golang:1.24
DBG_MAKEFILE ?=
ifneq ($(DBG_MAKEFILE),1)
@ -277,11 +277,8 @@ container-clean:
bin-clean:
rm -rf .go bin
lint-staticcheck:
go run honnef.co/go/tools/cmd/staticcheck@2023.1.3
lint-golangci-lint:
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.0 run
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.0 run -v
lint-shellcheck:
docker run \
@ -292,4 +289,4 @@ lint-shellcheck:
shellcheck \
$$(git ls-files ':!:vendor' '*.sh')
lint: lint-staticcheck lint-golangci-lint lint-shellcheck
lint: lint-golangci-lint lint-shellcheck

View File

@ -48,7 +48,7 @@ type credentialSliceValue struct {
var _ pflag.Value = &credentialSliceValue{}
var _ pflag.SliceValue = &credentialSliceValue{}
// pflagCredentialSlice is like pflag.StringSlice()
// pflagCredentialSlice is like pflag.StringSlice().
func pflagCredentialSlice(name, def, usage string) *[]credential {
p := &credentialSliceValue{}
_ = p.Set(def)

2
env.go
View File

@ -296,7 +296,7 @@ type explicitFlag[T comparable] struct {
flagPtr *T
}
// newExplicitFlag allocates an explicitFlag
// newExplicitFlag allocates an explicitFlag.
func newExplicitFlag[T comparable](ptr *T, name, usage string, fn func(name string, value T, usage string) *T) {
h := &explicitFlag[T]{
realPtr: ptr,

2
go.mod
View File

@ -20,4 +20,4 @@ require (
google.golang.org/protobuf v1.33.0 // indirect
)
go 1.22
go 1.23

109
main.go
View File

@ -378,7 +378,7 @@ func main() {
// Handle print-and-exit cases.
if *flVersion {
fmt.Println(version.VERSION)
fmt.Fprintln(os.Stdout, version.VERSION)
os.Exit(0)
}
if *flHelp {
@ -415,7 +415,7 @@ func main() {
cmdRunner := cmd.NewRunner(log)
if *flRepo == "" {
fatalConfigError(log, true, "required flag: --repo must be specified")
fatalConfigErrorf(log, true, "required flag: --repo must be specified")
}
switch {
@ -428,27 +428,27 @@ func main() {
log.V(0).Info("setting --ref from deprecated --rev")
*flRef = *flDeprecatedRev
case *flDeprecatedBranch != "" && *flDeprecatedRev != "":
fatalConfigError(log, true, "deprecated flag combo: can't set --ref from deprecated --branch and --rev (one or the other is OK)")
fatalConfigErrorf(log, true, "deprecated flag combo: can't set --ref from deprecated --branch and --rev (one or the other is OK)")
}
if *flRef == "" {
fatalConfigError(log, true, "required flag: --ref must be specified")
fatalConfigErrorf(log, true, "required flag: --ref must be specified")
}
if *flDepth < 0 { // 0 means "no limit"
fatalConfigError(log, true, "invalid flag: --depth must be greater than or equal to 0")
fatalConfigErrorf(log, true, "invalid flag: --depth must be greater than or equal to 0")
}
switch submodulesMode(*flSubmodules) {
case submodulesRecursive, submodulesShallow, submodulesOff:
default:
fatalConfigError(log, true, "invalid flag: --submodules must be one of %q, %q, or %q", submodulesRecursive, submodulesShallow, submodulesOff)
fatalConfigErrorf(log, true, "invalid flag: --submodules must be one of %q, %q, or %q", submodulesRecursive, submodulesShallow, submodulesOff)
}
switch *flGitGC {
case gcAuto, gcAlways, gcAggressive, gcOff:
default:
fatalConfigError(log, true, "invalid flag: --git-gc must be one of %q, %q, %q, or %q", gcAuto, gcAlways, gcAggressive, gcOff)
fatalConfigErrorf(log, true, "invalid flag: --git-gc must be one of %q, %q, %q, or %q", gcAuto, gcAlways, gcAggressive, gcOff)
}
if *flDeprecatedDest != "" {
@ -467,11 +467,11 @@ func main() {
*flPeriod = time.Duration(int(*flDeprecatedWait*1000)) * time.Millisecond
}
if *flPeriod < 10*time.Millisecond {
fatalConfigError(log, true, "invalid flag: --period must be at least 10ms")
fatalConfigErrorf(log, true, "invalid flag: --period must be at least 10ms")
}
if *flDeprecatedChmod != 0 {
fatalConfigError(log, true, "deprecated flag: --change-permissions is no longer supported")
fatalConfigErrorf(log, true, "deprecated flag: --change-permissions is no longer supported")
}
var syncSig syscall.Signal
@ -488,7 +488,7 @@ func main() {
}
}
if syncSig == 0 {
fatalConfigError(log, true, "invalid flag: --sync-on-signal must be a valid signal name or number")
fatalConfigErrorf(log, true, "invalid flag: --sync-on-signal must be a valid signal name or number")
}
}
@ -498,7 +498,7 @@ func main() {
*flSyncTimeout = time.Duration(*flDeprecatedTimeout) * time.Second
}
if *flSyncTimeout < 10*time.Millisecond {
fatalConfigError(log, true, "invalid flag: --sync-timeout must be at least 10ms")
fatalConfigErrorf(log, true, "invalid flag: --sync-timeout must be at least 10ms")
}
if *flDeprecatedMaxSyncFailures != 0 {
@ -514,10 +514,10 @@ func main() {
}
if *flExechookCommand != "" {
if *flExechookTimeout < time.Second {
fatalConfigError(log, true, "invalid flag: --exechook-timeout must be at least 1s")
fatalConfigErrorf(log, true, "invalid flag: --exechook-timeout must be at least 1s")
}
if *flExechookBackoff < time.Second {
fatalConfigError(log, true, "invalid flag: --exechook-backoff must be at least 1s")
fatalConfigErrorf(log, true, "invalid flag: --exechook-backoff must be at least 1s")
}
}
@ -527,13 +527,13 @@ func main() {
*flWebhookStatusSuccess = 0
}
if *flWebhookStatusSuccess < 0 {
fatalConfigError(log, true, "invalid flag: --webhook-success-status must be a valid HTTP code or 0")
fatalConfigErrorf(log, true, "invalid flag: --webhook-success-status must be a valid HTTP code or 0")
}
if *flWebhookTimeout < time.Second {
fatalConfigError(log, true, "invalid flag: --webhook-timeout must be at least 1s")
fatalConfigErrorf(log, true, "invalid flag: --webhook-timeout must be at least 1s")
}
if *flWebhookBackoff < time.Second {
fatalConfigError(log, true, "invalid flag: --webhook-backoff must be at least 1s")
fatalConfigErrorf(log, true, "invalid flag: --webhook-backoff must be at least 1s")
}
}
@ -543,79 +543,79 @@ func main() {
}
if *flUsername != "" {
if *flPassword == "" && *flPasswordFile == "" {
fatalConfigError(log, true, "required flag: $GITSYNC_PASSWORD or --password-file must be specified when --username is specified")
fatalConfigErrorf(log, true, "required flag: $GITSYNC_PASSWORD or --password-file must be specified when --username is specified")
}
if *flPassword != "" && *flPasswordFile != "" {
fatalConfigError(log, true, "invalid flag: only one of $GITSYNC_PASSWORD and --password-file may be specified")
fatalConfigErrorf(log, true, "invalid flag: only one of $GITSYNC_PASSWORD and --password-file may be specified")
}
if u, err := url.Parse(*flRepo); err == nil { // it may not even parse as a URL, that's OK
if u.User != nil {
fatalConfigError(log, true, "invalid flag: credentials may not be specified in --repo when --username is specified")
fatalConfigErrorf(log, true, "invalid flag: credentials may not be specified in --repo when --username is specified")
}
}
} else {
if *flPassword != "" {
fatalConfigError(log, true, "invalid flag: $GITSYNC_PASSWORD may only be specified when --username is specified")
fatalConfigErrorf(log, true, "invalid flag: $GITSYNC_PASSWORD may only be specified when --username is specified")
}
if *flPasswordFile != "" {
fatalConfigError(log, true, "invalid flag: --password-file may only be specified when --username is specified")
fatalConfigErrorf(log, true, "invalid flag: --password-file may only be specified when --username is specified")
}
}
if *flGithubAppApplicationID != 0 || *flGithubAppClientID != "" {
if *flGithubAppApplicationID != 0 && *flGithubAppClientID != "" {
fatalConfigError(log, true, "invalid flag: only one of --github-app-application-id or --github-app-client-id may be specified")
fatalConfigErrorf(log, true, "invalid flag: only one of --github-app-application-id or --github-app-client-id may be specified")
}
if *flGithubAppInstallationID == 0 {
fatalConfigError(log, true, "invalid flag: --github-app-installation-id must be specified when --github-app-application-id or --github-app-client-id are specified")
fatalConfigErrorf(log, true, "invalid flag: --github-app-installation-id must be specified when --github-app-application-id or --github-app-client-id are specified")
}
if *flGithubAppPrivateKey == "" && *flGithubAppPrivateKeyFile == "" {
fatalConfigError(log, true, "invalid flag: $GITSYNC_GITHUB_APP_PRIVATE_KEY or --github-app-private-key-file must be specified when --github-app-application-id or --github-app-client-id are specified")
fatalConfigErrorf(log, true, "invalid flag: $GITSYNC_GITHUB_APP_PRIVATE_KEY or --github-app-private-key-file must be specified when --github-app-application-id or --github-app-client-id are specified")
}
if *flGithubAppPrivateKey != "" && *flGithubAppPrivateKeyFile != "" {
fatalConfigError(log, true, "invalid flag: only one of $GITSYNC_GITHUB_APP_PRIVATE_KEY or --github-app-private-key-file may be specified")
fatalConfigErrorf(log, true, "invalid flag: only one of $GITSYNC_GITHUB_APP_PRIVATE_KEY or --github-app-private-key-file may be specified")
}
if *flUsername != "" {
fatalConfigError(log, true, "invalid flag: --username may not be specified when --github-app-private-key-file is specified")
fatalConfigErrorf(log, true, "invalid flag: --username may not be specified when --github-app-private-key-file is specified")
}
if *flPassword != "" {
fatalConfigError(log, true, "invalid flag: --password may not be specified when --github-app-private-key-file is specified")
fatalConfigErrorf(log, true, "invalid flag: --password may not be specified when --github-app-private-key-file is specified")
}
if *flPasswordFile != "" {
fatalConfigError(log, true, "invalid flag: --password-file may not be specified when --github-app-private-key-file is specified")
fatalConfigErrorf(log, true, "invalid flag: --password-file may not be specified when --github-app-private-key-file is specified")
}
} else {
if *flGithubAppApplicationID != 0 {
fatalConfigError(log, true, "invalid flag: --github-app-application-id may only be specified when --github-app-private-key-file is specified")
fatalConfigErrorf(log, true, "invalid flag: --github-app-application-id may only be specified when --github-app-private-key-file is specified")
}
if *flGithubAppInstallationID != 0 {
fatalConfigError(log, true, "invalid flag: --github-app-installation-id may only be specified when --github-app-private-key-file is specified")
fatalConfigErrorf(log, true, "invalid flag: --github-app-installation-id may only be specified when --github-app-private-key-file is specified")
}
}
if len(*flCredentials) > 0 {
for _, cred := range *flCredentials {
if cred.URL == "" {
fatalConfigError(log, true, "invalid flag: --credential URL must be specified")
fatalConfigErrorf(log, true, "invalid flag: --credential URL must be specified")
}
if cred.Username == "" {
fatalConfigError(log, true, "invalid flag: --credential username must be specified")
fatalConfigErrorf(log, true, "invalid flag: --credential username must be specified")
}
if cred.Password == "" && cred.PasswordFile == "" {
fatalConfigError(log, true, "invalid flag: --credential password or password-file must be specified")
fatalConfigErrorf(log, true, "invalid flag: --credential password or password-file must be specified")
}
if cred.Password != "" && cred.PasswordFile != "" {
fatalConfigError(log, true, "invalid flag: only one of --credential password and password-file may be specified")
fatalConfigErrorf(log, true, "invalid flag: only one of --credential password and password-file may be specified")
}
}
}
if *flHTTPBind == "" {
if *flHTTPMetrics {
fatalConfigError(log, true, "required flag: --http-bind must be specified when --http-metrics is set")
fatalConfigErrorf(log, true, "required flag: --http-bind must be specified when --http-metrics is set")
}
if *flHTTPprof {
fatalConfigError(log, true, "required flag: --http-bind must be specified when --http-pprof is set")
fatalConfigErrorf(log, true, "required flag: --http-bind must be specified when --http-pprof is set")
}
}
@ -1105,8 +1105,8 @@ func logSafeFlags(v int) []string {
}
// Handle --credential
if arg == "credential" {
orig := fl.Value.(*credentialSliceValue)
sl := []credential{} // make a copy of the slice so we can mutate it
orig := fl.Value.(*credentialSliceValue) //nolint:forcetypeassert
sl := []credential{} // make a copy of the slice so we can mutate it
for _, cred := range orig.value {
if cred.Password != "" {
cred.Password = redactedString
@ -1153,10 +1153,12 @@ func sleepForever() {
os.Exit(0)
}
// fatalConfigError prints the error to the standard error, prints the usage
// fatalConfigErrorf prints the error to the standard error, prints the usage
// if the `printUsage` flag is true, exports the error to the error file and
// exits the process with the exit code.
func fatalConfigError(log *logging.Logger, printUsage bool, format string, a ...interface{}) {
//
//nolint:unparam
func fatalConfigErrorf(log *logging.Logger, printUsage bool, format string, a ...interface{}) {
s := fmt.Sprintf(format, a...)
fmt.Fprintln(os.Stderr, s)
if printUsage {
@ -1399,7 +1401,7 @@ func dirIsEmpty(dir absPath) (bool, error) {
return len(dirents) == 0, nil
}
// removeDirContents iterated the specified dir and removes all contents
// removeDirContents iterated the specified dir and removes all contents.
func removeDirContents(dir absPath, log *logging.Logger) error {
return removeDirContentsIf(dir, log, func(fi os.FileInfo) (bool, error) {
return true, nil
@ -1445,7 +1447,7 @@ func removeDirContentsIf(dir absPath, log *logging.Logger, fn func(fi os.FileInf
// publishSymlink atomically sets link to point at the specified target. If the
// link existed, this returns the previous target.
func (git *repoSync) publishSymlink(ctx context.Context, worktree worktree) error {
func (git *repoSync) publishSymlink(worktree worktree) error {
targetPath := worktree.Path()
linkDir, linkFile := git.link.Split()
@ -1475,7 +1477,7 @@ func (git *repoSync) publishSymlink(ctx context.Context, worktree worktree) erro
return nil
}
// removeWorktree is used to remove a worktree and its folder
// removeWorktree is used to remove a worktree and its folder.
func (git *repoSync) removeWorktree(ctx context.Context, worktree worktree) error {
// Clean up worktree, if needed.
_, err := os.Stat(worktree.Path().String())
@ -1527,7 +1529,7 @@ func (git *repoSync) configureWorktree(ctx context.Context, worktree worktree) e
// /git/.git/worktrees/<worktree-dir-name>. Replace it with a reference
// using relative paths, so that other containers can use a different volume
// mount name.
rootDotGit := ""
var rootDotGit string
if rel, err := filepath.Rel(worktree.Path().String(), git.root.String()); err != nil {
return err
} else {
@ -1745,7 +1747,7 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
// Figure out what we got. The ^{} syntax "peels" annotated tags to
// their underlying commit hashes, but has no effect if we fetched a
// branch, plain tag, or hash.
remoteHash := ""
var remoteHash string
if output, _, err := git.Run(ctx, git.root, "rev-parse", "FETCH_HEAD^{}"); err != nil {
return false, "", err
} else {
@ -1802,7 +1804,7 @@ func (git *repoSync) SyncRepo(ctx context.Context, refreshCreds func(context.Con
// If we have a new hash, update the symlink to point to the new worktree.
if changed {
err := git.publishSymlink(ctx, newWorktree)
err := git.publishSymlink(newWorktree)
if err != nil {
return false, "", err
}
@ -1976,7 +1978,7 @@ func (git *repoSync) CallAskPassURL(ctx context.Context) error {
return http.ErrUseLastResponse
},
}
httpReq, err := http.NewRequestWithContext(ctx, "GET", git.authURL, nil)
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, git.authURL, nil)
if err != nil {
return fmt.Errorf("can't create auth request: %w", err)
}
@ -1987,7 +1989,7 @@ func (git *repoSync) CallAskPassURL(ctx context.Context) error {
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != 200 {
if resp.StatusCode != http.StatusOK {
errMessage, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("auth URL returned status %d, failed to read body: %w", resp.StatusCode, err)
@ -2021,7 +2023,8 @@ func (git *repoSync) CallAskPassURL(ctx context.Context) error {
return nil
}
// RefreshGitHubAppToken generates a new installation token for a GitHub app and stores it as a credential
// RefreshGitHubAppToken generates a new installation token for a GitHub app
// and stores it as a credential.
func (git *repoSync) RefreshGitHubAppToken(ctx context.Context, githubBaseURL, privateKey, privateKeyFile, clientID string, appID, installationID int) error {
git.log.V(3).Info("refreshing GitHub app token")
@ -2080,7 +2083,7 @@ func (git *repoSync) RefreshGitHubAppToken(ctx context.Context, githubBaseURL, p
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != 201 {
if resp.StatusCode != http.StatusCreated {
errMessage, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("GitHub app installation endpoint returned status %d, failed to read body: %w", resp.StatusCode, err)
@ -2247,8 +2250,8 @@ func parseGitConfigKey(r rune, ch <-chan rune) (string, error) {
buf = append(buf, r)
for r := range ch {
switch {
case r == ':':
switch r {
case ':':
return string(buf), nil
default:
buf = append(buf, r)
@ -2777,5 +2780,5 @@ HOOKS
`
func printManPage() {
fmt.Print(manual)
fmt.Fprint(os.Stdout, manual)
}

View File

@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package cmd provides an API to run commands and log them in a consistent
// way.
package cmd
import (
@ -40,7 +42,7 @@ type logintf interface {
WithCallDepth(depth int) logr.Logger
}
// NewRunner returns a new CommandRunner
// NewRunner returns a new CommandRunner.
func NewRunner(log logintf) Runner {
return Runner{log: log}
}

View File

@ -25,7 +25,7 @@ import (
"k8s.io/git-sync/pkg/cmd"
)
// Exechook structure, implements Hook
// Exechook implements Hook in terms of executing a command.
type Exechook struct {
// Runner
cmdrunner cmd.Runner
@ -41,7 +41,7 @@ type Exechook struct {
log logintf
}
// NewExechook returns a new Exechook
// NewExechook returns a new Exechook.
func NewExechook(cmdrunner cmd.Runner, command string, getWorktree func(string) string, args []string, timeout time.Duration, log logintf) *Exechook {
return &Exechook{
cmdrunner: cmdrunner,
@ -53,12 +53,12 @@ func NewExechook(cmdrunner cmd.Runner, command string, getWorktree func(string)
}
}
// Name describes hook, implements Hook.Name
// Name describes hook, implements Hook.Name.
func (h *Exechook) Name() string {
return "exechook"
}
// Do runs exechook.command, implements Hook.Do
// Do runs exechook.command, implements Hook.Do.
func (h *Exechook) Do(ctx context.Context, hash string) error {
ctx, cancel := context.WithTimeout(ctx, h.timeout)
defer cancel()

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package hook provides a way to run hooks in a controlled way.
package hook
import (
@ -38,7 +39,7 @@ func init() {
prometheus.MustRegister(hookRunCount)
}
// Describes what a Hook needs to implement, run by HookRunner
// Hook describes a single hook of some sort, which can be run by HookRunner.
type Hook interface {
// Describes hook
Name() string
@ -52,7 +53,7 @@ type hookData struct {
hash string
}
// NewHookData returns a new HookData
// NewHookData returns a new HookData.
func NewHookData() *hookData {
return &hookData{
ch: make(chan struct{}, 1),
@ -87,7 +88,7 @@ func (d *hookData) send(newHash string) {
}
}
// NewHookRunner returns a new HookRunner
// NewHookRunner returns a new HookRunner.
func NewHookRunner(hook Hook, backoff time.Duration, data *hookData, log logintf, oneTime bool) *HookRunner {
hr := &HookRunner{hook: hook, backoff: backoff, data: data, log: log}
if oneTime {
@ -96,7 +97,7 @@ func NewHookRunner(hook Hook, backoff time.Duration, data *hookData, log logintf
return hr
}
// HookRunner struct
// HookRunner struct.
type HookRunner struct {
// Hook to run and check
hook Hook
@ -118,12 +119,12 @@ type logintf interface {
V(level int) logr.Logger
}
// Send sends hash to hookdata
// Send sends hash to hookdata.
func (r *HookRunner) Send(hash string) {
r.data.send(hash)
}
// Run waits for trigger events from the channel, and run hook when triggered
// Run waits for trigger events from the channel, and run hook when triggered.
func (r *HookRunner) Run(ctx context.Context) {
var lastHash string
@ -171,7 +172,7 @@ func (r *HookRunner) sendOneTimeResultAndTerminate(completedSuccessfully bool) {
// WaitForCompletion waits for HookRunner to send completion message to
// calling thread and returns either true if HookRunner executed successfully
// and some error otherwise.
// Assumes that r.oneTimeResult is not nil, but if it is, returns an error
// Assumes that r.oneTimeResult is not nil, but if it is, returns an error.
func (r *HookRunner) WaitForCompletion() error {
// Make sure function should be called
if r.oneTimeResult == nil {

View File

@ -43,7 +43,7 @@ func TestHookData(t *testing.T) {
t.Run("last update wins when channel buffer is full", func(t *testing.T) {
hd := NewHookData()
for i := 0; i < 10; i++ {
for i := range 10 {
h := fmt.Sprintf("111111111111111111111111111111111111111%d", i)
hd.send(h)
}

View File

@ -24,7 +24,7 @@ import (
"time"
)
// WebHook structure, implements Hook
// Webhook implements Hook for HTTP requests.
type Webhook struct {
// Url for the http/s request
url string
@ -39,7 +39,7 @@ type Webhook struct {
log logintf
}
// NewWebhook returns a new WebHook
// NewWebhook returns a new WebHook.
func NewWebhook(url, method string, success int, timeout time.Duration, log logintf) *Webhook {
return &Webhook{
url: url,
@ -50,12 +50,12 @@ func NewWebhook(url, method string, success int, timeout time.Duration, log logi
}
}
// Name describes hook, implements Hook.Name
// Name describes hook, implements Hook.Name.
func (w *Webhook) Name() string {
return "webhook"
}
// Do calls webhook.url, implements Hook.Do
// Do calls webhook.url, implements Hook.Do.
func (w *Webhook) Do(ctx context.Context, hash string) error {
req, err := http.NewRequest(w.method, w.url, nil)
if err != nil {

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package logging provides a logging interface.
package logging
import (

View File

@ -14,6 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package pid1 provides a simple way to convert the current process into an
// init-like process. This is useful for containerized applications that need
// to manage child processes.
package pid1
import (
@ -53,6 +56,7 @@ func runInit(firstborn int) (int, error) {
for sig := range sigs {
if sig != syscall.SIGCHLD {
// Pass it on to the real process.
//nolint:forcetypeassert
if err := syscall.Kill(firstborn, sig.(syscall.Signal)); err != nil {
return 0, err
}

View File

@ -27,14 +27,14 @@ import (
func main() {
// In case we come up as pid 1, act as init.
if os.Getpid() == 1 {
fmt.Printf("detected pid 1, running as init\n")
fmt.Fprintf(os.Stdout, "detected pid 1, running as init\n")
code, err := pid1.ReRun()
if err == nil {
os.Exit(code)
}
fmt.Printf("unhandled pid1 error: %v\n", err)
fmt.Fprintf(os.Stdout, "unhandled pid1 error: %v\n", err)
os.Exit(127)
}
fmt.Printf("main app\n")
fmt.Fprintf(os.Stdout, "main app\n")
os.Exit(42)
}

View File

@ -14,6 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package version contains version information for the current binary.
package version
// VERSION is the version of the binary. This can be set by the linker at
// build time.
var VERSION = "UNKNOWN"