mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
125 lines
3.8 KiB
Bash
Executable File
125 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Collect third-party license texts into LICENSES.md
|
|
# Usage: scripts/collect_licenses.sh [output-path]
|
|
# output-path defaults to LICENSES.md at the repo root
|
|
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
OUT="${1:-$REPO_ROOT/LICENSES.md}"
|
|
|
|
# ── Backend (Python) — uses pip-licenses ─────────────────────────────
|
|
backend_licenses() {
|
|
cd "$REPO_ROOT"
|
|
|
|
# Extract direct dependency names from pyproject.toml
|
|
local packages
|
|
packages=$(uv run python3 -c "
|
|
import re, tomllib
|
|
with open('pyproject.toml', 'rb') as f:
|
|
deps = tomllib.load(f)['project']['dependencies']
|
|
names = [re.split(r'[\[><=!;]', d)[0].strip() for d in deps]
|
|
print(' '.join(names))
|
|
")
|
|
|
|
# shellcheck disable=SC2086
|
|
uv run pip-licenses \
|
|
--packages $packages \
|
|
--with-license-file \
|
|
--no-license-path \
|
|
--format=json \
|
|
| uv run python3 -c "
|
|
import json, sys
|
|
|
|
data = sorted(json.load(sys.stdin), key=lambda d: d['Name'].lower())
|
|
for d in data:
|
|
name = d['Name']
|
|
version = d['Version']
|
|
lic = d.get('License', 'Unknown')
|
|
text = d.get('LicenseText', '').strip()
|
|
|
|
print(f'### {name} ({version}) — {lic}\n')
|
|
if text and text != 'UNKNOWN':
|
|
print('<details>')
|
|
print('<summary>Full license text</summary>')
|
|
print()
|
|
print('\`\`\`')
|
|
print(text)
|
|
print('\`\`\`')
|
|
print()
|
|
print('</details>')
|
|
else:
|
|
print('*License file not found in package metadata.*')
|
|
print()
|
|
"
|
|
}
|
|
|
|
# ── Frontend (npm) ───────────────────────────────────────────────────
|
|
frontend_licenses() {
|
|
cd "$REPO_ROOT/frontend"
|
|
|
|
node -e "
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
const depNames = Object.keys(pkg.dependencies || {}).sort((a, b) =>
|
|
a.toLowerCase().localeCompare(b.toLowerCase())
|
|
);
|
|
|
|
for (const name of depNames) {
|
|
const pkgDir = path.join('node_modules', name);
|
|
let version = 'unknown';
|
|
let licenseType = 'Unknown';
|
|
let licenseText = null;
|
|
|
|
// Read package.json for version + license type
|
|
try {
|
|
const depPkg = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8'));
|
|
version = depPkg.version || version;
|
|
licenseType = depPkg.license || licenseType;
|
|
} catch {}
|
|
|
|
// Find license file (case-insensitive search)
|
|
try {
|
|
const files = fs.readdirSync(pkgDir);
|
|
const licFile = files.find(f => /^(licen[sc]e|copying)/i.test(f));
|
|
if (licFile) {
|
|
licenseText = fs.readFileSync(path.join(pkgDir, licFile), 'utf8').trim();
|
|
}
|
|
} catch {}
|
|
|
|
console.log('### ' + name + ' (' + version + ') — ' + licenseType + '\n');
|
|
if (licenseText) {
|
|
console.log('<details>');
|
|
console.log('<summary>Full license text</summary>');
|
|
console.log();
|
|
console.log('\`\`\`');
|
|
console.log(licenseText);
|
|
console.log('\`\`\`');
|
|
console.log();
|
|
console.log('</details>');
|
|
} else {
|
|
console.log('*License file not found in package.*');
|
|
}
|
|
console.log();
|
|
}
|
|
"
|
|
}
|
|
|
|
# ── Assemble ─────────────────────────────────────────────────────────
|
|
{
|
|
echo "# Third-Party Licenses"
|
|
echo
|
|
echo "Auto-generated by \`scripts/collect_licenses.sh\` — do not edit by hand."
|
|
echo
|
|
echo "## Backend (Python) Dependencies"
|
|
echo
|
|
backend_licenses
|
|
echo "## Frontend (npm) Dependencies"
|
|
echo
|
|
frontend_licenses
|
|
} > "$OUT"
|
|
|
|
echo "Wrote $OUT" >&2
|