Skip to content

Commit 4a12241

Browse files
committed
initial user docs and refactor for 2025
1 parent 580c538 commit 4a12241

15 files changed

+242
-301
lines changed

documentation/user/README.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
2+
3+
## Basic Example Use
4+
5+
6+
7+
8+
## Supported tools/ standards
9+
10+
Licensecheck supports a broad range of different tools and workflows. Though please note that
11+
for some of these tools, behaviour may differ from what is expected
12+
13+
| Name of tool | Supported | Notes |
14+
| ------------ | --------- | ----- |
15+
| Poetry 2.x || ??? |
16+
17+
18+
## Resolve all deps
19+
20+
Previous versions of the licensecheck tool implemented a custom resolver to discover packages.
21+
Current versions look to move away from this for a number of reasons, such as correctness and
22+
reducing the maintenance burden. Over time many contributors helped out with the custom
23+
resolver which is very much appreciated. Now, we use `uv` to attempt to resolve deps before
24+
falling back to the legacy approach, which is needed in certain cases where uv fails
25+
26+
Q: Why doesn't this use packages from my lockfile?
27+
A: The answer to this somewhat depends on what resolver licensecheck ends up using to
28+
find all of the packages in use by your project. Ideally, `uv` is used which has pretty
29+
good support for pyproject.toml and some other standard requirements formats and will discover
30+
packages. The legacy resolver is deprecated and may result in funky output in some cases
31+
32+
Q: The license for my dep has changed in v >1.0, so I'm using v < 1.0, why doesn't licensecheck report the correct license version?
33+
A: In some cases it will, for example if licensecheck can find the dep metadata via importlib. Otherwise we reach out to pypi.org for this metadata. There are no plans at present to resolve this
34+
35+
[note to me: I 'might' look at this as we should have a copy of the package version ]
36+
37+
## License lookup format
38+
39+
40+
At present the licenses are not looked up via the SPDX format, which would be preffred going forwards, but via a custom mapping that corresponds to a substring of the python license classifiers. The table below shows the current lookup
41+
42+
Some means of normalizing this, perhaps with the aid of a 3rd party lib is planned
43+
44+
45+
| License Name Containing | License Type |
46+
| ------------------------------------ | --------------- |
47+
| PUBLIC DOMAIN | L.PUBLIC |
48+
| CC-PDDC | L.PUBLIC |
49+
| CC0-1.0 | L.PUBLIC |
50+
| UNLICENSE | L.UNLICENSE |
51+
| WTFPL | L.UNLICENSE |
52+
| BOOST | L.BOOST |
53+
| BSL-1.0 | L.BOOST |
54+
| MIT | L.MIT |
55+
| BSD | L.BSD |
56+
| ISC | L.ISC |
57+
| NCSA | L.NCSA |
58+
| PYTHON | L.PSFL |
59+
| PSF-2.0 | L.PSFL |
60+
| APACHE | L.APACHE |
61+
| ECLIPSE | L.ECLIPSE |
62+
| AFL | L.ACADEMIC_FREE |
63+
| LGPLV2+ | L.LGPL_2_PLUS |
64+
| LGPL-2.0-OR-LATER | L.LGPL_2_PLUS |
65+
| LGPLV3+ | L.LGPL_3_PLUS |
66+
| LGPL-3.0-OR-LATER | L.LGPL_3_PLUS |
67+
| LGPL-2.0-ONLY | L.LGPL_2 |
68+
| LGPLV2 | L.LGPL_2 |
69+
| LGPL-3.0-ONLY | L.LGPL_3 |
70+
| LGPLV3 | L.LGPL_3 |
71+
| LGPL | L.LGPL_X |
72+
| AGPL | L.AGPL_3_PLUS |
73+
| GNU AFFERO GENERAL PUBLIC LICENSE V3 | L.AGPL_3_PLUS |
74+
| GPL-2.0-OR-LATER | L.GPL_2_PLUS |
75+
| GPLV2+ | L.GPL_2_PLUS |
76+
| GPL-3.0-OR-LATER | L.GPL_3_PLUS |
77+
| GPLV3+ | L.GPL_3_PLUS |
78+
| GPLV2 | L.GPL_2 |
79+
| GPL-2.0 | L.GPL_2 |
80+
| GPLV3 | L.GPL_3 |
81+
| GPL-3.0 | L.GPL_3 |
82+
| GPL | L.GPL_X |
83+
| MPL | L.MPL |
84+
| EUPL | L.EU |
85+
| PROPRIETARY | L.PROPRIETARY |
86+
87+
88+
89+
90+
91+
## Output formats
92+
93+
The formatter is reponsible for outputting the list of PackageInfo[s].
94+
95+
Note the PackageInfo has the following attributes, that we can use to build each output format:
96+
- name: str
97+
- version: str
98+
- namever: str
99+
- size: int = -1
100+
- homePage: str
101+
- author: str
102+
- license: ucstr
103+
- licenseCompat: bool
104+
- errorCode: int = 0
105+
106+
107+
The available output formats are defined as follows
108+
109+
110+
- ansi: Plain text output with ANSI color codes for terminal display.
111+
used for simple, color-coded output on the command line.
112+
- plain: A basic, no-frills plain text format, used when a clean and simple
113+
textual representation is needed without any additional markup or styling.
114+
- markdown: A lightweight markup language with plain-text formatting syntax. Ideal
115+
for creating formatted documents that can be easily converted into HTML for web display.
116+
- html: A format suitable for rendering in web browsers. (can be styled with CSS
117+
for more complex presentation.)
118+
- json: A structured data format. This format representing the list of PackageInfo[s]
119+
as a JSON object
120+
- csv: A simple, comma-separated values format. widely used in spreadsheets and
121+
databases for easy import/export of data.
122+
123+
Note that these support the get_filtered_dict method, which allows users
124+
to hide some of the output via the `--hide-output-parameters` cli flag. In addition
125+
these support the show_only_failing method, which allows users
126+
to show only packages that are not compatible with out license via the
127+
`--show-only-failing` cli flag
128+
129+
130+
## Using in CI/CD

