argsbarg 5.1.1 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/docs/configure.md +2 -0
- package/docs/distribution-homebrew.md +19 -0
- package/docs/output-schema.md +1 -1
- package/examples/full-example/README.md +2 -2
- package/examples/full-example/justfile +15 -7
- package/examples/full-example/scripts/ensure-brew-github-token.sh +9 -0
- package/examples/full-example/scripts/formula-shared.ts +53 -4
- package/examples/full-example/scripts/print-identity.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [5.1.2] - 2026-07-04
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Private GitHub release installs** — release formulae use `GitHubPrivateReleaseDownloadStrategy` (GitHub API + `GitHub::API.credentials` / `HOMEBREW_GITHUB_API_TOKEN`); `just install-production` and `just test-release` export the token (with `gh auth token` fallback). Documented in `docs/distribution-homebrew.md`.
|
|
15
|
+
|
|
10
16
|
## [5.1.1] - 2026-07-04
|
|
11
17
|
|
|
12
18
|
### Fixed
|
|
@@ -595,7 +601,8 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
|
|
|
595
601
|
- Migrate schemas: rename every `children` property to **`commands`**; move positional definitions to **`CliPositional`** objects on `positionals` and strip `positional` / `argMin` / `argMax` from flag definitions under `options` (flags only carry `name`, `description`, `kind`, and optional `shortName`).
|
|
596
602
|
- Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
|
|
597
603
|
|
|
598
|
-
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.
|
|
604
|
+
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.2...HEAD
|
|
605
|
+
[5.1.2]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.2
|
|
599
606
|
[5.1.1]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.1
|
|
600
607
|
[5.1.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.0
|
|
601
608
|
[5.0.3]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.0.3
|
package/docs/configure.md
CHANGED
|
@@ -14,6 +14,8 @@ brew install <tap>/<key>
|
|
|
14
14
|
|
|
15
15
|
Upgrade with `brew upgrade <key>`. Shell completions are installed by Homebrew during `brew install`. Users must configure their shell per [Homebrew Shell Completion](https://docs.brew.sh/Shell-Completion).
|
|
16
16
|
|
|
17
|
+
Private GitHub release assets require `HOMEBREW_GITHUB_API_TOKEN` at install time — see [distribution-homebrew.md](distribution-homebrew.md#end-user-install).
|
|
18
|
+
|
|
17
19
|
**Uninstall the binary:** remove agent artifacts first (while the CLI is still on PATH), then `brew uninstall`:
|
|
18
20
|
|
|
19
21
|
```bash
|
|
@@ -20,6 +20,16 @@ brew install <tap>/{key}
|
|
|
20
20
|
{key} configure # when app config is required
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
For **private or internal GitHub repos**, release formulae attach `HOMEBREW_GITHUB_API_TOKEN` when downloading the binary. Export a PAT with `repo` scope (or rely on `gh auth login` — `just install-production` and `just test-release` fall back to `gh auth token`):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)"
|
|
27
|
+
brew tap <org>/<repo> git@github.com:<org>/<repo>.git
|
|
28
|
+
brew install <tap>/{key}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Local dev installs (`just install-local`) use a `file://` staging URL and do not need the token.
|
|
32
|
+
|
|
23
33
|
### Developer install
|
|
24
34
|
|
|
25
35
|
```bash
|
|
@@ -56,6 +66,15 @@ def post_install
|
|
|
56
66
|
end
|
|
57
67
|
```
|
|
58
68
|
|
|
69
|
+
Release formulae generated by `scripts/formula-shared.ts` embed a `GitHubPrivateReleaseDownloadStrategy` that resolves the release asset through the GitHub API at download time and authenticates with `GitHub::API.credentials` (backed by `HOMEBREW_GITHUB_API_TOKEN`, `gh auth`, or other Homebrew GitHub credential sources):
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
url "https://github.com/<org>/<repo>/releases/download/vX.Y.Z/{key}",
|
|
73
|
+
using: GitHubPrivateReleaseDownloadStrategy
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Local dev formulae (`just install-local`) use a plain `file://` URL and do not need the token.
|
|
77
|
+
|
|
59
78
|
Completions require users to configure their shell per [Homebrew Shell Completion](https://docs.brew.sh/Shell-Completion).
|
|
60
79
|
|
|
61
80
|
**Why configure is separate from `post_install`:** the wizard is interactive (TTY + prompts for secrets). Formula `post_install` runs non-interactively during `brew install` and in CI (`brew test`). Apps with `appConfig` print a one-line configure hint in formula `caveats` instead.
|
package/docs/output-schema.md
CHANGED
|
@@ -43,7 +43,7 @@ Production CLIs with several JSON commands tend to use **codegen** so types, han
|
|
|
43
43
|
|
|
44
44
|
## Recommended pipeline (copy per repo)
|
|
45
45
|
|
|
46
|
-
No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-
|
|
46
|
+
No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-manager**, **idp-trees**, **poc-sqsp-i18n-tools** (see each repo’s `docs/architecture.md` for which commands use which schema root).
|
|
47
47
|
|
|
48
48
|
```mermaid
|
|
49
49
|
flowchart LR
|
|
@@ -59,8 +59,8 @@ Requires [Homebrew](https://brew.sh) and a compiled binary at `dist/full-example
|
|
|
59
59
|
just build
|
|
60
60
|
just install-local # first-time dev formula (`just install` is an alias)
|
|
61
61
|
just reinstall-local # fast binary swap during development
|
|
62
|
-
just install-production # uninstall local dev, install from GitHub tap
|
|
63
|
-
just test-release
|
|
62
|
+
just install-production # uninstall local dev, install from GitHub tap (needs HOMEBREW_GITHUB_API_TOKEN for private repos)
|
|
63
|
+
just test-release # same token requirement when formula uses a GitHub release URL
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
Undo a local dev install:
|
|
@@ -8,6 +8,8 @@ cli_key := `bun scripts/print-identity.ts key`
|
|
|
8
8
|
tap_org := `bun scripts/print-identity.ts tapOrg`
|
|
9
9
|
tap_repo := `bun scripts/print-identity.ts tapRepo`
|
|
10
10
|
tap := `bun scripts/print-identity.ts tap`
|
|
11
|
+
release_repo := `bun scripts/print-identity.ts releaseRepo`
|
|
12
|
+
tap_git_url := "git@github.com:" + release_repo + ".git"
|
|
11
13
|
brew_prefix := `brew --prefix`
|
|
12
14
|
tap_parent := brew_prefix + "/Library/Taps/" + tap_org
|
|
13
15
|
tap_path := tap_parent + "/homebrew-" + tap_repo
|
|
@@ -59,12 +61,15 @@ install-local: build
|
|
|
59
61
|
@echo ""
|
|
60
62
|
@echo "Next: {{cli_key}} configure"
|
|
61
63
|
|
|
62
|
-
# Remove local dev install, then install from GitHub tap
|
|
64
|
+
# Remove local dev install, then install from GitHub tap (private release assets need HOMEBREW_GITHUB_API_TOKEN)
|
|
63
65
|
install-production: uninstall
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
#!/usr/bin/env bash
|
|
67
|
+
set -eu -o pipefail
|
|
68
|
+
source scripts/ensure-brew-github-token.sh
|
|
69
|
+
brew tap {{release_repo}} {{tap_git_url}}
|
|
70
|
+
brew install --formula {{release_repo}}/{{cli_key}}
|
|
71
|
+
echo ""
|
|
72
|
+
echo "Next: {{cli_key}} configure"
|
|
68
73
|
|
|
69
74
|
# Alias for backward compatibility
|
|
70
75
|
reinstall: reinstall-local
|
|
@@ -96,10 +101,13 @@ test: check
|
|
|
96
101
|
|
|
97
102
|
# Install release formula from tap and run formula test
|
|
98
103
|
test-release:
|
|
99
|
-
|
|
104
|
+
#!/usr/bin/env bash
|
|
105
|
+
set -eu -o pipefail
|
|
106
|
+
source scripts/ensure-brew-github-token.sh
|
|
107
|
+
brew untap {{tap}} 2>/dev/null || true
|
|
100
108
|
mkdir -p {{tap_parent}}
|
|
101
109
|
ln -sfn '{{justfile_directory()}}' {{tap_path}}
|
|
102
|
-
|
|
110
|
+
brew uninstall --formula {{tap}}/{{cli_key}} 2>/dev/null || true
|
|
103
111
|
brew install --formula {{tap}}/{{cli_key}}
|
|
104
112
|
brew test {{cli_key}}
|
|
105
113
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Ensure HOMEBREW_GITHUB_API_TOKEN is set for private GitHub release downloads.
|
|
3
|
+
: "${HOMEBREW_GITHUB_API_TOKEN:=$(gh auth token 2>/dev/null || true)}"
|
|
4
|
+
if [[ -z "${HOMEBREW_GITHUB_API_TOKEN}" ]]; then
|
|
5
|
+
echo "HOMEBREW_GITHUB_API_TOKEN is required to download private GitHub release assets." >&2
|
|
6
|
+
echo "Export a GitHub PAT with repo scope, or run: gh auth login" >&2
|
|
7
|
+
exit 1
|
|
8
|
+
fi
|
|
9
|
+
export HOMEBREW_GITHUB_API_TOKEN
|
|
@@ -30,8 +30,51 @@ export const formulaTestRuby = `test do
|
|
|
30
30
|
|
|
31
31
|
export interface FormulaCoords {
|
|
32
32
|
url: string;
|
|
33
|
+
urlStanza: string;
|
|
33
34
|
version: string;
|
|
34
35
|
sha256: string;
|
|
36
|
+
/** When true, embed {@link githubPrivateReleaseDownloadStrategyRuby} in the formula class. */
|
|
37
|
+
privateRelease?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Resolves private GitHub release assets via the API at download time. */
|
|
41
|
+
export const githubPrivateReleaseDownloadStrategyRuby = ` class GitHubPrivateReleaseDownloadStrategy < CurlDownloadStrategy
|
|
42
|
+
def initialize(url, name, version, **meta)
|
|
43
|
+
super
|
|
44
|
+
pattern = %r{https://github\\.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(\\S+)}
|
|
45
|
+
match = url.match(pattern)
|
|
46
|
+
raise CurlDownloadStrategyError, "Invalid GitHub release URL: #{url}" unless match
|
|
47
|
+
@owner, @repo, @tag, @filename = match.captures
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def _fetch(url:, resolved_url: resolved_download_url, timeout:)
|
|
53
|
+
curl_download resolved_download_url,
|
|
54
|
+
"--header", "Accept: application/octet-stream",
|
|
55
|
+
"--header", "Authorization: Bearer #{GitHub::API.credentials}",
|
|
56
|
+
to: temporary_path
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def resolved_download_url
|
|
60
|
+
@resolved_download_url ||= begin
|
|
61
|
+
asset = GitHub.get_release(@owner, @repo, @tag).fetch("assets")
|
|
62
|
+
.find { |a| a["name"] == @filename }
|
|
63
|
+
raise CurlDownloadStrategyError, "Release asset not found: #{@filename}" unless asset
|
|
64
|
+
asset.fetch("url")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end`;
|
|
68
|
+
|
|
69
|
+
/** Homebrew `url` for local dev staging paths. */
|
|
70
|
+
export function devUrlStanza(url: string): string {
|
|
71
|
+
return `url "${url}"`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Homebrew `url` for GitHub release assets (uses {@link githubPrivateReleaseDownloadStrategyRuby}). */
|
|
75
|
+
export function releaseUrlStanza(url: string): string {
|
|
76
|
+
return `url "${url}",
|
|
77
|
+
using: GitHubPrivateReleaseDownloadStrategy`;
|
|
35
78
|
}
|
|
36
79
|
|
|
37
80
|
export function releaseFormulaUrl(version: string): string {
|
|
@@ -39,10 +82,11 @@ export function releaseFormulaUrl(version: string): string {
|
|
|
39
82
|
}
|
|
40
83
|
|
|
41
84
|
export function renderFormula(coords: FormulaCoords): string {
|
|
85
|
+
const strategy = coords.privateRelease ? `${githubPrivateReleaseDownloadStrategyRuby}\n\n ` : "";
|
|
42
86
|
return `class ${className} < Formula
|
|
43
|
-
desc "${desc}"
|
|
87
|
+
${strategy}desc "${desc}"
|
|
44
88
|
homepage "${homepage}"
|
|
45
|
-
|
|
89
|
+
${coords.urlStanza}
|
|
46
90
|
version "${coords.version}"
|
|
47
91
|
sha256 "${coords.sha256}"
|
|
48
92
|
{dependsOnBlock}
|
|
@@ -58,16 +102,21 @@ end
|
|
|
58
102
|
}
|
|
59
103
|
|
|
60
104
|
export function renderReleaseFormula(version: string, sha256: string): string {
|
|
105
|
+
const url = releaseFormulaUrl(version);
|
|
61
106
|
return renderFormula({
|
|
62
|
-
url
|
|
107
|
+
url,
|
|
108
|
+
urlStanza: releaseUrlStanza(url),
|
|
63
109
|
version,
|
|
64
110
|
sha256,
|
|
111
|
+
privateRelease: true,
|
|
65
112
|
});
|
|
66
113
|
}
|
|
67
114
|
|
|
68
115
|
export function renderDevFormula(stagingPath: string, version: string, sha256: string): string {
|
|
116
|
+
const url = `file://${stagingPath}`;
|
|
69
117
|
return renderFormula({
|
|
70
|
-
url
|
|
118
|
+
url,
|
|
119
|
+
urlStanza: devUrlStanza(url),
|
|
71
120
|
version,
|
|
72
121
|
sha256,
|
|
73
122
|
});
|
|
@@ -5,7 +5,7 @@ import { createIdentity } from "./create-identity.ts";
|
|
|
5
5
|
|
|
6
6
|
const field = process.argv[2];
|
|
7
7
|
if (!field) {
|
|
8
|
-
console.error("Usage: bun scripts/print-identity.ts <key|className|tap|tapOrg|tapRepo|envPrefix>");
|
|
8
|
+
console.error("Usage: bun scripts/print-identity.ts <key|className|tap|tapOrg|tapRepo|releaseRepo|envPrefix>");
|
|
9
9
|
process.exit(1);
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -17,6 +17,7 @@ const values: Record<string, string> = {
|
|
|
17
17
|
tapOrg: tapOrg ?? "",
|
|
18
18
|
tapRepo: tapRepo ?? "",
|
|
19
19
|
envPrefix: createIdentity.envPrefix,
|
|
20
|
+
releaseRepo: createIdentity.releaseRepo,
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const value = values[field];
|