Cavil-CLI

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        - Repurposed from a code-search / plagiarism client into a legal-review client. "check" now uploads the
          project's working tree to Cavil, waits for the standard legal review (unpack, index, analyze), and
          reports its licensing risk; the code-search "baseline" command, local fingerprinting and result cache
          are gone, along with their Cavil::Matcher, Mojo::SQLite, Text::Glob and Cpanel::JSON::XS dependencies.
        - The uploaded archive is the working tree as it sits on disk, including installed vendored dependencies
          (node_modules and the like) that .gitignore usually hides but a full legal review must cover; only .git
          and explicit excludes are dropped. Use --respect-gitignore for the leaner case, --exclude-path or a
          .cavilignore file to drop more.
        - The CI gate is the report's licensing risk: --fail-on-risk defaults to the instance's acceptable risk
          plus one, so a project the instance would accept passes without any per-project configuration. --sbom
          and --notice download the SPDX SBOM and NOTICE attribution file.

0.02   2026-08-31
        - Removed --token, and --url is now accepted only by "config". A token passed as an argument is
          world-readable in ps output and stays in shell history, and once the token can only come from the
          saved config or CAVIL_API_KEY, --url elsewhere would have aimed that token at a different server.
          Server and token are now resolved together from one source, never mixed, for the same reason.
        - New "baseline" command: record a tree's current matches as accepted in a committed
          .cavil-baseline.json, so later checks report only what is not in it. Most projects carry some copies
          they have already decided about, and repeating them every run is how the report stops being read.
          Entries are pinned to the file's content and to what it matched (so an edit brings the finding back),

README.md  view on Meta::CPAN

```
# Save the server and token once (prompts for the token without echoing it)
cavil-cli config --url https://legaldb.suse.de

# Confirm it works (and time the round trip)
cavil-cli whoami

# Upload the current directory for a legal review and print the verdict
cavil-cli check

# Check another directory, and also download the SBOM
cavil-cli check ./project --sbom
```

Credentials come from the saved config in `~/.config/cavil-cli`, or from `CAVIL_URL` and `CAVIL_API_KEY` in CI
- always as a pair, from one source. There is no `--token`, because an argument is world-readable in `ps` and
stays in your shell history, and no `--url` outside `config`, because pointing at another server would send it
a token saved for this one. `cavil-cli config --show` displays what is saved, with the token masked.

A check prints a headline tied to the CI gate, a one-line tally, then the licenses found, highest risk first:

README.md  view on Meta::CPAN

```sh
cavil-cli check              # the current directory
cavil-cli check ./project    # another directory
```

| Option | Description |
| --- | --- |
| `--name <name>` | Package name to review under (default: the directory name) |
| `--priority <n>` | Review priority 1-8 (default 5) |
| `--fail-on-risk <n>` | Exit non-zero at this risk or above (default: the instance's acceptable risk + 1) |
| `--sbom [<file>]` | Download the SPDX SBOM (default file: `<name>.spdx.json`) |
| `--notice [<file>]` | Download the NOTICE attribution file (default file: `<name>.NOTICE.txt`) |
| `--respect-gitignore` | Also drop `.gitignore`'d paths from the archive (off by default, to keep vendored code) |
| `--exclude-path <p>` | Drop this path from the archive (a `tar` pattern). Repeatable; also `CAVIL_EXCLUDE_PATHS` |
| `--external-link <s>` | Source label for traceability (default: the git remote and commit, if any) |
| `--timeout <n>` | Seconds to wait for the review before giving up (default 900) |
| `--format text\|json` | Output format; `json` for CI to police or store |
| `--no-color` | Never colour the output (also honours `NO_COLOR`) |
| `--quiet` | No progress output |
| `-h`, `--help` | Show usage |

docs/Architecture.md  view on Meta::CPAN

that cost; until it exists, `check` is for admins and for CI configured with an appropriately privileged key.
The client preflights with `whoami` so a key that cannot submit is reported clearly before a large tree is
packaged, rather than as an opaque rejection afterwards.

## The service contract

The CLI depends on a small, stable contract with the Cavil server, deliberately narrow so it can be reasoned
about and mocked. An identity endpoint backs `whoami`. An upload endpoint takes the archive and its checksum
and starts a review, returning the new package's id. A report endpoint returns the report for that id, or "not
ready" while it builds, with the risk and acceptable-risk fields the gate needs. A documents endpoint serves
the generated SPDX SBOM and NOTICE files, likewise "not ready" until generated. That is all; the CLI needs no
knowledge of Cavil's internals beyond these questions and their answers.

The upload also carries an `ephemeral` flag, asking for a one-off report with no lasting side effects, no open
review left in the legal backlog. That is what a developer or CI check always wants, so it is always sent. It
is the forward edge of the planned sandbox mode: today's servers do not act on it (which is why submission is
still gated to high access), but a server that gains the ad-hoc mode can honour it without any client change,
and the access gate can then relax for ephemeral requests.

