Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions COMPARISON.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ Repolicense CLI originated as a terminal port of the [repolicense web applicatio

| Area | Original web application | Current CLI |
| --- | --- | --- |
| Interaction | Browser yes/no controls | Terminal answers, `back`, `reset`, and `quit` |
| Interaction | Browser yes/no controls | Optional Gum menus or standalone numbered/label prompts; back/restart/quit |
| State | Browser session storage | In-memory session history |
| License details | GitHub API integration | Local explanations and SPDX license-text links; no network calls |
| Implementation | JavaScript, HTML/CSS, Shoelace | Zig 0.17.0 and the standard library |
| Tree representation | JavaScript objects | Static typed nodes with canonical license metadata |
| Implementation | JavaScript, HTML/CSS, Shoelace | Zig 0.17.0 and standard library; optional external Gum executable |
| Tree representation | JavaScript objects | Static typed menu graph with canonical license metadata |
| Compatibility | Not part of the original port's web interface | `--compat` / `-c`, all-input target assessment and conditional prerequisites |
| Distribution | Browser application | Native executable; Linux, macOS, and Windows CI |

## Intentional decision-tree changes

The [current tree](./TREE_STRUCTURE.md) separates fonts from software immediately, checks software licensing rights, and distinguishes concrete patent/notice obligations before recommending a permissive license. Copyleft paths distinguish combined programs, library boundaries, files, and modified network services instead of ranking licenses by vague strength or business friendliness.
The [current graph](./TREE_STRUCTURE.md) separates software, fonts, and unsupported assets; checks authority independently; and handles existing project constraints before new-work preferences. The common MIT/Apache path takes six selections rather than a sequence of specialist yes/no questions. Advanced permissive choices retain the BSD/ISC/0BSD/Boost/Zlib/Unlicense distinctions.

GNU recommendations explicitly choose `-only` or `-or-later`; older GPL, LGPL, and EPL versions require an existing-project reason. Boost and Zlib add meaningful binary-notice/origin distinctions. Every real recommendation carries obligations and an SPDX link, while preferences outside the supported model produce guidance without a fake license link.
Copyleft choices distinguish combined programs, library boundaries, and files. AGPL's network source offer is an explicit goal, not a consequence of merely running a server. GNU grants explicitly choose `-only` or `-or-later`; legacy versions require a specific authorized reason. Fonts require accepting OFL-specific conditions. Every recommendation carries a rationale, obligations, and an SPDX link; unsupported goals produce typed guidance without a fake license link.

Both CLI modes use `src/licenses.zig`. Compatibility results preserve original component obligations and distinguish conditional library/file/font/module combinations from unconditional permission to relicense. The supported catalog and limitations are documented in the [README](./README.md).

Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ git switch -c fix/describe-your-change
zig build
```

The project uses only the Zig standard library. There are no additional packages to install.
The build uses only the Zig standard library. [Gum](https://github.com/charmbracelet/gum) is an optional runtime executable for terminal menus, never a required package or automatic download. Use `--plain` to exercise the standalone interface.

## Run the CLI

Expand All @@ -41,7 +41,7 @@ zig fmt --check src/

To format changed Zig files, use `zig fmt path/to/file.zig`.

Also exercise the affected CLI mode. For navigation, try `yes`, `no`, `back`, `reset`, and `quit`, including at a recommendation. For compatibility, check `GPL-2.0-only, Apache-2.0` (no combined-work target), `GPL-2.0-or-later, Apache-2.0` (GPL version 3 available), and `MIT, OFL-1.1` (conditional separate font assets). Reverse the input order and check that candidate statuses remain unchanged. See the [test plan](./TEST_PLAN.md) for additional boundaries.
Also exercise the affected CLI mode. For navigation, try numeric and label choices, `back`, `reset`, and `quit`, including at a recommendation and an advisory. Check a real Gum terminal session, cancellation, and a terminal without Gum; redirected output must contain no ANSI controls. For compatibility, check `GPL-2.0-only, Apache-2.0` (no combined-work target), `GPL-2.0-or-later, Apache-2.0` (GPL version 3 available), and `MIT, OFL-1.1` (conditional separate font assets). Reverse inputs and check statuses remain unchanged. See the [test plan](./TEST_PLAN.md).

CI builds and tests pull requests on Linux, macOS, and Windows. Formatting is checked separately on Linux.

Expand All @@ -52,19 +52,19 @@ CI installs the compiler through `.github/actions/setup-zig/action.yml`, verifie
| File | Responsibility |
| --- | --- |
| `src/main.zig` | Process setup, input handling, and the two CLI modes |
| `src/tree.zig` | License-selection decision tree |
| `src/tree.zig` | Static intent-based menu graph and typed recommendation/advisory outcomes |
| `src/licenses.zig` | Shared canonical SPDX identifiers, categories, obligations, and license-text URLs |
| `src/compatibility.zig` | Directed combined-work assessments, conditional prerequisites, and common-target checks |
| `src/ui.zig` | ANSI terminal-screen rendering |
| `src/*_test.zig` | Decision-tree, compatibility, and rendering tests |
| `src/ui.zig` | Optional Gum subprocess menus, plain prompts, and selection parsing |
| `src/*_test.zig` | Licensing graph, compatibility, and input-boundary tests |
| `build.zig` | Build, run, and test steps |

Keep changes focused, follow existing Zig conventions, and let `zig fmt` handle indentation. Comments should explain non-obvious decisions rather than repeat the code.

## Adding or correcting licenses

1. Add a canonical SPDX tag and its category/obligations in `src/licenses.zig`. Parsing, display, SPDX links, and the CLI's supported list derive from this shared catalog; do not duplicate them.
2. Add a concrete obligation-driven path in `src/tree.zig`. Actual recommendations use typed `Node.license` metadata; advisory results leave it null. Explain distribution/network triggers, version permission, and any legacy-project requirement rather than ranking licenses as "simplest" or "business-friendly."
2. Add an intent- and obligation-driven path in `src/tree.zig`. `node(Id)` returns static choices with explicit destinations. Recommendations use typed `Node.license`; advisory outcomes use `Node.advisory`. Keep the common path short, preserve existing-license constraints, explain GNU grant permissions, and avoid ranking licenses as "simplest" or "business-friendly."
3. Update directed `assess()` rules in `src/compatibility.zig`. Distinguish ordinary compliance, specific conditional prerequisites, and actual combined-work conflicts. The target must satisfy **all** input licenses; original components keep their obligations. A symmetric pair result is a common-target search, not a directional relicensing verdict.
4. Add behavioral regressions in `src/tree_test.zig` / `src/compatibility_test.zig`: preference-to-license paths, permission/version boundaries, conditional combinations, and input-order independence. Avoid wording assertions, copied-metadata tests, or enum-membership checks without consumer behavior.
5. Update the [README](./README.md), [tree guide](./TREE_STRUCTURE.md), and [test plan](./TEST_PLAN.md) when affected. Include authoritative license sections in the pull request; exceptions, secondary-license notices, file/library boundaries, and GNU `-only` / `-or-later` permissions cannot be inferred from a short license name alone.
Expand Down
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@

A terminal companion to [repolicense](https://github.com/lucasfth/repolicense), built with Zig and its standard library. Answer a series of questions to explore licenses for your project, or enter existing licenses to check the compatibility rules for combining code.

- **License selection** — separate font/software paths, concrete obligations, and explained recommendations.
- **Navigation** — go back to an earlier question or reset the session.
- **License selection** — intent-based software/font menus, ownership checks, and explained recommendations.
- **Navigation** — go back to an earlier question or restart the session.
- **Compatibility checks** — supported and conditional combined-work targets, with explicit GNU versions.
- **Local operation** — no account, service, or runtime dependency; the CLI provides links rather than making API calls.
- **Local operation** — no account, service, or required runtime dependency. Optional [Gum](https://github.com/charmbracelet/gum) adds terminal menus; the CLI never downloads it or makes API calls.

> This tool offers general guidance, not legal advice. Review the actual license terms and your project's obligations before choosing a license or combining code.

Expand Down Expand Up @@ -86,20 +86,36 @@ Ensure `$HOME/.local/bin` is on your shell's `PATH`. Repeat the build command af

### Choose a license

Start without arguments. Fonts are routed first; software questions then cover licensing rights, patent grants, notices, and the scope of copyleft. Older GNU/EPL versions are offered for existing-project requirements, not as arbitrary fallbacks. Every recommendation includes its obligations and a link to the SPDX license text.
Start without arguments to open a menu: **Choose a license**, **Check compatibility**, or **Quit**. Select Choose a license, then software, font, or another asset, confirm licensing authority, and establish whether existing project terms constrain the choice. Existing/forked/community projects receive guidance to preserve their grants rather than a fresh license recommendation. Other assets get an explicit out-of-scope result.

You can revisit answers at any point, including after reaching a recommendation. A preference outside the supported choices produces guidance rather than a misleading license recommendation.
For new software, select broad open-source permissions and then permissive or copyleft goals. The common MIT/Apache path takes six selections. Specialist permissive licenses remain under advanced choices. Copyleft offers file, library, whole-program, and Eclipse-specific choices; only whole-program sharing asks about the additional AGPL network source offer. GNU version grants are explicit. Fonts require accepting OFL's same-license, notice, naming, and standalone-sale conditions.

| Input | Action |
Every recommendation explains why it fits, its obligations and limitations, and links to the SPDX text. Back/restart remain available at recommendations and advisory outcomes.

### Optional terminal menus

Install Gum separately if desired, for example `brew install gum` on macOS or `winget install charmbracelet.gum` on Windows. See [Gum installation](https://github.com/charmbracelet/gum#installation) for other platforms. It is not a build requirement.

When `gum` is on `PATH`, all three standard streams are terminals, and `TERM` is not `dumb`, the CLI uses a styled header, rounded question/guidance/result panels, and highlighted arrow-key menus. Enter confirms a choice. Compatibility mode uses a styled introduction/results heading and searchable multi-select picker: type to search, Tab toggles and advances, Enter checks the selection, and Ctrl-C cancels. Gum renders its own menus; Repolicense replaces the viewport between questionnaire steps rather than guessing frame line counts. Styling and terminal behavior were exercised with Gum 2.0.2.

Use `repolicense --plain` or `repolicense --compat --plain` to force plain mode. Missing Gum falls back automatically; redirected streams always use plain output without ANSI escapes. Gum's own exit status 1 can mean either cancellation or a runtime error: its diagnostics remain visible and no recommendation is inferred from that exit.

Interactive questionnaire navigation replaces the previous view, including in numbered mode without Gum. Back and Restart clear the old question rather than adding another copy below it. Redirected streams and `TERM=dumb` retain a readable transcript instead. In Gum menus, Back is an explicit action; Esc/Ctrl-C cancels the session rather than selecting Back.

| Plain input | Action |
| --- | --- |
| `yes` or `y` | Answer yes |
| `no` or `n` | Answer no |
| Number or displayed label | Select an option |
| `y` / `n` | Select a literal Yes / No option, where offered |
| `back` or `b` | Return to the previous question |
| `reset` or `r` | Start again |
| `reset`, `restart`, or `r` | Start again |
| `quit`, `q`, or `exit` | End the session |

`--help` / `-h` shows usage. Unknown arguments exit with status 2.

### Check compatibility

Choose **Check compatibility** from the start menu, or use `--compat` / `-c` to skip it. Gum results open a compact overview: selected identifiers, whether supported common targets exist, and ordinary/conditional target counts. Ordinary targets still require standard license compliance; conditional targets have additional prerequisites. **View targets and conditions** opens the full scrollable assessment, including pairwise checks; `q` returns to the overview. **Check another combination** reopens selection; **Quit** exits. Plain mode prints the full assessment directly.

```sh
zig build run -- --compat
```
Expand Down Expand Up @@ -152,7 +168,7 @@ zig build test
zig fmt --check src/
```

The tests cover every recommendation/advisory path, graph navigation invariants, canonical license parsing, version/obligation boundaries, order-independent compatibility, and terminal-screen rendering. Exercise the actual CLI as described in the [test plan](./TEST_PLAN.md), not just the unit suite. [CI](https://github.com/lucasfth/repolicense-cli/actions/workflows/ci.yml) builds and tests on Linux, macOS, and Windows using Zig 0.17.0, with a separate formatting check.
The tests cover recommendation reachability, scope and authority boundaries, explicit version grants, canonical license parsing, order-independent compatibility, and menu input boundaries. Exercise the actual CLI with and without Gum as described in the [test plan](./TEST_PLAN.md), not just the unit suite. [CI](https://github.com/lucasfth/repolicense-cli/actions/workflows/ci.yml) builds and tests on Linux, macOS, and Windows using Zig 0.17.0, with a separate formatting check.

For the decision-tree layout and project background, see [Tree structure](./TREE_STRUCTURE.md) and [Web/CLI comparison](./COMPARISON.md).

Expand Down
Loading
Loading