Skip to content

Commit 8a2b8db

Browse files
aRustyDevclaude
andcommitted
docs(skills): add language-specific research guides and reference docs
Go, Rust, and Python lang docs with research tables, quick-check commands, install patterns, schema fields, and common issues. Includes checklists, FAQ, testing patterns, and Brewfile. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 22ff9f3 commit 8a2b8db

9 files changed

Lines changed: 367 additions & 0 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# bash
2+
# jq
3+
# yq
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## Local Validation
2+
3+
### Step 1: Sync to Tap Location
4+
5+
Formula files must be in the Homebrew tap location for testing:
6+
7+
```bash
8+
mkdir -p /opt/homebrew/Library/Taps/arustydev/homebrew-tap/Formula/<letter>/
9+
cp Formula/<letter>/<name>.rb /opt/homebrew/Library/Taps/arustydev/homebrew-tap/Formula/<letter>/
10+
```
11+
12+
**Note:** On Apple Silicon Macs the prefix is `/opt/homebrew`, on Intel Macs it's `/usr/local`. Check with `brew --prefix`.
13+
14+
### Step 2: Run Audit
15+
16+
```bash
17+
brew audit --new --formula arustydev/tap/<name>
18+
```
19+
20+
This checks for common formula issues but NOT style violations.
21+
22+
### Step 3: Run CI Syntax Check (Critical)
23+
24+
```bash
25+
brew style arustydev/tap
26+
```
27+
28+
This runs rubocop against ALL files in the tap — same as CI. This catches issues that `brew audit` misses.
29+
30+
### Step 4: Test Installation
31+
32+
```bash
33+
brew install --build-from-source arustydev/tap/<name>
34+
# For HEAD-only:
35+
brew install --HEAD arustydev/tap/<name>
36+
```
37+
38+
### Step 5: Run Formula Tests
39+
40+
```bash
41+
brew test arustydev/tap/<name>
42+
```
43+
44+
### Step 6: Verify Binary
45+
46+
```bash
47+
<name> --help
48+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Common Issues
2+
3+
### CI Failures from Rubocop
4+
5+
**Problem:** `brew style` fails on markdown files containing Ruby code blocks.
6+
7+
**Cause:** `brew style` uses rubocop-md which lints code fenced as `ruby` in markdown files. The tap's `.rubocop.yml` exclusions do NOT apply — `brew style` uses Homebrew's central config.
8+
9+
**Solution:** Use `text` instead of `ruby` for code fence language in any markdown documentation.
10+
11+
### Line Length Errors
12+
13+
**Problem:** Lines longer than 118 characters.
14+
15+
**Solution:** Split long strings or use Homebrew's allowed patterns (URLs, sha256 lines, etc. are exempt).
16+
17+
### Test Block Failures
18+
19+
**Problem:** Formula installs but `brew test` fails.
20+
21+
**Solution:** Check if the binary exits non-zero on `--help` and use `shell_output("...", exit_code)`. Ensure test creates necessary files and uses `testpath`.
22+
23+
### Typed/Frozen String Headers
24+
25+
The `# typed: strict` and `# frozen_string_literal: true` headers are **optional** for tap formulas. They are not enforced by `brew style` and many tap formulas omit them. Include them for consistency if the tap already uses them, otherwise omit.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## Go Formula Patterns
2+
3+
### Researching a Go Project
4+
5+
| What | Where to Look | Command / File |
6+
|------|---------------|----------------|
7+
| Build system confirmation | Repo root | Look for `go.mod` — confirms it's a Go module |
8+
| Binary name(s) | `cmd/` directory or repo root | `ls cmd/` — each subdirectory is typically a binary |
9+
| Main package location | `cmd/<name>/main.go` or `main.go` at root | If root: no path arg needed; if `cmd/`: use `"./cmd/<name>"` |
10+
| Version injection | `main.go` or `internal/version` | `grep -r 'version' main.go` — look for `var version` to set via `-X` ldflags |
11+
| CGO usage | Source files | `grep -r 'import "C"'` or `grep -r '#cgo'` — if found, need system library deps |
12+
| Build tags | Source files, CI config | `grep -r '//go:build'` or check CI for `-tags` flags |
13+
| Runtime dependencies | Import statements, docs | `grep -r 'os/exec'` for external tool calls; check README for runtime requirements |
14+
| Completions | CLI framework used | If using cobra: look for `GenBashCompletion`; if using urfave/cli: check for `EnableBashCompletion` |
15+
| Test command | README, `--help` output | Most Go CLIs support `--help` or `--version`; check if exit code is 0 |
16+
17+
**Quick check sequence:**
18+
19+
```bash
20+
# Confirm Go project and find binaries
21+
gh api repos/OWNER/REPO/contents/go.mod --jq '.name' 2>/dev/null && echo "Go project"
22+
gh api repos/OWNER/REPO/contents/cmd --jq '.[].name' 2>/dev/null || echo "main.go at root"
23+
24+
# Check for version variable
25+
gh api repos/OWNER/REPO/contents/main.go --jq '.content' | base64 -d | grep -i 'version'
26+
```
27+
28+
### Dependencies
29+
30+
```text
31+
depends_on "go" => :build
32+
```
33+
34+
### Install Block
35+
36+
```text
37+
def install
38+
system "go", "build", *std_go_args(ldflags: "-s -w -X main.version=#{version}"), "./cmd/binary"
39+
end
40+
```
41+
42+
- If `main.go` is at repo root: omit the path argument
43+
- If `main.go` is at `./cmd/<name>/`: include `"./cmd/<name>"`
44+
- `-s -w` strips debug info for smaller binary
45+
- `-X main.version=#{version}` injects version at build time
46+
47+
### JSON Schema Fields (`install-go`)
48+
49+
| Field | Default | Purpose |
50+
|-------|---------|---------|
51+
| `ldflags` | `"-s -w -X main.version=#{version}"` | Linker flags |
52+
| `cmd_path` | `"./cmd/..."` | Go package path to build |
53+
| `output` | formula name | Output binary name |
54+
| `tags` || Go build tags (e.g. `["netgo", "osusergo"]`) |
55+
| `env` || Environment variables (e.g. `{"CGO_ENABLED": "0"}`) |
56+
57+
### Mustache Partial
58+
59+
The `langs/go.mustache` partial renders `std_go_args(ldflags:)` with optional `cmd_path`.
60+
61+
### Common Issues
62+
63+
- **Binary name differs from formula name:** Check for `cmd/` subdirectories — the directory name is usually the binary name
64+
- **CGO dependencies:** If the project uses CGO, add system library deps and ensure `CGO_ENABLED` is not set to `0`
65+
- **Multiple binaries:** Use `cmd_path: "./cmd/..."` to build all, or specify individual paths
66+
67+
### Reference
68+
69+
See `reference/templates/formulas/go.rb` for a pipeline-generated example.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
## Python Formula Patterns
2+
3+
### Researching a Python Project
4+
5+
| What | Where to Look | Command / File |
6+
|------|---------------|----------------|
7+
| Build system | Repo root | `pyproject.toml` (modern), `setup.py`/`setup.cfg` (legacy) |
8+
| Binary name(s) | `pyproject.toml` `[project.scripts]` or `setup.py` `entry_points` | The key is the binary name, the value is the module path |
9+
| Python version | `pyproject.toml` `requires-python` | Map to Homebrew's `python@3.XX` — use latest compatible |
10+
| Direct dependencies | `pyproject.toml` `[project.dependencies]` or `requirements.txt` | Each becomes a `resource` block unless already in homebrew-core |
11+
| Resource URLs | PyPI | `https://pypi.org/project/<pkg>/#files` — use the `.tar.gz` sdist, not wheel |
12+
| Completions | CLI framework | If using `click`: look for `shell_complete`; if using `argparse`: check for custom completion |
13+
| Native extensions | `setup.py` or `pyproject.toml` build-backend | If using `setuptools` with C extensions: needs compiler deps |
14+
| Test command | README, `--help` output | Check if tool supports `--version` or `--help` |
15+
16+
**Quick check sequence:**
17+
18+
```bash
19+
# Confirm Python project, find entry points
20+
gh api repos/OWNER/REPO/contents/pyproject.toml --jq '.content' | base64 -d | grep -A10 '\[project.scripts\]'
21+
22+
# Find Python version requirement
23+
gh api repos/OWNER/REPO/contents/pyproject.toml --jq '.content' | base64 -d | grep 'requires-python'
24+
25+
# List dependencies
26+
gh api repos/OWNER/REPO/contents/pyproject.toml --jq '.content' | base64 -d | grep -A30 '\[project\]' | grep -A20 'dependencies'
27+
```
28+
29+
**Generating resource blocks:** After initial formula creation, use `brew update-python-resources <formula>` to auto-generate resource blocks from PyPI.
30+
31+
### Dependencies
32+
33+
```text
34+
depends_on "python@3.12"
35+
```
36+
37+
### Install Block
38+
39+
```text
40+
include Language::Python::Virtualenv
41+
42+
def install
43+
virtualenv_install_with_resources
44+
end
45+
```
46+
47+
- `virtualenv_install_with_resources` creates a venv, installs resource blocks, then installs the formula
48+
- Check `pyproject.toml`, `setup.py`, or `setup.cfg` for the project's build system
49+
50+
### JSON Schema Fields (`install-python`)
51+
52+
| Field | Default | Purpose |
53+
|-------|---------|---------|
54+
| `python_version` | `"python3"` | Python version dependency |
55+
| `using` | `"virtualenv"` | Install method (`virtualenv`, `pip`, `setuptools`) |
56+
| `site_packages` | `false` | Allow access to system site-packages |
57+
| `resources` || Python package dependencies (defined at formula level) |
58+
59+
### Mustache Partial
60+
61+
The `langs/python.mustache` partial renders `virtualenv_install_with_resources`.
62+
63+
### Resource Blocks
64+
65+
Python formulas need `resource` blocks for pip dependencies not in homebrew-core:
66+
67+
```text
68+
resource "certifi" do
69+
url "https://files.pythonhosted.org/packages/certifi-2024.2.2.tar.gz"
70+
sha256 "..."
71+
end
72+
```
73+
74+
Generate resource blocks with:
75+
76+
```bash
77+
brew update-python-resources <formula-name>
78+
```
79+
80+
### Entry Points
81+
82+
Check `pyproject.toml` `[project.scripts]` for the binary names the formula will install:
83+
84+
```toml
85+
[project.scripts]
86+
my-tool = "my_package.cli:main"
87+
```
88+
89+
### Common Issues
90+
91+
- **Missing resources:** Python dependencies must be declared as `resource` blocks — they're not auto-resolved
92+
- **Version pinning:** Use the exact source tarball versions that match the project's requirements
93+
- **Site packages:** Set `site_packages: true` only when the formula needs access to Homebrew-installed Python packages
94+
95+
### Reference
96+
97+
See `reference/templates/formulas/python.rb` for a pipeline-generated example.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
## Rust Formula Patterns
2+
3+
### Researching a Rust Project
4+
5+
| What | Where to Look | Command / File |
6+
|------|---------------|----------------|
7+
| Build system confirmation | Repo root | Look for `Cargo.toml` — confirms it's a Rust/Cargo project |
8+
| Binary name(s) | `Cargo.toml` `[[bin]]` section | May differ from repo name (e.g. `jwt-ui` installs `jui`) |
9+
| Workspace layout | `Cargo.toml` `[workspace]` | If workspace: find the CLI crate in `members` list, use its path |
10+
| Features | `Cargo.toml` `[features]` | Check for `default`, optional features like `tls`, `jemalloc` |
11+
| System dependencies | `build.rs`, CI config | `grep -r 'pkg-config\|system-deps\|cc::Build'` — indicates C library deps |
12+
| OpenSSL / TLS usage | `Cargo.toml` deps | `grep -i 'openssl\|native-tls\|rustls'` — may need `openssl@3` dep |
13+
| uses_from_macos | Linked system libs | If uses `zlib`, `libxml2`, `curl` etc. via `-sys` crates |
14+
| Completions | CLI framework | If using `clap`: look for `clap_complete` in deps; check for `completions` subcommand |
15+
| Minimum Rust version | `Cargo.toml` `rust-version` or `rust-toolchain.toml` | Homebrew provides latest stable — flag if MSRV is unusual |
16+
| Test command | README, `--help` output | Most Rust CLIs support `--help` or `--version` |
17+
18+
**Quick check sequence:**
19+
20+
```bash
21+
# Confirm Rust project, find binary names and features
22+
gh api repos/OWNER/REPO/contents/Cargo.toml --jq '.content' | base64 -d | grep -A5 '\[\[bin\]\]'
23+
gh api repos/OWNER/REPO/contents/Cargo.toml --jq '.content' | base64 -d | grep -A20 '\[features\]'
24+
25+
# Check for system deps
26+
gh api repos/OWNER/REPO/contents/build.rs --jq '.name' 2>/dev/null && echo "Has build.rs — check for C deps"
27+
```
28+
29+
### Dependencies
30+
31+
```text
32+
depends_on "rust" => :build
33+
```
34+
35+
### Install Block
36+
37+
```text
38+
def install
39+
system "cargo", "install", *std_cargo_args
40+
end
41+
```
42+
43+
- `std_cargo_args` handles `--root`, `--path`, and `--locked`
44+
- Check `Cargo.toml` `[[bin]]` — binary name may differ from formula name (e.g. `jwt-ui` installs `jui`)
45+
46+
### JSON Schema Fields (`install-rust`)
47+
48+
| Field | Default | Purpose |
49+
|-------|---------|---------|
50+
| `path` | `"."` | Path to Cargo.toml directory |
51+
| `features` || Cargo features to enable |
52+
| `all_features` | `false` | Enable all Cargo features |
53+
| `no_default_features` | `false` | Disable default features |
54+
| `bins` || Specific binaries to install |
55+
56+
### Mustache Partial
57+
58+
The `langs/rust.mustache` partial renders `std_cargo_args` with optional `path` and `features`.
59+
60+
### Feature Selection
61+
62+
When a crate has optional features:
63+
64+
```text
65+
system "cargo", "install", *std_cargo_args, "--features", "tls,jemalloc"
66+
```
67+
68+
### Monorepo / Workspace Builds
69+
70+
When building from a subdirectory of a workspace:
71+
72+
```text
73+
def install
74+
cd "crates/cli" do
75+
system "cargo", "install", *std_cargo_args
76+
end
77+
end
78+
```
79+
80+
### Common Issues
81+
82+
- **Lock file version mismatch:** Ensure the Rust toolchain version matches the project's `Cargo.lock`
83+
- **Vendored dependencies:** Some projects vendor C libraries — check for `build.rs` and add system deps
84+
- **uses_from_macos:** Rust projects using `openssl` often need `uses_from_macos "zlib"`
85+
86+
### Reference
87+
88+
See `reference/templates/formulas/rust.rb` for a pipeline-generated example.

context/skills/pkgmgr-homebrew-formula-dev/reference/templates/ISSUE_TEMPLATE.md

Whitespace-only changes.

context/skills/pkgmgr-homebrew-formula-dev/reference/templates/PULL_REQUEST_TEMPLATE.md

Whitespace-only changes.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Test Block Patterns
2+
3+
### Simple help check
4+
5+
```text
6+
test do
7+
assert_match "tool-name", shell_output("#{bin}/tool --help")
8+
end
9+
```
10+
11+
### Non-zero exit on help
12+
13+
Some tools exit non-zero when showing help. Pass the expected exit code:
14+
15+
```text
16+
test do
17+
assert_match "tool-name", shell_output("#{bin}/tool --help", 2)
18+
end
19+
```
20+
21+
### Version check
22+
23+
```text
24+
test do
25+
assert_match version.to_s, shell_output("#{bin}/tool --version")
26+
end
27+
```
28+
29+
### Functional test with file I/O
30+
31+
```text
32+
test do
33+
(testpath/"input.txt").write("test content")
34+
output = shell_output("#{bin}/tool #{testpath}/input.txt")
35+
assert_equal "expected", output.strip
36+
end
37+
```

0 commit comments

Comments
 (0)