nix-reuse/modules/reuse.nix

213 lines
7.3 KiB
Nix
Raw Normal View History

2024-12-12 10:17:26 +01:00
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
#
# SPDX-License-Identifier: EUPL-1.2
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
filterAttrs
getExe
2024-12-12 10:17:26 +01:00
getExe'
mapAttrs'
mkDefault
mkIf
2024-12-12 10:17:26 +01:00
mkOption
nameValuePair
optionalString
2024-12-12 10:17:26 +01:00
;
inherit (lib.types)
attrsOf
bool
2024-12-12 10:17:26 +01:00
either
enum
listOf
nullOr
str
submodule
;
result = (pkgs.formats.toml { }).generate "REUSE.toml" {
version = 1;
2024-12-12 10:17:26 +01:00
annotations = builtins.map (
{
path,
precedence,
spdx,
...
}:
{
inherit path precedence;
}
// (mapAttrs' (name: value: nameValuePair "SPDX-${name}" value) (
filterAttrs (_: x: x != null) spdx
))
) config.annotations;
};
cfg = config;
in
{
options = {
installationScript = mkOption {
type = str;
description = ''
A bash snippet that installs the workflows files in the current project.
'';
readOnly = true;
};
defaultLicense = mkOption {
type = nullOr str;
default = null;
description = ''
Default license to use accross the repository.
'';
};
defaultCopyright = mkOption {
type = nullOr str;
default = null;
description = ''
Default copyright to use accross the repository.
'';
};
downloadLicenses = mkOption {
type = bool;
default = false;
description = ''
Try to download all licenses present in the configuration.
'';
};
generatedPaths = mkOption {
type = listOf str;
default = [ ];
description = ''
The list of computer generated files present in the project, an annotation will be added for these using:
- SPDX-License-Identifier = "CC0-1.0"
- SPDX-FileCopyrightText = "NONE"
'';
};
2024-12-12 10:17:26 +01:00
annotations = mkOption {
type = listOf (
submodule (
{ config, ... }:
{
options = {
path = mkOption {
type = either str (listOf str);
description = ''
A string or list of strings representing paths.
A path MUST use forward slashes as path separators.
A path SHOULD resolve to one or more Covered Files relative to the REUSE.toml files directory.
A path that resolves to a non-existent or non-Covered File is ignored.
A path MUST point to a location in the REUSE.toml files directory or deeper.
A path MAY use globbing to match several Covered Files in a single expression.
These are the globbing and matching rules:
- `*` matches everything except forward slashes (i.e. path separators).
- `**` and `**/` match everything including forward slashes (i.e. path separators).
- In order to escape an asterisk and include it verbatim, prefix it with `\\`. You cannot prefix it with `\` because that is invalid TOML. In order to include a backslash verbatim, use `\\\\`. `\\` followed by any other character is functionally equal to just typing that character.
'';
};
precedence = mkOption {
type = enum [
"closest"
"aggregate"
"override"
];
default = "closest";
description = ''
It determines the order of precedence for Licensing Information between the REUSE.toml
file and Covered Files in the table, and between multiple REUSE.toml files if they both
contain Licensing Information for the same Covered File.
Available values are:
- `closest`, the default value when precedence is not defined. This is an instruction to associate the Licensing Information inside of the Covered Files (or its adjacent `.license` file), if available. If no such Licensing Information is found, then the Licensing Information inside the table of the closest `REUSE.toml` that covers the File is associated. This algorithm is applied separately for copyright and for licensing. If a table for the same File in a closer `REUSE.toml` file has the override precedence, then that precedence is applied, and closest is ignored.
- `aggregate`. This is an instruction to always associate the Licensing Information defined in the table with the tables Covered Files. Subsequently, the closest logic is also applied.
- `override`. This is an instruction to associate the Licensing Information defined in the table with the tables Covered Files, and to ignore any other Licensing Information that is closer to the Files. The table in the `REUSE.toml` that is the closest to the root of the Project is authoritative.
'';
};
copyright = mkOption {
type = nullOr (either str (listOf str));
default = cfg.defaultCopyright;
description = ''
Each string MUST be a Copyright Notice to be associated with the tables Covered Files.
The prefix of the Copyright Notice MAY be omitted.
'';
};
license = mkOption {
type = nullOr (either str (listOf str));
default = cfg.defaultLicense;
description = ''
Each string MUST be a valid SPDX License Expression describing the licensing of the tables Covered Files.
'';
};
spdx = mkOption {
type = attrsOf (nullOr (either str (listOf str)));
default = { };
description = ''
Additional SPDX tags to be included in the `[[annotations]]` table.
'';
example = {
FileContributor = "Jane Doe <jane.doe@example.com>";
};
};
};
config.spdx = {
License-Identifier = mkDefault config.license;
FileCopyrightText = mkDefault config.copyright;
};
}
)
);
};
};
config = {
annotations = mkIf (config.generatedPaths != [ ]) [
{
path = config.generatedPaths;
copyright = "NONE";
license = "CC0-1.0";
}
];
2024-12-12 10:17:26 +01:00
installationScript =
# bash
''
if ! type -t git >/dev/null; then
# This happens in pure shells, including lorri
echo 1>&2 "WARNING: nix-reuse: git command not found; skipping installation."
elif ! git rev-parse --git-dir &> /dev/null; then
echo 1>&2 "WARNING: nix-reuse: .git not found; skipping installation."
else
GIT_WC=`git rev-parse --show-toplevel`
# Install REUSE.toml
if [ ! -f "$GIT_WC/REUSE.toml" ] || ! ${getExe' pkgs.diffutils "cmp"} -s "$GIT_WC/REUSE.toml" ${result} ; then
# Copy the updated workflow definition
cp --no-preserve=mode,ownership ${result} "$GIT_WC/REUSE.toml" && echo "nix-reuse: Updated REUSE.toml"
fi
fi
${optionalString config.downloadLicenses "${getExe pkgs.reuse} download --all"}
2024-12-12 10:17:26 +01:00
'';
};
}