docs: extract goget manpage to standalone troff source
This commit is contained in:
@@ -3,6 +3,13 @@
|
||||
# Build output
|
||||
bin/
|
||||
|
||||
# Generated copy of man/goget.1 (regenerated by `just build`).
|
||||
# Required because //go:embed cannot reference files outside the
|
||||
# embedding package, so man/goget.1 is copied into the package
|
||||
# tree at build time and embedded into the binary.
|
||||
cmd/goget/man-page-data/*.1
|
||||
!cmd/goget/man-page-data/.gitkeep
|
||||
|
||||
# Test artifacts
|
||||
*.test
|
||||
*.out
|
||||
|
||||
@@ -9,6 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
**Documentation**
|
||||
|
||||
- **Standalone troff manpage** — `man/goget.1` is now the single source
|
||||
of truth for the goget(1) manual. The previous embedded manpage listed
|
||||
only ~30 of the 138 CLI flags and was missing every standard section;
|
||||
the new file documents every flag with a dedicated entry, the
|
||||
full set of conventional `.SH` sections (NAME, SYNOPSIS, DESCRIPTION,
|
||||
OPTIONS, EXAMPLES, EXIT STATUS, FILES, ENVIRONMENT, SEE ALSO, HISTORY,
|
||||
AUTHORS, REPORTING BUGS, COPYRIGHT), curl/wget compatibility notes, and
|
||||
a release-history entry. The manpage is embedded into the binary via
|
||||
`//go:embed`, so `--generate-man-page` and `man goget` now agree.
|
||||
- **`just man`** — new task that runs `groff -man -ww -Kutf-8 -z` over
|
||||
`man/goget.1` to validate the troff source. Skips cleanly when `groff`
|
||||
is not installed (CI on minimal images still passes).
|
||||
- **`just install-man`** and **`just uninstall-man`** — install the
|
||||
manpage to `$HOME/.local/share/man/man1/goget.1.gz` (XDG rootless,
|
||||
gzipped, reinstall-safe). After `just install-man`, `man goget`
|
||||
resolves the page automatically via the user's `MANPATH`.
|
||||
|
||||
**Core engine**
|
||||
|
||||
- **Unified worker pool** — single protocol-agnostic worker pool (`internal/pool`)
|
||||
@@ -53,6 +72,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
output when combined with `--json`. Credentials embedded in the stored
|
||||
URL are masked before display (the password placeholder is `xxxxx`).
|
||||
|
||||
### Testing
|
||||
|
||||
- `cmd/goget/man_page_test.go` — new test file. Asserts the embedded
|
||||
manpage is non-empty, carries a `.TH GOGET 1` header, contains every
|
||||
mandatory `.SH` section, and documents every flag registered by
|
||||
`defineFlags` (so adding a new flag without documenting it now breaks
|
||||
the build). When `groff` is installed, also runs `groff -man -ww
|
||||
-Kutf-8 -z` over the embedded source and fails on any warning.
|
||||
|
||||
## [1.0.0] — 2026-06-26
|
||||
|
||||
First public release: a modern IPv6-first command-line download utility built on
|
||||
|
||||
@@ -271,13 +271,18 @@ just install # go mod download
|
||||
just run # run from source (development)
|
||||
just build # go vet + gofmt check + build → bin/goget
|
||||
just test # go test -race -count=1 ./...
|
||||
just man # validate man/goget.1 with groff
|
||||
just install-man # install manpage to ~/.local/share/man/man1/
|
||||
just uninstall # remove build artifacts
|
||||
just uninstall-man# remove installed manpage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- [`man/goget.1`](man/goget.1) — troff manual page (`man goget` after
|
||||
`just install-man`)
|
||||
- [`docs/architecture.md`](docs/architecture.md) — components and request flow
|
||||
- [`docs/configuration.md`](docs/configuration.md) — config schema (TOML)
|
||||
- [`docs/api.md`](docs/api.md) — public Go library API
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Placeholder so the directory is tracked by git. The actual file
|
||||
generated here by `just build` is `goget.1`, copied from
|
||||
`../../../man/goget.1`.
|
||||
+13
-206
@@ -1,217 +1,24 @@
|
||||
//go:build linux || freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"codeberg.org/petrbalvin/goget/internal/core"
|
||||
)
|
||||
|
||||
// manPage holds the canonical goget(1) manual page in troff/groff format.
|
||||
// The source of truth is ../../man/goget.1; a copy is kept here so it can
|
||||
// be embedded into the binary at build time (//go:embed cannot reference
|
||||
// files outside the embedding package). The copy is refreshed by the
|
||||
// `cp` step in `just build`.
|
||||
//
|
||||
//go:embed man-page-data/goget.1
|
||||
var manPage string
|
||||
|
||||
// handleGenManPage implements the --generate-man-page flag. It writes the
|
||||
// embedded manpage to standard output and exits 0.
|
||||
func handleGenManPage() int {
|
||||
fmt.Printf(`.TH GOGET 1 "2026-06" "goget %s" "User Commands"
|
||||
.SH NAME
|
||||
goget \- modern IPv6-first command-line download utility
|
||||
.SH SYNOPSIS
|
||||
.B goget
|
||||
\fB\-\-url\fR \fIURL\fR [\fIOPTIONS\fR]
|
||||
.SH DESCRIPTION
|
||||
goget is a modern replacement for curl and wget built on Go stdlib.
|
||||
Features IPv6-first connections, parallel downloads, resume support,
|
||||
compression, checksum verification, and recursive mirroring.
|
||||
.SH OPTIONS
|
||||
.SS "Target"
|
||||
.TP
|
||||
\fB\-\-url\fR=\fIURL\fR
|
||||
URL to download (can be specified multiple times)
|
||||
.SS "Basic Options"
|
||||
.TP
|
||||
\fB\-\-output\fR=\fIFILE\fR
|
||||
Output filename (default: auto from URL)
|
||||
.TP
|
||||
\fB\-\-verbose\fR
|
||||
Verbose output with progress bar (default: enabled)
|
||||
.TP
|
||||
\fB\-\-no-progress\fR
|
||||
Hide progress bar (keep other output)
|
||||
.TP
|
||||
\fB\-\-quiet\fR
|
||||
Suppress all output except errors
|
||||
.TP
|
||||
\fB\-\-debug\fR
|
||||
Debug mode with detailed info
|
||||
.TP
|
||||
\fB\-\-resume\fR
|
||||
Resume interrupted download
|
||||
.TP
|
||||
\fB\-\-restart\fR
|
||||
Delete existing file and restart download
|
||||
.TP
|
||||
\fB\-\-overwrite\fR
|
||||
Overwrite existing file
|
||||
.TP
|
||||
\fB\-\-no-decompress\fR
|
||||
Disable automatic decompression
|
||||
.TP
|
||||
\fB\-\-parallel\fR=\fIN\fR
|
||||
Parallel connections (0=auto, 1=sequential)
|
||||
.TP
|
||||
\fB\-\-json\fR
|
||||
Output progress as JSON (for scripting)
|
||||
.TP
|
||||
\fB\-\-info\fR
|
||||
Show file information without downloading
|
||||
.TP
|
||||
\fB\-\-benchmark\fR=\fIURL\fR
|
||||
Benchmark download speed
|
||||
.SS "Network"
|
||||
.TP
|
||||
\fB\-\-timeout\fR=\fIDURATION\fR
|
||||
Connection timeout (0 = auto based on size)
|
||||
.TP
|
||||
\fB\-\-proxy\fR=\fIURL\fR
|
||||
Proxy server URL (http://, https://, socks5://, socks5h://)
|
||||
.TP
|
||||
\fB\-\-dns-servers\fR=\fIIPs\fR
|
||||
Custom DNS servers (comma-separated)
|
||||
.TP
|
||||
\fB\-\-max-retries\fR=\fIN\fR
|
||||
Maximum number of retries on failure
|
||||
.TP
|
||||
\fB\-\-no-ipv4\fR
|
||||
Disable IPv4 fallback
|
||||
.TP
|
||||
\fB\-\-no-redirect\fR
|
||||
Disable following HTTP redirects
|
||||
.TP
|
||||
\fB\-\-show-headers\fR
|
||||
Print HTTP response headers
|
||||
.TP
|
||||
\fB\-\-keep-timestamps\fR
|
||||
Set file modification time from Last-Modified header
|
||||
.TP
|
||||
\fB\-\-content-disposition\fR
|
||||
Use server-provided filename from Content-Disposition header
|
||||
.SS "Authentication"
|
||||
.TP
|
||||
Credentials are loaded automatically from \fB~/.netrc\fR when no \fB\-\-username\fR is given.
|
||||
.TP
|
||||
\fB\-\-username\fR=\fIUSER\fR
|
||||
Username for HTTP Basic/Digest Auth
|
||||
.TP
|
||||
\fB\-\-password\fR=\fIPASS\fR
|
||||
Password for HTTP Basic/Digest Auth
|
||||
.TP
|
||||
\fB\-\-password-file\fR=\fIFILE\fR
|
||||
Read password from file
|
||||
.TP
|
||||
\fB\-\-auth-type\fR=\fITYPE\fR
|
||||
Auth type: basic, digest, auto
|
||||
.TP
|
||||
\fB\-\-cookie-jar\fR=\fIFILE\fR
|
||||
File for loading/saving cookies
|
||||
.TP
|
||||
\fB\-\-cookie\fR=\fINAME=VALUE\fR
|
||||
Set cookie from CLI (repeatable, curl-compatible)
|
||||
.TP
|
||||
\fB\-\-retry-all-errors\fR
|
||||
Retry on any HTTP 4xx/5xx response
|
||||
.TP
|
||||
\fB\-\-ssl-key-log\fR=\fIFILE\fR
|
||||
Log TLS session keys to file (SSLKEYLOGFILE for Wireshark)
|
||||
.SS "Config"
|
||||
.TP
|
||||
\fB\-\-config\fR=\fIFILE\fR
|
||||
Path to config file
|
||||
.TP
|
||||
\fB\-\-config-get\fR=\fIKEY\fR
|
||||
Get a config value
|
||||
.TP
|
||||
\fB\-\-config-set\fR=\fIKEY\fR \fIVALUE\fR
|
||||
Set a config value
|
||||
.TP
|
||||
\fB\-\-config-list\fR
|
||||
List all config values
|
||||
.TP
|
||||
\fB\-\-config-unset\fR=\fIKEY\fR
|
||||
Unset a config value
|
||||
.TP
|
||||
\fB\-\-init-config\fR
|
||||
Generate default config file
|
||||
.SS "Mirror & Recursive"
|
||||
.TP
|
||||
\fB\-\-mirror\fR
|
||||
Mirror entire website (infinite depth)
|
||||
.TP
|
||||
\fB\-\-recursive\fR
|
||||
Enable recursive downloading
|
||||
.TP
|
||||
\fB\-\-max-depth\fR=\fIN\fR
|
||||
Maximum recursion depth
|
||||
.SS "Scheduling & Hooks"
|
||||
.TP
|
||||
\fB\-\-schedule\fR=\fITIME\fR
|
||||
Schedule download ("YYYY-MM-DD HH:MM" or cron "0 2 * * *")
|
||||
.TP
|
||||
\fB\-\-on-complete\fR=\fICMD\fR
|
||||
Run shell command after successful download
|
||||
.TP
|
||||
\fB\-\-bind-interface\fR=\fIIFACE\fR
|
||||
Bind to specific network interface
|
||||
.SS "Other"
|
||||
.TP
|
||||
\fB\-\-batch-file\fR=\fIFILE\fR
|
||||
Download multiple URLs from a file
|
||||
.TP
|
||||
\fB\-\-checksum-file\fR=\fIFILE\fR
|
||||
Read expected checksum from SHA256SUMS file
|
||||
.TP
|
||||
\fB\-\-generate-man-page\fR
|
||||
Generate this man page
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
Show help
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Show version
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
Download a file:
|
||||
goget --url https://example.com/file.zip
|
||||
.TP
|
||||
Parallel download:
|
||||
goget --url https://example.com/large.iso --parallel 4
|
||||
.TP
|
||||
Resume interrupted download:
|
||||
goget --url https://example.com/file.zip --resume
|
||||
.TP
|
||||
Mirror website:
|
||||
goget --url https://example.com --mirror --output ./mirror
|
||||
.TP
|
||||
Recursive download:
|
||||
goget --url https://example.com --recursive --max-depth 2
|
||||
.TP
|
||||
JSON progress (for scripting):
|
||||
goget --url https://example.com/file.zip --json --no-progress > progress.jsonl
|
||||
.TP
|
||||
Scheduled download at 2 AM:
|
||||
goget --url https://example.com/daily.zip --schedule "0 2 * * *"
|
||||
.TP
|
||||
Run import script after download:
|
||||
goget --url https://example.com/data.csv --on-complete "import.sh"
|
||||
.SH FILES
|
||||
.TP
|
||||
~/.config/goget/config.json
|
||||
Configuration file
|
||||
.TP
|
||||
<file>.goget.meta
|
||||
Resume metadata file
|
||||
.SH BUGS
|
||||
Report bugs at https://codeberg.org/petrbalvin/goget/issues
|
||||
.SH AUTHOR
|
||||
Petr Balvin
|
||||
.SH LICENSE
|
||||
MIT License`, core.Version)
|
||||
fmt.Print(manPage)
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
//go:build linux || freebsd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"codeberg.org/petrbalvin/goget/internal/config"
|
||||
)
|
||||
|
||||
// manPageRequiredSections lists the conventional manpage sections that
|
||||
// goget(1) must include. Every section in this list must be present
|
||||
// in the manpage source as a ".SH <NAME>" header. Adding a new section
|
||||
// here forces the manpage author to document it.
|
||||
var manPageRequiredSections = []string{
|
||||
"NAME",
|
||||
"SYNOPSIS",
|
||||
"DESCRIPTION",
|
||||
"OPTIONS",
|
||||
"EXAMPLES",
|
||||
"EXIT STATUS",
|
||||
"FILES",
|
||||
"ENVIRONMENT",
|
||||
"SEE ALSO",
|
||||
"HISTORY",
|
||||
"AUTHORS",
|
||||
"REPORTING BUGS",
|
||||
"COPYRIGHT",
|
||||
}
|
||||
|
||||
// TestManPageEmbedded is the simplest smoke test: the embed succeeded
|
||||
// and the variable is not empty. Any first line beginning with `.`
|
||||
// (either a `.\"` comment or a macro such as `.TH`) is accepted as
|
||||
// proof the embedded blob is troff source.
|
||||
func TestManPageEmbedded(t *testing.T) {
|
||||
if manPage == "" {
|
||||
t.Fatal("embedded manPage is empty — //go:embed failed at build time")
|
||||
}
|
||||
if !strings.HasPrefix(manPage, ".") {
|
||||
t.Errorf("embedded manPage does not look like troff (got prefix %q)", firstLine(manPage))
|
||||
}
|
||||
}
|
||||
|
||||
// TestManPageHasTHHeader verifies the .TH macro is present with the
|
||||
// expected program name, section, and version. The .TH line is the
|
||||
// entry point that `man` uses to identify the page.
|
||||
func TestManPageHasTHHeader(t *testing.T) {
|
||||
if !strings.Contains(manPage, ".TH GOGET 1 ") {
|
||||
t.Error("manpage is missing the .TH GOGET 1 header")
|
||||
}
|
||||
}
|
||||
|
||||
// TestManPageHasMandatorySections asserts that every section in
|
||||
// manPageRequiredSections exists as a .SH heading. This keeps the page
|
||||
// discoverable in `man goget` and ensures consistency with project
|
||||
// documentation conventions.
|
||||
//
|
||||
// In troff, multi-word section names must be quoted to keep the
|
||||
// spaces inside a single argument: `.SH "SEE ALSO"`. The matcher
|
||||
// accepts both the bare form (`.SH SEE ALSO`) and the quoted form
|
||||
// (`.SH "SEE ALSO"`), so authors can use either convention.
|
||||
func TestManPageHasMandatorySections(t *testing.T) {
|
||||
for _, sec := range manPageRequiredSections {
|
||||
bare := "\n.SH " + sec + "\n"
|
||||
quoted := "\n.SH \"" + sec + "\"\n"
|
||||
if !strings.Contains(manPage, bare) && !strings.Contains(manPage, quoted) {
|
||||
t.Errorf("manpage is missing required section: .SH %s (or .SH \"%s\")", sec, sec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestManPageDocumentsEveryFlag is a guard against drift between the
|
||||
// CLI surface (defineFlags) and the manpage. For every flag
|
||||
// registered on the FlagSet, the manpage must contain the
|
||||
// corresponding option entry. The expected on-page form escapes
|
||||
// every hyphen in the flag name as `\-` (per the convention used
|
||||
// throughout the manpage) and prefixes the entry with `\-\-`.
|
||||
//
|
||||
// Adding a new flag in defineFlags but forgetting the manpage (or
|
||||
// vice versa) makes this test fail with a clear missing-flag list.
|
||||
func TestManPageDocumentsEveryFlag(t *testing.T) {
|
||||
cfg := config.DefaultConfig()
|
||||
fs := newTestFlagSet("goget-test-man-page")
|
||||
defineFlags(fs, cfg)
|
||||
|
||||
var missing []string
|
||||
fs.VisitAll(func(f *flag.Flag) {
|
||||
escaped := strings.ReplaceAll(f.Name, "-", `\-`)
|
||||
needle := `\-\-` + escaped
|
||||
if !strings.Contains(manPage, needle) {
|
||||
missing = append(missing, f.Name)
|
||||
}
|
||||
})
|
||||
if len(missing) > 0 {
|
||||
sort.Strings(missing)
|
||||
t.Errorf("manpage does not document %d flag(s):\n --%s",
|
||||
len(missing), strings.Join(missing, "\n --"))
|
||||
}
|
||||
}
|
||||
|
||||
// TestManPageRendersWithGroff runs `groff -man -ww -Kutf-8 -z` on the
|
||||
// embedded manpage and fails if it reports any warnings or errors.
|
||||
// The `-z` flag suppresses output; `-ww` enables maximum warning
|
||||
// verbosity; `-Kutf-8` accepts UTF-8 source (em-dash, etc.).
|
||||
//
|
||||
// If `groff` is not installed on the test machine the test is
|
||||
// skipped — we still want it to pass on minimal CI images — but a
|
||||
// CI image with `groff` available will catch regressions in the
|
||||
// troff source.
|
||||
func TestManPageRendersWithGroff(t *testing.T) {
|
||||
if _, err := exec.LookPath("groff"); err != nil {
|
||||
t.Skip("groff not installed; skipping manpage render check")
|
||||
}
|
||||
cmd := exec.Command("groff", "-man", "-ww", "-Kutf-8", "-z")
|
||||
cmd.Stdin = strings.NewReader(manPage)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("groff rejected the manpage: %v\n%s", err, out)
|
||||
} else if len(out) > 0 {
|
||||
t.Fatalf("groff produced unexpected output:\n%s", out)
|
||||
}
|
||||
}
|
||||
|
||||
// firstLine returns the first line of s, trimmed of the trailing
|
||||
// newline. Used only for error messages.
|
||||
func firstLine(s string) string {
|
||||
if i := strings.IndexByte(s, '\n'); i >= 0 {
|
||||
return s[:i]
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -11,6 +11,10 @@ run:
|
||||
|
||||
# Build the binary
|
||||
build:
|
||||
# Keep the embedded manpage in sync with man/goget.1. //go:embed
|
||||
# cannot reference files outside the embedding package, so we copy
|
||||
# the source-of-truth manpage into the package tree before compiling.
|
||||
cp man/goget.1 cmd/goget/man-page-data/goget.1
|
||||
go vet ./...
|
||||
gofmt -l $(find cmd internal pkg -name '*.go') | grep . && exit 1 || true
|
||||
go build -ldflags "-s -w" -o bin/goget ./cmd/goget
|
||||
@@ -22,3 +26,22 @@ test:
|
||||
# Remove build artifacts
|
||||
uninstall:
|
||||
rm -rf bin/ coverage.out
|
||||
|
||||
# Validate the manpage with groff (zero warnings on success). Requires
|
||||
# `groff` to be installed — skipped silently otherwise.
|
||||
man:
|
||||
@command -v groff >/dev/null || { echo "groff not installed, skipping"; exit 0; }
|
||||
groff -man -ww -Kutf-8 -z man/goget.1
|
||||
|
||||
# Install the manpage to ~/.local/share/man/man1/ (XDG rootless).
|
||||
# After install, `man goget` resolves it automatically. Re-run safely to
|
||||
# pick up edits.
|
||||
install-man: man
|
||||
@mkdir -p "$HOME/.local/share/man/man1"
|
||||
gzip -c -f man/goget.1 > "$HOME/.local/share/man/man1/goget.1.gz"
|
||||
@echo "Installed: $HOME/.local/share/man/man1/goget.1.gz"
|
||||
|
||||
# Remove the manpage installed by `just install-man`.
|
||||
uninstall-man:
|
||||
rm -f "$HOME/.local/share/man/man1/goget.1.gz"
|
||||
@echo "Removed: $HOME/.local/share/man/man1/goget.1.gz"
|
||||
|
||||
+950
@@ -0,0 +1,950 @@
|
||||
.\" Manpage for goget.
|
||||
.\" Source of truth — kept in sync with cmd/goget/man-page-data/goget.1
|
||||
.\" by the `cp` step in `just build`. The duplicate is required because
|
||||
.\" //go:embed cannot reference files outside the embedding package.
|
||||
.\"
|
||||
.\" Conventions used in this file:
|
||||
.\" .TP tag-paragraph (one option per entry)
|
||||
.\" \fB...\fR bold (the flag itself)
|
||||
.\" \fI...\fR italic (the argument placeholder)
|
||||
.\" \- literal hyphen (escapes groff's dash-to-endash conversion)
|
||||
.\" \\- alternative escape for the same purpose
|
||||
.\"
|
||||
.\" Validate with: groff -man -ww man/goget.1 > /dev/null
|
||||
.\" Render with: groff -man -Tutf8 man/goget.1 | less
|
||||
.\"
|
||||
.TH GOGET 1 "2026-06-26" "goget 1.0.0" "User Commands"
|
||||
.SH NAME
|
||||
goget \- modern IPv6-first command-line download utility
|
||||
.SH SYNOPSIS
|
||||
.B goget
|
||||
[\fIOPTION\fR]... \fIURL\fR...
|
||||
.SH DESCRIPTION
|
||||
.B goget
|
||||
is a modern replacement for
|
||||
.BR curl (1)
|
||||
and
|
||||
.BR wget (1)
|
||||
built on the Go standard library.
|
||||
It provides IPv6-first connections (with automatic IPv4 fallback), parallel
|
||||
chunked downloads, resume support, checksum verification, recursive website
|
||||
mirroring, and support for nine network protocols
|
||||
.RB ( HTTP / HTTPS ", " FTP / FTPS ", " SFTP ", " WebDAV / WebDAVS ", "
|
||||
.BR file:// ", " data: ", " Gopher ", and " Gemini ") \(em all in a
|
||||
single static binary with zero runtime dependencies.
|
||||
.PP
|
||||
Safety features include TLS 1.2 minimum, certificate verification, SSRF
|
||||
protection (private/internal addresses are blocked by default), SSH host-key
|
||||
verification for SFTP, HSTS cache (RFC 6797), and certificate or host-key
|
||||
pinning.
|
||||
.PP
|
||||
URLs are specified positionally after the flags; the
|
||||
.B \-\-url
|
||||
flag is an alias for the first positional URL and may be repeated to download
|
||||
several files in one invocation.
|
||||
.PP
|
||||
Configuration is loaded from
|
||||
.IR ~/.config/goget/config.toml
|
||||
(overridable with
|
||||
.BR \-\-config " or the " GOGET_CONFIG
|
||||
environment variable) and merged on top of compiled-in defaults. Command-line
|
||||
flags always take precedence over configuration values.
|
||||
.SH OPTIONS
|
||||
.SS "Target"
|
||||
.TP
|
||||
\fB\-\-url\fR=\fIURL\fR
|
||||
URL to download. May be repeated for multiple URLs, or supplied as positional
|
||||
arguments after the flags.
|
||||
.SS "Output"
|
||||
.TP
|
||||
\fB\-\-output\fR=\fIFILE\fR
|
||||
Output filename or directory. When omitted, the filename is derived from the
|
||||
URL.
|
||||
.TP
|
||||
\fB\-\-restart\fR
|
||||
Delete any existing output file and restart the download from byte zero.
|
||||
.TP
|
||||
\fB\-\-overwrite\fR
|
||||
Overwrite an existing output file without using atomic rename.
|
||||
.TP
|
||||
\fB\-\-content\-disposition\fR
|
||||
Use the filename from the server's
|
||||
.B Content\-Disposition
|
||||
header instead of the one derived from the URL.
|
||||
.TP
|
||||
\fB\-\-create\-dirs\fR
|
||||
Create missing parent directories of
|
||||
.BR \-\-output
|
||||
(enabled by default; disable with
|
||||
.B \-\-create\-dirs=false
|
||||
for
|
||||
.BR curl (1) " /" wget (1)
|
||||
compatibility). Ignored for stdout output.
|
||||
.TP
|
||||
\fB\-\-keep\-timestamps\fR
|
||||
Set the output file's modification time to the server's
|
||||
.B Last\-Modified
|
||||
value.
|
||||
.TP
|
||||
\fB\-\-no\-clobber\fR
|
||||
Skip the download if the output file already exists.
|
||||
.TP
|
||||
\fB\-\-continue\fR
|
||||
Auto-resume the download if a partial output file is present.
|
||||
.TP
|
||||
\fB\-\-timestamping\fR
|
||||
Download only when the remote file is newer than the local copy.
|
||||
.SS "Progress and output"
|
||||
.TP
|
||||
\fB\-\-verbose\fR
|
||||
Verbose output (default: enabled when set in the config file).
|
||||
.TP
|
||||
\fB\-\-no\-progress\fR
|
||||
Hide the progress bar; keep every other piece of output.
|
||||
.TP
|
||||
\fB\-\-progress\fR=\fISTYLE\fR
|
||||
Progress bar style. One of
|
||||
.B bar
|
||||
(default) or
|
||||
.BR dot .
|
||||
.TP
|
||||
\fB\-\-quiet\fR
|
||||
Suppress all output except errors.
|
||||
.TP
|
||||
\fB\-\-json\fR
|
||||
Emit progress and completion events as newline-delimited JSON on stdout.
|
||||
Each event is a single JSON object with
|
||||
.BR type " (" progress " or " complete "), " downloaded ", " total ", " speed ,
|
||||
and (for the
|
||||
.B progress
|
||||
event) an
|
||||
.B eta_ms
|
||||
field when the total size and speed are known.
|
||||
.TP
|
||||
\fB\-\-debug\fR
|
||||
Enable debug output with detailed connection and protocol information.
|
||||
.TP
|
||||
\fB\-\-show\-headers\fR
|
||||
Print HTTP response headers during the download.
|
||||
.TP
|
||||
\fB\-\-write\-out\fR=\fIFORMAT\fR
|
||||
Print metadata after the transfer, using a
|
||||
.BR curl (1)\-compatible
|
||||
format string. Supported directives:
|
||||
.BR %\{http_code\} ", " %\{size_download\} ", " %\{time_total\} ", "
|
||||
.BR %\{speed_download\} .
|
||||
.TP
|
||||
\fB\-\-trace\-time\fR
|
||||
Print an HTTP timing breakdown after the download:
|
||||
.BR DNS ", " TCP ", " TLS ", " TTFB ", and " Total .
|
||||
.SS "Network"
|
||||
.TP
|
||||
\fB\-\-timeout\fR=\fIDURATION\fR
|
||||
Overall connection timeout.
|
||||
.B 0
|
||||
selects a smart auto-calculation based on the file size.
|
||||
.TP
|
||||
\fB\-\-connect\-timeout\fR=\fIDURATION\fR
|
||||
Timeout for the TCP (or SSH) connection establishment phase.
|
||||
.TP
|
||||
\fB\-\-max\-time\fR=\fIDURATION\fR
|
||||
Maximum total transfer time; abort if exceeded.
|
||||
.B 0
|
||||
disables the limit.
|
||||
.TP
|
||||
\fB\-\-max\-retries\fR=\fIN\fR
|
||||
Maximum number of retry attempts on failure.
|
||||
.B 0
|
||||
selects the built-in default.
|
||||
.TP
|
||||
\fB\-\-retry\-delay\fR=\fIDURATION\fR
|
||||
Delay inserted between retry attempts.
|
||||
.TP
|
||||
\fB\-\-retry\-all\-errors\fR
|
||||
Retry on any HTTP 4xx or 5xx response (in addition to network errors).
|
||||
.TP
|
||||
\fB\-\-retry\-on\-http\-error\fR=\fICODES\fR
|
||||
Retry on the given HTTP status codes (comma-separated; e.g.
|
||||
.BR 503,429 ).
|
||||
.TP
|
||||
\fB\-\-max\-filesize\fR=\fISIZE\fR
|
||||
Abort the transfer if the remote file exceeds this size (e.g.
|
||||
.BR 100MB ", " 1GB ).
|
||||
.TP
|
||||
\fB\-\-proxy\fR=\fIURL\fR
|
||||
Proxy URL.
|
||||
.B http://
|
||||
and
|
||||
.B https://
|
||||
trigger HTTP CONNECT;
|
||||
.B socks5://
|
||||
uses local DNS,
|
||||
.B socks5h://
|
||||
uses remote DNS.
|
||||
Optional
|
||||
.B user:pass@
|
||||
credentials are supported.
|
||||
.TP
|
||||
\fB\-\-no\-ipv4\fR
|
||||
Disable IPv4 fallback; connect over IPv6 only.
|
||||
.TP
|
||||
\fB\-\-no\-redirect\fR
|
||||
Do not follow HTTP 3xx redirects.
|
||||
.TP
|
||||
\fB\-\-dns\-servers\fR=\fIIPS\fR
|
||||
Custom DNS servers, comma-separated (e.g.
|
||||
.BR 1.1.1.1,8.8.8.8 ).
|
||||
.TP
|
||||
\fB\-\-bind\-interface\fR=\fIIFACE\fR
|
||||
Bind outgoing connections to a specific network interface (Linux only).
|
||||
.TP
|
||||
\fB\-\-allow\-private\fR
|
||||
Allow connections to private or internal IP addresses. By default these
|
||||
are blocked as an SSRF safeguard.
|
||||
.TP
|
||||
\fB\-\-pinned\-cert\fR=\fISHA256\fR
|
||||
Pin the server certificate by its leaf SHA-256 fingerprint. Applies to all
|
||||
TLS-bearing protocols (HTTPS, FTPS, Gemini, WebDAVS); abort on mismatch.
|
||||
.TP
|
||||
\fB\-\-pinned\-host\-key\fR=\fIFINGERPRINT\fR
|
||||
Pin the SSH host key (SFTP). Accepts
|
||||
.BR SHA256:<base64>
|
||||
(as emitted by
|
||||
.BR "ssh\-keygen \-lf" )
|
||||
or a raw lowercase-hex SHA-256 of the key wire format. Pinning takes
|
||||
precedence over
|
||||
.B \-\-ssh\-insecure
|
||||
and any
|
||||
.I known_hosts
|
||||
entry.
|
||||
.TP
|
||||
\fB\-\-rate\-limit\fR=\fIRATE\fR
|
||||
Maximum download speed (e.g.
|
||||
.BR 1MB/s ", " 500KB/s ).
|
||||
.B 0
|
||||
disables the limit.
|
||||
.TP
|
||||
\fB\-\-max\-speed\fR=\fIRATE\fR
|
||||
Alias for
|
||||
.B \-\-rate\-limit
|
||||
in the legacy "bytes per second" form.
|
||||
.TP
|
||||
\fB\-\-range\fR=\fIN\fB\-\fIN\fR
|
||||
Download only a byte range (e.g.
|
||||
.BR 0\-999 ).
|
||||
.SS "HTTP and request shaping"
|
||||
.TP
|
||||
\fB\-\-header\fR=\fI"Key: Value"\fR
|
||||
Custom HTTP header. May be repeated.
|
||||
.TP
|
||||
\fB\-\-insecure\fR
|
||||
Skip TLS certificate verification. Use only for testing.
|
||||
.TP
|
||||
\fB\-\-cert\fR=\fIFILE\fR
|
||||
Client certificate in PEM format (for mTLS).
|
||||
.TP
|
||||
\fB\-\-key\fR=\fIFILE\fR
|
||||
Client private key in PEM format (for mTLS).
|
||||
.TP
|
||||
\fB\-\-ca\-certificate\fR=\fIFILE\fR
|
||||
Path to a custom CA certificate bundle.
|
||||
.TP
|
||||
\fB\-\-ssl\-key\-log\fR=\fIFILE\fR
|
||||
Log TLS session keys to
|
||||
.I FILE
|
||||
in the NSS Key Log format used by Wireshark
|
||||
.RB ( SSLKEYLOGFILE ).
|
||||
.TP
|
||||
\fB\-\-data\fR=\fI"key=value"\fR
|
||||
Send
|
||||
.I key=value
|
||||
as the request body. Implies HTTP POST.
|
||||
.TP
|
||||
\fB\-\-form\fR=\fI"field=value"\fR
|
||||
Multipart form field; repeatable. A value of
|
||||
.B field=@/path
|
||||
attaches a file upload.
|
||||
.TP
|
||||
\fB\-\-post\-file\fR=\fIFILE\fR
|
||||
POST the contents of
|
||||
.I FILE
|
||||
as the request body.
|
||||
.TP
|
||||
\fB\-\-referer\fR=\fIURL\fR
|
||||
Set the
|
||||
.B Referer
|
||||
request header.
|
||||
.TP
|
||||
\fB\-\-compressed\fR
|
||||
Send an
|
||||
.B Accept\-Encoding
|
||||
header so the server returns a compressed response. By default
|
||||
.B goget
|
||||
already handles compressed responses transparently; this flag is provided
|
||||
for
|
||||
.BR curl (1)
|
||||
compatibility.
|
||||
.TP
|
||||
\fB\-\-spider\fR
|
||||
Check whether the URL exists via a HEAD request; do not download the body.
|
||||
.TP
|
||||
\fB\-\-fail\fR
|
||||
Exit with a non-zero status on HTTP 4xx or 5xx responses.
|
||||
.TP
|
||||
\fB\-\-no\-decompress\fR
|
||||
Disable automatic decompression of compressed response bodies.
|
||||
.SS "Recursive downloading and mirroring"
|
||||
.TP
|
||||
\fB\-\-recursive\fR
|
||||
Follow links discovered in HTML pages.
|
||||
.TP
|
||||
\fB\-\-mirror\fR
|
||||
Mirror an entire website. Shorthand for
|
||||
.BR "\-\-recursive \-\-convert\-links \-\-page\-requisites" .
|
||||
.TP
|
||||
\fB\-\-max\-depth\fR=\fIN\fR
|
||||
Maximum recursion depth.
|
||||
.TP
|
||||
\fB\-\-recursive\-parallel\fR=\fIN\fR
|
||||
Number of concurrent file downloads in recursive mode across all protocols
|
||||
(HTTP, WebDAV, FTP, SFTP).
|
||||
.B 0
|
||||
runs sequentially (default).
|
||||
.TP
|
||||
\fB\-\-follow\-external\fR
|
||||
Follow links to domains other than the starting domain.
|
||||
.TP
|
||||
\fB\-\-span\-hosts\fR
|
||||
Alias for
|
||||
.B \-\-follow\-external
|
||||
in the
|
||||
.BR wget (1)
|
||||
style.
|
||||
.TP
|
||||
\fB\-\-domains\fR=\fILIST\fR
|
||||
Restrict recursive crawling to the listed comma-separated domains.
|
||||
.TP
|
||||
\fB\-\-accept\fR=\fIPATTERN\fR
|
||||
Accept patterns (filename glob or MIME type), comma-separated. Only
|
||||
matching resources are downloaded.
|
||||
.TP
|
||||
\fB\-\-reject\fR=\fIPATTERN\fR
|
||||
Reject patterns (glob), comma-separated. Matching resources are skipped.
|
||||
.TP
|
||||
\fB\-\-exclude\-pattern\fR=\fIPATTERN\fR
|
||||
Alias for
|
||||
.B \-\-reject
|
||||
used by the recursive crawler.
|
||||
.TP
|
||||
\fB\-\-no\-parent\fR
|
||||
Do not ascend to parent directories during recursive download.
|
||||
.TP
|
||||
\fB\-\-page\-requisites\fR
|
||||
Download CSS, JavaScript, and images required to render the HTML pages.
|
||||
.TP
|
||||
\fB\-\-convert\-links\fR
|
||||
Rewrite links in downloaded HTML for local offline viewing.
|
||||
.TP
|
||||
\fB\-\-no\-convert\-links\fR
|
||||
Skip HTML link rewriting (faster; output is not offline-ready).
|
||||
.TP
|
||||
\fB\-\-backup\-converted\fR
|
||||
Keep a
|
||||
.B .orig
|
||||
backup of each file before link conversion.
|
||||
.TP
|
||||
\fB\-\-no\-mirror\-assets\fR
|
||||
Do not download CSS, JavaScript, and images during a mirror.
|
||||
.TP
|
||||
\fB\-\-no\-robots\fR
|
||||
Do not honour
|
||||
.I robots.txt
|
||||
during mirroring.
|
||||
.TP
|
||||
\fB\-\-wait\fR=\fIDURATION\fR
|
||||
Delay between requests in recursive or mirror mode (e.g.
|
||||
.BR 1s ", " 500ms ).
|
||||
.TP
|
||||
\fB\-\-random\-wait\fR
|
||||
Randomize the wait time between 0.5x and 1.5x of
|
||||
.BR \-\-wait .
|
||||
.TP
|
||||
\fB\-\-adjust\-extension\fR
|
||||
Append a
|
||||
.B .html
|
||||
extension to text/html files that lack one.
|
||||
.TP
|
||||
\fB\-\-cut\-dirs\fR=\fIN\fR
|
||||
Ignore the first
|
||||
.I N
|
||||
path components when constructing local filenames.
|
||||
.TP
|
||||
\fB\-\-protocol\-directories\fR
|
||||
Create protocol-prefixed subdirectories
|
||||
.RB ( .http/ ", " .ftp/ )
|
||||
in recursive mode.
|
||||
.TP
|
||||
\fB\-\-dry\-run\fR
|
||||
List the URLs that would be downloaded in recursive or mirror mode without
|
||||
writing any files to disk.
|
||||
.TP
|
||||
\fB\-\-warc\-file\fR=\fIFILE\fR
|
||||
Write a WARC (Web ARChive) record of the transfer to
|
||||
.IR FILE .
|
||||
.SS "Download management"
|
||||
.TP
|
||||
\fB\-\-batch\-file\fR=\fIFILE\fR
|
||||
Read URLs from
|
||||
.IR FILE ,
|
||||
one per line. Lines beginning with
|
||||
.B #
|
||||
are treated as comments and skipped.
|
||||
.TP
|
||||
\fB\-\-input\-file\fR=\fIFILE\fR
|
||||
Alias for
|
||||
.BR \-\-batch\-file .
|
||||
A value of
|
||||
.B \-
|
||||
reads from standard input.
|
||||
.TP
|
||||
\fB\-\-glob\fR
|
||||
Expand
|
||||
.B [1-3]
|
||||
and
|
||||
.B {a,b,c}
|
||||
patterns in the URL before issuing requests.
|
||||
.TP
|
||||
\fB\-\-queue\fR
|
||||
Add the URL to the persistent download queue instead of downloading it
|
||||
immediately.
|
||||
.TP
|
||||
\fB\-\-queue\-list\fR
|
||||
List all items in the download queue and exit.
|
||||
.TP
|
||||
\fB\-\-queue\-process\fR
|
||||
Process (download) every pending item in the queue and exit.
|
||||
.TP
|
||||
\fB\-\-queue\-clear\fR
|
||||
Remove completed items from the queue.
|
||||
.TP
|
||||
\fB\-\-queue\-file\fR=\fIPATH\fR
|
||||
Use a custom queue file (default
|
||||
.IR ~/.config/goget/queue.json ).
|
||||
.TP
|
||||
\fB\-\-queue\-priority\fR=\fIN\fR
|
||||
Priority for the queued item (1\(en10; higher values are processed first).
|
||||
Default: 5.
|
||||
.TP
|
||||
\fB\-\-schedule\fR=\fITIME\fR
|
||||
Schedule the download. Accepts an absolute timestamp
|
||||
.RB ( " YYYY\-MM\-DD HH:MM ")
|
||||
or a cron expression in the standard
|
||||
.B MIN HOUR DOM MON DOW
|
||||
format (e.g.
|
||||
.BR "0 2 * * *" ).
|
||||
.TP
|
||||
\fB\-\-on\-complete\fR=\fICMD\fR
|
||||
Run
|
||||
.I CMD
|
||||
after a successful download. The following environment variables are
|
||||
exported into the hook:
|
||||
.RS
|
||||
.TP
|
||||
.B GOGET_OUTPUT
|
||||
Absolute path of the downloaded file.
|
||||
.TP
|
||||
.B GOGET_SIZE
|
||||
Downloaded size in bytes.
|
||||
.TP
|
||||
.B GOGET_URL
|
||||
The (credential-stripped) source URL.
|
||||
.RE
|
||||
.IP
|
||||
The command is split into tokens with shell-like quoting rules but is
|
||||
executed directly via
|
||||
.BR exec (3)
|
||||
\(em no shell is invoked, so metacharacters in arguments are not
|
||||
re-interpreted.
|
||||
.SS "Authentication"
|
||||
.TP
|
||||
\fB\-\-username\fR=\fIUSER\fR
|
||||
Username for HTTP Basic or Digest authentication. When omitted, credentials
|
||||
are auto-loaded from
|
||||
.I ~/.netrc
|
||||
if a matching machine entry is present.
|
||||
.TP
|
||||
\fB\-\-password\fR=\fIPASS\fR
|
||||
Password for HTTP Basic or Digest authentication. Prefer
|
||||
.B \-\-password\-file
|
||||
to avoid exposing the secret on the command line.
|
||||
.TP
|
||||
\fB\-\-password\-file\fR=\fIFILE\fR
|
||||
Read the password from
|
||||
.I FILE
|
||||
(the first line, with the trailing newline stripped).
|
||||
.TP
|
||||
\fB\-\-auth\-type\fR=\fITYPE\fR
|
||||
Authentication scheme:
|
||||
.BR basic ", " digest ", or " auto
|
||||
(default).
|
||||
.TP
|
||||
\fB\-\-cookie\-jar\fR=\fIFILE\fR
|
||||
Load cookies from and save cookies to
|
||||
.I FILE
|
||||
in Netscape format.
|
||||
.TP
|
||||
\fB\-\-cookie\fR=\fI"name=value"\fR
|
||||
Set a cookie on the request. May be repeated.
|
||||
.TP
|
||||
\fB\-\-no\-private\fR
|
||||
Disable
|
||||
.I .netrc
|
||||
and other credential-file auto-loading for this invocation.
|
||||
.TP
|
||||
\fB\-\-oauth\-client\-id\fR=\fIID\fR
|
||||
OAuth 2.0 client ID.
|
||||
.TP
|
||||
\fB\-\-oauth\-client\-secret\fR=\fISECRET\fR
|
||||
OAuth 2.0 client secret.
|
||||
.TP
|
||||
\fB\-\-oauth\-token\-url\fR=\fIURL\fR
|
||||
OAuth 2.0 token endpoint.
|
||||
.TP
|
||||
\fB\-\-oauth\-auth\-url\fR=\fIURL\fR
|
||||
OAuth 2.0 authorization endpoint (used by the
|
||||
.B authorization_code
|
||||
grant).
|
||||
.TP
|
||||
\fB\-\-oauth\-redirect\-uri\fR=\fIURI\fR
|
||||
OAuth 2.0 redirect URI.
|
||||
.TP
|
||||
\fB\-\-oauth\-scopes\fR=\fISCOPES\fR
|
||||
OAuth 2.0 scopes, comma-separated.
|
||||
.TP
|
||||
\fB\-\-oauth\-grant\-type\fR=\fITYPE\fR
|
||||
OAuth 2.0 grant type:
|
||||
.BR client_credentials ", " authorization_code ", " password ", or "
|
||||
.BR refresh_token .
|
||||
.TP
|
||||
\fB\-\-oauth\-access\-token\fR=\fITOKEN\fR
|
||||
OAuth 2.0 access token supplied directly.
|
||||
.TP
|
||||
\fB\-\-oauth\-refresh\-token\fR=\fITOKEN\fR
|
||||
OAuth 2.0 refresh token used to obtain a new access token.
|
||||
.SS "Upload"
|
||||
.TP
|
||||
\fB\-\-upload\fR
|
||||
Upload the file in
|
||||
.B \-\-upload\-file
|
||||
instead of downloading.
|
||||
.TP
|
||||
\fB\-\-upload\-method\fR=\fIMETHOD\fR
|
||||
HTTP method for the upload:
|
||||
.B PUT
|
||||
(default) or
|
||||
.BR POST .
|
||||
.TP
|
||||
\fB\-\-upload\-file\fR=\fIFILE\fR
|
||||
Path to the file to upload.
|
||||
.TP
|
||||
\fB\-\-form\-data\fR=\fI"k=v"\fR
|
||||
Additional multipart form data, comma-separated.
|
||||
.TP
|
||||
\fB\-\-file\-field\fR=\fINAME\fR
|
||||
Form field name used for the file part. Default:
|
||||
.BR file .
|
||||
.SS "Verification"
|
||||
.TP
|
||||
\fB\-\-checksum\fR=\fIHASH\fR
|
||||
Expected checksum, as a hex string.
|
||||
.TP
|
||||
\fB\-\-checksum\-algo\fR=\fIALG\fR
|
||||
Checksum algorithm:
|
||||
.BR sha256 ", " sha512 ", " blake2b ", " sha3\-256 ", " sha3\-512 ", or " md5 .
|
||||
Default:
|
||||
.BR sha256 .
|
||||
.TP
|
||||
\fB\-\-checksum\-file\fR=\fIFILE\fR
|
||||
Read expected checksums from
|
||||
.I FILE
|
||||
in the standard
|
||||
.B SHA256SUMS
|
||||
format.
|
||||
.SS "PGP / OpenPGP"
|
||||
.TP
|
||||
\fB\-\-pgp\-verify\fR
|
||||
Verify a PGP detached or inline signature after download.
|
||||
.TP
|
||||
\fB\-\-pgp\-decrypt\fR
|
||||
Decrypt a PGP-encrypted file after download.
|
||||
.TP
|
||||
\fB\-\-pgp\-sig\fR=\fIFILE\fR
|
||||
Path to a detached signature file (e.g.
|
||||
.BR .asc ", " .sig ).
|
||||
.TP
|
||||
\fB\-\-pgp\-key\fR=\fIFILE\fR
|
||||
Path to a PGP key (public or private, depending on the operation).
|
||||
.TP
|
||||
\fB\-\-pgp\-passphrase\fR=\fIPASS\fR
|
||||
Passphrase for the private key.
|
||||
.TP
|
||||
\fB\-\-pgp\-passphrase\-file\fR=\fIFILE\fR
|
||||
Read the private-key passphrase from
|
||||
.IR FILE .
|
||||
.SS "Metalink"
|
||||
.TP
|
||||
\fB\-\-metalink\fR
|
||||
Treat the URL as a Metalink file (multi-source download).
|
||||
.TP
|
||||
\fB\-\-metalink\-file\fR=\fIPATH\fR
|
||||
Read a Metalink description from
|
||||
.IR PATH .
|
||||
Accepts
|
||||
.B .meta4
|
||||
and
|
||||
.B .metalink
|
||||
formats.
|
||||
.SS "TLS and SSH"
|
||||
.TP
|
||||
\fB\-\-known\-hosts\fR=\fIFILE\fR
|
||||
Use a custom
|
||||
.I known_hosts
|
||||
file for SFTP (default
|
||||
.IR ~/.ssh/known_hosts ).
|
||||
.TP
|
||||
\fB\-\-ssh\-insecure\fR
|
||||
Skip SSH host key verification for SFTP (accept any key). Mutually
|
||||
incompatible with
|
||||
.BR \-\-pinned\-host\-key .
|
||||
.TP
|
||||
\fB\-\-hsts\-file\fR=\fIFILE\fR
|
||||
Use a custom HSTS cache file (default
|
||||
.IR ~/.config/goget/hsts ).
|
||||
.SS "Archive extraction"
|
||||
.TP
|
||||
\fB\-\-extract\fR
|
||||
Automatically extract recognized archives (TAR, TAR.GZ, TAR.BZ2, ZIP)
|
||||
after a successful download.
|
||||
.TP
|
||||
\fB\-\-extract\-dir\fR=\fIDIR\fR
|
||||
Directory to extract into. Default: alongside the downloaded archive.
|
||||
.TP
|
||||
\fB\-\-strip\-components\fR=\fIN\fR
|
||||
Strip the first
|
||||
.I N
|
||||
path components during archive extraction.
|
||||
.SS "Configuration"
|
||||
.TP
|
||||
\fB\-\-config\fR=\fIFILE\fR
|
||||
Path to the TOML configuration file.
|
||||
.TP
|
||||
\fB\-\-init\-config\fR
|
||||
Write a default configuration file to
|
||||
.I ~/.config/goget/config.toml
|
||||
and exit.
|
||||
.TP
|
||||
\fB\-\-config\-get\fR=\fIKEY\fR
|
||||
Print the value of a single configuration key (e.g.
|
||||
.BR \-\-config\-get timeout )
|
||||
and exit.
|
||||
.TP
|
||||
\fB\-\-config\-set\fR=\fIKEY\fR \fIVALUE\fR
|
||||
Persist
|
||||
.I VALUE
|
||||
under
|
||||
.I KEY
|
||||
in the configuration file and exit.
|
||||
.TP
|
||||
\fB\-\-config\-list\fR
|
||||
Print every configuration key and value and exit.
|
||||
.TP
|
||||
\fB\-\-config\-unset\fR=\fIKEY\fR
|
||||
Remove
|
||||
.I KEY
|
||||
from the configuration file and exit.
|
||||
.SS "Information and shell integration"
|
||||
.TP
|
||||
\fB\-\-info\fR=\fIURL\fR
|
||||
Show file metadata (size, content type, server, last-modified) without
|
||||
downloading the body.
|
||||
.TP
|
||||
\fB\-\-benchmark\fR=\fIURL\fR
|
||||
Benchmark the download speed by transferring the first 10 MB and reporting
|
||||
the average throughput.
|
||||
.TP
|
||||
\fB\-\-show\-metadata\fR=\fIPATH\fR
|
||||
Display the contents of a
|
||||
.B .goget.meta
|
||||
sidecar for debugging interrupted or resumed downloads. Accepts either a
|
||||
path to the downloaded file (the sidecar is located next to it) or a direct
|
||||
path to the sidecar. Renders a human-readable summary by default; combines
|
||||
with
|
||||
.B \-\-json
|
||||
for raw output. Credentials embedded in the stored URL are masked.
|
||||
.TP
|
||||
\fB\-\-generate\-man\-page\fR
|
||||
Print this manual page in troff format to standard output and exit.
|
||||
.TP
|
||||
\fB\-\-completion\fR=\fISHELL\fR
|
||||
Print a shell completion script for
|
||||
.IR SHELL \(lqbbash\(rqq, \(rqqzsh\(rqq, or \(rqqfish\(rqq\(en to standard output and exit.
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
Print the short help summary and exit.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Print the program name and version and exit.
|
||||
.SH EXAMPLES
|
||||
.SS "Simple download"
|
||||
.PP
|
||||
Download a single file to the current directory:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/file.zip
|
||||
.fi
|
||||
.RE
|
||||
.SS "Parallel chunks and resume"
|
||||
.PP
|
||||
Files larger than 100 MB are automatically split into parallel chunks. To
|
||||
force four connections explicitly and resume an interrupted transfer:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/large.iso \-\-parallel 4
|
||||
goget \-\-url https://example.com/file.zip \-\-resume
|
||||
.fi
|
||||
.RE
|
||||
.SS "Verification"
|
||||
.PP
|
||||
Verify a download against a known checksum and PGP signature:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/release.tar.gz \\
|
||||
\-\-checksum\-algo sha256 \-\-checksum 5b9d...e2 \\
|
||||
\-\-pgp\-verify \-\-pgp\-sig release.tar.gz.asc \\
|
||||
\-\-pgp\-key maintainer.asc
|
||||
.fi
|
||||
.RE
|
||||
.SS "Recursive mirror"
|
||||
.PP
|
||||
Mirror a documentation site, convert links for offline use, and respect
|
||||
.IR robots.txt :
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/docs/ \\
|
||||
\-\-mirror \-\-convert\-links \-\-output ./mirror
|
||||
.fi
|
||||
.RE
|
||||
.SS "Scripting with JSON progress"
|
||||
.PP
|
||||
Stream machine-readable progress to a file for a downstream tool:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/data.csv \\
|
||||
\-\-json \-\-no\-progress > progress.jsonl
|
||||
.fi
|
||||
.RE
|
||||
.SS "Scheduled download with a post-hook"
|
||||
.PP
|
||||
Fetch a daily report at 02:00 and feed it into a processor:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-url https://example.com/daily.zip \\
|
||||
\-\-schedule "0 2 * * *" \\
|
||||
\-\-on\-complete "import.sh"
|
||||
.fi
|
||||
.RE
|
||||
.SS "Batch file"
|
||||
.PP
|
||||
Read URLs from a file (one per line; lines starting with
|
||||
.B #
|
||||
are comments):
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
goget \-\-batch\-file urls.txt
|
||||
.fi
|
||||
.RE
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
.B 0
|
||||
Success.
|
||||
.TP
|
||||
.B 1
|
||||
Generic failure (network error, protocol error, invalid input).
|
||||
.TP
|
||||
.B 2
|
||||
Invalid command-line arguments or configuration.
|
||||
.TP
|
||||
.B 3
|
||||
File I/O error (cannot write output, cannot read source).
|
||||
.TP
|
||||
.B 4
|
||||
Authentication failure.
|
||||
.TP
|
||||
.B 5
|
||||
TLS or certificate error (including pinning mismatch).
|
||||
.TP
|
||||
.B 6
|
||||
Checksum or PGP verification failed.
|
||||
.TP
|
||||
.B 7
|
||||
Operation cancelled (SIGINT, SIGTERM, context cancellation).
|
||||
.TP
|
||||
.B 8
|
||||
Resource limit exceeded
|
||||
.RB ( \-\-max\-filesize ", " \-\-max\-time ", etc.).
|
||||
.PP
|
||||
Only the generic
|
||||
.B 0
|
||||
and
|
||||
.B 1
|
||||
codes are guaranteed; the project reserves the other values and their
|
||||
meaning is part of the stable interface.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I ~/.config/goget/config.toml
|
||||
Default configuration file. Overridden by
|
||||
.B \-\-config
|
||||
or the
|
||||
.B GOGET_CONFIG
|
||||
environment variable.
|
||||
.TP
|
||||
.I ~/.config/goget/queue.json
|
||||
Persistent download queue. Path can be overridden with
|
||||
.BR \-\-queue\-file .
|
||||
.TP
|
||||
.I ~/.config/goget/hsts
|
||||
HSTS cache (RFC 6797). Path can be overridden with
|
||||
.BR \-\-hsts\-file .
|
||||
.TP
|
||||
.I ~/.ssh/known_hosts
|
||||
Default SFTP host-key database. Path can be overridden with
|
||||
.BR \-\-known\-hosts .
|
||||
.TP
|
||||
.I <output>.goget.meta
|
||||
Resume metadata sidecar written next to a partial output file. Deleted on
|
||||
successful completion; consulted by
|
||||
.B \-\-resume
|
||||
or
|
||||
.BR \-\-continue .
|
||||
.TP
|
||||
.I ~/.netrc
|
||||
Auto-loaded credentials. Disabled for the current invocation by
|
||||
.BR \-\-no\-private .
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B GOGET_CONFIG
|
||||
Path to the configuration file. Takes precedence over
|
||||
.IR ~/.config/goget/config.toml
|
||||
and
|
||||
.BR \-\-config .
|
||||
.TP
|
||||
.B NO_COLOR
|
||||
When set to a non-empty value, colour output is disabled regardless of the
|
||||
.BR color " setting in the config file (see " https://no\-color.org )."
|
||||
.TP
|
||||
.B SSLKEYLOGFILE
|
||||
Equivalent to passing
|
||||
.B \-\-ssl\-key\-log
|
||||
with the same value. Used by Wireshark to decrypt TLS traffic.
|
||||
.TP
|
||||
.B GOGET_OUTPUT
|
||||
Exported into the environment of
|
||||
.B \-\-on\-complete
|
||||
hooks; contains the absolute path of the downloaded file.
|
||||
.TP
|
||||
.B GOGET_SIZE
|
||||
Exported into
|
||||
.B \-\-on\-complete
|
||||
hooks; contains the downloaded size in bytes.
|
||||
.TP
|
||||
.B GOGET_URL
|
||||
Exported into
|
||||
.B \-\-on\-complete
|
||||
hooks; contains the source URL with credentials stripped
|
||||
.RB ( core.SafeURL ).
|
||||
.TP
|
||||
.B HOME
|
||||
Used to locate
|
||||
.I ~/.config/goget/
|
||||
and
|
||||
.IR ~/.ssh/known_hosts .
|
||||
.TP
|
||||
.B HTTP_PROXY
|
||||
.IR "https_proxy" ", " ALL_PROXY ", " NO_PROXY
|
||||
Standard proxy environment variables; respected unless
|
||||
.B \-\-proxy
|
||||
is given explicitly.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl (1),
|
||||
.BR wget (1),
|
||||
.BR sftp (1),
|
||||
.BR ssh\-keygen (1),
|
||||
.BR groff (1),
|
||||
.BR man (1)
|
||||
.PP
|
||||
Project home page and issue tracker:
|
||||
.RI < https://codeberg.org/petrbalvin/goget >
|
||||
.PP
|
||||
Full documentation set:
|
||||
.RS
|
||||
.TP
|
||||
.I docs/configuration.md
|
||||
Configuration schema.
|
||||
.TP
|
||||
.I docs/cli-reference.md
|
||||
Full flag reference.
|
||||
.TP
|
||||
.I docs/protocols.md
|
||||
Protocol handler details.
|
||||
.TP
|
||||
.I docs/recursive-mirror.md
|
||||
Recursive and mirror behaviour.
|
||||
.TP
|
||||
.I docs/security.md
|
||||
Threat model and security controls.
|
||||
.TP
|
||||
.I docs/api.md
|
||||
Public Go library API.
|
||||
.RE
|
||||
.SH HISTORY
|
||||
goget 1.0.0 (2026-06-26) is the first public release.
|
||||
The project was created as a modern, IPv6-first, Go-stdlib-only replacement
|
||||
for
|
||||
.BR curl (1)
|
||||
and
|
||||
.BR wget (1).
|
||||
.SH AUTHORS
|
||||
Petr Balvín
|
||||
.RI < opensource@petrbalvin.org >
|
||||
\(em upstream maintainer.
|
||||
.PP
|
||||
See
|
||||
.RI < https://codeberg.org/petrbalvin/goget >
|
||||
for the full contributor list.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to the issue tracker at
|
||||
.RI < https://codeberg.org/petrbalvin/goget/issues >.
|
||||
.PP
|
||||
For security issues, do not open a public issue; email
|
||||
.RI < opensource@petrbalvin.org >
|
||||
instead.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2026 Petr Balvín.
|
||||
.PP
|
||||
Licensed under the MIT License.
|
||||
Permission is granted to use, copy, modify, and distribute this software
|
||||
without restriction, provided that the above copyright notice and this
|
||||
permission notice appear in all copies.
|
||||
.PP
|
||||
.B goget
|
||||
is provided
|
||||
.B "AS IS"
|
||||
without any warranty of any kind. See the MIT License text distributed with
|
||||
the source for the full disclaimer.
|
||||
Reference in New Issue
Block a user