#license #fetch #embed #find #about #fetch-about-find

license-fetcher

Fetch licenses of dependencies at build time and embed them into your program

20 releases (7 breaking)

new 0.8.3 May 12, 2025
0.7.3 Apr 23, 2025
0.6.3 Jan 27, 2025
0.5.0 Oct 27, 2024

#10 in #license

Download history 1080/week @ 2025-01-22 232/week @ 2025-01-29 29/week @ 2025-02-05 23/week @ 2025-02-12 8/week @ 2025-02-19 18/week @ 2025-02-26 13/week @ 2025-03-12 66/week @ 2025-04-09 366/week @ 2025-04-16 331/week @ 2025-04-23 9/week @ 2025-04-30 502/week @ 2025-05-07

1,271 downloads per month
Used in 2 crates

MPL-2.0 license

78KB
1K SLoC

license-fetcher

Fetch licenses of dependencies at build time and embed them into your program.

Crates.io Version GitHub License docs.rs lib.rs link dependency status

Aspirations

  1. Fetch licenses!
  2. Fast!
  3. Do it in the build step!

[!NOTE] If you are in search for a cli checkout flicense.

Workings

Crates that are compiled with your program are fetched via cargo metadata and cargo tree. License texts are read from the .cargo/registry/src folder. The data is then serialized and compressed.

Usage

Here is a small rundown how to use this library for fetching licenses during build time. Though fetching licenses at runtime is also supported. See the docs.

Include Dependency

[!WARNING] Include this library as build dependency and as normal dependency!

cargo add --build --features build license-fetcher
cargo add license-fetcher

Build Script

This library requires you to execute it for fetching licenses in a build script. Create a file called build.rs in the root of your project and add following contents:

use license_fetcher::build::config::{ConfigBuilder, Config};
use license_fetcher::build::package_list_with_licenses;
use license_fetcher::PackageList;

fn main() {
    // Config with environment variables set by cargo, to fetch licenses at build time.
    let config: Config = ConfigBuilder::from_build_env()
        .build()
        .expect("Failed to build configuration.");

    // Fetch metadata and licenses.
    let packages: PackageList = package_list_with_licenses(config)
                                    .expect("Failed to fetch metadata or licenses.");

    // Write packages to out dir to be embedded.
    packages.write_package_list_to_out_dir().expect("Failed to write package list.");

    // Rerun only if one of the following files changed:
    println!("cargo::rerun-if-changed=build.rs");
    println!("cargo::rerun-if-changed=Cargo.lock");
    println!("cargo::rerun-if-changed=Cargo.toml");
}

Main

Add following content to your main.rs:

use license_fetcher::read_package_list_from_out_dir;

fn main() {
    let package_list = read_package_list_from_out_dir!().unwrap();
}

Caveats

license-fetcher fetches licenses that are at the root of a package. This results in some caveats, mainly:

  • Some projects do not upload licenses with their packages. This might happen if a project is split up into many packages.
  • Some wrappers do not attribute the library they are wrapping.
  • Dependencies that are not packages, like dictionaries, are not detected.

To work around the former points, it is advisable to use flicense --stats . on your package, to see what packages license-fetcher fetches.

For the later point there is no workaround, as there is no automated way to detect the use of such dependencies.

Alternatives

license-retriever

This project was a big inspiration for license-fetcher. The idea of fetching licenses during build step did not even occur to me beforehand.

A big shout-out!

Pros

  • Also retrieves licenses in the build step and loads them into the program.
  • Can also use repo url to fetch licenses.
  • Can also use spdx to fetch licenses.

Cons

  • Does not compress licenses.
  • LGPL-3.0

cargo-about

Pros

  • Generates very nice html.

Cons

  • Is not a library to access said data but rather a command line tool.
  • Does not fetch licenses from local source files.

Screenshots

Display trait included 😉

Screenshot

Dependencies

~0.4–7.5MB
~53K SLoC