-
Notifications
You must be signed in to change notification settings - Fork 24
feat: Go CLI skeleton — version command and lola mod stubs #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
4764836
chore: ignore asdf .tool-versions file
mrbrandao eee2f54
chore: bootstrap Go CLI with Cobra
mrbrandao 9500fff
chore: adding initial version command
mrbrandao 1ea55f3
feat(version): implement resolveVersion with build-info fallback chain
mrbrandao fea6bd0
feat(version): wire rootCmd.Version in root, move template to version…
mrbrandao 5523633
fix(version): use cmd.Root().Version in Run, add 7-char hash boundary…
mrbrandao 3e1fd76
build: add go-build, go-test, go-vet Makefile targets
mrbrandao 5ccf01b
chore: improving .gitignore
mrbrandao 83fa4ae
feat(modules): add internal/modules stub package
mrbrandao d40ad21
docs(modules): add package and function doc comments, TODO return types
mrbrandao 5066603
feat(mod): add lola mod cobra skeleton
mrbrandao f60fe73
fix(cmd): copyright header and Execute signature
mrbrandao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,4 @@ help: ## - print the help and usage | |
| include mk/dev.mk | ||
| include mk/mkdocs.mk | ||
| include mk/adr.mk | ||
| include mk/go.mk | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| package cmd | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
|
|
||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/LobsterTrap/lola/internal/modules" | ||
| ) | ||
|
|
||
| var modCmd = &cobra.Command{ | ||
| Use: "mod", | ||
| Short: "Manage lola modules", | ||
| } | ||
|
|
||
| var modAddCmd = &cobra.Command{ | ||
| Use: "add <source>", | ||
| Short: "Add a module from a source", | ||
| Args: cobra.ExactArgs(1), | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| if err := modules.Add(args[0]); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| var modRmCmd = &cobra.Command{ | ||
| Use: "rm <name>", | ||
| Short: "Remove a registered module", | ||
| Args: cobra.ExactArgs(1), | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| if err := modules.Remove(args[0]); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| var modLsCmd = &cobra.Command{ | ||
| Use: "ls", | ||
| Short: "List registered modules", | ||
| Args: cobra.NoArgs, | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| if err := modules.List(); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| var modInfoCmd = &cobra.Command{ | ||
| Use: "info [name]", | ||
| Short: "Show detailed info for a module", | ||
| Args: cobra.MaximumNArgs(1), | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| name := "" | ||
| if len(args) > 0 { | ||
| name = args[0] | ||
| } | ||
| if err := modules.Info(name); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| var modUpdateCmd = &cobra.Command{ | ||
| Use: "update [name]", | ||
| Short: "Update a module from its source", | ||
| Args: cobra.MaximumNArgs(1), | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| name := "" | ||
| if len(args) > 0 { | ||
| name = args[0] | ||
| } | ||
| if err := modules.Update(name); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| var modInitCmd = &cobra.Command{ | ||
| Use: "init <name>", | ||
| Short: "Scaffold a new module", | ||
| Args: cobra.ExactArgs(1), | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| if err := modules.Init(args[0]); err != nil { | ||
| fmt.Fprintln(os.Stderr, err) | ||
| os.Exit(1) | ||
| } | ||
| }, | ||
| } | ||
|
|
||
| func init() { | ||
| modCmd.AddCommand(modAddCmd, modRmCmd, modLsCmd, modInfoCmd, modUpdateCmd, modInitCmd) | ||
| rootCmd.AddCommand(modCmd) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package cmd | ||
|
|
||
| import "github.com/spf13/cobra" | ||
|
|
||
| var rootCmd = &cobra.Command{ | ||
| Use: "lola", | ||
| Short: "AI Context Package Manager", | ||
| Long: `lola - Universal AI Context Package Manager | ||
|
|
||
| Lola is a universal AI Context Package Manager, for skills, plugins, | ||
| profiles or Context Modules. Lola strives for AI sovereignty without | ||
| vendor lock-in. Write your AI Skills once, run anywhere. | ||
|
|
||
| Quick start: | ||
| lola mod add [git-url|folder|zip|tar] Add a module | ||
| lola mod ls List modules | ||
| lola install [module] -a [assistant] Install skills`, | ||
| } | ||
|
|
||
| func Execute() error { | ||
| return rootCmd.Execute() | ||
| } | ||
|
|
||
| func init() { | ||
| rootCmd.Version = currentVersion() | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| package cmd | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "runtime" | ||
| "runtime/debug" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| // version is injected at build time: | ||
| // -ldflags "-X github.com/LobsterTrap/lola/cmd.version=v1.2.0" | ||
| var version string | ||
|
|
||
| // resolveVersion determines the version string based on available version sources | ||
| // in order of priority: build-time injection, go install module version, git commit hash, or default dev version. | ||
| // | ||
| // Parameters: | ||
| // - version: version injected at build time via ldflags | ||
| // - moduleVersion: version from debug.ReadBuildInfo().Main.Version | ||
| // - vcsRevision: git commit hash from debug.ReadBuildInfo().Settings | ||
| // | ||
| // Returns the resolved version string following the fallback chain: | ||
| // 1. If version is set (build-time injection) → return it | ||
| // 2. If moduleVersion is set and not "(devel)" → return it | ||
| // 3. If vcsRevision is set → return "0.0.0-dev+" with first 7 chars of commit hash | ||
| // 4. Default → return "0.0.0-dev" | ||
| func resolveVersion(version, moduleVersion, vcsRevision string) string { | ||
| switch { | ||
| case version != "": | ||
| return version | ||
| case moduleVersion != "" && moduleVersion != "(devel)": | ||
| return moduleVersion | ||
| case vcsRevision != "": | ||
| return "0.0.0-dev+" + vcsRevision[:min(7, len(vcsRevision))] | ||
| default: | ||
| return "0.0.0-dev" | ||
| } | ||
| } | ||
|
|
||
| // currentVersion queries runtime build info and returns the resolved version. | ||
| // It extracts moduleVersion and vcsRevision from debug.ReadBuildInfo() and passes | ||
| // them to resolveVersion along with the build-time injected version variable. | ||
| func currentVersion() string { | ||
| var moduleVersion, vcsRevision string | ||
| if bi, ok := debug.ReadBuildInfo(); ok { | ||
| moduleVersion = bi.Main.Version | ||
| for _, s := range bi.Settings { | ||
| if s.Key == "vcs.revision" { | ||
| vcsRevision = s.Value | ||
| break | ||
| } | ||
| } | ||
| } | ||
| return resolveVersion(version, moduleVersion, vcsRevision) | ||
| } | ||
|
|
||
| // versionCmd represents the version command. | ||
| var versionCmd = &cobra.Command{ | ||
| Use: "version", | ||
| Short: "Print lola version and platform info", | ||
| Run: func(cmd *cobra.Command, args []string) { | ||
| fmt.Printf("lola version %s %s/%s\n", cmd.Root().Version, runtime.GOOS, runtime.GOARCH) | ||
| }, | ||
| } | ||
|
|
||
| func init() { | ||
| rootCmd.AddCommand(versionCmd) | ||
| rootCmd.SetVersionTemplate("{{.Version}}\n") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package cmd | ||
|
|
||
| import "testing" | ||
|
|
||
| func TestResolveVersion(t *testing.T) { | ||
| tt := []struct { | ||
| name string | ||
| version string | ||
| moduleVersion string | ||
| vcsRevision string | ||
| want string | ||
| }{ | ||
| {"release build", "v1.2.0", "(devel)", "a3f9b12abc", "v1.2.0"}, | ||
| {"go install", "", "v1.2.0", "", "v1.2.0"}, | ||
| {"dev with commit", "", "(devel)", "a3f9b12abc", "0.0.0-dev+a3f9b12"}, | ||
| {"dev short hash", "", "(devel)", "abc", "0.0.0-dev+abc"}, | ||
| {"dev exact 7 hash", "", "(devel)", "a3f9b12", "0.0.0-dev+a3f9b12"}, | ||
| {"dev no vcs", "", "(devel)", "", "0.0.0-dev"}, | ||
| {"no context at all", "", "", "", "0.0.0-dev"}, | ||
| } | ||
| for _, tc := range tt { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| if got := resolveVersion(tc.version, tc.moduleVersion, tc.vcsRevision); got != tc.want { | ||
| t.Errorf("got %q, want %q", got, tc.want) | ||
| } | ||
| }) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| module github.com/LobsterTrap/lola | ||
|
|
||
| go 1.26.3 | ||
|
mrbrandao marked this conversation as resolved.
|
||
|
|
||
| require ( | ||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| github.com/spf13/cobra v1.10.2 // indirect | ||
| github.com/spf13/pflag v1.0.9 // indirect | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= | ||
| github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | ||
| github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | ||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||
| 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 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= | ||
| github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
| go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= | ||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package modules | ||
|
|
||
| // Add registers a new module from the given source (git URL, local path, zip, tar, or OCI reference). | ||
| func Add(source string) error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| // Package modules implements Lola's module management domain logic. | ||
| package modules | ||
|
|
||
| import "errors" | ||
|
|
||
| // ErrNotImplemented is returned by stub functions that have not yet been implemented. | ||
| // It serves as the template for domain-specific errors (e.g. ErrModuleNotFound) that | ||
| // will be added to this file as each function is implemented. | ||
| var ErrNotImplemented = errors.New("not yet implemented") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package modules | ||
|
|
||
| // Info returns detailed information about the named module. | ||
| // TODO: return (*Module, error) once the Module type is defined in pkg/models. | ||
| func Info(name string) error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package modules | ||
|
|
||
| // Init scaffolds a new module directory structure with the given name. | ||
| func Init(name string) error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package modules | ||
|
|
||
| // List returns all modules registered in LOLA_HOME. | ||
| // TODO: return ([]Module, error) once the Module type is defined in pkg/models. | ||
| func List() error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package modules | ||
|
|
||
| // Remove unregisters the module with the given name from LOLA_HOME. | ||
| func Remove(name string) error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package modules | ||
|
|
||
| // Update re-fetches the module with the given name from its original source. | ||
| // If name is empty, all registered modules are updated. | ||
| func Update(name string) error { | ||
| return ErrNotImplemented | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // Copyright © 2026 LobsterTrap Contributors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "os" | ||
|
|
||
| "github.com/LobsterTrap/lola/cmd" | ||
| ) | ||
|
|
||
| func main() { | ||
| if err := cmd.Execute(); err != nil { | ||
| os.Exit(1) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Go build targets | ||
| # VERSION is set only when HEAD is exactly on a tag; empty string otherwise, | ||
| # which causes resolveVersion to fall through to VCS stamping. | ||
| VERSION := $(shell git describe --tags --exact-match 2>/dev/null || echo "") | ||
| LDFLAGS := -X github.com/LobsterTrap/lola/cmd.version=$(VERSION) | ||
|
|
||
| .PHONY: go-build go-test go-vet | ||
|
|
||
| go-build: ## - build lola binary (version from tag if on one, else from VCS) | ||
| go build -ldflags "$(LDFLAGS)" -o bin/lola . | ||
|
|
||
| go-test: ## - run Go test suite | ||
| go test ./... | ||
|
|
||
| go-vet: ## - run go vet static analysis | ||
| go vet ./... |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.