Cavil-CLI

 view release on metacpan or  search on metacpan

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

}

# Download a generated document to a file, polling while the server builds it. Returns the path written.
sub _save_document ($client, $id, $key, $requested, $default, $timeout) {
  my $file     = length($requested // '') ? $requested : $default;
  my $deadline = Time::HiRes::time + $timeout;
  while (1) {
    my $body = $client->document($id, $key);
    if (defined $body) { path($file)->spew($body); return $file }
    last if Time::HiRes::time >= $deadline;
    Time::HiRes::sleep(1);
  }
  print STDERR "Timed out waiting for the $key document\n";
  return undef;
}

# A package name Cavil accepts (^[A-Za-z0-9.-]+$), derived from the directory being checked.
sub _package_name ($dir) {
  my $base = path($dir)->to_abs->basename;
  $base =~ s/[^A-Za-z0-9.\-]+/-/g;
  $base =~ s/^-+|-+$//g;
  return length $base ? $base : 'project';
}

# Best-effort provenance for the review: the git remote and short commit, when the tree is a checkout.
sub _external_link ($dir) {
  my $rev = _git($dir, 'rev-parse', '--short', 'HEAD') // return undef;
  my $url = _git($dir, 'config',    '--get',   'remote.origin.url');
  return defined $url ? "$url\@$rev" : $rev;
}

sub _git ($dir, @args) {
  my $cmd = join ' ', 'git', '-C', quotemeta($dir), map { quotemeta $_ } @args;
  my $out = `$cmd 2>/dev/null`;
  return undef if !defined $out || $? != 0;
  chomp $out;
  return length $out ? $out : undef;
}

1;

=encoding utf8

=head1 NAME

Cavil::CLI - Submit a project to Cavil for a legal review and gate CI on the result

=head1 SYNOPSIS

  Usage: cavil-cli <command> [DIR] [OPTIONS]

    # 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)

  Credentials come from the saved config ("cavil-cli config"), or CAVIL_URL/CAVIL_API_KEY in CI, always as a
  pair from one source. There is no --token (an argument is world-readable in ps and stays in shell history),
  and --url is only accepted by "config", since aiming elsewhere would send it a token saved for this server.

  The uploaded archive is the working tree as it sits on disk, including installed vendored dependencies
  (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

A command-line client that uploads the project you are working on to a Cavil instance, runs its standard legal
review, and reports the licensing risk, for a developer's laptop or a CI gate. See C<docs/Architecture.md> for
the design.

=cut



( run in 2.059 seconds using v1.01-cache-2.11-cpan-364913b4093 )