summaryrefslogtreecommitdiffstats
path: root/classes/go-mod-discovery.bbclass
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2026-04-28 18:49:19 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2026-04-28 18:49:19 +0000
commitcd15723c5d62bbfa4c07c36eb7ab7bd962bd4936 (patch)
tree0dea471977d0b5c14e1523f2a1a206d9d3fd6137 /classes/go-mod-discovery.bbclass
parenta66c8df6fdc9025d0cbfae76252e12fc530a4824 (diff)
downloadmeta-virtualization-cd15723c5d62bbfa4c07c36eb7ab7bd962bd4936.tar.gz
oe-go-mod-fetcher: add license scanning for Go module dependencies
Add --scan-licenses to oe-go-mod-fetcher.py which scans Go module zips for license files and generates go-mod-licenses.inc with LICENSE and LIC_FILES_CHKSUM entries matching OE-core's go-mod-update-modules format. License detection uses OE-core's glob patterns and MD5 + crunched MD5 matching against known SPDX licenses. The hash database resolves from: 1. --common-license-dir (explicit path) 2. Auto-detected poky tree common-licenses 3. Bundled scripts/data/license-hashes.csv (offline fallback) New files: - scripts/generate-license-hashes.py: regenerate bundled CSV - scripts/data/license-hashes.csv: pre-computed hash DB (704 entries) bbclass changes: - go-mod-discovery: pass --scan-licenses during do_generate_modules - GO_MOD_DISCOVERY_SKIP_LICENSES variable to bypass scanning - do_update_license_hashes task to refresh bundled CSV Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'classes/go-mod-discovery.bbclass')
-rw-r--r--classes/go-mod-discovery.bbclass88
1 files changed, 84 insertions, 4 deletions
diff --git a/classes/go-mod-discovery.bbclass b/classes/go-mod-discovery.bbclass
index 39cc38da..9609ee35 100644
--- a/classes/go-mod-discovery.bbclass
+++ b/classes/go-mod-discovery.bbclass
@@ -32,6 +32,10 @@
32# bitbake <recipe> -c clean_discovery 32# bitbake <recipe> -c clean_discovery
33# Remove the persistent discovery cache 33# Remove the persistent discovery cache
34# 34#
35# bitbake <recipe> -c update_license_hashes
36# Regenerate the bundled license-hashes.csv from COMMON_LICENSE_DIR
37# Run after OE-core upgrades to keep standalone CSV current
38#
35# CONFIGURATION: 39# CONFIGURATION:
36# 40#
37# Required (must be set by recipe): 41# Required (must be set by recipe):
@@ -74,6 +78,9 @@
74# GO_MOD_DISCOVERY_RECIPEDIR - Output directory for generated .inc files 78# GO_MOD_DISCOVERY_RECIPEDIR - Output directory for generated .inc files
75# Default: "${FILE_DIRNAME}" (recipe's directory) 79# Default: "${FILE_DIRNAME}" (recipe's directory)
76# 80#
81# GO_MOD_DISCOVERY_SKIP_LICENSES - Set to "1" to skip license scanning
82# Default: "" (scan enabled)
83#
77# WORKFLOW EXAMPLES: 84# WORKFLOW EXAMPLES:
78# 85#
79# Full automatic (one command does everything): 86# Full automatic (one command does everything):
@@ -122,6 +129,11 @@ GO_MOD_DISCOVERY_RECIPEDIR ?= "${FILE_DIRNAME}"
122# Usage: GO_MOD_DISCOVERY_SKIP_VERIFY = "1" in local.conf or recipe 129# Usage: GO_MOD_DISCOVERY_SKIP_VERIFY = "1" in local.conf or recipe
123GO_MOD_DISCOVERY_SKIP_VERIFY ?= "" 130GO_MOD_DISCOVERY_SKIP_VERIFY ?= ""
124 131
132# Skip license scanning during generation
133# Set to "1" to bypass license scanning (default: scan licenses)
134# Usage: GO_MOD_DISCOVERY_SKIP_LICENSES = "1" in local.conf or recipe
135GO_MOD_DISCOVERY_SKIP_LICENSES ?= ""
136
125# Modules to exclude from git:// generation (space-separated prefixes) 137# Modules to exclude from git:// generation (space-separated prefixes)
126# Excluded modules must be fetched via gomod:// in the recipe's SRC_URI 138# Excluded modules must be fetched via gomod:// in the recipe's SRC_URI
127# Usage: GO_MOD_VCS_EXCLUDE = "github.com/vtolstov/go-ioctl" 139# Usage: GO_MOD_VCS_EXCLUDE = "github.com/vtolstov/go-ioctl"
@@ -406,13 +418,19 @@ Or run 'bitbake ${PN} -c show_upgrade_commands' to see manual options."
406 EXCLUDE_FLAGS="${EXCLUDE_FLAGS} --exclude-module ${mod}" 418 EXCLUDE_FLAGS="${EXCLUDE_FLAGS} --exclude-module ${mod}"
407 done 419 done
408 420
421 LICENSE_FLAGS=""
422 if [ "${GO_MOD_DISCOVERY_SKIP_LICENSES}" != "1" ]; then
423 LICENSE_FLAGS="--scan-licenses --common-license-dir ${COMMON_LICENSE_DIR} --discovery-cache ${GO_MOD_DISCOVERY_DIR}/cache"
424 fi
425
409 python3 "${FETCHER_SCRIPT}" \ 426 python3 "${FETCHER_SCRIPT}" \
410 --discovered-modules "${GO_MOD_DISCOVERY_MODULES_JSON}" \ 427 --discovered-modules "${GO_MOD_DISCOVERY_MODULES_JSON}" \
411 --git-repo "${GO_MOD_DISCOVERY_GIT_REPO}" \ 428 --git-repo "${GO_MOD_DISCOVERY_GIT_REPO}" \
412 --git-ref "${GO_MOD_DISCOVERY_GIT_REF}" \ 429 --git-ref "${GO_MOD_DISCOVERY_GIT_REF}" \
413 --recipedir "${GO_MOD_DISCOVERY_RECIPEDIR}" \ 430 --recipedir "${GO_MOD_DISCOVERY_RECIPEDIR}" \
414 ${SKIP_VERIFY_FLAG} \ 431 ${SKIP_VERIFY_FLAG} \
415 ${EXCLUDE_FLAGS} 432 ${EXCLUDE_FLAGS} \
433 ${LICENSE_FLAGS}
416 434
417 if [ $? -eq 0 ]; then 435 if [ $? -eq 0 ]; then
418 echo "" 436 echo ""
@@ -422,6 +440,7 @@ Or run 'bitbake ${PN} -c show_upgrade_commands' to see manual options."
422 echo "Files generated in: ${GO_MOD_DISCOVERY_RECIPEDIR}" 440 echo "Files generated in: ${GO_MOD_DISCOVERY_RECIPEDIR}"
423 echo " - go-mod-git.inc" 441 echo " - go-mod-git.inc"
424 echo " - go-mod-cache.inc" 442 echo " - go-mod-cache.inc"
443 echo " - go-mod-licenses.inc (if license scanning enabled)"
425 echo "" 444 echo ""
426 echo "You can now build the recipe:" 445 echo "You can now build the recipe:"
427 echo " bitbake ${PN}" 446 echo " bitbake ${PN}"
@@ -434,7 +453,7 @@ Or run 'bitbake ${PN} -c show_upgrade_commands' to see manual options."
434addtask generate_modules 453addtask generate_modules
435do_generate_modules[nostamp] = "1" 454do_generate_modules[nostamp] = "1"
436do_generate_modules[vardeps] += "GO_MOD_DISCOVERY_MODULES_JSON GO_MOD_DISCOVERY_GIT_REPO \ 455do_generate_modules[vardeps] += "GO_MOD_DISCOVERY_MODULES_JSON GO_MOD_DISCOVERY_GIT_REPO \
437 GO_MOD_DISCOVERY_GIT_REF GO_MOD_DISCOVERY_RECIPEDIR" 456 GO_MOD_DISCOVERY_GIT_REF GO_MOD_DISCOVERY_RECIPEDIR GO_MOD_DISCOVERY_SKIP_LICENSES"
438do_generate_modules[postfuncs] = "do_show_hybrid_recommendation" 457do_generate_modules[postfuncs] = "do_show_hybrid_recommendation"
439 458
440# Show hybrid conversion recommendations after VCS generation 459# Show hybrid conversion recommendations after VCS generation
@@ -627,12 +646,22 @@ python do_show_upgrade_commands() {
627 bb.plain(f" --git-ref {git_ref} \\") 646 bb.plain(f" --git-ref {git_ref} \\")
628 bb.plain(f" --recipedir {recipedir}") 647 bb.plain(f" --recipedir {recipedir}")
629 bb.plain("") 648 bb.plain("")
649 bb.plain("Add --scan-licenses to also generate go-mod-licenses.inc:")
650 bb.plain("")
651 bb.plain(f" {fetcher_script} \\")
652 bb.plain(f" --discovered-modules {modules_json} \\")
653 bb.plain(f" --git-repo {git_repo} \\")
654 bb.plain(f" --git-ref {git_ref} \\")
655 bb.plain(f" --recipedir {recipedir} \\")
656 bb.plain(f" --scan-licenses --discovery-cache {discovery_dir}/cache")
657 bb.plain("")
630 bb.plain("") 658 bb.plain("")
631 bb.plain("Generated files:") 659 bb.plain("Generated files:")
632 bb.plain("-" * 70) 660 bb.plain("-" * 70)
633 bb.plain("") 661 bb.plain("")
634 bb.plain(" go-mod-git.inc - SRC_URI entries for fetching module git repos") 662 bb.plain(" go-mod-git.inc - SRC_URI entries for fetching module git repos")
635 bb.plain(" go-mod-cache.inc - Module path mappings for cache creation") 663 bb.plain(" go-mod-cache.inc - Module path mappings for cache creation")
664 bb.plain(" go-mod-licenses.inc - LICENSE and LIC_FILES_CHKSUM for dependencies")
636 bb.plain("") 665 bb.plain("")
637 bb.plain("=" * 70) 666 bb.plain("=" * 70)
638 bb.plain("") 667 bb.plain("")
@@ -642,3 +671,54 @@ addtask show_upgrade_commands
642do_show_upgrade_commands[nostamp] = "1" 671do_show_upgrade_commands[nostamp] = "1"
643do_show_upgrade_commands[vardeps] += "GO_MOD_DISCOVERY_GIT_REPO GO_MOD_DISCOVERY_GIT_REF \ 672do_show_upgrade_commands[vardeps] += "GO_MOD_DISCOVERY_GIT_REPO GO_MOD_DISCOVERY_GIT_REF \
644 GO_MOD_DISCOVERY_RECIPEDIR GO_MOD_DISCOVERY_DIR GO_MOD_DISCOVERY_MODULES_JSON" 673 GO_MOD_DISCOVERY_RECIPEDIR GO_MOD_DISCOVERY_DIR GO_MOD_DISCOVERY_MODULES_JSON"
674
675# =============================================================================
676# TASK: do_update_license_hashes - Regenerate bundled license hash CSV
677# =============================================================================
678# Regenerates scripts/data/license-hashes.csv from ${COMMON_LICENSE_DIR}.
679# Run after OE-core upgrades to keep the bundled CSV current for standalone users.
680#
681# Usage: bitbake <any-go-recipe> -c update_license_hashes
682#
683python do_update_license_hashes() {
684 import subprocess
685 from pathlib import Path
686
687 common_license_dir = d.getVar('COMMON_LICENSE_DIR')
688 if not common_license_dir or not os.path.isdir(common_license_dir):
689 bb.fatal(f"COMMON_LICENSE_DIR not found: {common_license_dir}")
690
691 # Find the generator script and output path
692 layerdir = None
693 for layer in d.getVar('BBLAYERS').split():
694 candidate = os.path.join(layer, 'scripts', 'generate-license-hashes.py')
695 if os.path.exists(candidate):
696 layerdir = layer
697 break
698
699 if not layerdir:
700 bb.fatal("Could not find generate-license-hashes.py in any layer")
701
702 script = os.path.join(layerdir, 'scripts', 'generate-license-hashes.py')
703 output = os.path.join(layerdir, 'scripts', 'data', 'license-hashes.csv')
704
705 bb.plain(f"Regenerating {output} from {common_license_dir}")
706
707 result = subprocess.run(
708 ['python3', script, common_license_dir],
709 capture_output=True, text=True, timeout=60
710 )
711
712 if result.returncode != 0:
713 bb.fatal(f"generate-license-hashes.py failed: {result.stderr}")
714
715 os.makedirs(os.path.dirname(output), exist_ok=True)
716 with open(output, 'w') as f:
717 f.write(result.stdout)
718
719 lines = [l for l in result.stdout.splitlines() if l and not l.startswith('#')]
720 bb.plain(f"Generated {len(lines)} license hash entries in {output}")
721}
722
723addtask update_license_hashes
724do_update_license_hashes[nostamp] = "1"