licensecheck/license_matrix.py

-197
This file was deleted.

licensecheck/license_matrix/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,17 @@ def licenseLookup(licenseStr: ucstr, ignoreLicenses: list[ucstr] | None = None)
102102
:param list[ucstr] | None ignoreLicenses: licenses to ignore, defaults to None
103103
:return L: License represented by licenseStr
104104
"""
105+
if len(licenseStr or "") < 1:
106+
return L.NO_LICENSE
105107

106108
for liceStr, lice in termToLicense.items():
107109
if liceStr.strip() in licenseStr:
108110
return lice
109111

110112

111113
if licenseStr not in (ignoreLicenses or ""):
112-
logger.warning(f"'{licenseStr}' License not identified so falling back to NO_LICENSE")
113-
return L.NO_LICENSE
114+
logger.warning(f"'{licenseStr}' License not identified so falling back to UNKNOWN")
115+
return L.UNKNOWN
114116

115117

116118

licensecheck/matrix.csv

-27
This file was deleted.

licensecheck/resolvers/uv.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def get_reqs(
3434
result = subprocess.run(command, shell=True, capture_output=True, text=True, check=False)
3535

3636
if result.returncode != 0:
37-
raise RuntimeError(result.stderr)
37+
raise RuntimeError(result.stderr, result.stdout)
3838

3939
reqs = requirements.parse(result.stdout)
4040
reqs_out = [ucstr(x.name) for x in reqs]

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "licensecheck"
3-
version = "2024.3"
3+
version = "2025"
44
description = "Output the licenses used by dependencies and check if these are compatible with the project license"
55
authors = [{ name = "FredHappyface" }]
66
requires-python = ">=3.9"

0 commit comments

Comments
 (0)