Skip to content

Commit 44f3725

Browse files
feat: Big UI overhaul, using different charm libraries to enhance command line interface experience
1 parent d39c306 commit 44f3725

23 files changed

+1195
-421
lines changed

cmd/enrich.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/idlab-discover/AIBoMGen-cli/internal/enricher"
88
bomio "github.com/idlab-discover/AIBoMGen-cli/internal/io"
9+
"github.com/idlab-discover/AIBoMGen-cli/internal/ui"
910
"github.com/spf13/cobra"
1011
"github.com/spf13/viper"
1112
)
@@ -117,7 +118,8 @@ from Hugging Face API and README before enrichment.`,
117118
}
118119

119120
if level != "quiet" {
120-
fmt.Fprintf(cmd.OutOrStdout(), "\n✓ Enriched BOM saved to %s\n", outPath)
121+
msg := fmt.Sprintf("Enriched BOM saved to %s", outPath)
122+
fmt.Fprintf(cmd.OutOrStdout(), "\n%s\n", ui.SuccessBox.Render(ui.GetCheckMark()+" "+msg))
121123
}
122124

123125
return nil

cmd/generate.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func runGenerate(cmd *cobra.Command, args []string) error {
161161

162162
// Deprecation warning
163163
if viper.GetBool("generate.enrich") {
164-
fmt.Fprintf(cmd.ErrOrStderr(), "%s --enrich flag is deprecated. Use 'aibomgen-cli enrich' command instead.\n", ui.WarnMark)
164+
fmt.Fprintf(cmd.ErrOrStderr(), "%s --enrich flag is deprecated. Use 'aibomgen-cli enrich' command instead.\n", ui.GetWarnMark())
165165
}
166166

167167
// Determine output settings
@@ -320,11 +320,11 @@ func runModelIDMode(ctx context.Context, genUI *ui.GenerateUI, modelIDs []string
320320
fmt.Println()
321321
for _, m := range completedModels {
322322
if m.err != "" {
323-
fmt.Printf(" %s %s %s\n", ui.CrossMark, ui.Highlight.Render(m.id), ui.Error.Render("→ "+m.err))
323+
fmt.Printf(" %s %s %s\n", ui.GetCrossMark(), ui.Highlight.Render(m.id), ui.Error.Render("→ "+m.err))
324324
} else if m.datasets > 0 {
325-
fmt.Printf(" %s %s %s\n", ui.CheckMark, ui.Highlight.Render(m.id), ui.Dim.Render(fmt.Sprintf("→ %d dataset(s)", m.datasets)))
325+
fmt.Printf(" %s %s %s\n", ui.GetCheckMark(), ui.Highlight.Render(m.id), ui.Dim.Render(fmt.Sprintf("→ %d dataset(s)", m.datasets)))
326326
} else {
327-
fmt.Printf(" %s %s\n", ui.CheckMark, ui.Highlight.Render(m.id))
327+
fmt.Printf(" %s %s\n", ui.GetCheckMark(), ui.Highlight.Render(m.id))
328328
}
329329
}
330330
}
@@ -454,11 +454,11 @@ func runScanMode(ctx context.Context, genUI *ui.GenerateUI, inputPath, mode, hfT
454454
fmt.Println()
455455
for _, m := range completedModels {
456456
if m.err != "" {
457-
fmt.Printf(" %s %s %s\n", ui.CrossMark, ui.Highlight.Render(m.id), ui.Error.Render("→ "+m.err))
457+
fmt.Printf(" %s %s %s\n", ui.GetCrossMark(), ui.Highlight.Render(m.id), ui.Error.Render("→ "+m.err))
458458
} else if m.datasets > 0 {
459-
fmt.Printf(" %s %s %s\n", ui.CheckMark, ui.Highlight.Render(m.id), ui.Dim.Render(fmt.Sprintf("→ %d dataset(s)", m.datasets)))
459+
fmt.Printf(" %s %s %s\n", ui.GetCheckMark(), ui.Highlight.Render(m.id), ui.Dim.Render(fmt.Sprintf("→ %d dataset(s)", m.datasets)))
460460
} else {
461-
fmt.Printf(" %s %s\n", ui.CheckMark, ui.Highlight.Render(m.id))
461+
fmt.Printf(" %s %s\n", ui.GetCheckMark(), ui.Highlight.Render(m.id))
462462
}
463463
}
464464
}

cmd/root.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import (
66
"os"
77
"strings"
88

9+
"github.com/idlab-discover/AIBoMGen-cli/internal/ui"
910
"github.com/spf13/cobra"
1011
"github.com/spf13/viper"
11-
12-
"github.com/idlab-discover/AIBoMGen-cli/internal/ui"
1312
)
1413

1514
// rootCmd represents the base command
@@ -31,10 +30,17 @@ var rootCmd = &cobra.Command{
3130
}
3231

3332
var cfgFile string
33+
var version string
34+
35+
// SetVersion sets the version for the CLI
36+
func SetVersion(v string) {
37+
version = v
38+
rootCmd.Version = v
39+
}
3440

35-
// Execute executes the root command.
36-
func Execute() {
37-
rootCmd.Execute()
41+
// GetRootCmd returns the root command for use with fang
42+
func GetRootCmd() *cobra.Command {
43+
return rootCmd
3844
}
3945

4046
func init() {
@@ -86,7 +92,8 @@ func initConfig() {
8692
}
8793

8894
if err == nil {
89-
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
95+
configMsg := ui.Dim.Render("Using config file: ") + ui.Secondary.Render(viper.ConfigFileUsed())
96+
fmt.Fprintln(os.Stderr, configMsg)
9097
}
9198

9299
return
@@ -108,7 +115,8 @@ func initConfig() {
108115
// The config file is optional, we shouldn't exit when the config is not found
109116
break
110117
default:
111-
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
118+
configMsg := ui.Dim.Render("Using config file: ") + ui.Secondary.Render(viper.ConfigFileUsed())
119+
fmt.Fprintln(os.Stderr, configMsg)
112120
}
113121
}
114122

@@ -129,5 +137,5 @@ func initUIAndBanner(cmd *cobra.Command) {
129137
if cmd == nil {
130138
return
131139
}
132-
cmd.Root().Long = ui.Color(bannerASCII, ui.FgGreen) + "\n" + longDescription
140+
cmd.Root().Long = ui.Primary.Render(bannerASCII) + "\n" + longDescription
133141
}

config/defaults.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ enrich:
3333
# Path to existing AIBOM (required)
3434
input: "./dist/WiebeVandendriessche_model-card-example_aibom.json"
3535
# Output file path (default: overwrite input)
36-
output: "./dist/WiebeVandendriessche_model-card-example_aibom.json"
36+
output: ""
3737
# Input BOM format: json|xml|auto
3838
format: "auto"
3939
# Output BOM format: json|xml|auto

go.mod

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ module github.com/idlab-discover/AIBoMGen-cli
33
go 1.25.4
44

55
require (
6+
charm.land/bubbles/v2 v2.0.0-rc.1
7+
charm.land/bubbletea/v2 v2.0.0-rc.2
8+
charm.land/lipgloss/v2 v2.0.0-beta.3.0.20251106193318-19329a3e8410
69
github.com/CycloneDX/cyclonedx-go v0.9.3
10+
github.com/charmbracelet/fang v0.4.4
11+
github.com/charmbracelet/huh v0.8.0
12+
github.com/charmbracelet/lipgloss v1.1.0
713
github.com/spf13/cobra v1.10.2
814
github.com/spf13/viper v1.21.0
915
go.yaml.in/yaml/v3 v3.0.4
@@ -14,27 +20,36 @@ require (
1420
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
1521
github.com/catppuccin/go v0.3.0 // indirect
1622
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect
17-
github.com/charmbracelet/bubbletea v1.3.10 // indirect
18-
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
19-
github.com/charmbracelet/harmonica v0.2.0 // indirect
20-
github.com/charmbracelet/huh v0.8.0 // indirect
21-
github.com/charmbracelet/lipgloss v1.1.0 // indirect
22-
github.com/charmbracelet/x/ansi v0.10.1 // indirect
23-
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
23+
github.com/charmbracelet/bubbletea v1.3.6 // indirect
24+
github.com/charmbracelet/colorprofile v0.4.1 // indirect
25+
github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.3.0.20250917201909-41ff0bf215ea // indirect
26+
github.com/charmbracelet/ultraviolet v0.0.0-20251116181749-377898bcce38 // indirect
27+
github.com/charmbracelet/x/ansi v0.11.4 // indirect
28+
github.com/charmbracelet/x/cellbuf v0.0.14 // indirect
29+
github.com/charmbracelet/x/exp/charmtone v0.0.0-20250603201427-c31516f43444 // indirect
2430
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect
25-
github.com/charmbracelet/x/term v0.2.1 // indirect
31+
github.com/charmbracelet/x/term v0.2.2 // indirect
32+
github.com/charmbracelet/x/termios v0.1.1 // indirect
33+
github.com/charmbracelet/x/windows v0.2.2 // indirect
34+
github.com/clipperhouse/displaywidth v0.7.0 // indirect
35+
github.com/clipperhouse/stringish v0.1.1 // indirect
36+
github.com/clipperhouse/uax29/v2 v2.3.1 // indirect
2637
github.com/dustin/go-humanize v1.0.1 // indirect
2738
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
2839
github.com/fsnotify/fsnotify v1.9.0 // indirect
2940
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
3041
github.com/inconshreveable/mousetrap v1.1.0 // indirect
31-
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
42+
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
3243
github.com/mattn/go-isatty v0.0.20 // indirect
3344
github.com/mattn/go-localereader v0.0.1 // indirect
34-
github.com/mattn/go-runewidth v0.0.16 // indirect
45+
github.com/mattn/go-runewidth v0.0.19 // indirect
3546
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
3647
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
3748
github.com/muesli/cancelreader v0.2.2 // indirect
49+
github.com/muesli/mango v0.1.0 // indirect
50+
github.com/muesli/mango-cobra v1.2.0 // indirect
51+
github.com/muesli/mango-pflag v0.1.0 // indirect
52+
github.com/muesli/roff v0.1.0 // indirect
3853
github.com/muesli/termenv v0.16.0 // indirect
3954
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
4055
github.com/rivo/uniseg v0.4.7 // indirect
@@ -44,7 +59,8 @@ require (
4459
github.com/spf13/pflag v1.0.10 // indirect
4560
github.com/subosito/gotenv v1.6.0 // indirect
4661
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
47-
golang.org/x/sys v0.39.0 // indirect
62+
golang.org/x/sync v0.19.0 // indirect
63+
golang.org/x/sys v0.40.0 // indirect
4864
golang.org/x/text v0.32.0 // indirect
4965
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
5066
)

0 commit comments

Comments
 (0)