Short build tag in version number (#2658)

* use short commit hash in version number
* var -> const
* cscli: extract version.go, doc.go
* don't repeat commit hash in version number
This commit is contained in:
mmetc 2023-12-14 09:16:38 +01:00 committed by GitHub
parent 51f70e47e3
commit 67cdf91f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 107 deletions

49
cmd/crowdsec-cli/doc.go Normal file
View file

@ -0,0 +1,49 @@
package main
import (
"fmt"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
type cliDoc struct{}
func NewCLIDoc() *cliDoc {
return &cliDoc{}
}
func (cli cliDoc) NewCommand(rootCmd *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "doc",
Short: "Generate the documentation in `./doc/`. Directory must exist.",
Args: cobra.ExactArgs(0),
Hidden: true,
DisableAutoGenTag: true,
RunE: func(_ *cobra.Command, _ []string) error {
if err := doc.GenMarkdownTreeCustom(rootCmd, "./doc/", cli.filePrepender, cli.linkHandler); err != nil {
return fmt.Errorf("failed to generate cobra doc: %s", err)
}
return nil
},
}
return cmd
}
func (cli cliDoc) filePrepender(filename string) string {
const header = `---
id: %s
title: %s
---
`
name := filepath.Base(filename)
base := strings.TrimSuffix(name, filepath.Ext(name))
return fmt.Sprintf(header, base, strings.ReplaceAll(base, "_", " "))
}
func (cli cliDoc) linkHandler(name string) string {
return fmt.Sprintf("/cscli/%s", name)
}

View file

@ -1,21 +1,15 @@
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"slices"
"github.com/fatih/color"
cc "github.com/ivanpirog/coloredcobra"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"slices"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/fflag"
)
@ -36,6 +30,7 @@ var flagBranch = ""
func initConfig() {
var err error
if trace_lvl {
log.SetLevel(log.TraceLevel)
} else if dbg_lvl {
@ -70,6 +65,7 @@ func initConfig() {
if OutputFormat != "" {
csConfig.Cscli.Output = OutputFormat
if OutputFormat != "json" && OutputFormat != "raw" && OutputFormat != "human" {
log.Fatalf("output format %s unknown", OutputFormat)
}
@ -86,12 +82,14 @@ func initConfig() {
if OutputColor != "" {
csConfig.Cscli.Color = OutputColor
if OutputColor != "yes" && OutputColor != "no" && OutputColor != "auto" {
log.Fatalf("output color %s unknown", OutputColor)
}
}
}
// list of valid subcommands for the shell completion
var validArgs = []string{
"alerts", "appsec-configs", "appsec-rules", "bouncers", "capi", "collections",
"completion", "config", "console", "contexts", "dashboard", "decisions", "explain",
@ -99,30 +97,14 @@ var validArgs = []string{
"postoverflows", "scenarios", "simulation", "support", "version",
}
func prepender(filename string) string {
const header = `---
id: %s
title: %s
---
`
name := filepath.Base(filename)
base := strings.TrimSuffix(name, filepath.Ext(name))
return fmt.Sprintf(header, base, strings.ReplaceAll(base, "_", " "))
var NoNeedConfig = []string{
"doc",
"help",
"completion",
"version",
"hubtest",
}
func linkHandler(name string) string {
return fmt.Sprintf("/cscli/%s", name)
}
var (
NoNeedConfig = []string{
"help",
"completion",
"version",
"hubtest",
}
)
func main() {
// set the formatter asap and worry about level later
logFormatter := &log.TextFormatter{TimestampFormat: "2006-01-02 15:04:05", FullTimestamp: true}
@ -136,7 +118,7 @@ func main() {
log.Fatalf("failed to set feature flags from env: %s", err)
}
var rootCmd = &cobra.Command{
cmd := &cobra.Command{
Use: "cscli",
Short: "cscli allows you to manage crowdsec",
Long: `cscli is the main command to interact with your crowdsec service, scenarios & db.
@ -149,7 +131,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
}
cc.Init(&cc.Config{
RootCmd: rootCmd,
RootCmd: cmd,
Headings: cc.Yellow,
Commands: cc.Green + cc.Bold,
CmdShortDescr: cc.Cyan,
@ -160,45 +142,19 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
Flags: cc.Green,
FlagsDescr: cc.Cyan,
})
rootCmd.SetOut(color.Output)
cmd.SetOut(color.Output)
var cmdDocGen = &cobra.Command{
Use: "doc",
Short: "Generate the documentation in `./doc/`. Directory must exist.",
Args: cobra.ExactArgs(0),
Hidden: true,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
if err := doc.GenMarkdownTreeCustom(rootCmd, "./doc/", prepender, linkHandler); err != nil {
return fmt.Errorf("Failed to generate cobra doc: %s", err)
}
return nil
},
}
rootCmd.AddCommand(cmdDocGen)
/*usage*/
var cmdVersion = &cobra.Command{
Use: "version",
Short: "Display version",
Args: cobra.ExactArgs(0),
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
cwversion.Show()
},
}
rootCmd.AddCommand(cmdVersion)
cmd.PersistentFlags().StringVarP(&ConfigFilePath, "config", "c", csconfig.DefaultConfigPath("config.yaml"), "path to crowdsec config file")
cmd.PersistentFlags().StringVarP(&OutputFormat, "output", "o", "", "Output format: human, json, raw")
cmd.PersistentFlags().StringVarP(&OutputColor, "color", "", "auto", "Output color: yes, no, auto")
cmd.PersistentFlags().BoolVar(&dbg_lvl, "debug", false, "Set logging to debug")
cmd.PersistentFlags().BoolVar(&nfo_lvl, "info", false, "Set logging to info")
cmd.PersistentFlags().BoolVar(&wrn_lvl, "warning", false, "Set logging to warning")
cmd.PersistentFlags().BoolVar(&err_lvl, "error", false, "Set logging to error")
cmd.PersistentFlags().BoolVar(&trace_lvl, "trace", false, "Set logging to trace")
rootCmd.PersistentFlags().StringVarP(&ConfigFilePath, "config", "c", csconfig.DefaultConfigPath("config.yaml"), "path to crowdsec config file")
rootCmd.PersistentFlags().StringVarP(&OutputFormat, "output", "o", "", "Output format: human, json, raw")
rootCmd.PersistentFlags().StringVarP(&OutputColor, "color", "", "auto", "Output color: yes, no, auto")
rootCmd.PersistentFlags().BoolVar(&dbg_lvl, "debug", false, "Set logging to debug")
rootCmd.PersistentFlags().BoolVar(&nfo_lvl, "info", false, "Set logging to info")
rootCmd.PersistentFlags().BoolVar(&wrn_lvl, "warning", false, "Set logging to warning")
rootCmd.PersistentFlags().BoolVar(&err_lvl, "error", false, "Set logging to error")
rootCmd.PersistentFlags().BoolVar(&trace_lvl, "trace", false, "Set logging to trace")
rootCmd.PersistentFlags().StringVar(&flagBranch, "branch", "", "Override hub branch on github")
if err := rootCmd.PersistentFlags().MarkHidden("branch"); err != nil {
cmd.PersistentFlags().StringVar(&flagBranch, "branch", "", "Override hub branch on github")
if err := cmd.PersistentFlags().MarkHidden("branch"); err != nil {
log.Fatalf("failed to hide flag: %s", err)
}
@ -222,44 +178,46 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
}
/*don't sort flags so we can enforce order*/
rootCmd.Flags().SortFlags = false
rootCmd.PersistentFlags().SortFlags = false
cmd.Flags().SortFlags = false
cmd.PersistentFlags().SortFlags = false
rootCmd.AddCommand(NewConfigCmd())
rootCmd.AddCommand(NewCLIHub().NewCommand())
rootCmd.AddCommand(NewMetricsCmd())
rootCmd.AddCommand(NewCLIDashboard().NewCommand())
rootCmd.AddCommand(NewCLIDecisions().NewCommand())
rootCmd.AddCommand(NewCLIAlerts().NewCommand())
rootCmd.AddCommand(NewCLISimulation().NewCommand())
rootCmd.AddCommand(NewCLIBouncers().NewCommand())
rootCmd.AddCommand(NewCLIMachines().NewCommand())
rootCmd.AddCommand(NewCLICapi().NewCommand())
rootCmd.AddCommand(NewLapiCmd())
rootCmd.AddCommand(NewCompletionCmd())
rootCmd.AddCommand(NewConsoleCmd())
rootCmd.AddCommand(NewCLIExplain().NewCommand())
rootCmd.AddCommand(NewCLIHubTest().NewCommand())
rootCmd.AddCommand(NewCLINotifications().NewCommand())
rootCmd.AddCommand(NewCLISupport().NewCommand())
rootCmd.AddCommand(NewCLIPapi().NewCommand())
rootCmd.AddCommand(NewCLICollection().NewCommand())
rootCmd.AddCommand(NewCLIParser().NewCommand())
rootCmd.AddCommand(NewCLIScenario().NewCommand())
rootCmd.AddCommand(NewCLIPostOverflow().NewCommand())
rootCmd.AddCommand(NewCLIContext().NewCommand())
rootCmd.AddCommand(NewCLIAppsecConfig().NewCommand())
rootCmd.AddCommand(NewCLIAppsecRule().NewCommand())
cmd.AddCommand(NewCLIDoc().NewCommand(cmd))
cmd.AddCommand(NewCLIVersion().NewCommand())
cmd.AddCommand(NewConfigCmd())
cmd.AddCommand(NewCLIHub().NewCommand())
cmd.AddCommand(NewMetricsCmd())
cmd.AddCommand(NewCLIDashboard().NewCommand())
cmd.AddCommand(NewCLIDecisions().NewCommand())
cmd.AddCommand(NewCLIAlerts().NewCommand())
cmd.AddCommand(NewCLISimulation().NewCommand())
cmd.AddCommand(NewCLIBouncers().NewCommand())
cmd.AddCommand(NewCLIMachines().NewCommand())
cmd.AddCommand(NewCLICapi().NewCommand())
cmd.AddCommand(NewLapiCmd())
cmd.AddCommand(NewCompletionCmd())
cmd.AddCommand(NewConsoleCmd())
cmd.AddCommand(NewCLIExplain().NewCommand())
cmd.AddCommand(NewCLIHubTest().NewCommand())
cmd.AddCommand(NewCLINotifications().NewCommand())
cmd.AddCommand(NewCLISupport().NewCommand())
cmd.AddCommand(NewCLIPapi().NewCommand())
cmd.AddCommand(NewCLICollection().NewCommand())
cmd.AddCommand(NewCLIParser().NewCommand())
cmd.AddCommand(NewCLIScenario().NewCommand())
cmd.AddCommand(NewCLIPostOverflow().NewCommand())
cmd.AddCommand(NewCLIContext().NewCommand())
cmd.AddCommand(NewCLIAppsecConfig().NewCommand())
cmd.AddCommand(NewCLIAppsecRule().NewCommand())
if fflag.CscliSetup.IsEnabled() {
rootCmd.AddCommand(NewSetupCmd())
cmd.AddCommand(NewSetupCmd())
}
if fflag.PapiClient.IsEnabled() {
rootCmd.AddCommand(NewCLIPapi().NewCommand())
cmd.AddCommand(NewCLIPapi().NewCommand())
}
if err := rootCmd.Execute(); err != nil {
if err := cmd.Execute(); err != nil {
log.Fatal(err)
}
}

View file

@ -0,0 +1,27 @@
package main
import (
"github.com/spf13/cobra"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
)
type cliVersion struct{}
func NewCLIVersion() *cliVersion {
return &cliVersion{}
}
func (cli cliVersion) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Display version",
Args: cobra.ExactArgs(0),
DisableAutoGenTag: true,
Run: func(_ *cobra.Command, _ []string) {
cwversion.Show()
},
}
return cmd
}

View file

@ -1,7 +1,7 @@
BUILD_CODENAME ?= alphaga
GOARCH ?= $(shell go env GOARCH)
BUILD_TAG ?= $(shell git rev-parse HEAD)
BUILD_TAG ?= $(shell git rev-parse --short HEAD)
ifeq ($(OS), Windows_NT)
SHELL := pwsh.exe

View file

@ -9,32 +9,45 @@ import (
"strings"
goversion "github.com/hashicorp/go-version"
"github.com/crowdsecurity/go-cs-lib/version"
)
var (
Codename string // = "SoumSoum"
System = runtime.GOOS // = "linux"
Codename string // = "SoumSoum"
System = runtime.GOOS // = "linux"
Libre2 = "WebAssembly"
)
const (
Constraint_parser = ">= 1.0, <= 2.0"
Constraint_scenario = ">= 1.0, < 3.0"
Constraint_api = "v1"
Constraint_acquis = ">= 1.0, < 2.0"
Libre2 = "WebAssembly"
)
func versionWithTag() string {
ret := version.Version
if !strings.HasSuffix(ret, version.Tag) {
ret += fmt.Sprintf("-%s", version.Tag)
}
return ret
}
func ShowStr() string {
ret := ""
ret += fmt.Sprintf("version: %s-%s\n", version.Version, version.Tag)
ret := fmt.Sprintf("version: %s", versionWithTag())
ret += fmt.Sprintf("Codename: %s\n", Codename)
ret += fmt.Sprintf("BuildDate: %s\n", version.BuildDate)
ret += fmt.Sprintf("GoVersion: %s\n", version.GoVersion)
ret += fmt.Sprintf("Platform: %s\n", System)
return ret
}
func Show() {
log.Printf("version: %s-%s", version.Version, version.Tag)
log.Printf("version: %s", versionWithTag())
log.Printf("Codename: %s", Codename)
log.Printf("BuildDate: %s", version.BuildDate)
log.Printf("GoVersion: %s", version.GoVersion)
@ -53,6 +66,7 @@ func VersionStr() string {
func VersionStrip() string {
version := strings.Split(version.Version, "~")
version = strings.Split(version[0], "-")
return version[0]
}
@ -61,13 +75,16 @@ func Satisfies(strvers string, constraint string) (bool, error) {
if err != nil {
return false, fmt.Errorf("failed to parse '%s' : %v", strvers, err)
}
constraints, err := goversion.NewConstraint(constraint)
if err != nil {
return false, fmt.Errorf("failed to parse constraint '%s'", constraint)
}
if !constraints.Check(vers) {
return false, nil
}
return true, nil
}
@ -85,6 +102,7 @@ func Latest() (string, error) {
if err != nil {
return "", err
}
if _, ok := latest["name"]; !ok {
return "", fmt.Errorf("unable to find latest release name from github api: %+v", latest)
}

View file

@ -334,7 +334,7 @@ teardown() {
cd "$BATS_TEST_TMPDIR"
rune -1 cscli doc
refute_output
assert_stderr --regexp 'Failed to generate cobra doc: open doc/.*: no such file or directory'
assert_stderr --regexp 'failed to generate cobra doc: open doc/.*: no such file or directory'
mkdir -p doc
rune -0 cscli doc