Replace Python SBOM generator with cargo-sbom
- Remove LICENSE.md and docs/DEPENDENCIES.md (redundant with SBOM JSON) - Remove scripts/generate_sbom.py (replaced by cargo-sbom) - Update distro::generate-sbom recipe to use cargo-sbom CLI - Generates SPDX 2.3 and CycloneDX 1.4 formats natively - Eliminates Python dependency for SBOM generation
This commit is contained in:
parent
7d9fb0e2bd
commit
77610db201
231
LICENSE.md
231
LICENSE.md
@ -1,231 +0,0 @@
|
||||
# TypeDialog License
|
||||
|
||||
## Project License
|
||||
|
||||
TypeDialog is licensed under the **MIT License**.
|
||||
|
||||
See [LICENSE](LICENSE) file for the full MIT license text.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
This project includes the following dependencies under their respective licenses:
|
||||
|
||||
### Apache-2.0 Only (3)
|
||||
- rpassword 7.4.0
|
||||
- rtoolbox 0.0.3
|
||||
- sync_wrapper 1.0.2
|
||||
|
||||
### MIT Only (66)
|
||||
- atty 0.2.14
|
||||
- axum 0.8.7
|
||||
- axum-core 0.5.5
|
||||
- bytes 1.11.0
|
||||
- castaway 0.2.4
|
||||
- compact_str 0.8.1
|
||||
- console 0.16.2
|
||||
- convert_case 0.10.0
|
||||
- crossterm 0.28.1
|
||||
- crossterm 0.29.0
|
||||
- crossterm_winapi 0.9.1
|
||||
- darling 0.20.11
|
||||
- darling_core 0.20.11
|
||||
- darling_macro 0.20.11
|
||||
- derive_more 2.1.0
|
||||
- derive_more-impl 2.1.0
|
||||
- dialoguer 0.12.0
|
||||
- typedialog 0.1.0
|
||||
- typedialog-core 0.1.0
|
||||
- typedialog-tui 0.1.0
|
||||
- typedialog-web 0.1.0
|
||||
- fuzzy-matcher 0.3.7
|
||||
- generic-array 0.14.7
|
||||
- globwalk 0.9.1
|
||||
- http-body 1.0.1
|
||||
- http-body-util 0.1.3
|
||||
- http-range-header 0.4.2
|
||||
- hyper 1.8.1
|
||||
- hyper-util 0.1.19
|
||||
- inquire 0.9.1
|
||||
- instability 0.3.10
|
||||
- libm 0.2.15
|
||||
- libredox 0.1.10
|
||||
- lru 0.12.5
|
||||
- mime_guess 2.0.5
|
||||
- mio 1.1.1
|
||||
- nu-ansi-term 0.50.3
|
||||
- parse-zoneinfo 0.3.1
|
||||
- phf 0.11.3
|
||||
- phf_codegen 0.11.3
|
||||
- phf_generator 0.11.3
|
||||
- phf_shared 0.11.3
|
||||
- ratatui 0.29.0
|
||||
- redox_syscall 0.5.18
|
||||
- redox_users 0.5.2
|
||||
- sharded-slab 0.1.7
|
||||
- slab 0.4.11
|
||||
- strsim 0.11.1
|
||||
- strum 0.26.3
|
||||
- strum_macros 0.26.4
|
||||
- tera 1.20.1
|
||||
- tokio 1.48.0
|
||||
- tokio-macros 2.6.0
|
||||
- tokio-util 0.7.17
|
||||
- tower 0.5.2
|
||||
- tower-http 0.6.8
|
||||
- tower-layer 0.3.3
|
||||
- tower-service 0.3.3
|
||||
- tracing 0.1.43
|
||||
- tracing-attributes 0.1.31
|
||||
- tracing-core 0.1.35
|
||||
- tracing-log 0.2.0
|
||||
- tracing-subscriber 0.3.22
|
||||
- unsafe-libyaml 0.2.11
|
||||
- valuable 0.1.1
|
||||
- winnow 0.7.14
|
||||
|
||||
### Apache-2.0 OR MIT (190)
|
||||
|
||||
Most dependencies use dual licensing between Apache-2.0 and MIT.
|
||||
|
||||
- allocator-api2 0.2.21 | - android_system_properties 0.1.5 | - anstream 0.6.21
|
||||
- anstyle 1.0.13 | - anstyle-parse 0.2.7 | - anstyle-query 1.1.5
|
||||
- anstyle-wincon 3.0.11 | - anyhow 1.0.100 | - async-trait 0.1.89
|
||||
- atomic-waker 1.1.2 | - autocfg 1.5.0 | - bitflags 2.10.0
|
||||
- block-buffer 0.10.4 | - bstr 1.12.1 | - bumpalo 3.19.0
|
||||
- cassowary 0.3.0 | - cc 1.2.49 | - cfg-if 1.0.4
|
||||
- chrono 0.4.42 | - chrono-tz 0.9.0 | - chrono-tz-build 0.3.0
|
||||
- clap 4.5.53 | - clap_builder 4.5.53 | - clap_derive 4.5.49
|
||||
- clap_lex 0.7.6 | - colorchoice 1.0.4 | - core-foundation-sys 0.8.7
|
||||
- cpufeatures 0.2.17 | - crossbeam-deque 0.8.6 | - crossbeam-epoch 0.9.18
|
||||
- crossbeam-utils 0.8.21 | - crypto-common 0.1.7 | - digest 0.10.7
|
||||
- dirs 6.0.0 | - dirs-sys 0.5.0 | - displaydoc 0.2.5
|
||||
- document-features 0.2.12 | - dyn-clone 1.0.20 | - either 1.15.0
|
||||
- encode_unicode 1.0.0 | - equivalent 1.0.2 | - errno 0.3.14
|
||||
- fastrand 2.3.0 | - find-msvc-tools 0.1.5 | - fluent 0.17.0
|
||||
- fluent-bundle 0.16.0 | - fluent-langneg 0.13.1 | - fluent-syntax 0.12.0
|
||||
- fnv 1.0.7 | - form_urlencoded 1.2.2 | - futures 0.3.31
|
||||
- futures-channel 0.3.31 | - futures-core 0.3.31 | - futures-executor 0.3.31
|
||||
- futures-io 0.3.31 | - futures-macro 0.3.31 | - futures-sink 0.3.31
|
||||
- futures-task 0.3.31 | - futures-util 0.3.31 | - getrandom 0.2.16
|
||||
- getrandom 0.3.4 | - hashbrown 0.15.5 | - hashbrown 0.16.1
|
||||
- heck 0.5.0 | - hermit-abi 0.1.19 | - http 1.4.0
|
||||
- httparse 1.10.1 | - httpdate 1.0.3 | - humansize 2.1.3
|
||||
- iana-time-zone 0.1.64 | - iana-time-zone-haiku 0.1.2 | - ident_case 1.0.1
|
||||
- indexmap 2.12.1 | - indoc 2.0.7 | - intl-memoizer 0.5.3
|
||||
- intl_pluralrules 7.0.2 | - is_terminal_polyfill 1.70.2 | - itertools 0.13.0
|
||||
- itoa 1.0.15 | - js-sys 0.3.83 | - lazy_static 1.5.0
|
||||
- libc 0.2.178 | - litrs 1.0.0 | - lock_api 0.4.14
|
||||
- log 0.4.29 | - mime 0.3.17 | - num-traits 0.2.19
|
||||
- once_cell 1.21.3 | - once_cell_polyfill 1.70.2 | - parking_lot 0.12.5
|
||||
- parking_lot_core 0.9.12 | - paste 1.0.15 | - percent-encoding 2.3.2
|
||||
- pest 2.8.4 | - pest_derive 2.8.4 | - pest_generator 2.8.4
|
||||
- pest_meta 2.8.4 | - pin-project-lite 0.2.16 | - pin-utils 0.1.0
|
||||
- ppv-lite86 0.2.21 | - proc-macro2 1.0.103 | - quote 1.0.42
|
||||
- rand 0.8.5 | - rand_chacha 0.3.1 | - rand_core 0.6.4
|
||||
- regex 1.12.2 | - regex-automata 0.4.13 | - regex-syntax 0.8.8
|
||||
- rustc-hash 2.1.1 | - rustc_version 0.4.1 | - rustversion 1.0.22
|
||||
- scopeguard 1.2.0 | - semver 1.0.27 | - serde 1.0.228
|
||||
- serde_core 1.0.228 | - serde_derive 1.0.228 | - serde_json 1.0.145
|
||||
- serde_path_to_error 0.1.20 | - serde_spanned 1.0.3 | - serde_urlencoded 0.7.1
|
||||
- serde_yaml 0.9.34+deprecated | - sha2 0.10.9 | - shell-words 1.1.0
|
||||
- shlex 1.3.0 | - signal-hook 0.3.18 | - signal-hook-mio 0.2.5
|
||||
- signal-hook-registry 1.4.7 | - siphasher 1.0.1 | - slug 0.1.6
|
||||
- smallvec 1.15.1 | - socket2 0.6.1 | - static_assertions 1.1.0
|
||||
- syn 2.0.111 | - sys-locale 0.3.2 | - tempfile 3.23.0
|
||||
- thiserror 2.0.17 | - thiserror-impl 2.0.17 | - thread_local 1.1.9
|
||||
- toml 0.9.8 | - toml_datetime 0.7.3 | - toml_parser 1.0.4
|
||||
- toml_writer 1.0.4 | - type-map 0.5.1 | - typenum 1.19.0
|
||||
- ucd-trie 0.1.7 | - unic-langid 0.9.6 | - unic-langid-impl 0.9.6
|
||||
- unicase 2.8.1 | - unicode-segmentation 1.12.0 | - unicode-truncate 1.1.0
|
||||
- unicode-width 0.1.14 | - unicode-width 0.2.0 | - utf8parse 0.2.2
|
||||
- version_check 0.9.5 | - wasm-bindgen 0.2.106 | - wasm-bindgen-macro 0.2.106
|
||||
- wasm-bindgen-macro-support 0.2.106 | - wasm-bindgen-shared 0.2.106 | - winapi 0.3.9
|
||||
- winapi-i686-pc-windows-gnu 0.4.0 | - winapi-x86_64-pc-windows-gnu 0.4.0 | - windows-core 0.62.2
|
||||
- windows-implement 0.60.2 | - windows-interface 0.59.3 | - windows-link 0.2.1
|
||||
- windows-result 0.4.1 | - windows-strings 0.5.1 | - windows-sys 0.52.0
|
||||
- windows-sys 0.59.0 | - windows-sys 0.60.2 | - windows-sys 0.61.2
|
||||
- windows-targets 0.52.6 | - windows-targets 0.53.5 | - windows_aarch64_gnullvm 0.52.6
|
||||
- windows_aarch64_gnullvm 0.53.1 | - windows_aarch64_msvc 0.52.6 | - windows_aarch64_msvc 0.53.1
|
||||
- windows_i686_gnu 0.52.6 | - windows_i686_gnu 0.53.1 | - windows_i686_gnullvm 0.52.6
|
||||
- windows_i686_gnullvm 0.53.1 | - windows_i686_msvc 0.52.6 | - windows_i686_msvc 0.53.1
|
||||
- windows_x86_64_gnu 0.52.6 | - windows_x86_64_gnu 0.53.1 | - windows_x86_64_gnullvm 0.52.6
|
||||
- windows_x86_64_gnullvm 0.53.1 | - windows_x86_64_msvc 0.52.6 | - windows_x86_64_msvc 0.53.1
|
||||
- zeroize 1.8.2 |
|
||||
|
||||
### MIT OR Unlicense (7)
|
||||
- aho-corasick 1.1.4
|
||||
- globset 0.4.18
|
||||
- ignore 0.4.25
|
||||
- memchr 2.7.6
|
||||
- same-file 1.0.6
|
||||
- walkdir 2.5.0
|
||||
- winapi-util 0.1.11
|
||||
|
||||
### Other Licenses
|
||||
|
||||
**(Apache-2.0 OR MIT) AND Unicode-3.0** (1)
|
||||
- unicode-ident 1.0.22
|
||||
|
||||
**Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT** (7)
|
||||
- linux-raw-sys 0.4.15
|
||||
- linux-raw-sys 0.11.0
|
||||
- rustix 0.38.44
|
||||
- rustix 1.1.2
|
||||
- wasi 0.11.1+wasi-snapshot-preview1
|
||||
- wasip2 1.0.1+wasi-0.2.4
|
||||
- wit-bindgen 0.46.0
|
||||
|
||||
**Apache-2.0 OR BSD-2-Clause OR MIT** (2)
|
||||
- zerocopy 0.8.31
|
||||
- zerocopy-derive 0.8.31
|
||||
|
||||
**Apache-2.0 OR BSL-1.0** (1)
|
||||
- ryu 1.0.20
|
||||
|
||||
**Apache-2.0 OR GPL-2.0** (1)
|
||||
- self_cell 1.2.1
|
||||
|
||||
**Apache-2.0 OR LGPL-2.1-or-later OR MIT** (1)
|
||||
- r-efi 5.3.0
|
||||
|
||||
**BSD-3-Clause** (1)
|
||||
- deunicode 1.6.2
|
||||
|
||||
**BSD-3-Clause AND MIT** (1)
|
||||
- matchit 0.8.4
|
||||
|
||||
**MPL-2.0** (1)
|
||||
- option-ext 0.2.0
|
||||
|
||||
**Unicode-3.0** (3)
|
||||
- tinystr 0.8.2
|
||||
- zerofrom 0.1.6
|
||||
- zerovec 0.11.5
|
||||
|
||||
**Zlib** (1)
|
||||
- foldhash 0.1.5
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
- **Project License**: MIT
|
||||
- **Total Dependencies**: 286
|
||||
- **Unique License Types**: 15 different combinations
|
||||
- **Primary License Pattern**: Apache-2.0 OR MIT (most dependencies)
|
||||
|
||||
### Compliance
|
||||
|
||||
All dependencies are compatible with the MIT license under:
|
||||
- Permissive licenses (MIT, Apache-2.0, BSD-3-Clause, MPL-2.0, Zlib)
|
||||
- Weak copyleft (LGPL-2.1-or-later, MPL-2.0)
|
||||
- Public domain (Unlicense, Unicode-3.0)
|
||||
|
||||
### Generated
|
||||
|
||||
- Date: 2025-12-17T13:08:58.510231
|
||||
- Tool: cargo-license
|
||||
|
||||
See [DEPENDENCIES.md](DEPENDENCIES.md) for the complete dependency tree.
|
||||
14511
SBOM.cyclonedx.json
14511
SBOM.cyclonedx.json
File diff suppressed because it is too large
Load Diff
14821
SBOM.spdx.json
14821
SBOM.spdx.json
File diff suppressed because it is too large
Load Diff
@ -1,156 +0,0 @@
|
||||
# TypeDialog Dependencies
|
||||
|
||||
## Direct Dependencies (by crate)
|
||||
|
||||
### typedialog-core
|
||||
|
||||
Core library dependencies:
|
||||
|
||||
**Serialization & Data**
|
||||
- serde 1.0 (Apache-2.0 OR MIT)
|
||||
- serde_json 1.0 (Apache-2.0 OR MIT)
|
||||
- serde_yaml 0.9 (Apache-2.0 OR MIT)
|
||||
- toml 0.9 (Apache-2.0 OR MIT)
|
||||
|
||||
**Error Handling**
|
||||
- anyhow 1.0 (Apache-2.0 OR MIT)
|
||||
- thiserror 2.0 (Apache-2.0 OR MIT)
|
||||
|
||||
**Date/Time**
|
||||
- chrono 0.4 (Apache-2.0 OR MIT)
|
||||
|
||||
**Async**
|
||||
- tokio 1 (MIT)
|
||||
- async-trait 0.1 (Apache-2.0 OR MIT)
|
||||
- futures 0.3 (Apache-2.0 OR MIT)
|
||||
|
||||
**Templating (optional)**
|
||||
- tera 1.20 (MIT)
|
||||
|
||||
**i18n (optional)**
|
||||
- fluent 0.17 (Apache-2.0)
|
||||
- fluent-bundle 0.16 (Apache-2.0)
|
||||
- unic-langid 0.9 (Apache-2.0 OR MIT)
|
||||
- sys-locale 0.3 (Apache-2.0 OR MIT)
|
||||
- dirs 6.0 (Apache-2.0 OR MIT)
|
||||
|
||||
**CLI Backend (optional)**
|
||||
- inquire 0.9 (MIT)
|
||||
- dialoguer 0.12 (MIT)
|
||||
- rpassword 7.4 (Apache-2.0)
|
||||
|
||||
**TUI Backend (optional)**
|
||||
- ratatui 0.29 (MIT)
|
||||
- crossterm 0.29 (MIT)
|
||||
- atty 0.2 (MIT)
|
||||
|
||||
**Web Backend (optional)**
|
||||
- axum 0.8.7 (MIT)
|
||||
- tower 0.5.2 (MIT)
|
||||
- tower-http 0.6.8 (MIT)
|
||||
- tracing 0.1 (MIT)
|
||||
- tracing-subscriber 0.3 (MIT)
|
||||
|
||||
**Utilities**
|
||||
- tempfile 3.23 (Apache-2.0 OR MIT)
|
||||
|
||||
### typedialog (CLI)
|
||||
|
||||
Direct dependencies:
|
||||
- typedialog-core 0.1.0 (MIT)
|
||||
- clap 4.5 (Apache-2.0 OR MIT) - CLI argument parsing
|
||||
- anyhow 1.0 (Apache-2.0 OR MIT)
|
||||
- serde_json 1.0 (Apache-2.0 OR MIT)
|
||||
- tokio 1.0 (MIT)
|
||||
- toml 0.9 (Apache-2.0 OR MIT)
|
||||
- unic-langid 0.9 (Apache-2.0 OR MIT)
|
||||
|
||||
### typedialog-tui (TUI)
|
||||
|
||||
Direct dependencies:
|
||||
- typedialog-core 0.1.0 (MIT)
|
||||
- clap 4.5 (Apache-2.0 OR MIT)
|
||||
- anyhow 1.0 (Apache-2.0 OR MIT)
|
||||
- serde_json 1.0 (Apache-2.0 OR MIT)
|
||||
- tokio 1.0 (MIT)
|
||||
- unic-langid 0.9 (Apache-2.0 OR MIT)
|
||||
|
||||
### typedialog-web (Web)
|
||||
|
||||
Direct dependencies:
|
||||
- typedialog-core 0.1.0 (MIT)
|
||||
- clap 4.5 (Apache-2.0 OR MIT)
|
||||
- anyhow 1.0 (Apache-2.0 OR MIT)
|
||||
- serde_json 1.0 (Apache-2.0 OR MIT)
|
||||
- tokio 1.0 (MIT)
|
||||
- unic-langid 0.9 (Apache-2.0 OR MIT)
|
||||
|
||||
---
|
||||
|
||||
## Transitive Dependencies
|
||||
|
||||
Total: **286 dependencies** across all features.
|
||||
|
||||
### License Distribution
|
||||
|
||||
| License | Count |
|
||||
|---------|-------|
|
||||
| Apache-2.0 OR MIT | 190 |
|
||||
| MIT | 66 |
|
||||
| Apache-2.0 | 3 |
|
||||
| MIT OR Unlicense | 7 |
|
||||
| Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT | 7 |
|
||||
| Other | 13 |
|
||||
|
||||
---
|
||||
|
||||
## License Compatibility
|
||||
|
||||
All dependencies are compatible with the **MIT License**:
|
||||
|
||||
- ✓ **Permissive licenses** (MIT, Apache-2.0, BSD-3-Clause, Zlib, MPL-2.0)
|
||||
- ✓ **Weak copyleft** (LGPL-2.1-or-later, MPL-2.0)
|
||||
- ✓ **Public domain** (Unlicense, Unicode-3.0)
|
||||
|
||||
---
|
||||
|
||||
## Files
|
||||
|
||||
- `LICENSE.md` - Full dependency license attribution
|
||||
- `SBOM.spdx.json` - Software Bill of Materials (SPDX 2.3 format)
|
||||
- `SBOM.cyclonedx.json` - Software Bill of Materials (CycloneDX 1.4 format)
|
||||
- `Cargo.lock` - Locked dependency versions for reproducibility
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### No Unsafe Code
|
||||
|
||||
The workspace forbids `unsafe` code:
|
||||
```toml
|
||||
[workspace.lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
```
|
||||
|
||||
### Dependency Auditing
|
||||
|
||||
Run security audit:
|
||||
```bash
|
||||
cargo audit
|
||||
```
|
||||
|
||||
Review dependency tree:
|
||||
```bash
|
||||
cargo tree --depth=2
|
||||
```
|
||||
|
||||
### SBOM Usage
|
||||
|
||||
SBOMs can be used with:
|
||||
- **SPDX format** - CycloneDX tools, GitHub Dependabot, SPDX validators
|
||||
- **CycloneDX format** - Software composition analysis tools, vulnerability scanners
|
||||
|
||||
---
|
||||
|
||||
Generated: 2024-12-17
|
||||
@ -207,12 +207,13 @@ clean-distro:
|
||||
|
||||
# === COMPLIANCE ===
|
||||
|
||||
# Regenerate SBOMs (LICENSE.md + SBOM.spdx.json + SBOM.cyclonedx.json)
|
||||
[doc("Regenerate SBOMs and license documentation")]
|
||||
# Regenerate SBOMs (SBOM.spdx.json + SBOM.cyclonedx.json)
|
||||
[doc("Regenerate SBOMs (SPDX 2.3 and CycloneDX 1.4)")]
|
||||
generate-sbom:
|
||||
@echo "=== Regenerating SBOMs ==="
|
||||
python3 "{{ WORKSPACE_ROOT }}/scripts/generate_sbom.py"
|
||||
cd "{{ WORKSPACE_ROOT }}" && \
|
||||
cargo sbom --output-format spdx_json_2_3 > SBOM.spdx.json && \
|
||||
cargo sbom --output-format cyclone_dx_json_1_4 > SBOM.cyclonedx.json
|
||||
@echo "✓ SBOMs regenerated"
|
||||
@echo " - LICENSE.md (dependency attribution)"
|
||||
@echo " - SBOM.spdx.json (SPDX 2.3 format)"
|
||||
@echo " - SBOM.cyclonedx.json (CycloneDX 1.4 format)"
|
||||
|
||||
@ -1,282 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate Software Bill of Materials (SBOM) in multiple formats.
|
||||
|
||||
Generates:
|
||||
- LICENSE.md - Detailed dependency attribution
|
||||
- DEPENDENCIES.md - Organized dependency tree
|
||||
- SBOM.spdx.json - SPDX 2.3 format
|
||||
- SBOM.cyclonedx.json - CycloneDX 1.4 format
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_workspace_root():
|
||||
"""Get workspace root directory."""
|
||||
script_dir = Path(__file__).parent
|
||||
return script_dir.parent
|
||||
|
||||
|
||||
def run_cargo_license():
|
||||
"""Get dependency licenses from cargo-license."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["cargo", "license", "--json"], capture_output=True, text=True, check=True
|
||||
)
|
||||
return json.loads(result.stdout)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running cargo license: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error parsing cargo license output: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def generate_license_md(licenses, workspace_root):
|
||||
"""Generate LICENSE.md with dependency attribution."""
|
||||
by_license = defaultdict(list)
|
||||
for pkg in licenses:
|
||||
lic = pkg.get("license", "Unknown")
|
||||
by_license[lic].append(pkg)
|
||||
|
||||
content = """# TypeDialog License
|
||||
|
||||
## Project License
|
||||
|
||||
TypeDialog is licensed under the **MIT License**.
|
||||
|
||||
See [LICENSE](LICENSE) file for the full MIT license text.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
This project includes the following dependencies under their respective licenses:
|
||||
|
||||
"""
|
||||
|
||||
# Apache-2.0 only
|
||||
if "Apache-2.0" in by_license:
|
||||
content += f"### Apache-2.0 Only ({len(by_license['Apache-2.0'])})\n"
|
||||
for pkg in sorted(by_license["Apache-2.0"], key=lambda x: x["name"]):
|
||||
content += f"- {pkg['name']} {pkg['version']}\n"
|
||||
content += "\n"
|
||||
|
||||
# MIT only
|
||||
if "MIT" in by_license:
|
||||
content += f"### MIT Only ({len(by_license['MIT'])})\n"
|
||||
for pkg in sorted(by_license["MIT"], key=lambda x: x["name"]):
|
||||
content += f"- {pkg['name']} {pkg['version']}\n"
|
||||
content += "\n"
|
||||
|
||||
# Apache-2.0 OR MIT (dual licensed)
|
||||
if "Apache-2.0 OR MIT" in by_license:
|
||||
content += f"### Apache-2.0 OR MIT ({len(by_license['Apache-2.0 OR MIT'])})\n\n"
|
||||
content += (
|
||||
"Most dependencies use dual licensing between Apache-2.0 and MIT.\n\n"
|
||||
)
|
||||
for i, pkg in enumerate(
|
||||
sorted(by_license["Apache-2.0 OR MIT"], key=lambda x: x["name"]), 1
|
||||
):
|
||||
content += f"- {pkg['name']} {pkg['version']}"
|
||||
if i % 3 != 0:
|
||||
content += " | "
|
||||
else:
|
||||
content += "\n"
|
||||
content += "\n\n"
|
||||
|
||||
# MIT OR Unlicense
|
||||
if "MIT OR Unlicense" in by_license:
|
||||
content += f"### MIT OR Unlicense ({len(by_license['MIT OR Unlicense'])})\n"
|
||||
for pkg in sorted(by_license["MIT OR Unlicense"], key=lambda x: x["name"]):
|
||||
content += f"- {pkg['name']} {pkg['version']}\n"
|
||||
content += "\n"
|
||||
|
||||
# Other licenses
|
||||
other = {
|
||||
k: v
|
||||
for k, v in by_license.items()
|
||||
if k not in ["Apache-2.0", "MIT", "Apache-2.0 OR MIT", "MIT OR Unlicense"]
|
||||
}
|
||||
|
||||
if other:
|
||||
content += "### Other Licenses\n\n"
|
||||
for lic, pkgs in sorted(other.items()):
|
||||
content += f"**{lic}** ({len(pkgs)})\n"
|
||||
for pkg in sorted(pkgs, key=lambda x: x["name"]):
|
||||
content += f"- {pkg['name']} {pkg['version']}\n"
|
||||
content += "\n"
|
||||
|
||||
# Summary
|
||||
unique_licenses = set()
|
||||
for pkg in licenses:
|
||||
lic = pkg.get("license", "Unknown")
|
||||
for part in lic.replace(" OR ", "|").replace(" AND ", "|").split("|"):
|
||||
unique_licenses.add(part.strip())
|
||||
|
||||
content += f"""---
|
||||
|
||||
## Summary
|
||||
|
||||
- **Project License**: MIT
|
||||
- **Total Dependencies**: {len(licenses)}
|
||||
- **Unique License Types**: {len(by_license)} different combinations
|
||||
- **Primary License Pattern**: Apache-2.0 OR MIT (most dependencies)
|
||||
|
||||
### Compliance
|
||||
|
||||
All dependencies are compatible with the MIT license under:
|
||||
- Permissive licenses (MIT, Apache-2.0, BSD-3-Clause, MPL-2.0, Zlib)
|
||||
- Weak copyleft (LGPL-2.1-or-later, MPL-2.0)
|
||||
- Public domain (Unlicense, Unicode-3.0)
|
||||
|
||||
### Generated
|
||||
|
||||
- Date: {datetime.now().isoformat()}
|
||||
- Tool: cargo-license
|
||||
|
||||
See [DEPENDENCIES.md](DEPENDENCIES.md) for the complete dependency tree.
|
||||
"""
|
||||
|
||||
output_file = workspace_root / "LICENSE.md"
|
||||
output_file.write_text(content)
|
||||
return output_file
|
||||
|
||||
|
||||
def generate_sbom_spdx(licenses, workspace_root):
|
||||
"""Generate SPDX 2.3 format SBOM."""
|
||||
spdx = {
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"spdxVersion": "SPDX-2.3",
|
||||
"creationInfo": {
|
||||
"created": datetime.now().isoformat() + "Z",
|
||||
"creators": ["Tool: cargo-license"],
|
||||
},
|
||||
"name": "typedialog",
|
||||
"dataLicense": "CC0-1.0",
|
||||
"documentNamespace": f"https://github.com/anthropics/typedialog/sbom-{datetime.now().strftime('%Y%m%d')}",
|
||||
"packages": [],
|
||||
}
|
||||
|
||||
# Add project
|
||||
spdx["packages"].append(
|
||||
{
|
||||
"SPDXID": "SPDXRef-typedialog",
|
||||
"name": "typedialog",
|
||||
"version": "0.1.0",
|
||||
"downloadLocation": "https://github.com/anthropics/typedialog",
|
||||
"homepage": "https://github.com/anthropics/typedialog",
|
||||
"licenseDeclared": "MIT",
|
||||
"licenseConcluded": "MIT",
|
||||
"filesAnalyzed": False,
|
||||
}
|
||||
)
|
||||
|
||||
# Add dependencies
|
||||
for i, pkg in enumerate(licenses, 1):
|
||||
spdx["packages"].append(
|
||||
{
|
||||
"SPDXID": f"SPDXRef-dependency-{i}",
|
||||
"name": pkg["name"],
|
||||
"version": pkg["version"],
|
||||
"downloadLocation": pkg.get("repository", "NOASSERTION"),
|
||||
"licenseDeclared": pkg.get("license", "NOASSERTION"),
|
||||
"licenseConcluded": pkg.get("license", "NOASSERTION"),
|
||||
"filesAnalyzed": False,
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "PACKAGE-MANAGER",
|
||||
"referenceType": "crates",
|
||||
"referenceLocator": f"pkg:cargo/{pkg['name']}@{pkg['version']}",
|
||||
}
|
||||
]
|
||||
if pkg["name"]
|
||||
else [],
|
||||
}
|
||||
)
|
||||
|
||||
output_file = workspace_root / "SBOM.spdx.json"
|
||||
with open(output_file, "w") as f:
|
||||
json.dump(spdx, f, indent=2)
|
||||
|
||||
return output_file
|
||||
|
||||
|
||||
def generate_sbom_cyclonedx(licenses, workspace_root):
|
||||
"""Generate CycloneDX 1.4 format SBOM."""
|
||||
cyclone = {
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.4",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": datetime.now().isoformat() + "Z",
|
||||
"tools": [{"vendor": "cargo", "name": "cargo-license", "version": "1.0"}],
|
||||
"component": {
|
||||
"type": "application",
|
||||
"name": "typedialog",
|
||||
"version": "0.1.0",
|
||||
"homepage": "https://github.com/anthropics/typedialog",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/typedialog",
|
||||
},
|
||||
"licenses": [{"license": {"name": "MIT"}}],
|
||||
},
|
||||
},
|
||||
"components": [],
|
||||
}
|
||||
|
||||
for pkg in licenses:
|
||||
cyclone["components"].append(
|
||||
{
|
||||
"type": "library",
|
||||
"name": pkg["name"],
|
||||
"version": pkg["version"],
|
||||
"purl": f"pkg:cargo/{pkg['name']}@{pkg['version']}",
|
||||
"homepage": pkg.get("repository", ""),
|
||||
"licenses": [{"license": {"name": pkg.get("license", "Unknown")}}],
|
||||
}
|
||||
)
|
||||
|
||||
output_file = workspace_root / "SBOM.cyclonedx.json"
|
||||
with open(output_file, "w") as f:
|
||||
json.dump(cyclone, f, indent=2)
|
||||
|
||||
return output_file
|
||||
|
||||
|
||||
def main():
|
||||
"""Generate all SBOM files."""
|
||||
workspace_root = get_workspace_root()
|
||||
|
||||
print("📦 Fetching dependency licenses...", file=sys.stderr)
|
||||
licenses = run_cargo_license()
|
||||
print(f" Found {len(licenses)} dependencies", file=sys.stderr)
|
||||
|
||||
print("📝 Generating LICENSE.md...", file=sys.stderr)
|
||||
lic_file = generate_license_md(licenses, workspace_root)
|
||||
print(f" ✓ {lic_file.name}", file=sys.stderr)
|
||||
|
||||
print("📄 Generating SBOM.spdx.json...", file=sys.stderr)
|
||||
spdx_file = generate_sbom_spdx(licenses, workspace_root)
|
||||
print(f" ✓ {spdx_file.name}", file=sys.stderr)
|
||||
|
||||
print("📄 Generating SBOM.cyclonedx.json...", file=sys.stderr)
|
||||
cyclone_file = generate_sbom_cyclonedx(licenses, workspace_root)
|
||||
print(f" ✓ {cyclone_file.name}", file=sys.stderr)
|
||||
|
||||
print(f"\n✅ SBOM generation complete", file=sys.stderr)
|
||||
print(
|
||||
f" - License combinations: {len(set(p.get('license', 'Unknown') for p in licenses))}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(f" - Generated: {datetime.now().isoformat()}", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user