opencode-homebrew-agent 1.0.0
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/LICENSE +21 -0
- package/README.md +175 -0
- package/agents/brew.md +146 -0
- package/package.json +22 -0
- package/src/AGENTS.md +172 -0
- package/src/scripts/brew-analyze.sh +373 -0
- package/src/scripts/brew-deps.sh +140 -0
- package/src/scripts/brew-env.sh +288 -0
- package/src/scripts/brew-search.sh +150 -0
- package/src/scripts/brew-template.sh +263 -0
- package/src/scripts/package.json +21 -0
- package/src/skills/homebrew-agent/SKILL.md +203 -0
- package/src/skills/homebrew-tap/SKILL.md +97 -0
- package/src/templates/taps/01-full-ci/AGENTS.md +71 -0
- package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/autobump.yml +24 -0
- package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/publish.yml +33 -0
- package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/tests.yml +33 -0
- package/src/templates/taps/01-full-ci/tap-structure/Formula/_formula.rb +31 -0
- package/src/templates/taps/01-full-ci/tap-structure/README.md +27 -0
- package/src/templates/taps/01-full-ci/tap-structure/cmd/.gitkeep +0 -0
- package/src/templates/taps/01-full-ci/tap-structure/formula_renames.json +1 -0
- package/src/templates/taps/01-full-ci/tap-structure/lib/.gitkeep +0 -0
- package/src/templates/taps/01-full-ci/tap-structure/require/.gitkeep +0 -0
- package/src/templates/taps/01-full-ci/tap-structure/tap_migrations.json +1 -0
- package/src/templates/taps/01-full-ci/template.md +45 -0
- package/src/templates/taps/02-root-level/AGENTS.md +72 -0
- package/src/templates/taps/02-root-level/tap-structure/README.md +27 -0
- package/src/templates/taps/02-root-level/tap-structure/_formula.rb +29 -0
- package/src/templates/taps/02-root-level/template.md +35 -0
- package/src/templates/taps/03-simple-script/AGENTS.md +71 -0
- package/src/templates/taps/03-simple-script/tap-structure/Formula/_formula.rb +27 -0
- package/src/templates/taps/03-simple-script/tap-structure/README.md +27 -0
- package/src/templates/taps/03-simple-script/tap-structure/scripts/release.rb +46 -0
- package/src/templates/taps/03-simple-script/template.md +41 -0
- package/src/templates/taps/04-python-venv/AGENTS.md +83 -0
- package/src/templates/taps/04-python-venv/tap-structure/Formula/_formula.rb +57 -0
- package/src/templates/taps/04-python-venv/tap-structure/README.md +27 -0
- package/src/templates/taps/04-python-venv/tap-structure/scripts/release.rb +44 -0
- package/src/templates/taps/04-python-venv/template.md +58 -0
- package/src/templates/taps/05-node-npm/AGENTS.md +90 -0
- package/src/templates/taps/05-node-npm/tap-structure/Formula/_formula.rb +46 -0
- package/src/templates/taps/05-node-npm/tap-structure/README.md +27 -0
- package/src/templates/taps/05-node-npm/tap-structure/scripts/release.rb +40 -0
- package/src/templates/taps/05-node-npm/template.md +74 -0
- package/src/templates/taps/06-keg-only/AGENTS.md +82 -0
- package/src/templates/taps/06-keg-only/tap-structure/Formula/_formula.rb +45 -0
- package/src/templates/taps/06-keg-only/tap-structure/README.md +27 -0
- package/src/templates/taps/06-keg-only/template.md +60 -0
- package/src/templates/taps/07-cask-only/AGENTS.md +97 -0
- package/src/templates/taps/07-cask-only/tap-structure/Casks/_app.rb +26 -0
- package/src/templates/taps/07-cask-only/tap-structure/README.md +27 -0
- package/src/templates/taps/07-cask-only/template.md +58 -0
- package/src/templates/taps/08-go-binary/AGENTS.md +86 -0
- package/src/templates/taps/08-go-binary/tap-structure/Formula/_formula.rb +40 -0
- package/src/templates/taps/08-go-binary/tap-structure/README.md +27 -0
- package/src/templates/taps/08-go-binary/tap-structure/scripts/release.rb +38 -0
- package/src/templates/taps/08-go-binary/template.md +60 -0
- package/src/workflows/analyze-source.sh +124 -0
- package/src/workflows/convert-npm-to-bun.sh +112 -0
- package/src/workflows/create-tap.sh +196 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# <Tap Name>
|
|
2
|
+
|
|
3
|
+
Homebrew tap for <formula>.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
brew tap <user>/<tapname>
|
|
9
|
+
brew install <formula>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Upgrade
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
brew upgrade <formula>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Uninstall
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
brew uninstall <formula>
|
|
22
|
+
brew untap <user>/<tapname>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## License
|
|
26
|
+
|
|
27
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
# Root-level formula — place this file at the repository root.
|
|
3
|
+
# Replace <formula>, <description>, <url>, <sha256> with real values.
|
|
4
|
+
# IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
|
|
5
|
+
|
|
6
|
+
class <Formula> < Formula
|
|
7
|
+
desc "<one-line description>"
|
|
8
|
+
homepage "https://github.com/<user>/<repo>"
|
|
9
|
+
url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
|
|
10
|
+
sha256 "<sha256>"
|
|
11
|
+
version "<version>"
|
|
12
|
+
license "MIT"
|
|
13
|
+
|
|
14
|
+
livecheck do
|
|
15
|
+
url :stable
|
|
16
|
+
regex(/^v?(\d+(?:\.\d+)+)$/i)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
depends_on "<dep>"
|
|
20
|
+
|
|
21
|
+
def install
|
|
22
|
+
system "<build-command>"
|
|
23
|
+
bin.install "<binary>"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test do
|
|
27
|
+
assert_match "<expected>", shell_output("#{bin}/<cli> --help")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Template 02: Root-Level `.rb`
|
|
2
|
+
|
|
3
|
+
## Pattern: `yakitrak/homebrew-yakitrak`
|
|
4
|
+
|
|
5
|
+
A minimal tap with formula files at the repository root. No `Formula/`
|
|
6
|
+
subdirectory, no CI, no scripts. Best for **1-2 formula taps** where
|
|
7
|
+
simplicity is king.
|
|
8
|
+
|
|
9
|
+
### Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
homebrew-<tap>/
|
|
13
|
+
├── <formula>.rb # Formula at root (no Formula/ dir)
|
|
14
|
+
├── LICENSE
|
|
15
|
+
└── README.md
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### When to Use
|
|
19
|
+
|
|
20
|
+
- You have 1-2 simple formulae
|
|
21
|
+
- You don't need CI in the tap
|
|
22
|
+
- You want the absolute minimum structure
|
|
23
|
+
|
|
24
|
+
### When NOT to Use
|
|
25
|
+
|
|
26
|
+
- You need CI/bottle workflows (use template 01)
|
|
27
|
+
- You need script-driven releases (use template 03)
|
|
28
|
+
- You need Python virtualenv deps (use template 04)
|
|
29
|
+
|
|
30
|
+
### Reference
|
|
31
|
+
|
|
32
|
+
- `brew install <user>/<tap>/<formula>` works regardless of file location
|
|
33
|
+
- Homebrew scans root, `Formula/`, and `HomebrewFormula/` for `.rb` files
|
|
34
|
+
|
|
35
|
+
- Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: homebrew-tap-simple-script
|
|
3
|
+
description: Creates and maintains lean Homebrew taps with script-driven release automation (oven-sh/homebrew-bun pattern).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# homebrew-tap-simple-script
|
|
7
|
+
|
|
8
|
+
Agent for working with Simple + Script tap templates.
|
|
9
|
+
|
|
10
|
+
## Description
|
|
11
|
+
Helps create and maintain lean Homebrew taps with script-driven release automation and optional versioned formula aliases.
|
|
12
|
+
|
|
13
|
+
## Stacks
|
|
14
|
+
- homebrew
|
|
15
|
+
- ruby
|
|
16
|
+
- scripts
|
|
17
|
+
|
|
18
|
+
## Requires
|
|
19
|
+
- basic-homebrew-knowledge
|
|
20
|
+
|
|
21
|
+
## Key Actions
|
|
22
|
+
|
|
23
|
+
### Release Script Pattern
|
|
24
|
+
The `scripts/release.rb` takes a version tag, fetches release assets, computes SHA256s, and rewrites the formula. Modeled on `oven-sh/homebrew-bun/scripts/release.rb`.
|
|
25
|
+
|
|
26
|
+
### Versioned Formulae
|
|
27
|
+
Optionally create `Formula/<formula>@X.Y.Z.rb` aliases by copying the main formula with a modified class name (e.g., `class BunAT1314` for version `1.3.14`).
|
|
28
|
+
|
|
29
|
+
### Permissions
|
|
30
|
+
- Read/write to `Formula/` and `scripts/`
|
|
31
|
+
- Network access for downloading release assets
|
|
32
|
+
|
|
33
|
+
### Common Pitfalls
|
|
34
|
+
|
|
35
|
+
- After running `release.rb`, always `git diff` to verify version/SHA substitution worked.
|
|
36
|
+
- The release script hardcodes `_formula.rb`. If you rename the file, update the `FORMULA_FILE` path.
|
|
37
|
+
- `class <Formula>` must be replaced with the actual formula class name (e.g., `class MyTool < Formula`).
|
|
38
|
+
- For pre-built binary formulae, use versioned aliases (`formula@X.Y.Z.rb`) for rollback support.
|
|
39
|
+
- `ruby release.rb` without arguments prints usage. Always pass a version tag (e.g., `ruby release.rb 1.2.3`).
|
|
40
|
+
|
|
41
|
+
### LSP Validation
|
|
42
|
+
|
|
43
|
+
Before finishing any formula, validate with the Ruby LSP:
|
|
44
|
+
|
|
45
|
+
1. Ensure LSP is available:
|
|
46
|
+
```sh
|
|
47
|
+
ruby-lsp --version # Verify LSP is installed
|
|
48
|
+
```
|
|
49
|
+
2. Run syntax check:
|
|
50
|
+
```sh
|
|
51
|
+
ruby -c Formula/<formula>.rb
|
|
52
|
+
```
|
|
53
|
+
3. Run Homebrew linting:
|
|
54
|
+
```sh
|
|
55
|
+
brew style --tap <user>/<tapname> Formula/<formula>.rb
|
|
56
|
+
```
|
|
57
|
+
4. Run formula audit:
|
|
58
|
+
```sh
|
|
59
|
+
brew audit --new-formula Formula/<formula>.rb
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Do NOT mark work as complete until all diagnostics pass.
|
|
63
|
+
|
|
64
|
+
### Verification
|
|
65
|
+
```sh
|
|
66
|
+
ruby -c scripts/release.rb
|
|
67
|
+
ruby -c Formula/<formula>.rb
|
|
68
|
+
# Dry-run release:
|
|
69
|
+
ruby scripts/release.rb <version>
|
|
70
|
+
git diff # Verify changes
|
|
71
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
# Simple formula with script-driven release (oven-sh/homebrew-bun pattern).
|
|
3
|
+
# Replace <formula>, <description>, <url>, <sha256> with real values.
|
|
4
|
+
# IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
|
|
5
|
+
|
|
6
|
+
class <Formula> < Formula
|
|
7
|
+
desc "<one-line description>"
|
|
8
|
+
homepage "https://github.com/<user>/<repo>"
|
|
9
|
+
url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
|
|
10
|
+
sha256 "<sha256>"
|
|
11
|
+
version "<version>"
|
|
12
|
+
license "MIT"
|
|
13
|
+
|
|
14
|
+
livecheck do
|
|
15
|
+
url :stable
|
|
16
|
+
regex(/^v?(\d+(?:\.\d+)+)$/i)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def install
|
|
20
|
+
system "<build-command>"
|
|
21
|
+
bin.install "<binary>"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test do
|
|
25
|
+
assert_match "<expected>", shell_output("#{bin}/<cli> --version")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# <Tap Name>
|
|
2
|
+
|
|
3
|
+
Homebrew tap for <formula>.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
brew tap <user>/<tapname>
|
|
9
|
+
brew install <formula>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Upgrade
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
brew upgrade <formula>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Uninstall
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
brew uninstall <formula>
|
|
22
|
+
brew untap <user>/<tapname>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## License
|
|
26
|
+
|
|
27
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Release script modeled on oven-sh/homebrew-bun/scripts/release.rb.
|
|
5
|
+
# Usage: ruby scripts/release.rb <version>
|
|
6
|
+
#
|
|
7
|
+
# Fetches the release tarball, computes SHA256, and rewrites Formula/<formula>.rb.
|
|
8
|
+
|
|
9
|
+
require "open-uri"
|
|
10
|
+
require "digest"
|
|
11
|
+
|
|
12
|
+
TAP_DIR = File.dirname(__dir__)
|
|
13
|
+
FORMULA_FILE = File.join(TAP_DIR, "Formula", "_formula.rb") # rename to your formula name
|
|
14
|
+
|
|
15
|
+
def usage
|
|
16
|
+
puts "Usage: ruby scripts/release.rb <version>"
|
|
17
|
+
puts " e.g., ruby scripts/release.rb 1.2.3"
|
|
18
|
+
exit 1
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def fetch_sha256(url)
|
|
22
|
+
uri = URI.parse(url)
|
|
23
|
+
puts " Downloading #{url}..."
|
|
24
|
+
content = URI.open(uri).read
|
|
25
|
+
Digest::SHA256.hexdigest(content)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
version = ARGV.first || usage()
|
|
29
|
+
|
|
30
|
+
tarball_url = "https://github.com/<user>/<repo>/archive/refs/tags/v#{version}.tar.gz"
|
|
31
|
+
|
|
32
|
+
puts "Updating Formula/<formula>.rb to version #{version}..."
|
|
33
|
+
|
|
34
|
+
sha = fetch_sha256(tarball_url)
|
|
35
|
+
|
|
36
|
+
formula_content = File.read(FORMULA_FILE)
|
|
37
|
+
|
|
38
|
+
# Replace version and sha256
|
|
39
|
+
formula_content.sub!(/version "\d+\.\d+\.\d+"/, "version \"#{version}\"")
|
|
40
|
+
formula_content.sub!(/sha256 "[0-9a-f]{64}"/, "sha256 \"#{sha}\"")
|
|
41
|
+
|
|
42
|
+
File.write(FORMULA_FILE, formula_content)
|
|
43
|
+
|
|
44
|
+
puts "Done. Formula updated to v#{version}."
|
|
45
|
+
puts
|
|
46
|
+
puts "Review changes with: git diff Formula/<formula>.rb"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Template 03: Simple + Script
|
|
2
|
+
|
|
3
|
+
## Pattern: `oven-sh/homebrew-bun`
|
|
4
|
+
|
|
5
|
+
A lean tap with a `Formula/` subdirectory and a `scripts/release.rb` for
|
|
6
|
+
version bumps. No CI in the tap — releases are script-driven. Best for
|
|
7
|
+
**single-formula taps** where releases are manual or triggered externally.
|
|
8
|
+
|
|
9
|
+
### Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
homebrew-<tap>/
|
|
13
|
+
├── Formula/
|
|
14
|
+
│ ├── <formula>.rb # Latest version (overwritten on release)
|
|
15
|
+
│ └── <formula>@X.Y.Z.rb # (optional) Versioned aliases for rollback
|
|
16
|
+
├── scripts/
|
|
17
|
+
│ └── release.rb # Version bump script
|
|
18
|
+
├── .gitignore
|
|
19
|
+
├── LICENSE
|
|
20
|
+
└── README.md
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### When to Use
|
|
24
|
+
|
|
25
|
+
- You have a single formula (binary or script)
|
|
26
|
+
- You want a simple, script-driven release process
|
|
27
|
+
- You don't need CI in the tap itself
|
|
28
|
+
- You want versioned formula aliases for rollback support
|
|
29
|
+
|
|
30
|
+
### When NOT to Use
|
|
31
|
+
|
|
32
|
+
- You need CI/bottle workflows (use template 01)
|
|
33
|
+
- Your formula needs Python virtualenv (use template 04)
|
|
34
|
+
|
|
35
|
+
### Reference
|
|
36
|
+
|
|
37
|
+
- `scripts/release.rb` takes version, fetches assets, rewrites formula
|
|
38
|
+
- Versioned aliases (`<formula>@X.Y.Z.rb`) enable `brew install <formula>@1.2.3`
|
|
39
|
+
- See `oven-sh/homebrew-bun/scripts/release.rb` for the reference implementation
|
|
40
|
+
|
|
41
|
+
- Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: homebrew-tap-python-venv
|
|
3
|
+
description: Creates and maintains Homebrew taps for Python CLI tools with pip dependencies in a virtualenv (bendzgerona/homebrew-litellm pattern).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# homebrew-tap-python-venv
|
|
7
|
+
|
|
8
|
+
Agent for working with Python Virtualenv tap templates.
|
|
9
|
+
|
|
10
|
+
## Description
|
|
11
|
+
Helps create and maintain Homebrew taps for Python CLI tools with pip dependencies installed in a Homebrew-managed virtualenv.
|
|
12
|
+
|
|
13
|
+
## Stacks
|
|
14
|
+
- homebrew
|
|
15
|
+
- python
|
|
16
|
+
- ruby
|
|
17
|
+
|
|
18
|
+
## Requires
|
|
19
|
+
- basic-homebrew-knowledge
|
|
20
|
+
|
|
21
|
+
## Key Actions
|
|
22
|
+
|
|
23
|
+
### Formula Structure
|
|
24
|
+
```ruby
|
|
25
|
+
include Language::Python::Virtualenv
|
|
26
|
+
depends_on "python@3.13" # Pin to avoid brew's default
|
|
27
|
+
depends_on "openssl@3"
|
|
28
|
+
depends_on "pkgconf" => :build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Install Pattern
|
|
32
|
+
```ruby
|
|
33
|
+
venv = virtualenv_create(libexec, "python3.13")
|
|
34
|
+
venv.pip_install buildpath # Install the package itself
|
|
35
|
+
system venv.root/"bin/pip", "install", "package[extras]==#{version}"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Post-Install Notice
|
|
39
|
+
Use `def caveats` to instruct users about optional deps, service setup, and separate agent/config installation.
|
|
40
|
+
|
|
41
|
+
### Permissions
|
|
42
|
+
- Read/write to `Formula/` and `scripts/`
|
|
43
|
+
- Network access for pip installs
|
|
44
|
+
- `python@3.X` must be declared as dep (auto-installed)
|
|
45
|
+
|
|
46
|
+
### Common Pitfalls
|
|
47
|
+
|
|
48
|
+
- `python@3.13` must match what is available in homebrew-core. Pin to a version that actually exists.
|
|
49
|
+
- Brew's Python packages (uvicorn, fastapi, pydantic) all depend on brew's default python — incompatible with pinned venvs.
|
|
50
|
+
- `virtualenv_create` sets up a Homebrew-managed venv. Do NOT use `python3 -m venv` instead.
|
|
51
|
+
- `pip_install` may fail if wheels need compilation. Add `depends_on "pkgconf" => :build` and `depends_on "openssl@3"`.
|
|
52
|
+
- The `service` block runs `libexec/bin/<cli>` — ensure the symlink target is correct or the service will fail silently.
|
|
53
|
+
|
|
54
|
+
### LSP Validation
|
|
55
|
+
|
|
56
|
+
Before finishing any formula, validate with the Ruby LSP:
|
|
57
|
+
|
|
58
|
+
1. Ensure LSP is available:
|
|
59
|
+
```sh
|
|
60
|
+
ruby-lsp --version # Verify LSP is installed
|
|
61
|
+
```
|
|
62
|
+
2. Run syntax check:
|
|
63
|
+
```sh
|
|
64
|
+
ruby -c Formula/<formula>.rb
|
|
65
|
+
```
|
|
66
|
+
3. Run Homebrew linting:
|
|
67
|
+
```sh
|
|
68
|
+
brew style --tap <user>/<tapname> Formula/<formula>.rb
|
|
69
|
+
```
|
|
70
|
+
4. Run formula audit:
|
|
71
|
+
```sh
|
|
72
|
+
brew audit --new-formula Formula/<formula>.rb
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Do NOT mark work as complete until all diagnostics pass.
|
|
76
|
+
|
|
77
|
+
### Verification
|
|
78
|
+
```sh
|
|
79
|
+
brew sh --ruby
|
|
80
|
+
ruby -c Formula/<formula>.rb
|
|
81
|
+
brew style --tap <user>/<tapname> Formula/<formula>.rb
|
|
82
|
+
brew audit --new-formula Formula/<formula>.rb
|
|
83
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
# Python virtualenv formula (bendzgerona/homebrew-litellm pattern).
|
|
3
|
+
# Replace <formula>, <description>, <url>, <sha256> with real values.
|
|
4
|
+
# IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
|
|
5
|
+
|
|
6
|
+
class <Formula> < Formula
|
|
7
|
+
include Language::Python::Virtualenv
|
|
8
|
+
|
|
9
|
+
desc "<one-line description>"
|
|
10
|
+
homepage "https://github.com/<user>/<repo>"
|
|
11
|
+
url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
|
|
12
|
+
sha256 "<sha256>"
|
|
13
|
+
version "<version>"
|
|
14
|
+
license "MIT"
|
|
15
|
+
|
|
16
|
+
depends_on "python@3.13" # Pin to avoid brew's default 3.14
|
|
17
|
+
depends_on "openssl@3"
|
|
18
|
+
depends_on "pkgconf" => :build
|
|
19
|
+
|
|
20
|
+
livecheck do
|
|
21
|
+
url :stable
|
|
22
|
+
strategy :github_latest
|
|
23
|
+
regex(/^v?(\d+(?:\.\d+)+)$/i)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def install
|
|
27
|
+
venv = virtualenv_create(libexec, "python3.13")
|
|
28
|
+
venv.pip_install buildpath
|
|
29
|
+
|
|
30
|
+
# If the package has extras:
|
|
31
|
+
# system venv.root/"bin/pip", "install", "package[extras]==#{version}"
|
|
32
|
+
|
|
33
|
+
bin.install_symlink libexec/"bin/<cli>"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
service do
|
|
37
|
+
run [libexec/"bin/<cli>", "--config", etc/"<tool>/config.yaml"]
|
|
38
|
+
keep_alive true
|
|
39
|
+
log_path var/"log/<tool>.log"
|
|
40
|
+
error_log_path var/"log/<tool>.log"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def caveats
|
|
44
|
+
<<~EOS
|
|
45
|
+
Configuration file: #{etc/"<tool>/config.yaml"}
|
|
46
|
+
Start the service: brew services start <user>/<tap>/<formula>
|
|
47
|
+
|
|
48
|
+
Optional dependencies:
|
|
49
|
+
postgresql — for usage tracking via SQLite → PostgreSQL
|
|
50
|
+
redis — for request caching and rate limiting
|
|
51
|
+
EOS
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test do
|
|
55
|
+
assert_match version.to_s, shell_output("#{bin}/<cli> --version")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# <Tap Name>
|
|
2
|
+
|
|
3
|
+
Homebrew tap for <formula>.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
brew tap <user>/<tapname>
|
|
9
|
+
brew install <formula>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Upgrade
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
brew upgrade <formula>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Uninstall
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
brew uninstall <formula>
|
|
22
|
+
brew untap <user>/<tapname>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## License
|
|
26
|
+
|
|
27
|
+
MIT
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Version bump script for Python virtualenv formula.
|
|
5
|
+
# Usage: ruby scripts/update-formula.rb <version>
|
|
6
|
+
|
|
7
|
+
require "open-uri"
|
|
8
|
+
require "digest"
|
|
9
|
+
|
|
10
|
+
TAP_DIR = File.dirname(__dir__)
|
|
11
|
+
FORMULA_FILE = File.join(TAP_DIR, "Formula", "_formula.rb") # rename to your formula name
|
|
12
|
+
|
|
13
|
+
def usage
|
|
14
|
+
puts "Usage: ruby scripts/update-formula.rb <version>"
|
|
15
|
+
puts " e.g., ruby scripts/update-formula.rb 1.2.3"
|
|
16
|
+
exit 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fetch_sha256(url)
|
|
20
|
+
uri = URI.parse(url)
|
|
21
|
+
puts " Downloading #{url}..."
|
|
22
|
+
content = URI.open(uri).read
|
|
23
|
+
Digest::SHA256.hexdigest(content)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
version = ARGV.first || usage()
|
|
27
|
+
|
|
28
|
+
tarball_url = "https://github.com/<user>/<repo>/archive/refs/tags/v#{version}.tar.gz"
|
|
29
|
+
|
|
30
|
+
puts "Updating Formula/<formula>.rb to version #{version}..."
|
|
31
|
+
sha = fetch_sha256(tarball_url)
|
|
32
|
+
|
|
33
|
+
formula_content = File.read(FORMULA_FILE)
|
|
34
|
+
formula_content.sub!(/version "\d+\.\d+\.\d+"/, "version \"#{version}\"")
|
|
35
|
+
formula_content.sub!(/sha256 "[0-9a-f]{64}"/, "sha256 \"#{sha}\"")
|
|
36
|
+
|
|
37
|
+
# Also update the pip install version pin if present:
|
|
38
|
+
formula_content.gsub!('package[extras]==#{version}', "package[extras]==#{version}")
|
|
39
|
+
formula_content.sub!(/(# system venv\.root\/"bin\/pip", "install", "package\[extras\]==)#{version}/, "\\1#{version}")
|
|
40
|
+
|
|
41
|
+
File.write(FORMULA_FILE, formula_content)
|
|
42
|
+
|
|
43
|
+
puts "Done. Formula updated to v#{version}."
|
|
44
|
+
puts "Review: git diff Formula/<formula>.rb"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Template 04: Python Virtualenv
|
|
2
|
+
|
|
3
|
+
## Pattern: `bendzgerona/homebrew-litellm`
|
|
4
|
+
|
|
5
|
+
A tap for Python CLI tools that install dependencies via `pip` inside a
|
|
6
|
+
Homebrew-managed virtualenv. Combines the lean script-driven release
|
|
7
|
+
pattern (template 03) with Python virtualenv formula conventions.
|
|
8
|
+
|
|
9
|
+
### Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
homebrew-<tap>/
|
|
13
|
+
├── Formula/
|
|
14
|
+
│ └── <formula>.rb # Formula with Language::Python::Virtualenv
|
|
15
|
+
├── scripts/
|
|
16
|
+
│ └── release.rb # Version bump script (SHA256 + version)
|
|
17
|
+
├── .gitignore
|
|
18
|
+
├── LICENSE
|
|
19
|
+
└── README.md
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Key Formula Patterns
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
include Language::Python::Virtualenv
|
|
26
|
+
|
|
27
|
+
depends_on "python@3.13" # Pin Python version
|
|
28
|
+
depends_on "openssl@3" # For C-extension wheel compilation
|
|
29
|
+
depends_on "pkgconf" => :build
|
|
30
|
+
|
|
31
|
+
def install
|
|
32
|
+
venv = virtualenv_create(libexec, "python3.13")
|
|
33
|
+
venv.pip_install buildpath
|
|
34
|
+
system venv.root/"bin/pip", "install", "<package>[extras]==#{version}"
|
|
35
|
+
%w[cli-name another-cli].each do |cmd|
|
|
36
|
+
(bin/cmd).write_env_script(venv.root/"bin/#{cmd}", PATH: "#{venv.root}/bin:#{ENV["PATH"]}")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### When to Use
|
|
42
|
+
|
|
43
|
+
- Your formula installs a Python CLI tool with pip dependencies
|
|
44
|
+
- You need to pin a specific Python version (brew's default may conflict)
|
|
45
|
+
- You have exact pin constraints that differ from brew's versions
|
|
46
|
+
|
|
47
|
+
### When NOT to Use
|
|
48
|
+
|
|
49
|
+
- Your formula is a pre-built binary (use template 03)
|
|
50
|
+
- You need CI/bottle workflows (use template 01)
|
|
51
|
+
|
|
52
|
+
### Reference
|
|
53
|
+
|
|
54
|
+
- `bendzgerona/homebrew-litellm` — reference implementation
|
|
55
|
+
- Homebrew docs: `Python-for-Formula-Authors.md`, `Formula-Cookbook.md`
|
|
56
|
+
- Use `depends_on "python@3.X"` to pin; brew's default changes over time
|
|
57
|
+
|
|
58
|
+
- Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: homebrew-tap-node-npm
|
|
3
|
+
description: Creates and maintains Homebrew taps for JavaScript/TypeScript CLI tools using npm or bun.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# homebrew-tap-node-npm
|
|
7
|
+
|
|
8
|
+
Agent for working with Node.js / npm / bun tap templates.
|
|
9
|
+
|
|
10
|
+
## Description
|
|
11
|
+
Helps create and maintain Homebrew taps for JavaScript/TypeScript CLI tools using either npm or bun as the package manager.
|
|
12
|
+
|
|
13
|
+
## Stacks
|
|
14
|
+
- homebrew
|
|
15
|
+
- nodejs
|
|
16
|
+
- bun
|
|
17
|
+
- javascript
|
|
18
|
+
- typescript
|
|
19
|
+
|
|
20
|
+
## Requires
|
|
21
|
+
- basic-homebrew-knowledge
|
|
22
|
+
|
|
23
|
+
## Key Actions
|
|
24
|
+
|
|
25
|
+
### npm Pattern
|
|
26
|
+
```ruby
|
|
27
|
+
depends_on "node"
|
|
28
|
+
def install
|
|
29
|
+
system "npm", "install", *std_npm_args
|
|
30
|
+
bin.install_symlink Dir["#{libexec}/bin/*"]
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### bun Pattern
|
|
35
|
+
```ruby
|
|
36
|
+
depends_on "bun"
|
|
37
|
+
def install
|
|
38
|
+
system "bun", "install", "--production"
|
|
39
|
+
bin.install_symlink Dir["#{libexec}/bin/*"]
|
|
40
|
+
end
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Compiled bun binary pattern
|
|
44
|
+
```ruby
|
|
45
|
+
depends_on "bun"
|
|
46
|
+
def install
|
|
47
|
+
system "bun", "install"
|
|
48
|
+
system "bun", "build", "--compile", "--outfile=#{bin}/<cli>", "./src/index.ts"
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Permissions
|
|
53
|
+
- Read/write to `Formula/` and `scripts/`
|
|
54
|
+
- Network access for npm/bun installs
|
|
55
|
+
- `depends_on "bun"` requires `oven-sh/homebrew-bun` to be tapped
|
|
56
|
+
|
|
57
|
+
### Common Pitfalls
|
|
58
|
+
|
|
59
|
+
- `depends_on "bun"` requires `brew tap oven-sh/bun` first — the bun formula is not in homebrew-core.
|
|
60
|
+
- Uncomment exactly ONE of the three install patterns in `_formula.rb`. Multiple `def install` blocks cause a Ruby syntax error.
|
|
61
|
+
- `std_npm_args` is required for npm-based installs — it sets `--prefix`, `--global`, `--no-save`. Raw `npm install` will not place binaries in the correct libexec path.
|
|
62
|
+
|
|
63
|
+
### LSP Validation
|
|
64
|
+
|
|
65
|
+
Before finishing any formula, validate with the Ruby LSP:
|
|
66
|
+
|
|
67
|
+
1. Ensure LSP is available:
|
|
68
|
+
```sh
|
|
69
|
+
ruby-lsp --version # Verify LSP is installed
|
|
70
|
+
```
|
|
71
|
+
2. Run syntax check:
|
|
72
|
+
```sh
|
|
73
|
+
ruby -c Formula/<formula>.rb
|
|
74
|
+
```
|
|
75
|
+
3. Run Homebrew linting:
|
|
76
|
+
```sh
|
|
77
|
+
brew style --tap <user>/<tapname> Formula/<formula>.rb
|
|
78
|
+
```
|
|
79
|
+
4. Run formula audit:
|
|
80
|
+
```sh
|
|
81
|
+
brew audit --new-formula Formula/<formula>.rb
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Do NOT mark work as complete until all diagnostics pass.
|
|
85
|
+
|
|
86
|
+
### Verification
|
|
87
|
+
```sh
|
|
88
|
+
ruby -c Formula/<formula>.rb
|
|
89
|
+
brew style --tap <user>/<tapname> Formula/<formula>.rb
|
|
90
|
+
```
|