Skip to content

Commit 1ff4e52

Browse files
authored
Merge pull request #6 from BetterDiscord/feat/addon-commands
Add support for addons and improve output formatting
2 parents f258e96 + 1496e2f commit 1ff4e52

27 files changed

Lines changed: 2587 additions & 84 deletions

.golangci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: "2"
2+
3+
linters:
4+
disable:
5+
- exhaustruct # Overly strict for initialization
6+
settings:
7+
errcheck:
8+
exclude-functions:
9+
- fmt.Fprintln
10+
- fmt.Fprintf
11+
- fmt.Fscan
12+
- fmt.Fscanf
13+
- fmt.Sscanf

README.md

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ A cross-platform command-line interface for installing, updating, and managing [
1111

1212
- 🚀 Easy installation and uninstallation of BetterDiscord
1313
- 🔄 Support for multiple Discord channels (Stable, PTB, Canary)
14+
- 🧭 Discover Discord installs and suggested paths
15+
- 🧩 Manage plugins and themes (list, install, update, remove)
16+
- 🛒 Browse and search the BetterDiscord store
1417
- 🖥️ Cross-platform support (Windows, macOS, Linux)
1518
- 📦 Available via npm for easy distribution
1619
- ⚡ Fast and lightweight Go binary
@@ -47,6 +50,14 @@ Download the latest release for your platform from the [releases page](https://g
4750

4851
## Usage
4952

53+
### Global Options
54+
55+
```bash
56+
bdcli --silent <command> # Suppress non-error output
57+
```
58+
59+
You can also set `BDCLI_SILENT=1` to silence output in automation.
60+
5061
### Install BetterDiscord
5162

5263
Install BetterDiscord to a specific Discord channel:
@@ -79,12 +90,80 @@ Uninstall BetterDiscord by providing a Discord install path:
7990
bdcli uninstall --path /path/to/Discord
8091
```
8192

93+
Uninject BetterDiscord from all detected Discord installations (without deleting data):
94+
95+
```bash
96+
bdcli uninstall --all
97+
```
98+
99+
Fully uninstall BetterDiscord from all Discord installations and remove all BetterDiscord folders:
100+
101+
```bash
102+
bdcli uninstall --full
103+
```
104+
82105
### Check Version
83106

84107
```bash
85108
bdcli version
86109
```
87110

111+
### Update BetterDiscord
112+
113+
```bash
114+
bdcli update
115+
bdcli update --check
116+
```
117+
118+
### Show BetterDiscord Info
119+
120+
```bash
121+
bdcli info
122+
```
123+
124+
### Discover Discord Installs
125+
126+
```bash
127+
bdcli discover installs
128+
bdcli discover paths
129+
bdcli discover addons
130+
```
131+
132+
### Manage Plugins
133+
134+
```bash
135+
bdcli plugins list
136+
bdcli plugins info <name>
137+
bdcli plugins install <name|id|url>
138+
bdcli plugins update <name|id|url>
139+
bdcli plugins update <name|id> --check # Check for updates without installing
140+
bdcli plugins remove <name|id>
141+
```
142+
143+
### Manage Themes
144+
145+
```bash
146+
bdcli themes list
147+
bdcli themes info <name>
148+
bdcli themes install <name|id|url>
149+
bdcli themes update <name|id|url>
150+
bdcli themes update <name|id> --check # Check for updates without installing
151+
bdcli themes remove <name|id>
152+
```
153+
154+
### Browse the Store
155+
156+
```bash
157+
bdcli store search <query>
158+
bdcli store show <id|name>
159+
160+
bdcli store plugins search <query>
161+
bdcli store plugins show <id|name>
162+
163+
bdcli store themes search <query>
164+
bdcli store themes show <id|name>
165+
```
166+
88167
### Shell Completions
89168

90169
```bash
@@ -100,6 +179,18 @@ bdcli --help
100179
bdcli [command] --help
101180
```
102181

182+
### Automation
183+
184+
For scripts and CI jobs, you can suppress non-error output:
185+
186+
```bash
187+
# One-off command
188+
bdcli --silent install --channel stable
189+
190+
# Environment variable (applies to all commands)
191+
BDCLI_SILENT=1 bdcli update
192+
```
193+
103194
### CLI Help Output
104195

105196
```
@@ -111,13 +202,20 @@ Usage:
111202
112203
Available Commands:
113204
completion Generate shell completions
205+
discover Discover Discord installations and related data
114206
help Help about any command
207+
info Displays information about BetterDiscord installation
115208
install Installs BetterDiscord to your Discord
209+
plugins Manage BetterDiscord plugins
210+
store Browse and search the BetterDiscord store
211+
themes Manage BetterDiscord themes
116212
uninstall Uninstalls BetterDiscord from your Discord
213+
update Update BetterDiscord to the latest version
117214
version Print the version number
118215
119216
Flags:
120-
-h, --help help for bdcli
217+
--silent Suppress non-error output
218+
-h, --help help for bdcli
121219
122220
Use "bdcli [command] --help" for more information about a command.
123221
```
@@ -235,6 +333,12 @@ task coverage
235333
.
236334
├── cmd/ # Cobra commands
237335
│ ├── install.go # Install command
336+
│ ├── update.go # Update command
337+
│ ├── info.go # Info command
338+
│ ├── discover.go # Discover command
339+
│ ├── plugins.go # Plugins commands
340+
│ ├── themes.go # Themes commands
341+
│ ├── store.go # Store commands
238342
│ ├── uninstall.go # Uninstall command
239343
│ ├── version.go # Version command
240344
│ └── root.go # Root command

cmd/discover.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/betterdiscord/cli/internal/betterdiscord"
7+
"github.com/betterdiscord/cli/internal/discord"
8+
"github.com/betterdiscord/cli/internal/models"
9+
"github.com/betterdiscord/cli/internal/output"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
func init() {
14+
discoverCmd.AddCommand(discoverInstallsCmd)
15+
discoverCmd.AddCommand(discoverPathsCmd)
16+
discoverCmd.AddCommand(discoverAddonsCmd)
17+
rootCmd.AddCommand(discoverCmd)
18+
}
19+
20+
var discoverCmd = &cobra.Command{
21+
Use: "discover",
22+
Short: "Discover Discord installations and related data",
23+
RunE: func(cmd *cobra.Command, args []string) error {
24+
return discoverInstallsCmd.RunE(cmd, args)
25+
},
26+
}
27+
28+
var discoverInstallsCmd = &cobra.Command{
29+
Use: "installs",
30+
Short: "Show detected Discord installations",
31+
Long: "Lists detected Discord installations by channel, showing path, version, install type, and BetterDiscord status.",
32+
RunE: func(cmd *cobra.Command, args []string) error {
33+
installs := discord.GetAllInstalls()
34+
if len(installs) == 0 {
35+
output.Println("📭 No Discord installations detected.")
36+
return nil
37+
}
38+
39+
channels := []models.DiscordChannel{models.Stable, models.PTB, models.Canary}
40+
output.Printf("🔎 Discord installations:\n\n")
41+
tw := output.NewTableWriter()
42+
fmt.Fprintln(tw, "CHANNEL\tVERSION\tTYPE\tBD INJECTED\tPATH")
43+
44+
for _, ch := range channels {
45+
arr := installs[ch]
46+
for _, inst := range arr {
47+
typeLabel := "native"
48+
if inst.IsFlatpak {
49+
typeLabel = "flatpak"
50+
} else if inst.IsSnap {
51+
typeLabel = "snap"
52+
}
53+
bdStatus := "no"
54+
if inst.IsInjected() {
55+
bdStatus = "yes"
56+
}
57+
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\n", ch.Name(), inst.Version, typeLabel, bdStatus, inst.CorePath)
58+
}
59+
}
60+
61+
return tw.Flush()
62+
},
63+
}
64+
65+
var discoverPathsCmd = &cobra.Command{
66+
Use: "paths",
67+
Short: "Show suggested install paths per channel",
68+
RunE: func(cmd *cobra.Command, args []string) error {
69+
channels := []models.DiscordChannel{models.Stable, models.PTB, models.Canary}
70+
output.Printf("🧭 Suggested install paths:\n\n")
71+
tw := output.NewTableWriter()
72+
fmt.Fprintln(tw, "CHANNEL\tSUGGESTED PATH")
73+
for _, ch := range channels {
74+
p := discord.GetSuggestedPath(ch)
75+
if p == "" {
76+
p = "(none detected)"
77+
}
78+
fmt.Fprintf(tw, "%s\t%s\n", ch.Name(), p)
79+
}
80+
return tw.Flush()
81+
},
82+
}
83+
84+
var discoverAddonsCmd = &cobra.Command{
85+
Use: "addons",
86+
Short: "Summarize installed plugins and themes",
87+
RunE: func(cmd *cobra.Command, args []string) error {
88+
plugins, err := betterdiscord.ListAddons(betterdiscord.AddonPlugin)
89+
if err != nil {
90+
return err
91+
}
92+
themes, err := betterdiscord.ListAddons(betterdiscord.AddonTheme)
93+
if err != nil {
94+
return err
95+
}
96+
97+
output.Printf("🧩 Addons summary:\n")
98+
output.Printf(" Plugins: %d installed\n", len(plugins))
99+
for _, p := range plugins {
100+
output.Printf(" - %s (%s)\n", p.FullFilename, p.Path)
101+
}
102+
output.Printf(" Themes: %d installed\n", len(themes))
103+
for _, t := range themes {
104+
output.Printf(" - %s (%s)\n", t.FullFilename, t.Path)
105+
}
106+
return nil
107+
},
108+
}

cmd/info.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/spf13/cobra"
7+
8+
"github.com/betterdiscord/cli/internal/betterdiscord"
9+
)
10+
11+
func init() {
12+
rootCmd.AddCommand(infoCmd)
13+
}
14+
15+
var infoCmd = &cobra.Command{
16+
Use: "info",
17+
Short: "Displays information about BetterDiscord installation",
18+
Long: "Displays detailed information about the BetterDiscord installation, including version, commit, branch, build, and installation paths.",
19+
RunE: func(cmd *cobra.Command, args []string) error {
20+
bdinstall := betterdiscord.GetInstallation()
21+
22+
if !bdinstall.IsAsarInstalled() {
23+
return fmt.Errorf("BetterDiscord does not appear to be installed, try running 'bdcli install' first")
24+
}
25+
26+
bdinstall.LogBuildinfo()
27+
28+
return nil
29+
},
30+
}

cmd/install.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/betterdiscord/cli/internal/discord"
1010
"github.com/betterdiscord/cli/internal/models"
11+
"github.com/betterdiscord/cli/internal/output"
1112
)
1213

1314
func init() {
@@ -17,9 +18,10 @@ func init() {
1718
}
1819

1920
var installCmd = &cobra.Command{
20-
Use: "install",
21-
Short: "Installs BetterDiscord to your Discord",
22-
Long: "Install BetterDiscord by specifying either --path to a Discord install or --channel to auto-detect (default: stable).",
21+
Use: "install",
22+
Aliases: []string{"reinstall"},
23+
Short: "Installs BetterDiscord to your Discord",
24+
Long: "Install BetterDiscord by specifying either --path to a Discord install or --channel to auto-detect (default: stable).",
2325
RunE: func(cmd *cobra.Command, args []string) error {
2426
pathFlag, _ := cmd.Flags().GetString("path")
2527
channelFlag, _ := cmd.Flags().GetString("channel")
@@ -51,7 +53,25 @@ var installCmd = &cobra.Command{
5153
return fmt.Errorf("installation failed: %w", err)
5254
}
5355

54-
fmt.Printf("✅ BetterDiscord installed to %s\n", path.Dir(install.CorePath))
56+
output.Printf("✅ BetterDiscord installed to %s\n", path.Dir(install.CorePath))
57+
output.Blank()
58+
output.Printf("📋 Installation Summary:\n")
59+
output.Blank()
60+
output.Printf(" Release Channel: %s\n", install.Channel.Display())
61+
output.Printf(" Discord Version: %s\n", install.Version)
62+
output.Printf(" Install Type: %s\n", func() string {
63+
if install.IsFlatpak {
64+
return "flatpak"
65+
} else if install.IsSnap {
66+
return "snap"
67+
}
68+
return "native"
69+
}())
70+
output.Printf(" Core Path: %s\n", path.Dir(install.CorePath))
71+
output.Blank()
72+
73+
bdinstall := install.GetBetterDiscordInstall()
74+
bdinstall.LogBuildinfo()
5575
return nil
5676
},
5777
}

0 commit comments

Comments
 (0)