mirror of
https://github.com/thegeeklab/drone-admin.git
synced 2024-11-27 00:10:35 +00:00
refactor: add more linters and fix findings (#41)
This commit is contained in:
parent
5b1ee2a1b7
commit
db28a0858b
10
.drone.yml
10
.drone.yml
@ -8,7 +8,7 @@ platform:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: deps
|
- name: deps
|
||||||
image: golang:1.19
|
image: golang:1.20
|
||||||
commands:
|
commands:
|
||||||
- make deps
|
- make deps
|
||||||
volumes:
|
volumes:
|
||||||
@ -16,7 +16,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: lint
|
- name: lint
|
||||||
image: golang:1.19
|
image: golang:1.20
|
||||||
commands:
|
commands:
|
||||||
- make lint
|
- make lint
|
||||||
volumes:
|
volumes:
|
||||||
@ -24,7 +24,7 @@ steps:
|
|||||||
path: /go
|
path: /go
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
image: golang:1.19
|
image: golang:1.20
|
||||||
commands:
|
commands:
|
||||||
- make test
|
- make test
|
||||||
volumes:
|
volumes:
|
||||||
@ -51,7 +51,7 @@ platform:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: build
|
||||||
image: techknowlogick/xgo:go-1.19.x
|
image: techknowlogick/xgo:go-1.20.x
|
||||||
commands:
|
commands:
|
||||||
- ln -s /drone/src /source
|
- ln -s /drone/src /source
|
||||||
- make release
|
- make release
|
||||||
@ -292,6 +292,6 @@ depends_on:
|
|||||||
|
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: ccad191c33e8df2f7c7c51f10e2e2999e5e6f46a8a50de9aa1e8a5ae6c116600
|
hmac: ed52cf54615cff7806ee5d08c981a280bdd31d42bd1af00096686a60727a5526
|
||||||
|
|
||||||
...
|
...
|
||||||
|
114
.golangci.yml
114
.golangci.yml
@ -1,25 +1,92 @@
|
|||||||
linters:
|
linters:
|
||||||
enable:
|
|
||||||
- gosimple
|
|
||||||
- deadcode
|
|
||||||
- typecheck
|
|
||||||
- govet
|
|
||||||
- errcheck
|
|
||||||
- staticcheck
|
|
||||||
- unused
|
|
||||||
- structcheck
|
|
||||||
- varcheck
|
|
||||||
- dupl
|
|
||||||
- gofmt
|
|
||||||
- misspell
|
|
||||||
- gocritic
|
|
||||||
- bidichk
|
|
||||||
- ineffassign
|
|
||||||
- revive
|
|
||||||
- gofumpt
|
|
||||||
- depguard
|
|
||||||
enable-all: false
|
enable-all: false
|
||||||
disable-all: true
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- errcheck
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- staticcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- asasalint
|
||||||
|
- asciicheck
|
||||||
|
- bidichk
|
||||||
|
- bodyclose
|
||||||
|
- containedctx
|
||||||
|
- contextcheck
|
||||||
|
- decorder
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- dupword
|
||||||
|
- durationcheck
|
||||||
|
- errchkjson
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- execinquery
|
||||||
|
- exhaustive
|
||||||
|
- exportloopref
|
||||||
|
- forcetypeassert
|
||||||
|
- ginkgolinter
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
- gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- godot
|
||||||
|
- godox
|
||||||
|
- goerr113
|
||||||
|
- gofmt
|
||||||
|
- gofumpt
|
||||||
|
- goheader
|
||||||
|
- goimports
|
||||||
|
- gomnd
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- grouper
|
||||||
|
- importas
|
||||||
|
- interfacebloat
|
||||||
|
- ireturn
|
||||||
|
- lll
|
||||||
|
- loggercheck
|
||||||
|
- maintidx
|
||||||
|
- makezero
|
||||||
|
- misspell
|
||||||
|
- musttag
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- nlreturn
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- nosprintfhostport
|
||||||
|
- prealloc
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- reassign
|
||||||
|
- revive
|
||||||
|
# - rowserrcheck
|
||||||
|
# - sqlclosecheck
|
||||||
|
# - structcheck
|
||||||
|
- stylecheck
|
||||||
|
- tagliatelle
|
||||||
|
- tenv
|
||||||
|
- testableexamples
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- usestdlibvars
|
||||||
|
# - wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wsl
|
||||||
fast: false
|
fast: false
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@ -28,4 +95,11 @@ run:
|
|||||||
linters-settings:
|
linters-settings:
|
||||||
gofumpt:
|
gofumpt:
|
||||||
extra-rules: true
|
extra-rules: true
|
||||||
lang-version: "1.18"
|
lang-version: "1.20"
|
||||||
|
ireturn:
|
||||||
|
allow:
|
||||||
|
- anon
|
||||||
|
- error
|
||||||
|
- empty
|
||||||
|
- stdlib
|
||||||
|
- drone.Client
|
||||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
|||||||
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
# renovate: datasource=github-releases depName=mvdan/gofumpt
|
||||||
GOFUMPT_PACKAGE_VERSION := v0.4.0
|
GOFUMPT_PACKAGE_VERSION := v0.4.0
|
||||||
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
# renovate: datasource=github-releases depName=golangci/golangci-lint
|
||||||
GOLANGCI_LINT_PACKAGE_VERSION := v1.50.1
|
GOLANGCI_LINT_PACKAGE_VERSION := v1.51.1
|
||||||
|
|
||||||
EXECUTABLE := drone-admin
|
EXECUTABLE := drone-admin
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(G
|
|||||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||||
|
|
||||||
GENERATE ?=
|
GENERATE ?=
|
||||||
XGO_VERSION := go-1.19.x
|
XGO_VERSION := go-1.20.x
|
||||||
XGO_TARGETS ?= linux/amd64,linux/arm64,linux/arm-6,linux/arm-7
|
XGO_TARGETS ?= linux/amd64,linux/arm64,linux/arm-6,linux/arm-7
|
||||||
|
|
||||||
TARGETOS ?= linux
|
TARGETOS ?= linux
|
||||||
|
@ -2,10 +2,12 @@ package autoscaler
|
|||||||
|
|
||||||
import "github.com/urfave/cli/v2"
|
import "github.com/urfave/cli/v2"
|
||||||
|
|
||||||
var Command = &cli.Command{
|
func GetAutoscalerCmd() *cli.Command {
|
||||||
Name: "autoscaler",
|
return &cli.Command{
|
||||||
Usage: "manage autoscaler",
|
Name: "autoscaler",
|
||||||
Subcommands: []*cli.Command{
|
Usage: "manage autoscaler",
|
||||||
&autoscalerReaperCmd,
|
Subcommands: []*cli.Command{
|
||||||
},
|
getReaperCmd(),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,24 +11,28 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var autoscalerReaperCmd = cli.Command{
|
func getReaperCmd() *cli.Command {
|
||||||
Name: "reaper",
|
return &cli.Command{
|
||||||
Usage: "find and kill agents in error state",
|
Name: "reaper",
|
||||||
Action: autoscalerReaper,
|
Usage: "find and kill agents in error state",
|
||||||
Flags: []cli.Flag{
|
Action: reaper,
|
||||||
&cli.StringFlag{
|
Flags: []cli.Flag{
|
||||||
Name: "state-file",
|
&cli.StringFlag{
|
||||||
Usage: "state file",
|
Name: "state-file",
|
||||||
EnvVars: []string{"DRONE_ADMIN_AUTOSCALER_REAPER_STATE_FILE"},
|
Usage: "state file",
|
||||||
Value: "/tmp/droneclean.gob",
|
EnvVars: []string{"DRONE_ADMIN_AUTOSCALER_REAPER_STATE_FILE"},
|
||||||
|
Value: "/tmp/droneclean.gob",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func autoscalerReaper(c *cli.Context) error {
|
func reaper(ctx *cli.Context) error {
|
||||||
statefile := c.String("state-file")
|
const maxRetries = 3
|
||||||
scaler := c.StringSlice("server")
|
|
||||||
dry := c.Bool("dry-run")
|
statefile := ctx.String("state-file")
|
||||||
|
scaler := ctx.StringSlice("server")
|
||||||
|
dry := ctx.Bool("dry-run")
|
||||||
state := map[string]int{}
|
state := map[string]int{}
|
||||||
force := false
|
force := false
|
||||||
|
|
||||||
@ -44,7 +48,7 @@ func autoscalerReaper(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, scaler := range scaler {
|
for _, scaler := range scaler {
|
||||||
client, err := client.New(scaler, c.String("token"))
|
client, err := client.New(scaler, ctx.String("token"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -53,6 +57,7 @@ func autoscalerReaper(c *cli.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
serversAll := len(servers)
|
serversAll := len(servers)
|
||||||
servers = util.Filter(servers, func(s *drone.Server) bool {
|
servers = util.Filter(servers, func(s *drone.Server) bool {
|
||||||
return s.State == "running"
|
return s.State == "running"
|
||||||
@ -65,25 +70,26 @@ func autoscalerReaper(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
logrus.WithFields(searchFields).Infof("lookup agents in error state")
|
logrus.WithFields(searchFields).Infof("lookup agents in error state")
|
||||||
|
|
||||||
for _, s := range servers {
|
for _, server := range servers {
|
||||||
state[s.Name]++
|
state[server.Name]++
|
||||||
triage := state[s.Name]
|
triage := state[server.Name]
|
||||||
|
|
||||||
if state[s.Name] == 3 {
|
if state[server.Name] == maxRetries {
|
||||||
force = true
|
force = true
|
||||||
delete(state, s.Name)
|
|
||||||
|
|
||||||
|
delete(state, server.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
foundFields := logrus.Fields{
|
foundFields := logrus.Fields{
|
||||||
"server": scaler,
|
"server": scaler,
|
||||||
"agent": s.Name,
|
"agent": server.Name,
|
||||||
"triage": triage,
|
"triage": triage,
|
||||||
"force": force,
|
"force": force,
|
||||||
}
|
}
|
||||||
logrus.WithFields(foundFields).Infof("destroy agent")
|
logrus.WithFields(foundFields).Infof("destroy agent")
|
||||||
|
|
||||||
if !dry {
|
if !dry {
|
||||||
err = serverDestroy(client, s.Name, force)
|
err = serverDestroy(client, server.Name, force)
|
||||||
if err != nil && !strings.Contains(err.Error(), "client error 404") {
|
if err != nil && !strings.Contains(err.Error(), "client error 404") {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ package build
|
|||||||
|
|
||||||
import "github.com/urfave/cli/v2"
|
import "github.com/urfave/cli/v2"
|
||||||
|
|
||||||
var Command = &cli.Command{
|
func GetBuildCmd() *cli.Command {
|
||||||
Name: "build",
|
return &cli.Command{
|
||||||
Usage: "manage build",
|
Name: "build",
|
||||||
Subcommands: []*cli.Command{
|
Usage: "manage build",
|
||||||
&buidPruneCmd,
|
Subcommands: []*cli.Command{
|
||||||
},
|
getPruneCmd(),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,29 +11,34 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var buidPruneCmd = cli.Command{
|
const DroneClientPageSize = 50
|
||||||
Name: "prune",
|
|
||||||
Usage: "prune builds",
|
func getPruneCmd() *cli.Command {
|
||||||
ArgsUsage: "<repo/name>",
|
return &cli.Command{
|
||||||
Action: buidPrune,
|
Name: "prune",
|
||||||
Flags: []cli.Flag{
|
Usage: "prune builds",
|
||||||
&cli.StringFlag{
|
ArgsUsage: "<repo/name>",
|
||||||
Name: "older-than",
|
Action: prune,
|
||||||
Usage: "remove builds older than the specified time limit",
|
Flags: []cli.Flag{
|
||||||
EnvVars: []string{"DRONE_ADMIN_BUILD_PRUNE_OLDER_THAN"},
|
&cli.StringFlag{
|
||||||
Required: true,
|
Name: "older-than",
|
||||||
|
Usage: "remove builds older than the specified time limit",
|
||||||
|
EnvVars: []string{"DRONE_ADMIN_BUILD_PRUNE_OLDER_THAN"},
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "keep-min",
|
||||||
|
Usage: "minimum number of builds to keep",
|
||||||
|
EnvVars: []string{"DRONE_ADMIN_BUILD_PRUNE_KEEP_MIN"},
|
||||||
|
//nolint:gomnd
|
||||||
|
Value: 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
&cli.IntFlag{
|
}
|
||||||
Name: "keep-min",
|
|
||||||
Usage: "minimum number of builds to keep",
|
|
||||||
EnvVars: []string{"DRONE_ADMIN_BUILD_PRUNE_KEEP_MIN"},
|
|
||||||
Value: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buidPrune(c *cli.Context) error {
|
func prune(ctx *cli.Context) error {
|
||||||
client, err := client.New(c.StringSlice("server")[0], c.String("token"))
|
client, err := client.New(ctx.StringSlice("server")[0], ctx.String("token"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -43,11 +48,11 @@ func buidPrune(c *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dur := c.String("older-than")
|
buildDuration := ctx.String("older-than")
|
||||||
keep := c.Int("keep-min")
|
buildMin := ctx.Int("keep-min")
|
||||||
dry := c.Bool("dry-run")
|
dry := ctx.Bool("dry-run")
|
||||||
|
|
||||||
duration, err := time.ParseDuration(dur)
|
duration, err := time.ParseDuration(buildDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -56,10 +61,10 @@ func buidPrune(c *cli.Context) error {
|
|||||||
logrus.Info("dry-run enabled, no data will be removed")
|
logrus.Info("dry-run enabled, no data will be removed")
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof("prune builds older than %v, keep min %v", dur, keep)
|
logrus.Infof("prune builds older than %v, keep min %v", buildDuration, buildMin)
|
||||||
|
|
||||||
for _, r := range repos {
|
for _, repo := range repos {
|
||||||
builds, err := getBuilds(client, r)
|
builds, err := getBuilds(client, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -68,24 +73,23 @@ func buidPrune(c *cli.Context) error {
|
|||||||
return builds[i].Number > builds[j].Number
|
return builds[i].Number > builds[j].Number
|
||||||
})
|
})
|
||||||
|
|
||||||
if bl := len(builds); bl > 0 && bl > keep {
|
if buildCount := len(builds); buildCount > 0 && buildCount > buildMin {
|
||||||
builds = builds[keep:]
|
builds = builds[buildMin:]
|
||||||
builds = util.Filter(builds, func(b *drone.Build) bool {
|
builds = util.Filter(builds, func(b *drone.Build) bool {
|
||||||
return time.Since(time.Unix(b.Created, 0)) > duration
|
return time.Since(time.Unix(b.Created, 0)) > duration
|
||||||
})
|
})
|
||||||
|
|
||||||
logrus.Infof("prune %v/%v builds from '%v'", len(builds), bl, r.Slug)
|
logrus.Infof("prune %v/%v builds from '%v'", len(builds), buildCount, repo.Slug)
|
||||||
|
|
||||||
if !dry && len(builds) > 0 {
|
if !dry && len(builds) > 0 {
|
||||||
err := client.BuildPurge(r.Namespace, r.Name, int(builds[0].Number+1))
|
err := client.BuildPurge(repo.Namespace, repo.Name, int(builds[0].Number+1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logrus.Infof("skip '%v', number of %v builds lower than min value", r.Slug, len(builds))
|
logrus.Infof("skip '%v', number of %v builds lower than min value", repo.Slug, len(builds))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -96,21 +100,21 @@ func getRepos(client drone.Client) ([]*drone.Repo, error) {
|
|||||||
repos := make([]*drone.Repo, 0)
|
repos := make([]*drone.Repo, 0)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
r, err := client.RepoListAll(drone.ListOptions{Page: page, Size: 50})
|
repo, err := client.RepoListAll(drone.ListOptions{Page: page, Size: DroneClientPageSize})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(r) == 0 {
|
if len(repo) == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
repos = append(repos, r...)
|
repos = append(repos, repo...)
|
||||||
page++
|
page++
|
||||||
}
|
}
|
||||||
|
|
||||||
repos = util.Filter(repos, func(r *drone.Repo) bool {
|
repos = util.Filter(repos, func(repo *drone.Repo) bool {
|
||||||
return r.Active
|
return repo.Active
|
||||||
})
|
})
|
||||||
|
|
||||||
return repos, nil
|
return repos, nil
|
||||||
@ -121,17 +125,18 @@ func getBuilds(client drone.Client, repo *drone.Repo) ([]*drone.Build, error) {
|
|||||||
builds := make([]*drone.Build, 0)
|
builds := make([]*drone.Build, 0)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
b, err := client.BuildList(repo.Namespace, repo.Name, drone.ListOptions{Page: page, Size: 50})
|
build, err := client.BuildList(repo.Namespace, repo.Name, drone.ListOptions{Page: page, Size: DroneClientPageSize})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) == 0 {
|
if len(build) == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
builds = append(builds, b...)
|
builds = append(builds, build...)
|
||||||
page++
|
page++
|
||||||
}
|
}
|
||||||
|
|
||||||
return builds, nil
|
return builds, nil
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func New(server, token string) (drone.Client, error) {
|
func New(server, token string) (drone.Client, error) {
|
||||||
s, err := url.Parse(server)
|
serverURL, err := url.Parse(server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(s.Scheme) == 0 {
|
|
||||||
s.Scheme = "http"
|
if len(serverURL.Scheme) == 0 {
|
||||||
|
serverURL.Scheme = "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
// attempt to find system CA certs
|
// attempt to find system CA certs
|
||||||
@ -26,6 +27,7 @@ func New(server, token string) (drone.Client, error) {
|
|||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
RootCAs: certs,
|
RootCAs: certs,
|
||||||
InsecureSkipVerify: false,
|
InsecureSkipVerify: false,
|
||||||
|
MinVersion: tls.VersionTLS12,
|
||||||
}
|
}
|
||||||
|
|
||||||
oauth := new(oauth2.Config)
|
oauth := new(oauth2.Config)
|
||||||
@ -44,5 +46,5 @@ func New(server, token string) (drone.Client, error) {
|
|||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
}
|
}
|
||||||
|
|
||||||
return drone.NewClient(s.String(), authenticator), nil
|
return drone.NewClient(serverURL.String(), authenticator), nil
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,13 @@ import (
|
|||||||
|
|
||||||
func Filter[T any](vs []T, f func(T) bool) []T {
|
func Filter[T any](vs []T, f func(T) bool) []T {
|
||||||
filtered := make([]T, 0)
|
filtered := make([]T, 0)
|
||||||
|
|
||||||
for _, v := range vs {
|
for _, v := range vs {
|
||||||
if f(v) {
|
if f(v) {
|
||||||
filtered = append(filtered, v)
|
filtered = append(filtered, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +23,9 @@ func WriteGob(filePath string, object interface{}) error {
|
|||||||
encoder := gob.NewEncoder(file)
|
encoder := gob.NewEncoder(file)
|
||||||
err = encoder.Encode(object)
|
err = encoder.Encode(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Close()
|
file.Close()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +35,8 @@ func ReadGob(filePath string, object interface{}) error {
|
|||||||
decoder := gob.NewDecoder(file)
|
decoder := gob.NewDecoder(file)
|
||||||
err = decoder.Decode(object)
|
err = decoder.Decode(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Close()
|
file.Close()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//nolint:gochecknoglobals
|
||||||
var (
|
var (
|
||||||
BuildVersion = "devel"
|
BuildVersion = "devel"
|
||||||
BuildDate = "00000000"
|
BuildDate = "00000000"
|
||||||
@ -69,8 +70,8 @@ func main() {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
build.Command,
|
build.GetBuildCmd(),
|
||||||
autoscaler.Command,
|
autoscaler.GetAutoscalerCmd(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user