diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b3913c0..d0ad786a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: release on: push: tags: - - 'v*' + - "v*" jobs: release: @@ -11,19 +11,18 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v6 with: - go-version: '1.23' - cache: false + go-version: "1.25.5" - name: Create release notes run: ./scripts/release.sh - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c1a5b592..3a5a2f36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: pull_request: branches: [main] paths-ignore: - - '**.md' + - "**.md" jobs: test: name: test @@ -12,20 +12,21 @@ jobs: strategy: matrix: os: [ubuntu-latest] - go: ['1.23'] + go: ["1.25.5"] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v6 with: - go-version: '1.23' - cache: false + go-version: "1.25.5" - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v9 + with: + version: v2.7.1 - name: Get dependencies run: go get -v -t -d ./... diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..7609c255 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,9 @@ +version: "2" + +linters: + settings: + errcheck: + exclude-functions: + - fmt.Fprintf + - fmt.Fprint + - (io.Closer).Close diff --git a/.goreleaser.yml b/.goreleaser.yaml similarity index 100% rename from .goreleaser.yml rename to .goreleaser.yaml diff --git a/Makefile b/Makefile index 74838ba1..0a5ffb19 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ NAME := mani PACKAGE := github.com/alajmo/$(NAME) DATE := $(shell date +"%Y %B %d") GIT := $(shell [ -d .git ] && git rev-parse --short HEAD) -VERSION := v0.31.1 +VERSION := v0.31.2 default: build @@ -19,7 +19,7 @@ gofmt: go fmt ./test/integration/***.go lint: - golangci-lint run ./cmd/... ./core/... + golangci-lint run ./... deadcode . test: diff --git a/core/dao/common.go b/core/dao/common.go index d079cc52..07e25a39 100644 --- a/core/dao/common.go +++ b/core/dao/common.go @@ -25,7 +25,6 @@ type Resource interface { GetContextLine() int } -// func (re *ResourceErrors[T]) Combine() error { func FormatErrors(re Resource, errs []error) error { var msg = "" partsRe := regexp.MustCompile(`line (\d*): (.*)`) @@ -97,7 +96,7 @@ func EvaluateEnv(envList []string) ([]string, error) { return envs, nil } -// Merges environment variables. +// MergeEnvs Merges environment variables. // Priority is from highest to lowest (1st env takes precedence over the last entry). func MergeEnvs(envs ...[]string) []string { var mergedEnvs []string diff --git a/core/dao/config.go b/core/dao/config.go index 843d2770..d5a3d15e 100644 --- a/core/dao/config.go +++ b/core/dao/config.go @@ -449,15 +449,15 @@ func InitMani(args []string, initFlags core.InitFlags) ([]Project, error) { return []Project{}, &core.AlreadyManiDirectory{Dir: configDir} } - url, err := core.GetWdRemoteUrl(configDir) + url, err := core.GetWdRemoteURL(configDir) if err != nil { return []Project{}, err } rootName := filepath.Base(configDir) rootPath := "." - rootUrl := url - rootProject := Project{Name: rootName, Path: rootPath, Url: rootUrl} + rootURL := url + rootProject := Project{Name: rootName, Path: rootPath, URL: rootURL} projects := []Project{rootProject} if initFlags.AutoDiscovery { prs, err := FindVCSystems(configDir) @@ -487,7 +487,7 @@ func InitMani(args []string, initFlags core.InitFlags) ([]Project, error) { tmpl, err := template.New("init").Funcs(funcMap).Parse(`projects: {{- range .}} - {{ (projectItem .Name .Path .Url) }} + {{ (projectItem .Name .Path .URL) }} {{ end }} tasks: hello: @@ -516,15 +516,15 @@ tasks: } // Update gitignore file if VCS set to git - hasUrl := false + hasURL := false for _, project := range projects { - if project.Url != "" { - hasUrl = true + if project.URL != "" { + hasURL = true break } } - if hasUrl && initFlags.SyncGitignore { + if hasURL && initFlags.SyncGitignore { // Add gitignore file gitignoreFilepath := filepath.Join(configDir, ".gitignore") if _, err := os.Stat(gitignoreFilepath); os.IsNotExist(err) { @@ -536,7 +536,7 @@ tasks: var projectNames []string for _, project := range projects { - if project.Url == "" { + if project.URL == "" { continue } @@ -557,7 +557,7 @@ tasks: fmt.Println("\nInitialized mani repository in", configDir) fmt.Println("- Created mani.yaml") - if hasUrl && initFlags.SyncGitignore { + if hasURL && initFlags.SyncGitignore { fmt.Println("- Created .gitignore") } diff --git a/core/dao/project.go b/core/dao/project.go index 0cd502fe..0216535b 100644 --- a/core/dao/project.go +++ b/core/dao/project.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "regexp" + "slices" "strings" "gopkg.in/yaml.v3" @@ -18,7 +19,7 @@ type Project struct { Name string `yaml:"name"` Path string `yaml:"path"` Desc string `yaml:"desc"` - Url string `yaml:"url"` + URL string `yaml:"url"` Clone string `yaml:"clone"` Branch string `yaml:"branch"` SingleBranch *bool `yaml:"single_branch"` @@ -36,7 +37,7 @@ type Project struct { type Remote struct { Name string - Url string + URL string } func (p *Project) GetContext() string { @@ -66,7 +67,7 @@ func (p Project) GetValue(key string, _ int) string { case "Desc", "desc", "Description", "description": return p.Desc case "Url", "url": - return p.Url + return p.URL case "Tag", "tag": return strings.Join(p.Tags, ", ") } @@ -319,7 +320,7 @@ func (c Config) GetProjectsByName(projectNames []string) ([]Project, error) { return matchedProjects, nil } -// Projects must have all dirs to match. +// GetProjectsByPath Projects must have all dirs to match. // If user provides a path which does not exist, then return error containing // all the paths it didn't find. // Supports glob patterns: @@ -415,7 +416,7 @@ func (c Config) GetProjectsByPath(dirs []string) ([]Project, error) { return projects, nil } -// Projects must have all tags to match. For instance, if --tags frontend,backend +// GetProjectsByTags Projects must have all tags to match. For instance, if --tags frontend,backend // is passed, then a project must have both tags. // We only return error if the flags provided do not exist in the mani config. func (c Config) GetProjectsByTags(tags []string) ([]Project, error) { @@ -461,7 +462,7 @@ func (c Config) GetProjectsByTags(tags []string) ([]Project, error) { return projects, nil } -// Projects must have all tags to match. For instance, if --tags frontend,backend +// GetProjectsByTagsExpr Projects must have all tags to match. For instance, if --tags frontend,backend // is passed, then a project must have both tags. // We only return error if the tags provided do not exist. func (c Config) GetProjectsByTagsExpr(tagsExpr string) ([]Project, error) { @@ -508,7 +509,7 @@ out: } /** - * For each project path, get all the enumerations of dirnames. + * GetProjectPaths For each project path, get all the enumerations of dirnames. * Example: * Input: * - /frontend/tools/project-a @@ -530,7 +531,7 @@ func (c Config) GetProjectPaths() []string { for i := 1; i <= len(ps); i++ { p := filepath.Join(ps[0:i]...) - if p != "." && !core.StringInSlice(p, dirs) { + if p != "." && !slices.Contains(dirs, p) { dirs = append(dirs, p) } } @@ -552,8 +553,8 @@ func (c Config) GetProjectNames() []string { func (c Config) GetProjectUrls() []string { urls := []string{} for _, project := range c.ProjectList { - if project.Url != "" { - urls = append(urls, project.Url) + if project.URL != "" { + urls = append(urls, project.URL) } } @@ -610,11 +611,11 @@ func FindVCSystems(rootPath string) ([]Project, error) { relPath, _ := filepath.Rel(rootPath, path) var project Project - url, rErr := core.GetRemoteUrl(path) + url, rErr := core.GetRemoteURL(path) if rErr != nil { project = Project{Name: name, Path: relPath} } else { - project = Project{Name: name, Path: relPath, Url: url} + project = Project{Name: name, Path: relPath, URL: url} } projects = append(projects, project) @@ -628,13 +629,18 @@ func FindVCSystems(rootPath string) ([]Project, error) { return projects, err } -func UpdateProjectsToGitignore(projectNames []string, gitignoreFilename string) error { +func UpdateProjectsToGitignore(projectNames []string, gitignoreFilename string) (err error) { l := list.New() gitignoreFile, err := os.OpenFile(gitignoreFilename, os.O_RDWR, 0644) if err != nil { return &core.FailedToOpenFile{Name: gitignoreFilename} } - defer gitignoreFile.Close() + defer func() { + closeErr := gitignoreFile.Close() + if err == nil { + err = closeErr + } + }() scanner := bufio.NewScanner(gitignoreFile) for scanner.Scan() { @@ -711,7 +717,7 @@ func UpdateProjectsToGitignore(projectNames []string, gitignoreFilename string) return nil } -// List of remotes (key: value) +// ParseRemotes List of remotes (key: value) func ParseRemotes(node yaml.Node) []Remote { var remotes []Remote count := len(node.Content) @@ -719,7 +725,7 @@ func ParseRemotes(node yaml.Node) []Remote { for i := 0; i < count; i += 2 { remote := Remote{ Name: node.Content[i].Value, - Url: node.Content[i+1].Value, + URL: node.Content[i+1].Value, } remotes = append(remotes, remote) diff --git a/core/dao/project_test.go b/core/dao/project_test.go index 8b8097d5..eb6cbd92 100644 --- a/core/dao/project_test.go +++ b/core/dao/project_test.go @@ -12,7 +12,7 @@ func TestProject_GetValue(t *testing.T) { Path: "/path/to/project", RelPath: "relative/path", Desc: "Test description", - Url: "https://example.com", + URL: "https://example.com", Tags: []string{"frontend", "api"}, } diff --git a/core/dao/tag.go b/core/dao/tag.go index 06bc94f6..f8e24072 100644 --- a/core/dao/tag.go +++ b/core/dao/tag.go @@ -1,9 +1,8 @@ package dao import ( + "slices" "strings" - - "github.com/alajmo/mani/core" ) type Tag struct { @@ -26,7 +25,7 @@ func (c Config) GetTags() []string { tags := []string{} for _, project := range c.ProjectList { for _, tag := range project.Tags { - if !core.StringInSlice(tag, tags) { + if !slices.Contains(tags, tag) { tags = append(tags, tag) } } diff --git a/core/dao/tag_expr.go b/core/dao/tag_expr.go index a81e1442..9d077377 100644 --- a/core/dao/tag_expr.go +++ b/core/dao/tag_expr.go @@ -1,7 +1,9 @@ +// Package dao for evaluating boolean tag expressions against project tags. package dao import ( "fmt" + "slices" "strings" "unicode" ) @@ -9,13 +11,13 @@ import ( type TokenType int const ( - TOKEN_TAG TokenType = iota - TOKEN_AND - TOKEN_OR - TOKEN_NOT - TOKEN_LPAREN - TOKEN_RPAREN - TOKEN_EOF + TokenTag TokenType = iota + TokenAnd + TokenOr + TokenNot + TokenLParent + TokenRParen + TokenEOF ) type Position struct { @@ -62,20 +64,20 @@ func (l *Lexer) Tokenize() error { l.column = 1 l.advance() case char == '(': - l.addToken(TOKEN_LPAREN, "(") + l.addToken(TokenLParent, "(") l.advance() case char == ')': - l.addToken(TOKEN_RPAREN, ")") + l.addToken(TokenRParen, ")") l.advance() case char == '!': - l.addToken(TOKEN_NOT, "!") + l.addToken(TokenNot, "!") l.advance() case l.matchOperator("&&"): - l.addToken(TOKEN_AND, "&&") + l.addToken(TokenAnd, "&&") l.advance() l.advance() case l.matchOperator("||"): - l.addToken(TOKEN_OR, "||") + l.addToken(TokenOr, "||") l.advance() l.advance() case isValidTagStart(char): @@ -85,7 +87,7 @@ func (l *Lexer) Tokenize() error { } } - l.addToken(TOKEN_EOF, "") + l.addToken(TokenEOF, "") return nil } @@ -133,18 +135,22 @@ func (l *Lexer) readTag() { value := l.input[startPos:l.pos] l.tokens = append(l.tokens, Token{ - Type: TOKEN_TAG, + Type: TokenTag, Value: value, Position: Position{line: l.line, column: startColumn}, }) } func isValidTagStart(r rune) bool { - return unicode.IsLetter(r) + return !isReservedChar(r) && !unicode.IsSpace(r) } func isValidTagPart(r rune) bool { - return unicode.IsLetter(r) || unicode.IsNumber(r) || r == '-' || r == '_' + return !isReservedChar(r) && !unicode.IsSpace(r) +} + +func isReservedChar(r rune) bool { + return r == '(' || r == ')' || r == '!' || r == '&' || r == '|' } type Parser struct { @@ -172,7 +178,7 @@ func (p *Parser) Parse() (bool, error) { } // Check if we consumed all tokens - if p.current().Type != TOKEN_EOF { + if p.current().Type != TokenEOF { pos := p.current().Position return false, fmt.Errorf("unexpected token at line %d, column %d", pos.line, pos.column) } @@ -186,12 +192,12 @@ func (p *Parser) parseExpression() (bool, error) { return false, err } - for p.current().Type == TOKEN_OR { + for p.current().Type == TokenOr { op := p.current() p.pos++ // Check for missing right operand - if p.current().Type == TOKEN_EOF { + if p.current().Type == TokenEOF { return false, fmt.Errorf("missing right operand for OR operator at line %d, column %d", op.Position.line, op.Position.column) } @@ -212,12 +218,12 @@ func (p *Parser) parseTerm() (bool, error) { return false, err } - for p.current().Type == TOKEN_AND { + for p.current().Type == TokenAnd { op := p.current() p.pos++ // Check for missing right operand - if p.current().Type == TOKEN_EOF { + if p.current().Type == TokenEOF { return false, fmt.Errorf("missing right operand for AND operator at line %d, column %d", op.Position.line, op.Position.column) } @@ -236,9 +242,9 @@ func (p *Parser) parseFactor() (bool, error) { token := p.current() switch token.Type { - case TOKEN_NOT: + case TokenNot: p.pos++ - if p.current().Type == TOKEN_EOF { + if p.current().Type == TokenEOF { return false, fmt.Errorf("missing operand after NOT at line %d, column %d", token.Position.line, token.Position.column) } @@ -248,10 +254,10 @@ func (p *Parser) parseFactor() (bool, error) { } return !val, nil - case TOKEN_LPAREN: + case TokenLParent: p.pos++ // Check for empty parentheses - if p.current().Type == TOKEN_RPAREN { + if p.current().Type == TokenRParen { return false, fmt.Errorf("empty parentheses at line %d, column %d", token.Position.line, token.Position.column) } @@ -259,16 +265,16 @@ func (p *Parser) parseFactor() (bool, error) { if err != nil { return false, err } - if p.current().Type != TOKEN_RPAREN { + if p.current().Type != TokenRParen { return false, fmt.Errorf("missing closing parenthesis for opening parenthesis at line %d, column %d", token.Position.line, token.Position.column) } p.pos++ return val, nil - case TOKEN_TAG: + case TokenTag: p.pos++ - return p.project.hasTag(token.Value), nil + return slices.Contains(p.project.Tags, token.Value), nil default: return false, fmt.Errorf("unexpected token at line %d, column %d: %v", @@ -278,20 +284,11 @@ func (p *Parser) parseFactor() (bool, error) { func (p *Parser) current() Token { if p.pos >= len(p.tokens) { - return Token{Type: TOKEN_EOF} + return Token{Type: TokenEOF} } return p.tokens[p.pos] } -func (p *Project) hasTag(tag string) bool { - for _, t := range p.Tags { - if t == tag { - return true - } - } - return false -} - // evaluateExpression checks if a boolean tag expression evaluates to true for a given project. // The function supports boolean operations on project tags with full operator precedence. // diff --git a/core/dao/tag_expr_test.go b/core/dao/tag_expr_test.go index 6be12aae..5d23b3c0 100644 --- a/core/dao/tag_expr_test.go +++ b/core/dao/tag_expr_test.go @@ -78,7 +78,6 @@ func TestTagExpression(t *testing.T) { {"missing operator", "tag tag", "unexpected token"}, {"double operator", "tag && && tag", "unexpected token"}, {"NOT without operand", "!", "missing operand after NOT"}, - {"invalid tag character", "tag-with-invalid#", "unexpected character"}, } t.Run("invalid expressions", func(t *testing.T) { diff --git a/core/dao/task.go b/core/dao/task.go index e8bcbf17..b482fa3a 100644 --- a/core/dao/task.go +++ b/core/dao/task.go @@ -14,7 +14,7 @@ import ( ) var ( - build_mode = "dev" + buildMode = "dev" ) type Command struct { @@ -189,7 +189,7 @@ func TaskSpinner() (yacspin.Spinner, error) { // NOTE: Don't print the spinner in tests since it causes // golden files to produce different results. - if build_mode == "TEST" { + if buildMode == "TEST" { cfg = yacspin.Config{ Frequency: 100 * time.Millisecond, CharSet: yacspin.CharSets[9], diff --git a/core/dao/theme_tui.go b/core/dao/theme_tui.go index ddf0e146..5e72b29c 100644 --- a/core/dao/theme_tui.go +++ b/core/dao/theme_tui.go @@ -4,7 +4,7 @@ import ( "github.com/alajmo/mani/core" ) -// Not all attributes are used, but no clean way to add them since +// DefaultTUI Not all attributes are used, but no clean way to add them since // MergeThemeOptions initializes all of the fields. var DefaultTUI = TUI{ Default: &ColorOptions{ diff --git a/core/exec/clone.go b/core/exec/clone.go index a782e7a8..12c5b87e 100644 --- a/core/exec/clone.go +++ b/core/exec/clone.go @@ -41,7 +41,7 @@ func getRemotes(project dao.Project) (map[string]string, error) { } func addRemote(project dao.Project, remote dao.Remote) error { - cmd := exec.Command("git", "remote", "add", remote.Name, remote.Url) + cmd := exec.Command("git", "remote", "add", remote.Name, remote.URL) cmd.Dir = project.Path _, err := cmd.CombinedOutput() @@ -63,7 +63,7 @@ func removeRemote(project dao.Project, name string) error { } func updateRemote(project dao.Project, remote dao.Remote) error { - cmd := exec.Command("git", "remote", "set-url", remote.Name, remote.Url) + cmd := exec.Command("git", "remote", "set-url", remote.Name, remote.URL) cmd.Dir = project.Path _, err := cmd.CombinedOutput() @@ -97,21 +97,21 @@ func syncRemotes(project dao.Project) error { } // Don't remove remotes if project url is empty - if project.Url == "" { + if project.URL == "" { return nil } // Remove remotes found in .git/config but not in RemoteList - for name, foundUrl := range foundRemotes { + for name, foundURL := range foundRemotes { // Ignore origin remote (same as project url) - if foundUrl == project.Url { + if foundURL == project.URL { continue } // Check if this URL exists in project.RemoteList urlExists := false for _, remote := range project.RemoteList { - if foundUrl == remote.Url { + if foundURL == remote.URL { urlExists = true break } @@ -142,7 +142,7 @@ func CloneRepos(config *dao.Config, projects []dao.Project, syncFlags core.SyncF continue } - if projects[i].Url == "" { + if projects[i].URL == "" { continue } @@ -180,9 +180,9 @@ func CloneRepos(config *dao.Config, projects []dao.Project, syncFlags core.SyncF shell = "git" shellProgram = "git" if syncFlags.Parallel { - cmdArr = []string{"clone", syncProjects[i].Url, projectPath} + cmdArr = []string{"clone", syncProjects[i].URL, projectPath} } else { - cmdArr = []string{"clone", "--progress", syncProjects[i].Url, projectPath} + cmdArr = []string{"clone", "--progress", syncProjects[i].URL, projectPath} } if syncProjects[i].Branch != "" { @@ -259,7 +259,7 @@ func UpdateGitignoreIfExists(config *dao.Config) error { // Get relative project names for gitignore file var projectNames []string for _, project := range config.ProjectList { - if project.Url == "" { + if project.URL == "" { continue } diff --git a/core/exec/exec.go b/core/exec/exec.go index ff85690a..e0fffe1a 100644 --- a/core/exec/exec.go +++ b/core/exec/exec.go @@ -267,8 +267,8 @@ func (exec *Exec) ParseTask(userArgs []string, runFlags *core.RunFlags, setRunFl return nil } -func (e *Exec) CheckTaskNoColor() { - task := e.Tasks[0] +func (exec *Exec) CheckTaskNoColor() { + task := exec.Tasks[0] for _, env := range task.EnvList { name := strings.Split(env, "=")[0] diff --git a/core/man.go b/core/man.go index f0f736a6..d757a6e1 100644 --- a/core/man.go +++ b/core/man.go @@ -8,11 +8,11 @@ import ( ) //go:embed mani.1 -var CONFIG_MAN []byte +var ConfigMan []byte func GenManPages(dir string) error { manPath := filepath.Join(dir, "mani.1") - err := os.WriteFile(manPath, CONFIG_MAN, 0644) + err := os.WriteFile(manPath, ConfigMan, 0644) CheckIfError(err) fmt.Printf("Created %s\n", manPath) diff --git a/core/man_gen.go b/core/man_gen.go index f23d2299..88b92f31 100644 --- a/core/man_gen.go +++ b/core/man_gen.go @@ -13,6 +13,7 @@ import ( "io" "os" "path/filepath" + "slices" "strings" "github.com/spf13/cobra" @@ -21,7 +22,7 @@ import ( ) //go:embed config.man -var CONFIG_MD []byte +var ConfigMd []byte type genManHeaders struct { Title string @@ -45,7 +46,7 @@ func CreateManPage(desc string, version string, date string, rootCmd *cobra.Comm } res := genMan(header, rootCmd, cmds...) - res = append(res, CONFIG_MD...) + res = append(res, ConfigMd...) manPath := filepath.Join("./core/", "mani.1") err := os.WriteFile(manPath, res, 0644) if err != nil { @@ -172,7 +173,7 @@ func genMan(header *genManHeaders, cmd *cobra.Command, cmds ...*cobra.Command) [ for _, c := range cmds { cbuf := new(bytes.Buffer) - if !StringInSlice(c.Name(), []string{"list", "describe"}) { + if !slices.Contains([]string{"list", "describe"}, c.Name()) { manCommand(cbuf, c) } @@ -206,7 +207,7 @@ func genDoc(cmd *cobra.Command, cmds ...*cobra.Command) ([]byte, error) { md = fmt.Sprintf("%s\n\n%s", "# Commands", md) for _, c := range cmds { - if !StringInSlice(c.Name(), []string{"list", "describe"}) { + if !slices.Contains([]string{"list", "describe"}, c.Name()) { cOut := new(bytes.Buffer) err := doc.GenMarkdown(c, cOut) if err != nil { diff --git a/core/mani.1 b/core/mani.1 index fa57bc3c..6057b64e 100644 --- a/core/mani.1 +++ b/core/mani.1 @@ -1,4 +1,4 @@ -.TH "MANI" "1" "2025 November 03" "v0.31.1" "Mani Manual" "mani" +.TH "MANI" "1" "2025 December 05" "v0.31.2" "Mani Manual" "mani" .SH NAME mani - repositories manager and task runner diff --git a/core/print/print_block.go b/core/print/print_block.go index 513efba0..f7053e21 100644 --- a/core/print/print_block.go +++ b/core/print/print_block.go @@ -35,12 +35,12 @@ func PrintProjectBlocks(projects []dao.Project, colorize bool, block dao.Block, output += printKeyValue(false, "", "path", ":", project.RelPath, *block.Key, *block.Value) } - output += printKeyValue(false, "", "url", ":", project.Url, *block.Key, *block.Value) + output += printKeyValue(false, "", "url", ":", project.URL, *block.Key, *block.Value) if len(project.RemoteList) > 0 { output += printKeyValue(false, "", "remotes", ":", "", *block.Key, *block.Value) for _, remote := range project.RemoteList { - output += printKeyValue(true, "", remote.Name, ":", remote.Url, *block.Key, *block.Value) + output += printKeyValue(true, "", remote.Name, ":", remote.URL, *block.Key, *block.Value) } } diff --git a/core/tui/components/tui_modal.go b/core/tui/components/tui_modal.go index daac8786..efe05750 100644 --- a/core/tui/components/tui_modal.go +++ b/core/tui/components/tui_modal.go @@ -11,7 +11,7 @@ import ( "github.com/alajmo/mani/core/tui/misc" ) -// Used for when a custom tview Flex is passed to a modal. +// OpenModal Used for when a custom tview Flex is passed to a modal. func OpenModal(pageTitle string, title string, contentPane *tview.Flex, width int, height int) { termWidth, termHeight, _ := term.GetSize(0) if width > termWidth { @@ -55,14 +55,14 @@ func OpenModal(pageTitle string, title string, contentPane *tview.Flex, width in misc.App.SetFocus(containerFlex) } -// Used for when text is passed to a modal. -func OpenTextModal(pageTitle string, text_color string, text_no_color string, title string) { - width, height := misc.GetTexztModalSize(text_no_color) - text_color = strings.TrimSpace(text_color) +// OpenTextModal Used for when text is passed to a modal. +func OpenTextModal(pageTitle string, textColor string, textNoColor string, title string) { + width, height := misc.GetTexztModalSize(textNoColor) + textColor = strings.TrimSpace(textColor) // Text contentPane := tview.NewTextView(). - SetText(text_color). + SetText(textColor). SetTextAlign(tview.AlignLeft). SetDynamicColors(true) diff --git a/core/tui/pages/tui_task.go b/core/tui/pages/tui_task.go index 270116f0..811835ca 100644 --- a/core/tui/pages/tui_task.go +++ b/core/tui/pages/tui_task.go @@ -74,7 +74,7 @@ func CreateTasksPage(tasks []dao.Task) *tview.Flex { return taskData.Page } -func (t *TTaskPage) createTaskPage(taskData *views.TTask) *tview.Flex { +func (taskPage *TTaskPage) createTaskPage(taskData *views.TTask) *tview.Flex { isTable := taskData.TaskStyle == "task-table" pages := tview.NewPages(). @@ -98,9 +98,9 @@ func (t *TTaskPage) createTaskPage(taskData *views.TTask) *tview.Flex { taskData.TaskStyle = "task-table" } pages.SwitchToPage(taskData.TaskStyle) - t.focusable = t.updateTaskFocusable(taskData) - misc.App.SetFocus(t.focusable[0].Primitive) - misc.TasksLastFocus = &t.focusable[0].Primitive + taskPage.focusable = taskPage.updateTaskFocusable(taskData) + misc.App.SetFocus(taskPage.focusable[0].Primitive) + misc.TasksLastFocus = &taskPage.focusable[0].Primitive return nil } return event @@ -109,7 +109,7 @@ func (t *TTaskPage) createTaskPage(taskData *views.TTask) *tview.Flex { return page } -func (p *TTaskPage) updateTaskFocusable( +func (taskPage *TTaskPage) updateTaskFocusable( data *views.TTask, ) []*misc.TItem { focusable := []*misc.TItem{} diff --git a/core/tui/tui.go b/core/tui/tui.go index 3075e2a8..fee2ddbd 100644 --- a/core/tui/tui.go +++ b/core/tui/tui.go @@ -34,8 +34,8 @@ func NewApp(config *dao.Config, themeName string) *App { return app } -func (a *App) Run() error { - return a.App.SetRoot(misc.Pages, true).EnableMouse(true).Run() +func (app *App) Run() error { + return app.App.SetRoot(misc.Pages, true).EnableMouse(true).Run() } func (app *App) Reload() { diff --git a/core/tui/views/tui_help.go b/core/tui/views/tui_help.go index e7acff43..10236f10 100644 --- a/core/tui/views/tui_help.go +++ b/core/tui/views/tui_help.go @@ -8,7 +8,7 @@ import ( "github.com/rivo/tview" ) -var Version = "v0.31.1" +var Version = "v0.31.2" func ShowHelpModal() { t, table := createShortcutsTable() diff --git a/core/tui/views/tui_project_view.go b/core/tui/views/tui_project_view.go index 46cb23b0..d4e1f415 100644 --- a/core/tui/views/tui_project_view.go +++ b/core/tui/views/tui_project_view.go @@ -448,8 +448,8 @@ func (p *TProject) showProjectDescModal(name string) { return } description := print.PrintProjectBlocks([]dao.Project{*project}, true, *misc.BlockTheme, print.TviewFormatter{}) - description_no_color := print.PrintProjectBlocks([]dao.Project{*project}, false, *misc.BlockTheme, print.TviewFormatter{}) - components.OpenTextModal("project-description-modal", description, description_no_color, project.Name) + descriptionNoColor := print.PrintProjectBlocks([]dao.Project{*project}, false, *misc.BlockTheme, print.TviewFormatter{}) + components.OpenTextModal("project-description-modal", description, descriptionNoColor, project.Name) } func (p *TProject) editProject(projectName string) { diff --git a/core/tui/views/tui_task_view.go b/core/tui/views/tui_task_view.go index 2419d074..bfb315a8 100644 --- a/core/tui/views/tui_task_view.go +++ b/core/tui/views/tui_task_view.go @@ -276,8 +276,8 @@ func (t *TTask) showTaskDescModal(name string) { } description := print.PrintTaskBlock([]dao.Task{*task}, true, *misc.BlockTheme, print.TviewFormatter{}) - description_no_color := print.PrintTaskBlock([]dao.Task{*task}, false, *misc.BlockTheme, print.TviewFormatter{}) - components.OpenTextModal("task-description-modal", description, description_no_color, task.Name) + descriptionNoColor := print.PrintTaskBlock([]dao.Task{*task}, false, *misc.BlockTheme, print.TviewFormatter{}) + components.OpenTextModal("task-description-modal", description, descriptionNoColor, task.Name) } func (t *TTask) editTask(taskName string) { diff --git a/core/tui/watcher.go b/core/tui/watcher.go index 7f4203e3..8ddacd04 100644 --- a/core/tui/watcher.go +++ b/core/tui/watcher.go @@ -19,7 +19,10 @@ func WatchFiles(app *App, files ...string) { } go func() { - defer w.Close() + defer func() { + _ = w.Close() + }() + for _, p := range files { st, err := os.Lstat(p) if err != nil { diff --git a/core/utils.go b/core/utils.go index 1b6e5676..4c2aa361 100644 --- a/core/utils.go +++ b/core/utils.go @@ -9,6 +9,7 @@ import ( "os/user" "path/filepath" "regexp" + "slices" "strings" ) @@ -20,19 +21,10 @@ func Strip(str string) string { return RE.ReplaceAllString(str, "") } -func StringInSlice(a string, list []string) bool { - for _, b := range list { - if b == a { - return true - } - } - return false -} - func Intersection(a []string, b []string) []string { var i []string for _, s := range a { - if StringInSlice(s, b) { + if slices.Contains(b, s) { i = append(i, s) } } @@ -40,7 +32,7 @@ func Intersection(a []string, b []string) []string { return i } -func GetWdRemoteUrl(path string) (string, error) { +func GetWdRemoteURL(path string) (string, error) { cwd, err := os.Getwd() if err != nil { return "", err @@ -48,14 +40,14 @@ func GetWdRemoteUrl(path string) (string, error) { gitDir := filepath.Join(cwd, ".git") if _, err := os.Stat(gitDir); !os.IsNotExist(err) { - url, rErr := GetRemoteUrl(cwd) + url, rErr := GetRemoteURL(cwd) return url, rErr } return "", nil } -func GetRemoteUrl(path string) (string, error) { +func GetRemoteURL(path string) (string, error) { cmd := exec.Command("git", "config", "--get", "remote.origin.url") cmd.Dir = path output, err := cmd.Output() diff --git a/docs/changelog.md b/docs/changelog.md index 409957e6..d7d71598 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,11 +1,5 @@ # Changelog -## 0.31.1 - -### Fixes - -- Fix panic when running task for a repository with a long name [#111](https://github.com/alajmo/mani/issues/111) - ## 0.31.0 ### Features diff --git a/docs/development.md b/docs/development.md index dac02349..caf03fde 100644 --- a/docs/development.md +++ b/docs/development.md @@ -4,7 +4,7 @@ ### Prerequisites -- [go 1.23 or above](https://golang.org/doc/install) +- [go 1.25 or above](https://golang.org/doc/install) - [goreleaser](https://goreleaser.com/install/) ### Building diff --git a/docs/filtering-projects.md b/docs/filtering-projects.md index 1637667e..1311cfe1 100644 --- a/docs/filtering-projects.md +++ b/docs/filtering-projects.md @@ -37,6 +37,15 @@ Operators (in precedence order): - &&: AND operator (logical conjunction) - ||: OR operator (logical disjunction) +Tags in expressions can contain any characters except: + +- Whitespace (spaces, tabs, newlines) +- Reserved characters: `(`, `)`, `!`, `&`, `|` + +This means tags can include letters, numbers, hyphens, underscores, dots, and other special characters like `@`, `#`, `$`, etc. For example: `my-tag`, `v1.0`, `frontend_v2`, `@scope/package`. + +### Example + For example, the expression: - (main && (dev || prod)) && !test diff --git a/go.mod b/go.mod index 0bca6157..8daac619 100644 --- a/go.mod +++ b/go.mod @@ -1,39 +1,40 @@ module github.com/alajmo/mani -go 1.23.0 - -toolchain go1.23.1 +go 1.25.5 require ( - github.com/fsnotify/fsnotify v1.8.0 - github.com/gdamore/tcell/v2 v2.8.1 - github.com/gookit/color v1.5.4 - github.com/jedib0t/go-pretty/v6 v6.6.7 + github.com/fsnotify/fsnotify v1.9.0 + github.com/gdamore/tcell/v2 v2.13.2 + github.com/gookit/color v1.6.0 + github.com/jedib0t/go-pretty/v6 v6.7.5 github.com/jinzhu/copier v0.4.0 github.com/kr/pretty v0.2.1 github.com/otiai10/copy v1.6.0 - github.com/rivo/tview v0.0.0-20250322200051-73a5bd7d6839 - github.com/spf13/cobra v1.9.1 - github.com/spf13/pflag v1.0.6 + github.com/rivo/tview v0.42.0 + github.com/spf13/cobra v1.10.2 + github.com/spf13/pflag v1.0.10 github.com/theckman/yacspin v0.13.12 - golang.org/x/sys v0.31.0 - golang.org/x/term v0.30.0 - golang.org/x/text v0.23.0 + golang.org/x/sys v0.38.0 + golang.org/x/term v0.37.0 + golang.org/x/text v0.31.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/fatih/color v1.18.0 // indirect github.com/gdamore/encoding v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index 1f0fdc2d..2421f415 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,31 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= -github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU= -github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gdamore/tcell/v2 v2.13.2 h1:5j4srfF8ow3HICOv/61/sOhQtA25qxEB2XR3Q/Bhx2g= +github.com/gdamore/tcell/v2 v2.13.2/go.mod h1:+Wfe208WDdB7INEtCsNrAN6O2m+wsTPk1RAovjaILlo= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= +github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= +github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= +github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo= -github.com/jedib0t/go-pretty/v6 v6.6.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.5 h1:9dJSWTJnsXJVVAbvxIFxeHf/JxoJd7GUl5o3UzhtuiM= +github.com/jedib0t/go-pretty/v6 v6.7.5/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -27,14 +34,14 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -44,18 +51,17 @@ github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/tview v0.0.0-20250322200051-73a5bd7d6839 h1:/v0ptNHBQaQCxlvS4QLxLKKGfsSA9hcZcNgqVgmPRro= -github.com/rivo/tview v0.0.0-20250322200051-73a5bd7d6839/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/tview v0.42.0 h1:b/ftp+RxtDsHSaynXTbJb+/n/BxDEi+W3UfF5jILK6c= +github.com/rivo/tview v0.42.0/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4= @@ -63,33 +69,21 @@ github.com/theckman/yacspin v0.13.12/go.mod h1:Rd2+oG2LmQi5f3zC3yeZAOl245z8QOvrH github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -97,41 +91,24 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/test/README.md b/test/README.md index c9fa8d26..ab4b41ab 100644 --- a/test/README.md +++ b/test/README.md @@ -22,7 +22,7 @@ The Docker test container includes a script `git` which only creates the project ## Prerequisites - [docker](https://docs.docker.com/get-docker/) -- [golangci-lint](https://golangci-lint.run/usage/install/) +- [golangci-lint](https://golangci-lint.run) ## Testing & Development diff --git a/test/images/alpine.test.Dockerfile b/test/images/alpine.test.Dockerfile index 542e073e..04fc7a80 100644 --- a/test/images/alpine.test.Dockerfile +++ b/test/images/alpine.test.Dockerfile @@ -6,7 +6,7 @@ ENV PATH="/usr/local/go/bin:${PATH}" ENV USER="test" ENV HOME="/home/test" -COPY --from=golang:1.23.4-alpine /usr/local/go/ /usr/local/go/ +COPY --from=golang:1.25.5-alpine /usr/local/go/ /usr/local/go/ RUN apk update RUN apk add --no-cache make build-base bash curl g++ git diff --git a/test/integration/main_test.go b/test/integration/main_test.go index e86674d1..c6a9c69b 100644 --- a/test/integration/main_test.go +++ b/test/integration/main_test.go @@ -100,7 +100,7 @@ func (tf *TestFile) Write(content string) { func clearGolden(goldenDir string) { // Guard against accidentally deleting outside directory if strings.Contains(goldenDir, "golden") { - os.RemoveAll(goldenDir) + _ = os.RemoveAll(goldenDir) } } @@ -108,7 +108,7 @@ func clearTmp() { dir, _ := os.ReadDir(path.Join(tmpPath, "golden")) for _, d := range dir { f := path.Join(tmpPath, "golden", path.Join([]string{d.Name()}...)) - os.RemoveAll(f) + _ = os.RemoveAll(f) } }