Skip to content

Commit 066bc81

Browse files
authored
Merge pull request #5 from dAppCore/dev
v0.9.0 compliance: full upgrade against core/go reference
2 parents ad7db53 + 0bdbee3 commit 066bc81

132 files changed

Lines changed: 9141 additions & 4795 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.woodpecker.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Woodpecker CI pipeline.
2+
# Server: ci.lthn.sh. Lint + sonar in parallel, both depend only on clone.
3+
# sonar_token is admin-scoped on the Woodpecker server.
4+
5+
when:
6+
- event: push
7+
branch: [dev, main]
8+
9+
steps:
10+
- name: golangci-lint
11+
image: golangci/golangci-lint:latest-alpine
12+
depends_on: []
13+
environment:
14+
GOFLAGS: -buildvcs=false
15+
GOWORK: "off"
16+
commands:
17+
- golangci-lint run --timeout=5m ./...
18+
19+
- name: go-test
20+
image: golang:1.26-alpine
21+
depends_on: []
22+
environment:
23+
GOFLAGS: -buildvcs=false
24+
GOWORK: "off"
25+
CGO_ENABLED: "1"
26+
commands:
27+
- apk add --no-cache git build-base
28+
- go test -race -coverprofile=coverage.out -covermode=atomic -count=1 ./...
29+
- name: sonar
30+
image: sonarsource/sonar-scanner-cli:latest
31+
depends_on: [go-test]
32+
environment:
33+
SONAR_HOST_URL: https://sonar.lthn.sh
34+
SONAR_TOKEN:
35+
from_secret: sonar_token
36+
commands:
37+
- sonar-scanner

AGENTS.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Agent Notes
2+
3+
This repository is the `dappco.re/go/cli` module. It provides the shared command-line runtime, terminal UI helpers, daemon helpers, package commands, and i18n utilities used by Core command tools.
4+
5+
Work in this repo should follow the v0.9 Core conventions:
6+
7+
- Import `dappco.re/go` as `core` when a file needs Core wrappers.
8+
- Keep public-symbol tests in the sibling `<source>_test.go` file using `Test<File>_<Symbol>_{Good,Bad,Ugly}`.
9+
- Keep public-symbol examples in the sibling `<source>_example_test.go` file.
10+
- Prefer `core.Result` for fallible production functions so callers branch on `r.OK`.
11+
- Do not put compliance tests in aggregate AX-7 files or versioned test files.
12+
13+
The CLI package mutates process-level state for stdio, theme, colors, and global runtime registration. Tests that touch those globals should restore them with `t.Cleanup` or the local reset helpers before returning.
14+
15+
Before handing work back, run:
16+
17+
```sh
18+
GOWORK=off go mod tidy
19+
GOWORK=off go vet ./...
20+
GOWORK=off go test -count=1 ./...
21+
gofmt -l .
22+
bash /Users/snider/Code/core/go/tests/cli/v090-upgrade/audit.sh .
23+
```

cmd/core/config/cmd.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package config
22

33
import (
4-
"dappco.re/go/core"
4+
"dappco.re/go"
55
"dappco.re/go/cli/pkg/cli"
66
"dappco.re/go/config"
77
)
@@ -28,10 +28,10 @@ func AddConfigCommands(c *core.Core) {
2828
})
2929
}
3030

