licenses 0.6.1

Cargo subcommand for collecting licenses.
# licenses

[![crates.io](https://img.shields.io/crates/v/licenses)](https://crates.io/crates/licenses)
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/lhalf/licenses/on_commit.yml)](https://github.com/lhalf/licenses/actions/workflows/on_commit.yml)
[![MIT](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)

Cargo subcommand for collecting licenses.

## Install

```bash
$ cargo install licenses
```

## Usage

```bash
$ cargo licenses --help
```

<!-- `$ cargo run -q -- licenses --help` -->
```
Usage: cargo licenses <COMMAND> [OPTIONS]

Commands:
  collect  Collects all licenses into a folder
  summary  Provides a summary of all licenses
  check    Checks all licenses for inconsistencies
  diff     Diff between the current licenses folder and the licenses that would be collected

Options:
  -d, --dev                  Include dev dependencies [default: excluded]
  -b, --build                Include build dependencies [default: excluded]
  -D, --depth <DEPTH>        The depth of dependencies to include [default: all sub dependencies]
      --all-features         Activate all features [default: default features]
      --no-default-features  Do not activate default features [default: default features]
  -F, --feature <FEATURE>    Enable specified feature [default: default features]
  -e, --exclude <WORKSPACE>  Exclude specified workspace [default: all included]
  -i, --ignore <CRATE>       Ignore specified crate [default: all included]
  -c, --config <PATH>        Path to configuration file
  -h, --help                 Print help
```

## Commands

### Collect

Collects all licenses into a folder.

The output folder path can be specified with `--path`, defaults to `licenses`.

Prints a warning:

- If the crate had no declared license on crates.io (none declared)
- If no licenses were found for a crate (empty)
- If there were fewer licenses found for a crate than declared by the author on crates.io (too few)
- If there were more licenses found for a crate than declared by the author on crates.io (additional)
- If the content of the found licenses did not match the expected content for those licenses (mismatch)

```bash
$ cargo licenses collect --depth 1
```

### Summary

Summarises the declared licenses.

The declared license is what the author declares the license as on crates.io, it is not necessarily the same
as the actual licenses. The warnings generated by the `collect` and `check` commands will highlight discrepancies
between the
declared licenses and the actual licenses.

The summary can be formatted as JSON or TOML with `--json` or `--toml` respectively.

```bash
$ cargo licenses summary --depth 1
```

<!-- `$ cargo run -q -- licenses summary --depth 1` -->
```
Apache-2.0 - spdx
MIT - cargo_metadata,indicatif,strsim
MIT OR Apache-2.0 - anyhow,clap,itertools,serde,serde_json,toml
MPL-2.0 - colored
```

### Check

Checks all licenses for inconsistencies.

Returns a non-zero exit code:

- If the crate had no declared license on crates.io (none declared)
- If no licenses were found for a crate (empty)
- If there were fewer licenses found for a crate than declared by the author on crates.io (too few)
- If there were more licenses found for a crate than declared by the author on crates.io (additional)
- If the content of the found licenses did not match the expected content for those licenses (mismatch)

```bash
$ cargo licenses check
```

<!-- `$ cargo run -q -- licenses check || true` -->
```
warning: additional - found all declared licenses, but found additional licenses for:
	aho_corasick - COPYING
	memchr - COPYING
	unicode_normalization - COPYRIGHT
```

### Diff

Compares the current collected licenses folder against the licenses that would be collected.

Current licenses folder path can be specified with `--path`, defaults to `licenses`.

Returns a non-zero exit code if there is a difference between the licenses that would be collected and the current
collected licenses folder.

```
$ cargo licenses diff
```

## Configuration

A [TOML](https://toml.io/en/) configuration file can be used to store all passed flags, as well as enabling options
on a per-crate basis. If both a config and a flag set the same option, the flag will take precedence.

```
$ cargo licenses <COMMAND> --config licenses.toml
```

### Skipping licenses

The configuration file allows the selective skipping of licenses found by the various subcommands.
It is recommended to provide a comment per skipped license to indicate why it is deemed okay to skip, for instance it
might be
erroneously detected as a license because of the filename.

```toml
[crates]
example_crate = { skip = ["FILE"] } # comment on why the files are skipped
```

### Allowing warnings

Warnings generated by the `collect` or `check` command can be allowed in the configuration file, this allows erroneous
warnings to be selectively silenced. It is recommended to provide a comment on why a warning is being allowed. The
warnings
that can be allowed are included in the warning message, these are:

- `too few`
- `empty`
- `none declared`
- `{ additional = ["file1", "file2"] }`
- `{ mismatch = ["file1", "file2"] }`

```toml
[crates]
example_crate = { allow = "too few" }
```

### Unused configuration warnings

The `check` command will warn if any entries in the configuration file are not being used. This helps keep the
configuration file clean as dependencies change. The following unused entries are detected:

- A crate in the config that is not found in the dependency tree
- An `allow` that is not required because the license status is already valid
- A `skip` for a file that does not exist in the crate's directory

```
$ cargo licenses check --config licenses.toml
warning: unused - entries in the config are not being used:
        fake_crate - crate not found in dependencies
        example_crate - 'allow' is not required
        another_crate - 'skip' for NONEXISTENT is not required
```

### Include licenses

Additional licenses can be included for a specific crate via the configuration file.

```toml
[crates]
example_crate = { include = [{ name = "LICENSE", text = "custom license text" }] }
```

### Example

The below is an example of a TOML configuration file that could be used via the `--config` flag.

```toml
[global]
dev = true
build = true
depth = 1
all_features = true
exclude = ["workspace"]
ignore = ["crate"]

[crates]
crate_one = { skip = ["COPYING"] } # not a license, statement of which licenses the crate falls under
crate_two = { allow = { mismatch = ["LICENSE"] } } # erroneous license content mismatch
crate_three = { allow = "too few" } # only one license provided
```

## Usage patterns

This tool is designed to help collect required licenses when shipping software with open-source dependencies. The
intended pattern of use would look as follows:

- `summary` provides a quick way to see if any dependencies are using stricter licenses that might not be suitable,
  copy-left for instance
- `collect` to collect all licenses into an output folder, this would be done manually and the license folder commited
  as part of the repository
- the previous command might have raised warnings about licenses found, or not found, these can be manually assessed
  then skipped or allowed in the configuration file
- as part of a continuous integration system, or as a pre-commit hook, a `diff` should be run to check the licenses
  folder hasn't missed any licenses added by new dependencies or removed by removing dependencies
- as part of a continuous integration system a `check` should be run to confirm all license inconsistencies have been
  handled in the configuration

## Legal disclaimer

This is provided as a convenience to help with collecting and reviewing open-source licenses. **It does not guarantee
compliance with all legal licensing requirements.** It is
the user's responsibility to ensure that all applicable licenses are collected, reviewed and adhered to. The authors and
contributors of this tool accept no liability for missing,
incomplete or inaccurate licenses files, or for any consequences arising from its use.