## Testing

lib/Cavil/CLI.pm  view on Meta::CPAN


    # Save the URL and token once (prompts for the token without echoing it)
    cavil-cli config --url https://legaldb.suse.de

    # Confirm the URL and token are set up right (and time the round trip)
    cavil-cli whoami

    # Upload the current directory for a legal review and print the verdict
    cavil-cli check

    # Check another directory, and also download the SBOM
    cavil-cli check ./project --sbom

    # Machine-readable output for CI (URL and token from the environment)
    CAVIL_URL=https://legaldb.suse.de CAVIL_API_KEY=1234 cavil-cli check --format json

  Commands:
    check [DIR]              Upload a project for a legal review and report its licensing risk (default DIR: .)
    whoami                   Show the user the token belongs to, to verify login
    config                   Save the URL and token to ~/.config/cavil-cli (--show to display, token masked)

lib/Cavil/CLI.pm  view on Meta::CPAN

  (node_modules and the like) that a full legal review must cover; only .git and excludes are dropped. If the
  archive is over the server's upload limit (250 MiB by default, or CAVIL_MAX_UPLOAD_MB) the check refuses
  before uploading and tells you to trim it, so an accidental large file does not start a doomed upload.

  Options:
        --url <url>          Cavil server URL, when saving settings ("config" only)
        --name <name>        Package name to review under (default: the directory name)
        --priority <n>       Review priority 1-8 (default 5)
        --fail-on-risk <n>   Exit non-zero at this risk or above (default: the instance's acceptable risk + 1)
        --external-link <s>  Source label for traceability (default: the git remote and commit, if any)
        --sbom [<file>]      Download the SPDX SBOM (default file: <name>.spdx.json)
        --notice [<file>]    Download the NOTICE attribution file (default file: <name>.NOTICE.txt)
        --respect-gitignore  Also drop .gitignore'd paths from the archive (off by default, to keep vendored code)
        --exclude-path <p>   Drop this path from the archive (a tar pattern). Repeatable; also CAVIL_EXCLUDE_PATHS
        --timeout <n>        Seconds to wait for the review before giving up (default 900)
        --format <format>    Output format, "text" (default) or "json"
        --no-color           Disable coloured output
        --quiet              Do not show the progress line while working
    -h, --help               Show this summary of available options

=head1 DESCRIPTION

lib/Cavil/CLI/Util.pm  view on Meta::CPAN


  if (@licenses) {
    $out .= "\n";
    for my $l (@licenses) {
      my $g = _paint($color, _color($l->{risk}, $threshold), _glyph($l->{risk}, $threshold));
      $out .= sprintf "  %s  %-30s risk %d (%s)\n", $g, $l->{name}, $l->{risk}, _label($l->{risk});
    }
  }

  $out .= "\n  Report: $info->{report_url}\n" if $info->{report_url};
  $out .= "  SBOM:   $info->{sbom}\n"         if $info->{sbom};
  $out .= "  NOTICE: $info->{notice}\n"       if $info->{notice};

  return $out;
}

1;

t/scenario_sbom.t  view on Meta::CPAN


my $proj = tempdir;
$proj->child('file.c')->spew("int x;\n");
my $dest = tempdir;
my $sbom = $dest->child('out.spdx.json')->to_string;
my $test = CavilCliTest->new(app);

subtest '--sbom downloads the SPDX document, polling while it builds' => sub {
  my $result = $test->run('--name', 'proj', '--sbom', $sbom, $proj->to_string);
  is $result->{exit}, 0, 'a clean check still exits clean';
  ok -f $sbom, 'the SBOM was written';
  like path($sbom)->slurp, qr/spdx\.org/,        'and holds the SPDX content';
  like $result->{stdout},  qr/SBOM:.*out\.spdx/, 'the output names the file';
};

done_testing;



( run in 1.034 second using v1.01-cache-2.11-cpan-364913b4093 )