Skip to content

Commit 498e942

Browse files
authored
Merge pull request #2 from dAppCore/dev
Enhance CLI functionality with JSON output and improved help commands
2 parents e177418 + 20a2e77 commit 498e942

84 files changed

Lines changed: 4201 additions & 756 deletions

Some content is hidden

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

cmd/core/config/cmd.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
)
77

88
// AddConfigCommands registers the 'config' command group and all subcommands.
9+
//
10+
// config.AddConfigCommands(rootCmd)
911
func AddConfigCommands(root *cli.Command) {
1012
configCmd := cli.NewGroup("config", "Manage configuration", "")
1113
root.AddCommand(configCmd)
@@ -17,9 +19,9 @@ func AddConfigCommands(root *cli.Command) {
1719
}
1820

1921
func loadConfig() (*config.Config, error) {
20-
cfg, err := config.New()
22+
configuration, err := config.New()
2123
if err != nil {
2224
return nil, cli.Wrap(err, "failed to load config")
2325
}
24-
return cfg, nil
26+
return configuration, nil
2527
}

cmd/core/config/cmd_get.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
package config
22

33
import (
4-
"fmt"
5-
64
"forge.lthn.ai/core/cli/pkg/cli"
75
)
86

97
func addGetCommand(parent *cli.Command) {
108
cmd := cli.NewCommand("get", "Get a configuration value", "", func(cmd *cli.Command, args []string) error {
119
key := args[0]
1210

13-
cfg, err := loadConfig()
11+
configuration, err := loadConfig()
1412
if err != nil {
1513
return err
1614
}
1715

1816
var value any
19-
if err := cfg.Get(key, &value); err != nil {
17+
if err := configuration.Get(key, &value); err != nil {
2018
return cli.Err("key not found: %s", key)
2119
}
2220

23-
fmt.Println(value)
21+
cli.Println("%v", value)
2422
return nil
2523
})
2624

cmd/core/config/cmd_list.go

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

33
import (
4-
"fmt"
54
"maps"
65

76
"forge.lthn.ai/core/cli/pkg/cli"
@@ -10,23 +9,23 @@ import (
109

1110
func addListCommand(parent *cli.Command) {
1211
cmd := cli.NewCommand("list", "List all configuration values", "", func(cmd *cli.Command, args []string) error {
13-
cfg, err := loadConfig()
12+
configuration, err := loadConfig()
1413
if err != nil {
1514
return err
1615
}
1716

18-
all := maps.Collect(cfg.All())
17+
all := maps.Collect(configuration.All())
1918
if len(all) == 0 {
2019
cli.Dim("No configuration values set")
2120
return nil
2221
}
2322

24-
out, err := yaml.Marshal(all)
23+
output, err := yaml.Marshal(all)
2524
if err != nil {
2625
return cli.Wrap(err, "failed to format config")
2726
}
2827

29-
fmt.Print(string(out))
28+
cli.Print("%s", string(output))
3029
return nil
3130
})
3231

cmd/core/config/cmd_path.go

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

33
import (
4-
"fmt"
5-
64
"forge.lthn.ai/core/cli/pkg/cli"
75
)
86

97
func addPathCommand(parent *cli.Command) {
108
cmd := cli.NewCommand("path", "Show the configuration file path", "", func(cmd *cli.Command, args []string) error {
11-
cfg, err := loadConfig()
9+
configuration, err := loadConfig()
1210
if err != nil {
1311
return err
1412
}
1513

16-
fmt.Println(cfg.Path())
14+
cli.Println("%s", configuration.Path())
1715
return nil
1816
})
1917

cmd/core/config/cmd_set.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ func addSetCommand(parent *cli.Command) {
99
key := args[0]
1010
value := args[1]
1111

12-
cfg, err := loadConfig()
12+
configuration, err := loadConfig()
1313
if err != nil {
1414
return err
1515
}
1616

17-
if err := cfg.Set(key, value); err != nil {
17+
if err := configuration.Set(key, value); err != nil {
1818
return cli.Wrap(err, "failed to set config value")
1919
}
2020

cmd/core/doctor/cmd_checks.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package doctor
22

33
import (
44
"os/exec"
5-
"strings"
65

6+
"dappco.re/go/core"
77
"forge.lthn.ai/core/go-i18n"
88
)
99

@@ -26,6 +26,13 @@ func requiredChecks() []check {
2626
args: []string{"--version"},
2727
versionFlag: "--version",
2828
},
29+
{
30+
name: i18n.T("cmd.doctor.check.go.name"),
31+
description: i18n.T("cmd.doctor.check.go.description"),
32+
command: "go",
33+
args: []string{"version"},
34+
versionFlag: "version",
35+
},
2936
{
3037
name: i18n.T("cmd.doctor.check.gh.name"),
3138
description: i18n.T("cmd.doctor.check.gh.description"),
@@ -84,18 +91,20 @@ func optionalChecks() []check {
8491
}
8592
}
8693

87-
// runCheck executes a tool check and returns success status and version info
88-
func runCheck(c check) (bool, string) {
89-
cmd := exec.Command(c.command, c.args...)
90-
output, err := cmd.CombinedOutput()
94+
// runCheck executes a tool check and returns success status and version info.
95+
//
96+
// ok, version := runCheck(check{command: "git", args: []string{"--version"}})
97+
func runCheck(toolCheck check) (bool, string) {
98+
proc := exec.Command(toolCheck.command, toolCheck.args...)
99+
output, err := proc.CombinedOutput()
91100
if err != nil {
92101
return false, ""
93102
}
94103

95-
// Extract first line as version
96-
lines := strings.Split(strings.TrimSpace(string(output)), "\n")
104+
// Extract first line as version info.
105+
lines := core.Split(core.Trim(string(output)), "\n")
97106
if len(lines) > 0 {
98-
return true, strings.TrimSpace(lines[0])
107+
return true, core.Trim(lines[0])
99108
}
100109
return true, ""
101110
}

cmd/core/doctor/cmd_checks_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package doctor
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestRequiredChecksIncludesGo(t *testing.T) {
10+
checks := requiredChecks()
11+
12+
var found bool
13+
for _, c := range checks {
14+
if c.command == "go" {
15+
found = true
16+
assert.Equal(t, "version", c.versionFlag)
17+
break
18+
}
19+
}
20+
21+
assert.True(t, found, "required checks should include the Go compiler")
22+
}

cmd/core/doctor/cmd_commands.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
)
1717

1818
// AddDoctorCommands registers the 'doctor' command and all subcommands.
19+
//
20+
// doctor.AddDoctorCommands(rootCmd)
1921
func AddDoctorCommands(root *cobra.Command) {
2022
doctorCmd.Short = i18n.T("cmd.doctor.short")
2123
doctorCmd.Long = i18n.T("cmd.doctor.long")

cmd/core/doctor/cmd_doctor.go

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
package doctor
33

44
import (
5-
"errors"
6-
"fmt"
7-
85
"forge.lthn.ai/core/cli/pkg/cli"
96
"forge.lthn.ai/core/go-i18n"
107
"github.com/spf13/cobra"
@@ -32,89 +29,89 @@ func init() {
3229
}
3330

3431
func runDoctor(verbose bool) error {
35-
fmt.Println(i18n.T("common.progress.checking", map[string]any{"Item": "development environment"}))
36-
fmt.Println()
32+
cli.Println("%s", i18n.T("common.progress.checking", map[string]any{"Item": "development environment"}))
33+
cli.Blank()
3734

3835
var passed, failed, optional int
3936

4037
// Check required tools
41-
fmt.Println(i18n.T("cmd.doctor.required"))
42-
for _, c := range requiredChecks() {
43-
ok, version := runCheck(c)
38+
cli.Println("%s", i18n.T("cmd.doctor.required"))
39+
for _, toolCheck := range requiredChecks() {
40+
ok, version := runCheck(toolCheck)
4441
if ok {
4542
if verbose {
46-
fmt.Println(formatCheckResult(true, c.name, version))
43+
cli.Println("%s", formatCheckResult(true, toolCheck.name, version))
4744
} else {
48-
fmt.Println(formatCheckResult(true, c.name, ""))
45+
cli.Println("%s", formatCheckResult(true, toolCheck.name, ""))
4946
}
5047
passed++
5148
} else {
52-
fmt.Printf(" %s %s - %s\n", errorStyle.Render(cli.Glyph(":cross:")), c.name, c.description)
49+
cli.Println(" %s %s - %s", errorStyle.Render(cli.Glyph(":cross:")), toolCheck.name, toolCheck.description)
5350
failed++
5451
}
5552
}
5653

5754
// Check optional tools
58-
fmt.Printf("\n%s\n", i18n.T("cmd.doctor.optional"))
59-
for _, c := range optionalChecks() {
60-
ok, version := runCheck(c)
55+
cli.Println("\n%s", i18n.T("cmd.doctor.optional"))
56+
for _, toolCheck := range optionalChecks() {
57+
ok, version := runCheck(toolCheck)
6158
if ok {
6259
if verbose {
63-
fmt.Println(formatCheckResult(true, c.name, version))
60+
cli.Println("%s", formatCheckResult(true, toolCheck.name, version))
6461
} else {
65-
fmt.Println(formatCheckResult(true, c.name, ""))
62+
cli.Println("%s", formatCheckResult(true, toolCheck.name, ""))
6663
}
6764
passed++
6865
} else {
69-
fmt.Printf(" %s %s - %s\n", dimStyle.Render(cli.Glyph(":skip:")), c.name, dimStyle.Render(c.description))
66+
cli.Println(" %s %s - %s", dimStyle.Render(cli.Glyph(":skip:")), toolCheck.name, dimStyle.Render(toolCheck.description))
7067
optional++
7168
}
7269
}
7370

7471
// Check GitHub access
75-
fmt.Printf("\n%s\n", i18n.T("cmd.doctor.github"))
72+
cli.Println("\n%s", i18n.T("cmd.doctor.github"))
7673
if checkGitHubSSH() {
77-
fmt.Println(formatCheckResult(true, i18n.T("cmd.doctor.ssh_found"), ""))
74+
cli.Println("%s", formatCheckResult(true, i18n.T("cmd.doctor.ssh_found"), ""))
7875
} else {
79-
fmt.Printf(" %s %s\n", errorStyle.Render(cli.Glyph(":cross:")), i18n.T("cmd.doctor.ssh_missing"))
76+
cli.Println(" %s %s", errorStyle.Render(cli.Glyph(":cross:")), i18n.T("cmd.doctor.ssh_missing"))
8077
failed++
8178
}
8279

8380
if checkGitHubCLI() {
84-
fmt.Println(formatCheckResult(true, i18n.T("cmd.doctor.cli_auth"), ""))
81+
cli.Println("%s", formatCheckResult(true, i18n.T("cmd.doctor.cli_auth"), ""))
8582
} else {
86-
fmt.Printf(" %s %s\n", errorStyle.Render(cli.Glyph(":cross:")), i18n.T("cmd.doctor.cli_auth_missing"))
83+
cli.Println(" %s %s", errorStyle.Render(cli.Glyph(":cross:")), i18n.T("cmd.doctor.cli_auth_missing"))
8784
failed++
8885
}
8986

9087
// Check workspace
91-
fmt.Printf("\n%s\n", i18n.T("cmd.doctor.workspace"))
88+
cli.Println("\n%s", i18n.T("cmd.doctor.workspace"))
9289
checkWorkspace()
9390

9491
// Summary
95-
fmt.Println()
92+
cli.Blank()
9693
if failed > 0 {
9794
cli.Error(i18n.T("cmd.doctor.issues", map[string]any{"Count": failed}))
98-
fmt.Printf("\n%s\n", i18n.T("cmd.doctor.install_missing"))
95+
cli.Println("\n%s", i18n.T("cmd.doctor.install_missing"))
9996
printInstallInstructions()
100-
return errors.New(i18n.T("cmd.doctor.issues_error", map[string]any{"Count": failed}))
97+
return cli.Err("%s", i18n.T("cmd.doctor.issues_error", map[string]any{"Count": failed}))
10198
}
10299

103100
cli.Success(i18n.T("cmd.doctor.ready"))
104101
return nil
105102
}
106103

107104
func formatCheckResult(ok bool, name, detail string) string {
108-
check := cli.Check(name)
105+
checkBuilder := cli.Check(name)
109106
if ok {
110-
check.Pass()
107+
checkBuilder.Pass()
111108
} else {
112-
check.Fail()
109+
checkBuilder.Fail()
113110
}
114111
if detail != "" {
115-
check.Message(detail)
112+
checkBuilder.Message(detail)
116113
} else {
117-
check.Message("")
114+
checkBuilder.Message("")
118115
}
119-
return check.String()
116+
return checkBuilder.String()
120117
}

0 commit comments

Comments
 (0)