Skip to content

Commit 2b862d9

Browse files
committed
make sure help is also stylized
Signed-off-by: abzcoding <abzcoding@gmail.com>
1 parent 45b1063 commit 2b862d9

2 files changed

Lines changed: 94 additions & 20 deletions

File tree

cmd/hget/main.go

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"flag"
5-
"fmt"
65
"os"
76
"runtime"
87
"time"
@@ -18,6 +17,8 @@ import (
1817
var GitCommit string
1918

2019
func main() {
20+
flag.Usage = ui.PrintHelp
21+
2122
var proxy, filePath, bwLimit, resumeTask string
2223

2324
conn := flag.Int("n", runtime.NumCPU(), "number of connections")
@@ -77,7 +78,7 @@ func main() {
7778
if len(args) < 1 {
7879
if len(filePath) < 1 {
7980
ui.Errorln("A URL or input file with URLs is required")
80-
usage()
81+
ui.PrintHelp()
8182
os.Exit(1)
8283
}
8384
batch.RunBatchDownloads(filePath, *conn, *skiptls, proxy, bwLimit, *timeout, *verify)
@@ -121,21 +122,3 @@ func main() {
121122
ui.PrintVerifySummary(verifyOK, verifyDetail)
122123
}
123124
}
124-
125-
func usage() {
126-
fmt.Fprintf(os.Stderr, `Usage:
127-
hget [options] URL
128-
hget [options] --resume=TaskName
129-
130-
Options:
131-
-n int number of connections (default number of CPUs)
132-
-skip-tls bool skip certificate verification for https (default false)
133-
-proxy string proxy address (e.g., '127.0.0.1:12345' for socks5 or 'http://proxy.com:8080')
134-
-file string file path containing URLs (one per line)
135-
-rate string bandwidth limit during download (e.g., 10kB, 10MiB)
136-
-resume string resume a stopped download by providing its task name or URL
137-
-probe string probe URL for range and content-length without downloading
138-
-timeout timeout for awaiting response headers (default 15s)
139-
--verify download and GPG-verify the .sig signature file after download
140-
`)
141-
}

internal/ui/ui.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,97 @@ func ConfirmRedownload(filename string) bool {
915915
return proceed
916916
}
917917

918+
// PrintHelp renders a styled --help screen to stdout.
919+
func PrintHelp() {
920+
// ── Banner ────────────────────────────────────────────────────────────────
921+
fmt.Fprintln(Stdout, styleBanner.Render(banner))
922+
fmt.Fprintln(Stdout)
923+
924+
w := 68 // fixed help width
925+
sep := styleSep.Render(strings.Repeat("─", w))
926+
927+
// ── Shared style helpers ──────────────────────────────────────────────────
928+
sectionHeader := lipgloss.NewStyle().
929+
Foreground(colorPurple).
930+
Bold(true).
931+
MarginLeft(2)
932+
933+
flagName := lipgloss.NewStyle().
934+
Foreground(colorCyan).
935+
Bold(true).
936+
Width(20)
937+
938+
flagDesc := lipgloss.NewStyle().
939+
Foreground(colorWhite)
940+
941+
flagDefault := lipgloss.NewStyle().
942+
Foreground(colorMuted)
943+
944+
usageLine := lipgloss.NewStyle().
945+
Foreground(colorGreen).
946+
MarginLeft(4)
947+
948+
exampleLine := lipgloss.NewStyle().
949+
Foreground(colorCyan).
950+
MarginLeft(4)
951+
952+
commentLine := lipgloss.NewStyle().
953+
Foreground(colorMuted).
954+
MarginLeft(4)
955+
956+
// ── Usage ────────────────────────────────────────────────────────────────
957+
fmt.Fprintln(Stdout, sectionHeader.Render("USAGE"))
958+
fmt.Fprintln(Stdout, usageLine.Render("hget [options] <url>"))
959+
fmt.Fprintln(Stdout, usageLine.Render("hget [options] --resume=<task-name>"))
960+
fmt.Fprintln(Stdout, usageLine.Render("hget --file=<urls-file> [options]"))
961+
fmt.Fprintln(Stdout)
962+
fmt.Fprintln(Stdout, sep)
963+
fmt.Fprintln(Stdout)
964+
965+
// ── Options ───────────────────────────────────────────────────────────────
966+
type opt struct{ flag, desc, def string }
967+
options := []opt{
968+
{"-n <int>", "number of parallel connections", "# of CPUs"},
969+
{"--skip-tls", "skip TLS certificate verification", "false"},
970+
{"--proxy <addr>", "proxy (socks5: host:port | http: http://host:port)", ""},
971+
{"--file <path>", "path to a file containing one URL per line", ""},
972+
{"--rate <limit>", "bandwidth cap per download (e.g. 10kB, 5MiB)", ""},
973+
{"--resume <task>", "resume a stopped download by task name or URL", ""},
974+
{"--probe <url>", "probe URL for range support & content-length only", ""},
975+
{"--timeout <dur>", "timeout waiting for response headers (e.g. 30s, 1m)", "15s"},
976+
{"--verify", "download & GPG-verify the .sig signature file", "false"},
977+
}
978+
979+
fmt.Fprintln(Stdout, sectionHeader.Render("OPTIONS"))
980+
for _, o := range options {
981+
line := " " + flagName.Render(o.flag) + " " + flagDesc.Render(o.desc)
982+
if o.def != "" {
983+
line += " " + flagDefault.Render("(default: "+o.def+")")
984+
}
985+
fmt.Fprintln(Stdout, line)
986+
}
987+
fmt.Fprintln(Stdout)
988+
fmt.Fprintln(Stdout, sep)
989+
fmt.Fprintln(Stdout)
990+
991+
// ── Examples ─────────────────────────────────────────────────────────────
992+
fmt.Fprintln(Stdout, sectionHeader.Render("EXAMPLES"))
993+
994+
examples := []struct{ comment, cmd string }{
995+
{"basic download", "hget https://example.com/file.iso"},
996+
{"8 connections, 5 MiB/s cap", "hget -n 8 --rate 5MiB https://example.com/large.tar.gz"},
997+
{"resume an interrupted download", "hget --resume https://example.com/file.iso"},
998+
{"batch download from a file", "hget --file urls.txt"},
999+
{"probe server without downloading", "hget --probe https://example.com/file.iso"},
1000+
{"download & verify GPG signature", "hget --verify https://example.com/file.iso"},
1001+
}
1002+
for _, e := range examples {
1003+
fmt.Fprintln(Stdout, commentLine.Render("# "+e.comment))
1004+
fmt.Fprintln(Stdout, exampleLine.Render(e.cmd))
1005+
fmt.Fprintln(Stdout)
1006+
}
1007+
}
1008+
9181009
// PrintVerifySummary writes a styled one-line verify result to the terminal
9191010
// using charmbracelet/log (works after the TUI alt-screen has closed).
9201011
func PrintVerifySummary(ok bool, detail string) {

0 commit comments

Comments
 (0)