31-
func loadConfig() (*config.Config, error) {
31+
func loadConfig() core.Result {
3232
configuration, err := config.New()
3333
if err != nil {
34-
return nil, cli.Wrap(err, "failed to load config")
34+
return cli.Wrap(err, "failed to load config")
3535
}
36-
return configuration, nil
36+
return core.Ok(configuration)
3737
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package config
2+
3+
import core "dappco.re/go"
4+
5+
func ExampleAddConfigCommands() {
6+
core.Println("AddConfigCommands")
7+
// Output: AddConfigCommands
8+
}

cmd/core/config/cmd_get.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
package config
22

33
import (
4-
"dappco.re/go/core"
4+
"dappco.re/go"
55
"dappco.re/go/cli/pkg/cli"
6+
"dappco.re/go/config"
67
)
78

89
func configGetAction(opts core.Options) core.Result {
910
key := opts.String("_arg")
1011
if key == "" {
11-
return core.Result{Value: cli.Err("requires a configuration key argument"), OK: false}
12+
return cli.Err("requires a configuration key argument")
1213
}
1314

14-
configuration, err := loadConfig()
15-
if err != nil {
16-
return core.Result{Value: err, OK: false}
15+
configurationResult := loadConfig()
16+
if !configurationResult.OK {
17+
return configurationResult
1718
}
19+
configuration := configurationResult.Value.(*config.Config)
1820

1921
var value any
2022
if err := configuration.Get(key, &value); err != nil {
21-
return core.Result{Value: cli.Err("key not found: %s", key), OK: false}
23+
return cli.Err("key not found: %s", key)
2224
}
2325

2426
cli.Println("%v", value)
25-
return core.Result{OK: true}
27+
return core.Ok(nil)
2628
}

cmd/core/config/cmd_list.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,30 @@ package config
33
import (
44
"maps"
55

6-
"dappco.re/go/core"
6+
"dappco.re/go"
77
"dappco.re/go/cli/pkg/cli"
8+
"dappco.re/go/config"
89
"gopkg.in/yaml.v3"
910
)
1011

1112
func configListAction(_ core.Options) core.Result {
12-
configuration, err := loadConfig()
13-
if err != nil {
14-
return core.Result{Value: err, OK: false}
13+
configurationResult := loadConfig()
14+
if !configurationResult.OK {
15+
return configurationResult
1516
}
17+
configuration := configurationResult.Value.(*config.Config)
1618

1719
all := maps.Collect(configuration.All())
1820
if len(all) == 0 {
1921
cli.Dim("No configuration values set")
20-
return core.Result{OK: true}
22+
return core.Ok(nil)
2123
}
2224

2325
output, err := yaml.Marshal(all)
2426
if err != nil {
25-
return core.Result{Value: cli.Wrap(err, "failed to format config"), OK: false}
27+
return cli.Wrap(err, "failed to format config")
2628
}
2729

2830
cli.Print("%s", string(output))
29-
return core.Result{OK: true}
31+
return core.Ok(nil)
3032
}

cmd/core/config/cmd_path.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package config
22

33
import (
4-
"dappco.re/go/core"
4+
"dappco.re/go"
55
"dappco.re/go/cli/pkg/cli"
6+
"dappco.re/go/config"
67
)
78

89
func configPathAction(_ core.Options) core.Result {
9-
configuration, err := loadConfig()
10-
if err != nil {
11-
return core.Result{Value: err, OK: false}
10+
configurationResult := loadConfig()
11+
if !configurationResult.OK {
12+
return configurationResult
1213
}
14+
configuration := configurationResult.Value.(*config.Config)
1315

1416
cli.Println("%s", configuration.Path())
15-
return core.Result{OK: true}
17+
return core.Ok(nil)
1618
}

cmd/core/config/cmd_set.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package config
22

33
import (
4-
"dappco.re/go/core"
4+
"dappco.re/go"
55
"dappco.re/go/cli/pkg/cli"
6+
"dappco.re/go/config"
67
)
78

89
// configSetAction handles 'config set --key=<key> --value=<value>'.
@@ -18,21 +19,22 @@ func configSetAction(opts core.Options) core.Result {
1819
}
1920

2021
if key == "" {
21-
return core.Result{Value: cli.Err("requires --key and --value arguments (e.g. config set --key=dev.editor --value=vim)"), OK: false}
22+
return cli.Err("requires --key and --value arguments (e.g. config set --key=dev.editor --value=vim)")
2223
}
2324
if value == "" {
24-
return core.Result{Value: cli.Err("requires --value argument (e.g. config set --key=%s --value=<value>)", key), OK: false}
25+
return cli.Err("requires --value argument (e.g. config set --key=%s --value=<value>)", key)
2526
}
2627

27-
configuration, err := loadConfig()
28-
if err != nil {
29-
return core.Result{Value: err, OK: false}
28+
configurationResult := loadConfig()
29+
if !configurationResult.OK {
30+
return configurationResult
3031
}
32+
configuration := configurationResult.Value.(*config.Config)
3133

3234
if err := configuration.Set(key, value); err != nil {
33-
return core.Result{Value: cli.Wrap(err, "failed to set config value"), OK: false}
35+
return cli.Wrap(err, "failed to set config value")
3436
}
3537

3638
cli.Success(key + " = " + value)
37-
return core.Result{OK: true}
39+
return core.Ok(nil)
3840
}

cmd/core/config/cmd_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package config
2+
3+
import (
4+
. "dappco.re/go"
5+
)
6+
7+
func TestCmd_AddConfigCommands_Good(t *T) {
8+
c := New()
9+
AddConfigCommands(c)
10+
11+
AssertTrue(t, c.Command("config/get").OK)
12+
AssertTrue(t, c.Command("config/set").OK)
13+
}
14+
15+
func TestCmd_AddConfigCommands_Bad(t *T) {
16+
var c *Core
17+
18+
AssertPanics(t, func() { AddConfigCommands(c) })
19+
AssertNil(t, c)
20+
}
21+
22+
func TestCmd_AddConfigCommands_Ugly(t *T) {
23+
c := New()
24+
AddConfigCommands(c)
25+
AddConfigCommands(c)
26+
27+
AssertTrue(t, c.Command("config/list").OK)
28+
AssertTrue(t, c.Command("config/path").OK)
29+
}

cmd/core/doctor/cmd_checks.go

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package doctor
22

33
import (
4-
"context"
5-
6-
"dappco.re/go/core"
7-
"dappco.re/go/core/process"
8-
"dappco.re/go/i18n"
4+
"dappco.re/go"
5+
"dappco.re/go/cli/pkg/i18n"
96
)
107

118
// check represents a tool check configuration
@@ -96,27 +93,8 @@ func optionalChecks() []check {
9693
//
9794
// ok, version := runCheck(check{command: "git", args: []string{"--version"}})
9895
func runCheck(toolCheck check) (bool, string) {
99-
ctx := context.Background()
100-
processCore := core.New(core.WithService(process.Register))
101-
if startup := processCore.ServiceStartup(ctx, nil); !startup.OK {
96+
if !(core.App{}).Find(toolCheck.command, toolCheck.name).OK {
10297
return false, ""
10398
}
104-
defer processCore.ServiceShutdown(context.Background())
105-
106-
result := processCore.Process().Run(ctx, toolCheck.command, toolCheck.args...)
107-
if !result.OK {
108-
return false, ""
109-
}
110-
111-
output, ok := result.Value.(string)
112-
if !ok {
113-
return false, ""
114-
}
115-
116-
// Extract first line as version info.
117-
lines := core.Split(core.Trim(output), "\n")
118-
if len(lines) > 0 {
119-
return true, core.Trim(lines[0])
120-
}
121-
return true, ""
99+
return true, toolCheck.command
122100
}

0 commit comments

Comments
 (0)