Merge "Update minimum supported targetSdk to 28."
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index ab2564e..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["build_make_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
- name: "build_make_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- "SPDX-license-identifier-BSD",
- "SPDX-license-identifier-CC-BY",
- "SPDX-license-identifier-GPL",
- "SPDX-license-identifier-GPL-2.0",
- "SPDX-license-identifier-LGPL",
- "SPDX-license-identifier-MIT",
- "legacy_not_a_contribution",
- "legacy_restricted",
- ],
- // large-scale-change unable to identify any license_text files
-}
diff --git a/core/Makefile b/core/Makefile
index 4c1ae51..e65e949 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -527,16 +527,6 @@
$(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,GENERIC_RAMDISK,$(TARGET_RAMDISK_OUT),,modules.load,,$(kmd)))))
# -----------------------------------------------------------------
-# FSVerity metadata generation
-ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
-
-FSVERITY_APK_KEY_PATH := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
-FSVERITY_APK_OUT := system/etc/security/fsverity/BuildManifest.apk
-FSVERITY_APK_MANIFEST_PATH := system/security/fsverity/AndroidManifest.xml
-
-endif # PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
-
-# -----------------------------------------------------------------
# Cert-to-package mapping. Used by the post-build signing tools.
# Use a macro to add newline to each echo command
# $1 stem name of the package
@@ -784,6 +774,7 @@
$(INSTALLED_FILES_FILE_ROOT): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_ROOT)
$(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_ROOT_FILES) $(FILESLIST) $(FILESLIST_UTIL)
@echo Installed file list: $@
+ mkdir -p $(TARGET_ROOT_OUT)
mkdir -p $(dir $@)
rm -f $@
$(FILESLIST) $(TARGET_ROOT_OUT) > $(@:.txt=.json)
@@ -822,7 +813,7 @@
$(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk win_sdk sdk_addon, $(INSTALLED_FILES_FILE_RAMDISK))
+$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE_RAMDISK))
endif
BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
@@ -910,9 +901,11 @@
INTERNAL_INIT_BOOT_IMAGE_ARGS :=
+INTERNAL_BOOT_HAS_RAMDISK :=
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
ifneq ($(BUILDING_INIT_BOOT_IMAGE),true)
INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
+ INTERNAL_BOOT_HAS_RAMDISK := true
else
INTERNAL_INIT_BOOT_IMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
endif
@@ -961,21 +954,48 @@
--os_version $(PLATFORM_VERSION_LAST_STABLE) \
--os_patch_level $(PLATFORM_SECURITY_PATCH)
-ifdef BOARD_GKI_SIGNING_KEY_PATH
-ifndef BOARD_GKI_SIGNING_ALGORITHM
-$(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH)
-endif
-INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS := \
- --gki_signing_key $(BOARD_GKI_SIGNING_KEY_PATH) \
- --gki_signing_algorithm $(BOARD_GKI_SIGNING_ALGORITHM) \
- --gki_signing_avbtool_path $(AVBTOOL)
-endif
+# $(1): image target to certify
+# $(2): out certificate target
+# $(3): image name
+# $(4): additional AVB arguments
+define generate_generic_boot_image_certificate
+ rm -rf "$(2)"
+ mkdir -p "$(dir $(2))"
+ $(GENERATE_GKI_CERTIFICATE) $(INTERNAL_GKI_CERTIFICATE_ARGS) \
+ --additional_avb_args "$(4)" \
+ --name "$(3)" --output "$(2)" "$(1)"
+endef
-# Using double quote to pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string
-# to MKBOOTIMG, although it may contain multiple args.
-ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
-INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS += \
- --gki_signing_signature_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)"
+INTERNAL_GKI_CERTIFICATE_ARGS :=
+INTERNAL_GKI_CERTIFICATE_DEPS :=
+INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE :=
+ifdef BOARD_GKI_SIGNING_KEY_PATH
+ ifndef BOARD_GKI_SIGNING_ALGORITHM
+ $(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH)
+ endif
+
+ INTERNAL_GKI_CERTIFICATE_ARGS := \
+ --key "$(BOARD_GKI_SIGNING_KEY_PATH)" \
+ --algorithm "$(BOARD_GKI_SIGNING_ALGORITHM)" \
+ --avbtool "$(AVBTOOL)"
+
+ # Quote and pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string argument.
+ ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
+ INTERNAL_GKI_CERTIFICATE_ARGS += --additional_avb_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)"
+ endif
+
+ INTERNAL_GKI_CERTIFICATE_DEPS := \
+ $(GENERATE_GKI_CERTIFICATE) \
+ $(BOARD_GKI_SIGNING_KEY_PATH) \
+ $(AVBTOOL)
+
+ ifdef INSTALLED_RAMDISK_TARGET
+ INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE := \
+ $(call intermediates-dir-for,PACKAGING,generic_ramdisk)/boot_signature
+
+ $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE): $(INSTALLED_RAMDISK_TARGET) $(INTERNAL_GKI_CERTIFICATE_DEPS)
+ $(call generate_generic_boot_image_certificate,$(INSTALLED_RAMDISK_TARGET),$@,generic_ramdisk,$(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS))
+ endif
endif
# Define these only if we are building boot
@@ -992,8 +1012,15 @@
# $1: boot image target
define build_boot_board_avb_enabled
- $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
+ $(eval kernel := $(call bootimage-to-kernel,$(1)))
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH), \
+ $(eval kernel_signature := $(call intermediates-dir-for,PACKAGING,generic_kernel)/$(notdir $(kernel)).boot_signature) \
+ $(call generate_generic_boot_image_certificate,$(kernel),$(kernel_signature),generic_kernel,$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)) $(newline) \
+ $(if $(INTERNAL_BOOT_HAS_RAMDISK), \
+ cat $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE) >> $(kernel_signature) $(newline)))
+ $(MKBOOTIMG) --kernel $(kernel) $(INTERNAL_BOOTIMAGE_ARGS) \
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH),--boot_signature "$(kernel_signature)",$(INTERNAL_MKBOOTIMG_VERSION_ARGS)) \
+ $(BOARD_MKBOOTIMG_ARGS) --output $(1)
$(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(call get-bootimage-partition-size,$(1),boot)))
$(AVBTOOL) add_hash_footer \
--image $(1) \
@@ -1002,12 +1029,15 @@
$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
endef
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
+ifdef INTERNAL_BOOT_HAS_RAMDISK
+$(INSTALLED_BOOTIMAGE_TARGET): $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)
+endif
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(INTERNAL_GKI_CERTIFICATE_DEPS)
$(call pretty,"Target boot image: $@")
$(call build_boot_board_avb_enabled,$@)
.PHONY: bootimage-nodeps
-bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
+bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(INTERNAL_GKI_CERTIFICATE_DEPS)
@echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(call build_boot_board_avb_enabled,$(b)))
@@ -1106,9 +1136,12 @@
endif
ifeq ($(BOARD_AVB_ENABLE),true)
-$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_IMAGE_KEY_PATH)
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_KEY_PATH)
$(call pretty,"Target init_boot image: $@")
- $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_INIT_ARGS) --output $@
+ $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) \
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH),--boot_signature "$(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)",$(INTERNAL_MKBOOTIMG_VERSION_ARGS)) \
+ $(BOARD_MKBOOTIMG_INIT_ARGS) --output "$@"
$(call assert-max-image-size,$@,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
$(AVBTOOL) add_hash_footer \
--image $@ \
@@ -1146,6 +1179,49 @@
endif # BOARD_PREBUILT_INIT_BOOT_IMAGE
endif # BUILDING_INIT_BOOT_IMAGE is not true
+
+# -----------------------------------------------------------------
+# system dlkm image
+ifeq ($(BUILDING_SYSTEM_DLKM_IMAGE),true)
+
+INSTALLED_SYSTEM_DLKM_IMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
+
+ifeq ($(BOARD_AVB_ENABLE),true)
+$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(TARGET_SYSTEM_DLKM_SRC) $(MKEROFS) $(AVBTOOL)
+ $(call pretty,"Target system_dlkm image: $@")
+ rsync -rupE $(TARGET_SYSTEM_DLKM_SRC)/ $(TARGET_SYSTEM_DLKM_OUT)
+ $(MKEROFS) "-zlz4hc" $@ $(TARGET_SYSTEM_DLKM_OUT)
+ $(call assert-max-image-size,$@,$(BOARD_SYSTEM_DLKM_PARTITION_SIZE))
+ $(AVBTOOL) add_hash_footer \
+ --partition_name system_dlkm \
+ --partition_size $(BOARD_SYSTEM_DLKM_PARTITION_SIZE) \
+ --image $@
+else
+$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(TARGET_SYSTEM_DLKM_SRC) $(MKEROFS)
+ $(call pretty,"Target system_dlkm image: $@")
+ rsync -rupE $(TARGET_SYSTEM_DLKM_SRC)/ $(TARGET_SYSTEM_DLKM_OUT)
+ $(MKEROFS) "-zlz4hc" $@ $(TARGET_SYSTEM_DLKM_OUT)
+ $(call assert-max-image-size,$@,$(BOARD_SYSTEM_DLKM_PARTITION_SIZE))
+endif # BOARD_AVB_ENABLE
+
+else # BUILDING_SYSTEM_DLKM_IMAGE is not true
+
+ifdef BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
+
+INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE := $(BOARD_PREBUILT_SYSTEM_DLKM_IMAGE)
+INSTALLED_SYSTEM_DLKM_IMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
+$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE)
+ $(call pretty,"Using prebuilt system_dlkm image: $@")
+ cp $(INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE) $@
+
+else # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE not defined
+
+INSTALLED_SYSTEM_DLKM_IMAGE_TARGET :=
+
+endif # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
+
+endif # BUILDING_SYSTEM_DLKM_IMAGE is not true
+
# -----------------------------------------------------------------
# vendor boot image
ifeq ($(BUILDING_VENDOR_BOOT_IMAGE),true)
@@ -1743,11 +1819,6 @@
$(if $(filter $(2),system),\
$(if $(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE),$(hide) echo "system_other_size=$(INTERNAL_SYSTEM_OTHER_PARTITION_SIZE)" >> $(1))
$(if $(PRODUCT_SYSTEM_HEADROOM),$(hide) echo "system_headroom=$(PRODUCT_SYSTEM_HEADROOM)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity=$(HOST_OUT_EXECUTABLES)/fsverity" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_generate_metadata=true" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_key=$(FSVERITY_APK_KEY_PATH)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_manifest=$(FSVERITY_APK_MANIFEST_PATH)" >> $(1))
- $(if $(filter true,$(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA)),$(hide) echo "fsverity_apk_out=$(FSVERITY_APK_OUT)" >> $(1))
$(call add-common-ro-flags-to-image-props,system,$(1))
)
$(if $(filter $(2),system_other),\
@@ -2131,6 +2202,9 @@
ifdef TARGET_RECOVERY_FSTAB
recovery_fstab := $(TARGET_RECOVERY_FSTAB)
+else ifdef TARGET_RECOVERY_FSTAB_GENRULE
+# Specifies a soong genrule module that generates an fstab.
+recovery_fstab := $(call intermediates-dir-for,ETC,$(TARGET_RECOVERY_FSTAB_GENRULE))/$(TARGET_RECOVERY_FSTAB_GENRULE)
else
recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab))
endif
@@ -2309,7 +2383,7 @@
$(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \
--output $(1).unsigned, \
$(MKBOOTIMG) $(if $(strip $(2)),--kernel $(strip $(2))) $(INTERNAL_RECOVERYIMAGE_ARGS) \
- $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) \
+ $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
$(BOARD_RECOVERY_MKBOOTIMG_ARGS) --output $(1))
$(if $(filter true,$(PRODUCT_SUPPORTS_BOOT_SIGNER)),\
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
@@ -2338,9 +2412,6 @@
ifeq (true,$(BOARD_AVB_ENABLE))
recoveryimage-deps += $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
endif
-ifdef BOARD_GKI_SIGNING_KEY_PATH
- recoveryimage-deps += $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
-endif
ifdef BOARD_INCLUDE_RECOVERY_DTBO
ifdef BOARD_PREBUILT_RECOVERY_DTBOIMAGE
recoveryimage-deps += $(BOARD_PREBUILT_RECOVERY_DTBOIMAGE)
@@ -2504,17 +2575,17 @@
define build-debug-bootimage-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \
$(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
+ $(BOARD_MKBOOTIMG_ARGS) --output $1
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,boot-debug))
endef
# Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img
-$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(AVBTOOL)
$(call pretty,"Target boot debug image: $@")
$(call build-debug-bootimage-target, $@)
.PHONY: bootimage_debug-nodeps
-bootimage_debug-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+bootimage_debug-nodeps: $(MKBOOTIMG) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b))
@@ -2681,17 +2752,17 @@
define build-boot-test-harness-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-test-harness,kernel,$(notdir $(1)))) \
$(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+ $(BOARD_MKBOOTIMG_ARGS) --output $@
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@,boot-test-harness))
endef
# Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img.
-$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(AVBTOOL)
$(call pretty,"Target boot test harness image: $@")
$(call build-boot-test-harness-target,$@)
.PHONY: bootimage_test_harness-nodeps
-bootimage_test_harness-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+bootimage_test_harness-nodeps: $(MKBOOTIMG) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET),$(call build-boot-test-harness-target,$b))
@@ -2767,6 +2838,59 @@
# -----------------------------------------------------------------
# system image
+# FSVerity metadata generation
+# Generate fsverity metadata files (.fsv_meta) and build manifest
+# (system/etc/security/fsverity/BuildManifest.apk) BEFORE filtering systemimage files below
+ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
+
+# Generate fsv_meta
+fsverity-metadata-targets := $(sort $(filter \
+ $(TARGET_OUT)/framework/% \
+ $(TARGET_OUT)/etc/boot-image.prof \
+ $(TARGET_OUT)/etc/dirty-image-objects \
+ $(TARGET_OUT)/etc/classpaths/%.pb, \
+ $(ALL_GENERATED_SOURCES) $(ALL_DEFAULT_INSTALLED_MODULES)))
+
+define fsverity-generate-metadata
+$(1).fsv_meta: PRIVATE_SRC := $(1)
+$(1).fsv_meta: PRIVATE_FSVERITY := $(HOST_OUT_EXECUTABLES)/fsverity
+$(1).fsv_meta: $(HOST_OUT_EXECUTABLES)/fsverity_metadata_generator $(HOST_OUT_EXECUTABLES)/fsverity $(1)
+ $$< --fsverity-path $$(PRIVATE_FSVERITY) --signature none \
+ --hash-alg sha256 --output $$@ $$(PRIVATE_SRC)
+endef
+
+$(foreach f,$(fsverity-metadata-targets),$(eval $(call fsverity-generate-metadata,$(f))))
+ALL_DEFAULT_INSTALLED_MODULES += $(addsuffix .fsv_meta,$(fsverity-metadata-targets))
+
+# Generate BuildManifest.apk
+FSVERITY_APK_KEY_PATH := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
+FSVERITY_APK_OUT := $(TARGET_OUT)/etc/security/fsverity/BuildManifest.apk
+FSVERITY_APK_MANIFEST_PATH := system/security/fsverity/AndroidManifest.xml
+$(FSVERITY_APK_OUT): PRIVATE_FSVERITY := $(HOST_OUT_EXECUTABLES)/fsverity
+$(FSVERITY_APK_OUT): PRIVATE_AAPT2 := $(HOST_OUT_EXECUTABLES)/aapt2
+$(FSVERITY_APK_OUT): PRIVATE_MIN_SDK_VERSION := $(DEFAULT_APP_TARGET_SDK)
+$(FSVERITY_APK_OUT): PRIVATE_APKSIGNER := $(HOST_OUT_EXECUTABLES)/apksigner
+$(FSVERITY_APK_OUT): PRIVATE_MANIFEST := $(FSVERITY_APK_MANIFEST_PATH)
+$(FSVERITY_APK_OUT): PRIVATE_FRAMEWORK_RES := $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
+$(FSVERITY_APK_OUT): PRIVATE_KEY := $(FSVERITY_APK_KEY_PATH)
+$(FSVERITY_APK_OUT): PRIVATE_INPUTS := $(fsverity-metadata-targets)
+$(FSVERITY_APK_OUT): $(HOST_OUT_EXECUTABLES)/fsverity_manifest_generator \
+ $(HOST_OUT_EXECUTABLES)/fsverity $(HOST_OUT_EXECUTABLES)/aapt2 \
+ $(HOST_OUT_EXECUTABLES)/apksigner $(FSVERITY_APK_MANIFEST_PATH) \
+ $(FSVERITY_APK_KEY_PATH).x509.pem $(FSVERITY_APK_KEY_PATH).pk8 \
+ $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk \
+ $(fsverity-metadata-targets)
+ $< --fsverity-path $(PRIVATE_FSVERITY) --aapt2-path $(PRIVATE_AAPT2) \
+ --min-sdk-version $(PRIVATE_MIN_SDK_VERSION) \
+ --apksigner-path $(PRIVATE_APKSIGNER) --apk-key-path $(PRIVATE_KEY) \
+ --apk-manifest-path $(PRIVATE_MANIFEST) --framework-res $(PRIVATE_FRAMEWORK_RES) \
+ --output $@ \
+ --base-dir $(PRODUCT_OUT) $(PRIVATE_INPUTS)
+
+ALL_DEFAULT_INSTALLED_MODULES += $(FSVERITY_APK_OUT)
+
+endif # PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA
+
INTERNAL_SYSTEMIMAGE_FILES := $(sort $(filter $(TARGET_OUT)/%, \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES)))
@@ -2866,10 +2990,6 @@
ifeq ($(BOARD_AVB_ENABLE),true)
$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)
endif
-ifeq ($(PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA),true)
-$(BUILT_SYSTEMIMAGE): $(HOST_OUT_EXECUTABLES)/fsverity $(HOST_OUT_EXECUTABLES)/aapt2 $(HOST_OUT_EXECUTABLES)/apksigner \
- $(FSVERITY_APK_MANIFEST_PATH) $(FSVERITY_APK_KEY_PATH).x509.pem $(FSVERITY_APK_KEY_PATH).pk8
-endif
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
$(call build-systemimage-target,$@)
@@ -3546,7 +3666,10 @@
# $(INSTALLED_VENDORIMAGE_TARGET)" for "system vendor".
# (1): list of partitions like "system", "vendor" or "system product system_ext".
define images-for-partitions
-$(strip $(foreach item,$(1),$(if $(filter $(item),system_other),$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET))))
+$(strip $(foreach item,$(1),\
+ $(if $(filter $(item),system_other),$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),\
+ $(if $(filter $(item),init_boot),$(INSTALLED_INIT_BOOT_IMAGE_TARGET),\
+ $(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET)))))
endef
# -----------------------------------------------------------------
@@ -3663,6 +3786,10 @@
--prop com.android.build.boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
--prop com.android.build.boot.os_version:$(PLATFORM_VERSION_LAST_STABLE)
+BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.init_boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
+ --prop com.android.build.init_boot.os_version:$(PLATFORM_VERSION_LAST_STABLE)
+
BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.vendor_boot.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
@@ -3697,6 +3824,12 @@
ifdef BOOT_SECURITY_PATCH
BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.boot.security_patch:$(BOOT_SECURITY_PATCH)
+endif
+
+ifdef INIT_BOOT_SECURITY_PATCH
+BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
+ --prop com.android.build.init_boot.security_patch:$(INIT_BOOT_SECURITY_PATCH)
+else ifdef BOOT_SECURITY_PATCH
BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS += \
--prop com.android.build.init_boot.security_patch:$(BOOT_SECURITY_PATCH)
endif
@@ -3726,6 +3859,13 @@
--prop com.android.build.pvmfw.security_patch:$(PVMFW_SECURITY_PATCH)
endif
+# For upgrading devices without a init_boot partition, the init_boot footer args
+# should fallback to boot partition footer.
+ifndef INSTALLED_INIT_BOOT_IMAGE_TARGET
+BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
+ $(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
+endif
+
BOOT_FOOTER_ARGS := BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS
INIT_BOOT_FOOTER_ARGS := BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS
VENDOR_BOOT_FOOTER_ARGS := BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS
@@ -3819,7 +3959,9 @@
$(eval $(call check-and-set-avb-args,vendor_boot))
endif
+ifdef INSTALLED_SYSTEMIMAGE_TARGET
$(eval $(call check-and-set-avb-args,system))
+endif
ifdef INSTALLED_VENDORIMAGE_TARGET
$(eval $(call check-and-set-avb-args,vendor))
@@ -4435,6 +4577,7 @@
fec \
fsck.f2fs \
fs_config \
+ generate_gki_certificate \
generate_verity_key \
host_init_verifier \
img2simg \
@@ -4620,6 +4763,9 @@
endif
$(hide) echo "tool_extensions=$(tool_extensions)" >> $@
$(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $@
+ifdef PRODUCT_EXTRA_OTA_KEYS
+ $(hide) echo "extra_ota_keys=$(PRODUCT_EXTRA_OTA_KEYS)" >> $@
+endif
ifdef PRODUCT_EXTRA_RECOVERY_KEYS
$(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $@
endif
@@ -4630,8 +4776,6 @@
ifdef BOARD_GKI_SIGNING_KEY_PATH
$(hide) echo 'gki_signing_key_path=$(BOARD_GKI_SIGNING_KEY_PATH)' >> $@
$(hide) echo 'gki_signing_algorithm=$(BOARD_GKI_SIGNING_ALGORITHM)' >> $@
-endif
-ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
$(hide) echo 'gki_signing_signature_args=$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)' >> $@
endif
$(hide) echo "multistage_support=1" >> $@
@@ -4667,6 +4811,12 @@
$(hide) echo "avb_boot_algorithm=$(BOARD_AVB_BOOT_ALGORITHM)" >> $@
$(hide) echo "avb_boot_rollback_index_location=$(BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION)" >> $@
endif # BOARD_AVB_BOOT_KEY_PATH
+ $(hide) echo "avb_init_boot_add_hash_footer_args=$(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)" >> $@
+ifdef BOARD_AVB_INIT_BOOT_KEY_PATH
+ $(hide) echo "avb_init_boot_key_path=$(BOARD_AVB_INIT_BOOT_KEY_PATH)" >> $@
+ $(hide) echo "avb_init_boot_algorithm=$(BOARD_AVB_INIT_BOOT_ALGORITHM)" >> $@
+ $(hide) echo "avb_init_boot_rollback_index_location=$(BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX_LOCATION)" >> $@
+endif # BOARD_AVB_INIT_BOOT_KEY_PATH
echo "avb_vendor_boot_add_hash_footer_args=$(BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS)" >> $@
ifdef BOARD_AVB_VENDOR_BOOT_KEY_PATH
echo "avb_vendor_boot_key_path=$(BOARD_AVB_VENDOR_BOOT_KEY_PATH)" >> $@
@@ -4823,14 +4973,16 @@
tool_extension := $(wildcard $(tool_extensions)/releasetools.py)
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_TOOL_EXTENSION := $(tool_extension)
+updaer_dep :=
ifeq ($(AB_OTA_UPDATER),true)
-updater_dep := system/update_engine/update_engine.conf
-updater_dep := external/zucchini/version_info.h
+updater_dep += system/update_engine/update_engine.conf
+updater_dep += external/zucchini/version_info.h
+updater_dep += $(HOST_OUT_SHARED_LIBRARIES)/liblz4.so
endif
# Build OTA tools if non-A/B is allowed
ifeq ($(TARGET_OTA_ALLOW_NON_AB),true)
-updater_dep := $(built_ota_tools)
+updater_dep += $(built_ota_tools)
endif
$(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
@@ -4949,6 +5101,10 @@
# image.
ifdef BUILDING_SYSTEM_IMAGE
$(BUILT_TARGET_FILES_PACKAGE): $(FULL_SYSTEMIMAGE_DEPS)
+else
+ # releasetools may need the system build.prop even when building a
+ # system-image-less product.
+ $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_BUILD_PROP_TARGET)
endif
ifdef BUILDING_USERDATA_IMAGE
@@ -5195,6 +5351,12 @@
@# Contents of the system image
$(hide) $(call package_files-copy-root, \
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
+else ifdef INSTALLED_BUILD_PROP_TARGET
+ @# Copy the system build.prop even if not building a system image
+ @# because add_img_to_target_files may need it to build other partition
+ @# images.
+ $(hide) mkdir -p "$(zip_root)/SYSTEM"
+ $(hide) cp "$(INSTALLED_BUILD_PROP_TARGET)" "$(patsubst $(TARGET_OUT)/%,$(zip_root)/SYSTEM/%,$(INSTALLED_BUILD_PROP_TARGET))"
endif
ifdef BUILDING_USERDATA_IMAGE
@# Contents of the data image
@@ -5301,6 +5463,7 @@
@# When using the A/B updater, include the updater config files in the zip.
$(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt
$(hide) cp $(TOPDIR)external/zucchini/version_info.h $(zip_root)/META/zucchini_config.txt
+ $(hide) cp $(HOST_OUT_SHARED_LIBRARIES)/liblz4.so $(zip_root)/META/liblz4.so
$(hide) for part in $(strip $(AB_OTA_PARTITIONS)); do \
echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \
done
@@ -5330,11 +5493,11 @@
$(hide) cp $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) $(zip_root)/IMAGES/
endif
ifdef BOARD_PREBUILT_INIT_BOOT_IMAGE
- $(hide) mkdir -p $(zip_root)/IMAGES
- $(hide) cp $(INSTALLED_INIT_BOOT_IMAGE_TARGET) $(zip_root)/IMAGES/
+ $(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
+ $(hide) cp $(INSTALLED_INIT_BOOT_IMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
endif
ifndef BOARD_PREBUILT_BOOTIMAGE
-ifneq (,$(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES)))
+ifneq (,$(strip $(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES))))
ifdef INSTALLED_BOOTIMAGE_TARGET
$(hide) mkdir -p $(zip_root)/IMAGES
$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
@@ -6223,6 +6386,10 @@
haiku: $(SOONG_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_FUZZ_TARGETS)
$(call dist-for-goals,haiku,$(SOONG_FUZZ_PACKAGING_ARCH_MODULES))
+.PHONY: haiku-java
+haiku-java: $(SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_JAVA_FUZZ_TARGETS)
+$(call dist-for-goals,haiku-java,$(SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES))
+
.PHONY: haiku-rust
haiku-rust: $(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES) $(ALL_RUST_FUZZ_TARGETS)
$(call dist-for-goals,haiku-rust,$(SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES))
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index d4bdbbd..0befbfa 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -104,6 +104,9 @@
$(call add_soong_config_var_value,ANDROID,module_build_from_source,true)
endif
+# TODO(b/203088572): Remove when Java optimizations enabled by default for
+# SystemUI.
+$(call add_soong_config_var,ANDROID,SYSTEMUI_OPTIMIZE_JAVA)
# TODO(b/196084106): Remove when Java optimizations enabled by default for
# system packages.
$(call add_soong_config_var,ANDROID,SYSTEM_OPTIMIZE_JAVA)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 8a5440f..cec7792 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -981,6 +981,18 @@
ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS := \
$(ALL_MODULES.$(my_register_name).SYSTEM_SHARED_LIBS) $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+ifdef LOCAL_TEST_DATA
+ # Export the list of targets that are handled as data inputs and required
+ # by tests at runtime. The LOCAL_TEST_DATA format is generated from below
+ # https://cs.android.com/android/platform/superproject/+/master:build/soong/android/androidmk.go;l=925-944;drc=master
+ # which format is like $(path):$(relative_file) but for module-info, only
+ # the string after ":" is needed.
+ ALL_MODULES.$(my_register_name).TEST_DATA := \
+ $(strip $(ALL_MODULES.$(my_register_name).TEST_DATA) \
+ $(foreach f, $(LOCAL_TEST_DATA),\
+ $(call word-colon,2,$(f))))
+endif
+
##########################################################################
## When compiling against the VNDK, add the .vendor or .product suffix to
## required modules.
diff --git a/core/board_config.mk b/core/board_config.mk
index 95cbe3d..ad71951 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -77,6 +77,8 @@
_board_strip_readonly_list += BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
_board_strip_readonly_list += BOARD_PRODUCTIMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
+_board_strip_readonly_list += BOARD_SYSTEM_DLKM_PARTITION_SIZE
+_board_strip_readonly_list += BOARD_SYSTEM_DLKM_FILE_SYSTEM_TYPE
_board_strip_readonly_list += BOARD_SYSTEM_EXTIMAGE_PARTITION_SIZE
_board_strip_readonly_list += BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE
_board_strip_readonly_list += BOARD_ODMIMAGE_PARTITION_SIZE
@@ -125,6 +127,7 @@
# Prebuilt image variables
_board_strip_readonly_list += BOARD_PREBUILT_INIT_BOOT_IMAGE
+_board_strip_readonly_list += BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
# Defines the list of logical vendor ramdisk names to build or include in vendor_boot.
_board_strip_readonly_list += BOARD_VENDOR_RAMDISK_FRAGMENTS
@@ -502,6 +505,35 @@
endif
.KATI_READONLY := BUILDING_RECOVERY_IMAGE
+# Are we building a system_dlkm image for system_dlkm partition ?
+#
+# Two choices:
+# 1. Use kernel prebuilt system_dlkm.img BOARD_PREBUILT_SYSTEM_DLKM_IMAGE to point image
+# 2. Build from kernel prebuilt system_dlkm_staging set PRODUCT_BUILD_SYSTEM_DLKM_IMAGE
+#
+# Both requires: BOARD_SYSTEM_DLKM_PARTITION_SIZE and must be 64MB or higher (vts).
+#
+BUILDING_SYSTEM_DLKM_IMAGE :=
+ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),)
+ ifdef BOARD_USES_SYSTEM_DLKM_PARTITION
+ BUILDING_SYSTEM_DLKM_IMAGE := true
+ endif
+endif
+ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),true)
+ BUILDING_SYSTEM_DLKM_IMAGE := true
+endif
+.KATI_READONLY := BUILDING_SYSTEM_DLKM_IMAGE
+TARGET_SYSTEM_DLKM_SRC :=
+ifeq ($(BUILDING_SYSTEM_DLKM_IMAGE),true)
+ # Make sure we know the partition size; or warn for default to 64MB
+ ifndef BOARD_SYSTEM_DLKM_PARTITION_SIZE
+ $(error BOARD_SYSTEM_DLKM_PARTITION_SIZE is not defined; must be defined as 64MB or higher.)
+ endif
+ # Point to the source for signed module by kernel; if we are building system_dlkm
+ TARGET_SYSTEM_DLKM_SRC := kernel/prebuilts/$(TARGET_KERNEL_USE)/$(TARGET_ARCH)/system_dlkm_staging
+endif
+.KATI_READONLY := TARGET_SYSTEM_DLKM_SRC
+
# Are we building a vendor boot image
BUILDING_VENDOR_BOOT_IMAGE :=
ifdef BOARD_BOOT_HEADER_VERSION
diff --git a/core/config.mk b/core/config.mk
index e146f64..6f22b7c 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -577,6 +577,7 @@
MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
LZ4 := $(HOST_OUT_EXECUTABLES)/lz4$(HOST_EXECUTABLE_SUFFIX)
+GENERATE_GKI_CERTIFICATE := $(HOST_OUT_EXECUTABLES)/generate_gki_certificate$(HOST_EXECUTABLE_SUFFIX)
ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
else
@@ -596,6 +597,7 @@
FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs
MKE2FS_CONF := system/extras/ext4_utils/mke2fs.conf
+MKEROFS := $(HOST_OUT_EXECUTABLES)/mkfs.erofs
MKEROFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mkerofsimage.sh
MKSQUASHFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh
MKF2FSUSERIMG := $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh
diff --git a/core/envsetup.mk b/core/envsetup.mk
index b673050..e730c3a 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -259,6 +259,7 @@
# TARGET_COPY_OUT_* are all relative to the staging directory, ie PRODUCT_OUT.
# Define them here so they can be used in product config files.
TARGET_COPY_OUT_SYSTEM := system
+TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
TARGET_COPY_OUT_SYSTEM_OTHER := system_other
TARGET_COPY_OUT_DATA := data
TARGET_COPY_OUT_ASAN := $(TARGET_COPY_OUT_DATA)/asan
@@ -317,11 +318,17 @@
# Dumps all variables that match [A-Z][A-Z0-9_]* (with a few exceptions)
# to the file at $(1). It is used to print only the variables that are
# likely to be relevant to the product or board configuration.
+# Soong config variables are dumped as $(call soong_config_set) calls
+# instead of the raw variable values, because mk2rbc can't read the
+# raw ones.
define dump-variables-rbc
$(file >$(OUT_DIR)/dump-variables-rbc-temp.txt,$(subst $(space),$(newline),$(.VARIABLES)))\
$(file >$(1),\
$(foreach v, $(shell grep -he "^[A-Z][A-Z0-9_]*$$" $(OUT_DIR)/dump-variables-rbc-temp.txt | grep -vhE "^(SOONG_.*|LOCAL_PATH|TOPDIR|PRODUCT_COPY_OUT_.*)$$"),\
-$(v) := $(strip $($(v)))$(newline)))
+$(v) := $(strip $($(v)))$(newline))\
+$(foreach ns,$(SOONG_CONFIG_NAMESPACES),\
+$(foreach v,$(SOONG_CONFIG_$(ns)),\
+$$(call soong_config_set,$(ns),$(v),$(SOONG_CONFIG_$(ns)_$(v)))$(newline))))
endef
# Read the product specs so we can get TARGET_DEVICE and other
@@ -945,6 +952,9 @@
TARGET_VENDOR_DEBUG_RAMDISK_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR_DEBUG_RAMDISK)
TARGET_TEST_HARNESS_RAMDISK_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_TEST_HARNESS_RAMDISK)
+TARGET_SYSTEM_DLKM_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_DLKM)
+.KATI_READONLY := TARGET_SYSTEM_DLKM_OUT
+
TARGET_VENDOR_RAMDISK_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR_RAMDISK)
TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT)
diff --git a/core/force_aapt2.mk b/core/force_aapt2.mk
index 25b45e4..5f3182a 100644
--- a/core/force_aapt2.mk
+++ b/core/force_aapt2.mk
@@ -44,10 +44,3 @@
LOCAL_SDK_RES_VERSION := current
endif
-ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
- ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
- # work around missing manifests by creating a default one
- LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
- $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(call module-min-sdk-version))
- endif
-endif
diff --git a/core/main.mk b/core/main.mk
index d17f0cb..7e7575f 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1604,7 +1604,10 @@
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
.PHONY: initbootimage
-bootimage: $(INSTALLED_INIT_BOOT_IMAGE_TARGET)
+initbootimage: $(INSTALLED_INIT_BOOT_IMAGE_TARGET)
+
+.PHONY: system_dlkm_image
+system_dlkm_image: $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET)
ifeq (true,$(PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST))
$(call dist-for-goals, bootimage, $(INSTALLED_BOOTIMAGE_TARGET))
@@ -1630,6 +1633,7 @@
.PHONY: droidcore-unbundled
droidcore-unbundled: $(filter $(HOST_OUT_ROOT)/%,$(modules_to_install)) \
$(INSTALLED_SYSTEMIMAGE_TARGET) \
+ $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
@@ -1877,6 +1881,10 @@
)
endif
+ ifeq ($(PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST),true)
+ $(call dist-for-goals, droidcore-unbundled, $(INSTALLED_BOOTIMAGE_TARGET))
+ endif
+
ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
$(call dist-for-goals, droidcore-unbundled, \
$(recovery_ramdisk) \
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 800dbbc..8199ad2 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -97,6 +97,14 @@
endif
include $(BUILD_SYSTEM)/force_aapt2.mk
+# validate that app contains a manifest file for aapt2
+ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+ ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+ $(call pretty-error,App missing manifest file which is required by aapt2. \
+Provide a manifest file by either setting LOCAL_MANIFEST_FILE in Android.mk \
+or via a AndroidManifest.xml in this directory)
+ endif
+endif
# Process Support Library dependencies.
include $(BUILD_SYSTEM)/support_libraries.mk
diff --git a/core/product-graph.mk b/core/product-graph.mk
index f28ea3d..d425b22 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -126,6 +126,7 @@
$(hide) echo 'PRODUCT_CHARACTERISTICS=$(call get-product-var,$(1),PRODUCT_CHARACTERISTICS)' >> $$@
$(hide) echo 'PRODUCT_COPY_FILES=$(call get-product-var,$(1),PRODUCT_COPY_FILES)' >> $$@
$(hide) echo 'PRODUCT_OTA_PUBLIC_KEYS=$(call get-product-var,$(1),PRODUCT_OTA_PUBLIC_KEYS)' >> $$@
+ $(hide) echo 'PRODUCT_EXTRA_OTA_KEYS=$(call get-product-var,$(1),PRODUCT_EXTRA_OTA_KEYS)' >> $$@
$(hide) echo 'PRODUCT_EXTRA_RECOVERY_KEYS=$(call get-product-var,$(1),PRODUCT_EXTRA_RECOVERY_KEYS)' >> $$@
$(hide) echo 'PRODUCT_PACKAGE_OVERLAYS=$(call get-product-var,$(1),PRODUCT_PACKAGE_OVERLAYS)' >> $$@
$(hide) echo 'DEVICE_PACKAGE_OVERLAYS=$(call get-product-var,$(1),DEVICE_PACKAGE_OVERLAYS)' >> $$@
diff --git a/core/product.mk b/core/product.mk
index 04c59ff..21db81e 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -183,6 +183,7 @@
# signing tools can substitute them for the test key embedded by
# default.
_product_list_vars += PRODUCT_OTA_PUBLIC_KEYS
+_product_list_vars += PRODUCT_EXTRA_OTA_KEYS
_product_list_vars += PRODUCT_EXTRA_RECOVERY_KEYS
# Should we use the default resources or add any product specific overlays
@@ -383,6 +384,7 @@
# Controls for whether different partitions are built for the current product.
_product_single_value_vars += PRODUCT_BUILD_SYSTEM_IMAGE
+_product_single_value_vars += PRODUCT_BUILD_SYSTEM_DLKM_IMAGE
_product_single_value_vars += PRODUCT_BUILD_SYSTEM_OTHER_IMAGE
_product_single_value_vars += PRODUCT_BUILD_VENDOR_IMAGE
_product_single_value_vars += PRODUCT_BUILD_PRODUCT_IMAGE
@@ -444,7 +446,7 @@
# Install a copy of the debug policy to the system_ext partition, and allow
# init-second-stage to load debug policy from system_ext.
-# This option is only meant to be set by GSI products.
+# This option is only meant to be set by compliance GSI targets.
_product_single_value_vars += PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
# If set, metadata files for the following artifacts will be generated.
diff --git a/core/product_config.mk b/core/product_config.mk
index a376f74..6fae73e 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -381,6 +381,7 @@
ENFORCE_SYSTEM_CERTIFICATE_ALLOW_LIST := $(PRODUCT_ARTIFACT_SYSTEM_CERTIFICATE_REQUIREMENT_ALLOW_LIST)
PRODUCT_OTA_PUBLIC_KEYS := $(sort $(PRODUCT_OTA_PUBLIC_KEYS))
+PRODUCT_EXTRA_OTA_KEYS := $(sort $(PRODUCT_EXTRA_OTA_KEYS))
PRODUCT_EXTRA_RECOVERY_KEYS := $(sort $(PRODUCT_EXTRA_RECOVERY_KEYS))
# Resolve and setup per-module dex-preopt configs.
@@ -419,9 +420,15 @@
$(error Only one file may be in PRODUCT_ADB_KEYS: $(PRODUCT_ADB_KEYS))
endif
+# Show a warning wall of text if non-compliance-GSI products set this option.
ifdef PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT
- ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64,$(PRODUCT_NAME)))
- $(error Only GSI products are allowed to set PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT)
+ ifeq (,$(filter gsi_arm gsi_arm64 gsi_x86 gsi_x86_64 gsi_car_arm64 gsi_car_x86_64,$(PRODUCT_NAME)))
+ $(warning PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT is set but \
+ PRODUCT_NAME ($(PRODUCT_NAME)) doesn't look like a GSI for compliance \
+ testing. This is a special configuration for compliance GSI, so do make \
+ sure you understand the security implications before setting this \
+ option. If you don't know what this option does, then you probably \
+ shouldn't set this.)
endif
endif
diff --git a/core/proguard.flags b/core/proguard.flags
index 50049cb..185275e 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -15,35 +15,24 @@
@**.VisibleForTesting *;
}
-# Understand the @Keep support annotation.
--keep class android.support.annotation.Keep
--keep class androidx.annotation.Keep
+# Understand the common @Keep annotation from various Android packages:
+# * android.support.annotation
+# * androidx.annotation
+# * com.android.internal.annotations
+-keep class **android**.annotation*.Keep
--keep @android.support.annotation.Keep class * {*;}
--keep @androidx.annotation.Keep class * {*;}
+-keep @**android**.annotation*.Keep class * { *; }
-keepclasseswithmembers class * {
- @android.support.annotation.Keep <methods>;
+ @**android**.annotation*.Keep <methods>;
}
-keepclasseswithmembers class * {
- @androidx.annotation.Keep <methods>;
+ @**android**.annotation*.Keep <fields>;
}
-keepclasseswithmembers class * {
- @android.support.annotation.Keep <fields>;
-}
-
--keepclasseswithmembers class * {
- @androidx.annotation.Keep <fields>;
-}
-
--keepclasseswithmembers class * {
- @android.support.annotation.Keep <init>(...);
-}
-
--keepclasseswithmembers class * {
- @androidx.annotation.Keep <init>(...);
+ @**android**.annotation*.Keep <init>(...);
}
-include proguard_basic_keeps.flags
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 07dafc7..a8071a3 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -207,6 +207,7 @@
$(call add_json_str, PlatformSepolicyVersion, $(PLATFORM_SEPOLICY_VERSION))
$(call add_json_str, TotSepolicyVersion, $(TOT_SEPOLICY_VERSION))
+$(call add_json_list, PlatformSepolicyCompatVersions, $(PLATFORM_SEPOLICY_COMPAT_VERSIONS))
$(call add_json_bool, Flatten_apex, $(filter true,$(TARGET_FLATTEN_APEX)))
$(call add_json_bool, ForceApexSymlinkOptimization, $(filter true,$(TARGET_FORCE_APEX_SYMLINK_OPTIMIZATION)))
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 7a87322..4053985 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -101,6 +101,13 @@
include $(BUILD_SYSTEM)/java_renderscript.mk
ifeq (true,$(need_compile_res))
+# work around missing manifests by creating a default one
+ifeq (,$(strip $(LOCAL_MANIFEST_FILE)$(LOCAL_FULL_MANIFEST_FILE)))
+ ifeq (,$(wildcard $(LOCAL_PATH)/AndroidManifest.xml))
+ LOCAL_FULL_MANIFEST_FILE := $(call local-intermediates-dir,COMMON)/DefaultManifest.xml
+ $(call create-default-manifest-file,$(LOCAL_FULL_MANIFEST_FILE),$(call module-min-sdk-version))
+ endif
+endif
include $(BUILD_SYSTEM)/android_manifest.mk
LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
diff --git a/core/tasks/module-info.mk b/core/tasks/module-info.mk
index 5d5bfa8..aeeb403 100644
--- a/core/tasks/module-info.mk
+++ b/core/tasks/module-info.mk
@@ -23,6 +23,7 @@
'"classes_jar": [$(foreach w,$(sort $(ALL_MODULES.$(m).CLASSES_JAR)),"$(w)", )], ' \
'"test_mainline_modules": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_MAINLINE_MODULES)),"$(w)", )], ' \
'"is_unit_test": "$(ALL_MODULES.$(m).IS_UNIT_TEST)", ' \
+ '"data": [$(foreach w,$(sort $(ALL_MODULES.$(m).TEST_DATA)),"$(w)", )], ' \
'},\n' \
) | sed -e 's/, *\]/]/g' -e 's/, *\}/ }/g' -e '$$s/,$$//' >> $@
$(hide) echo '}' >> $@
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index bf19c5c..051de62 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -85,7 +85,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2021-12-05
+ PLATFORM_SECURITY_PATCH := 2022-01-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/target/board/BoardConfigGkiCommon.mk b/target/board/BoardConfigGkiCommon.mk
index c0f5db9..63ef2b4 100644
--- a/target/board/BoardConfigGkiCommon.mk
+++ b/target/board/BoardConfigGkiCommon.mk
@@ -16,11 +16,7 @@
# Enable GKI 2.0 signing.
BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
-
-# The following is needed to allow release signing process appends more extra
-# args, e.g., passing --signing_helper_with_files from mkbootimg to avbtool.
-# See b/178559811 for more details.
-BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar
+BOARD_GKI_SIGNING_SIGNATURE_ARGS :=
# Sets boot SPL.
BOOT_SECURITY_PATCH = $(PLATFORM_SECURITY_PATCH)
diff --git a/target/product/OWNERS b/target/product/OWNERS
index 82e6e88..b3d8998 100644
--- a/target/product/OWNERS
+++ b/target/product/OWNERS
@@ -2,4 +2,4 @@
# GSI
per-file gsi_release.mk = file:/target/product/gsi/OWNERS
-per-file gsi_keys.mk = file:/target/product/gsi/OWNERS
+per-file developer_gsi_keys.mk = file:/target/product/gsi/OWNERS
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index a995b8b..3d299fb 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -66,6 +66,7 @@
com.android.neuralnetworks \
com.android.scheduling \
com.android.sdkext \
+ com.android.sepolicy \
com.android.tethering \
com.android.tzdata \
com.android.wifi \
@@ -367,6 +368,7 @@
PRODUCT_PACKAGES_DEBUG := \
adb_keys \
arping \
+ com.android.sepolicy.cert-debug.der \
dmuserd \
idlcli \
init-debug.rc \
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index 1a0fc76..3223002 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -63,6 +63,7 @@
com.android.scheduling:framework-scheduling \
com.android.sdkext:framework-sdkextensions \
com.android.tethering:framework-connectivity \
+ com.android.tethering:framework-connectivity-tiramisu \
com.android.tethering:framework-tethering \
com.android.wifi:framework-wifi
diff --git a/target/product/gsi/Android.bp b/target/product/gsi/Android.bp
index 88472eb..a8af9c4 100644
--- a/target/product/gsi/Android.bp
+++ b/target/product/gsi/Android.bp
@@ -14,11 +14,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
filegroup {
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index 0d788fa..85e551d 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -60,11 +60,11 @@
endif
$(check-vndk-list-timestamp): $(INTERNAL_VNDK_LIB_LIST) $(LATEST_VNDK_LIB_LIST) $(HOST_OUT_EXECUTABLES)/update-vndk-list.sh
- $(hide) ($(_READ_INTERNAL_VNDK_LIB_LIST) | \
+ $(hide) ($(_READ_INTERNAL_VNDK_LIB_LIST) | sort | \
diff --old-line-format="Removed %L" \
--new-line-format="Added %L" \
--unchanged-line-format="" \
- $(LATEST_VNDK_LIB_LIST) - \
+ <(cat $(LATEST_VNDK_LIB_LIST) | sort) - \
|| ( echo -e $(_vndk_check_failure_message); exit 1 ))
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
@@ -73,8 +73,9 @@
# Script to update the latest VNDK lib list
include $(CLEAR_VARS)
LOCAL_MODULE := update-vndk-list.sh
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
LOCAL_IS_HOST_MODULE := true
@@ -170,8 +171,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := vndk_package
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
# Filter LLNDK libs moved to APEX to avoid pulling them into /system/LIB
LOCAL_REQUIRED_MODULES := \
$(filter-out $(LLNDK_MOVED_TO_APEX_LIBRARIES),$(LLNDK_LIBRARIES))
@@ -195,8 +197,9 @@
_vndk_versions += $(BOARD_VNDK_VERSION)
endif
LOCAL_MODULE := vndk_apex_snapshot_package
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(foreach vndk_ver,$(_vndk_versions),com.android.vndk.v$(vndk_ver))
include $(BUILD_PHONY_PACKAGE)
@@ -209,8 +212,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := gsi_skip_mount.cfg
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_STEM := skip_mount.cfg
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
@@ -234,8 +238,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init.gsi.rc
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_SYSTEM_EXT_MODULE := true
@@ -246,8 +251,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init.vndk-nodef.rc
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_SYSTEM_EXT_MODULE := true
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index e618226..f9c1f3d 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -29,10 +29,10 @@
VNDK-SP: android.hardware.graphics.mapper@3.0.so
VNDK-SP: android.hardware.graphics.mapper@4.0.so
VNDK-SP: android.hardware.renderscript@1.0.so
+VNDK-SP: android.hidl.safe_union@1.0.so
VNDK-SP: android.hidl.memory.token@1.0.so
VNDK-SP: android.hidl.memory@1.0-impl.so
VNDK-SP: android.hidl.memory@1.0.so
-VNDK-SP: android.hidl.safe_union@1.0.so
VNDK-SP: libRSCpuRef.so
VNDK-SP: libRSDriver.so
VNDK-SP: libRS_internal.so
@@ -56,9 +56,11 @@
VNDK-SP: libutils.so
VNDK-SP: libutilscallstack.so
VNDK-SP: libz.so
+VNDK-core: android.hardware.audio.common-V1-ndk.so
VNDK-core: android.hardware.audio.common@2.0.so
VNDK-core: android.hardware.authsecret-V1-ndk.so
VNDK-core: android.hardware.automotive.occupant_awareness-V1-ndk.so
+VNDK-core: android.hardware.bluetooth.audio-V1-ndk.so
VNDK-core: android.hardware.configstore-utils.so
VNDK-core: android.hardware.configstore@1.0.so
VNDK-core: android.hardware.configstore@1.1.so
@@ -80,6 +82,7 @@
VNDK-core: android.hardware.media@1.0.so
VNDK-core: android.hardware.memtrack-V1-ndk.so
VNDK-core: android.hardware.memtrack@1.0.so
+VNDK-core: android.hardware.nfc-V1-ndk.so
VNDK-core: android.hardware.oemlock-V1-ndk.so
VNDK-core: android.hardware.power-V2-ndk.so
VNDK-core: android.hardware.power.stats-V1-ndk.so
@@ -104,6 +107,7 @@
VNDK-core: android.hardware.wifi.supplicant-V1-ndk.so
VNDK-core: android.hidl.token@1.0-utils.so
VNDK-core: android.hidl.token@1.0.so
+VNDK-core: android.media.audio.common.types-V1-ndk.so
VNDK-core: android.system.keystore2-V1-ndk.so
VNDK-core: android.system.suspend-V1-ndk.so
VNDK-core: android.system.suspend@1.0.so
diff --git a/target/product/gsi_keys.mk b/target/product/gsi_keys.mk
deleted file mode 100644
index 5a814db..0000000
--- a/target/product/gsi_keys.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open-Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Include GSI keys into first-stage ramdisk, so we can enable verified
-# boot when booting a GSI.
-PRODUCT_PACKAGES += \
- q-gsi.avbpubkey \
- r-gsi.avbpubkey \
- s-gsi.avbpubkey \
diff --git a/target/product/handheld_system.mk b/target/product/handheld_system.mk
index b7a2d0d..3a59f6c 100644
--- a/target/product/handheld_system.mk
+++ b/target/product/handheld_system.mk
@@ -43,7 +43,6 @@
CameraExtensionsProxy \
CaptivePortalLogin \
CertInstaller \
- clatd \
DocumentsUI \
DownloadProviderUi \
EasterEgg \
diff --git a/target/product/security/Android.bp b/target/product/security/Android.bp
index 99f7742..1e26d59 100644
--- a/target/product/security/Android.bp
+++ b/target/product/security/Android.bp
@@ -1,11 +1,7 @@
// AOSP test certificate
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
android_app_certificate {
diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk
index cedad5b..ad25a92 100644
--- a/target/product/security/Android.mk
+++ b/target/product/security/Android.mk
@@ -5,8 +5,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := verity_key
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
@@ -26,8 +27,9 @@
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
include $(CLEAR_VARS)
LOCAL_MODULE := verity_key_ramdisk
- LOCAL_LICENSE_KINDS := legacy_restricted
- LOCAL_LICENSE_CONDITIONS := restricted
+ LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+ LOCAL_LICENSE_CONDITIONS := notice
+ LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := verity_key
LOCAL_MODULE_STEM := verity_key
@@ -41,8 +43,9 @@
ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),)
include $(CLEAR_VARS)
LOCAL_MODULE := adb_keys
- LOCAL_LICENSE_KINDS := legacy_restricted
- LOCAL_LICENSE_CONDITIONS := restricted
+ LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+ LOCAL_LICENSE_CONDITIONS := notice
+ LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_PREBUILT_MODULE_FILE := $(PRODUCT_ADB_KEYS)
@@ -57,15 +60,24 @@
include $(CLEAR_VARS)
LOCAL_MODULE := otacerts
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_STEM := otacerts.zip
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/security
include $(BUILD_SYSTEM)/base_rules.mk
+
+extra_ota_keys := $(addsuffix .x509.pem,$(PRODUCT_EXTRA_OTA_KEYS))
+
$(LOCAL_BUILT_MODULE): PRIVATE_CERT := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
-$(LOCAL_BUILT_MODULE): $(SOONG_ZIP) $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
- $(SOONG_ZIP) -o $@ -j -symlinks=false -f $(PRIVATE_CERT)
+$(LOCAL_BUILT_MODULE): PRIVATE_EXTRA_OTA_KEYS := $(extra_ota_keys)
+$(LOCAL_BUILT_MODULE): \
+ $(SOONG_ZIP) \
+ $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem \
+ $(extra_ota_keys)
+ $(SOONG_ZIP) -o $@ -j -symlinks=false \
+ $(addprefix -f ,$(PRIVATE_CERT) $(PRIVATE_EXTRA_OTA_KEYS))
#######################################
@@ -73,14 +85,15 @@
include $(CLEAR_VARS)
LOCAL_MODULE := otacerts.recovery
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_STEM := otacerts.zip
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc/security
include $(BUILD_SYSTEM)/base_rules.mk
-extra_recovery_keys := $(patsubst %,%.x509.pem,$(PRODUCT_EXTRA_RECOVERY_KEYS))
+extra_recovery_keys := $(addsuffix .x509.pem,$(PRODUCT_EXTRA_RECOVERY_KEYS))
$(LOCAL_BUILT_MODULE): PRIVATE_CERT := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
$(LOCAL_BUILT_MODULE): PRIVATE_EXTRA_RECOVERY_KEYS := $(extra_recovery_keys)
@@ -89,4 +102,4 @@
$(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem \
$(extra_recovery_keys)
$(SOONG_ZIP) -o $@ -j -symlinks=false \
- $(foreach key_file, $(PRIVATE_CERT) $(PRIVATE_EXTRA_RECOVERY_KEYS), -f $(key_file))
+ $(addprefix -f ,$(PRIVATE_CERT) $(PRIVATE_EXTRA_RECOVERY_KEYS))
diff --git a/tools/Android.bp b/tools/Android.bp
index 269e610..6601c60 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -14,41 +14,17 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- // SPDX-license-identifier-BSD
- // SPDX-license-identifier-CC-BY
- // SPDX-license-identifier-GPL
- // SPDX-license-identifier-MIT
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
python_binary_host {
name: "generate-self-extracting-archive",
srcs: ["generate-self-extracting-archive.py"],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: false,
- },
- },
}
python_binary_host {
name: "post_process_props",
srcs: ["post_process_props.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
}
python_test_host {
@@ -58,14 +34,6 @@
"post_process_props.py",
"test_post_process_props.py",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
test_config: "post_process_props_unittest.xml",
test_suites: ["general-tests"],
}
@@ -73,14 +41,6 @@
python_binary_host {
name: "extract_kernel",
srcs: ["extract_kernel.py"],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
}
genrule_defaults {
diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel
index 75b0de6..3170820 100644
--- a/tools/BUILD.bazel
+++ b/tools/BUILD.bazel
@@ -8,7 +8,7 @@
srcs=["java-event-log-tags.py"],
deps=[":event_log_tags"],
visibility = ["//visibility:public"],
- python_version = "PY2",
+ python_version = "PY3",
)
py_binary(
@@ -16,5 +16,5 @@
srcs=["merge-event-log-tags.py"],
deps=[":event_log_tags"],
visibility = ["//visibility:public"],
- python_version = "PY2",
+ python_version = "PY3",
)
diff --git a/tools/acp/Android.bp b/tools/acp/Android.bp
index 78738b0..47b23b2 100644
--- a/tools/acp/Android.bp
+++ b/tools/acp/Android.bp
@@ -4,11 +4,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary_host {
diff --git a/tools/atree/Android.bp b/tools/atree/Android.bp
index 7906d8b..fdae3e0 100644
--- a/tools/atree/Android.bp
+++ b/tools/atree/Android.bp
@@ -4,11 +4,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary_host {
diff --git a/tools/compliance/Android.bp b/tools/compliance/Android.bp
index afb3080..bbeb76f 100644
--- a/tools/compliance/Android.bp
+++ b/tools/compliance/Android.bp
@@ -48,7 +48,6 @@
bootstrap_go_package {
name: "compliance-module",
srcs: [
- "actionset.go",
"condition.go",
"conditionset.go",
"doc.go",
diff --git a/tools/compliance/actionset.go b/tools/compliance/actionset.go
deleted file mode 100644
index 656c5de..0000000
--- a/tools/compliance/actionset.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package compliance
-
-import (
- "fmt"
- "sort"
- "strings"
-)
-
-// actionSet maps `actOn` target nodes to the license conditions the actions resolve.
-type actionSet map[*TargetNode]*LicenseConditionSet
-
-// String returns a string representation of the set.
-func (as actionSet) String() string {
- var sb strings.Builder
- fmt.Fprintf(&sb, "{")
- osep := ""
- for actsOn, cs := range as {
- cl := cs.AsList()
- sort.Sort(cl)
- fmt.Fprintf(&sb, "%s%s -> %s", osep, actsOn.name, cl.String())
- osep = ", "
- }
- fmt.Fprintf(&sb, "}")
- return sb.String()
-}
-
-// byName returns the subset of `as` actions where the condition name is in `names`.
-func (as actionSet) byName(names ConditionNames) actionSet {
- result := make(actionSet)
- for actsOn, cs := range as {
- bn := cs.ByName(names)
- if bn.IsEmpty() {
- continue
- }
- result[actsOn] = bn
- }
- return result
-}
-
-// byActsOn returns the subset of `as` where `actsOn` is in the `reachable` target node set.
-func (as actionSet) byActsOn(reachable *TargetNodeSet) actionSet {
- result := make(actionSet)
- for actsOn, cs := range as {
- if !reachable.Contains(actsOn) || cs.IsEmpty() {
- continue
- }
- result[actsOn] = cs.Copy()
- }
- return result
-}
-
-// copy returns another actionSet with the same value as `as`
-func (as actionSet) copy() actionSet {
- result := make(actionSet)
- for actsOn, cs := range as {
- if cs.IsEmpty() {
- continue
- }
- result[actsOn] = cs.Copy()
- }
- return result
-}
-
-// addSet adds all of the actions of `other` if not already present.
-func (as actionSet) addSet(other actionSet) {
- for actsOn, cs := range other {
- as.add(actsOn, cs)
- }
-}
-
-// add makes the action on `actsOn` to resolve the conditions in `cs` a member of the set.
-func (as actionSet) add(actsOn *TargetNode, cs *LicenseConditionSet) {
- if acs, ok := as[actsOn]; ok {
- acs.AddSet(cs)
- } else {
- as[actsOn] = cs.Copy()
- }
-}
-
-// addCondition makes the action on `actsOn` to resolve `lc` a member of the set.
-func (as actionSet) addCondition(actsOn *TargetNode, lc LicenseCondition) {
- if _, ok := as[actsOn]; !ok {
- as[actsOn] = newLicenseConditionSet()
- }
- as[actsOn].Add(lc)
-}
-
-// isEmpty returns true if no action to resolve a condition exists.
-func (as actionSet) isEmpty() bool {
- for _, cs := range as {
- if !cs.IsEmpty() {
- return false
- }
- }
- return true
-}
-
-// conditions returns the set of conditions resolved by the action set.
-func (as actionSet) conditions() *LicenseConditionSet {
- result := newLicenseConditionSet()
- for _, cs := range as {
- result.AddSet(cs)
- }
- return result
-}
diff --git a/tools/compliance/cmd/checkshare.go b/tools/compliance/cmd/checkshare.go
index efac8dc..5114a28 100644
--- a/tools/compliance/cmd/checkshare.go
+++ b/tools/compliance/cmd/checkshare.go
@@ -30,8 +30,8 @@
Reports on stderr any targets where policy says that the source both
must and must not be shared. The error report indicates the target, the
-license condition with origin that has a source privacy policy, and the
-license condition with origin that has a source sharing policy.
+license condition that has a source privacy policy, and the license
+condition that has a source sharing policy.
Any given target may appear multiple times with different combinations
of conflicting license conditions.
diff --git a/tools/compliance/cmd/checkshare_test.go b/tools/compliance/cmd/checkshare_test.go
index 8ea7748..5036aa5 100644
--- a/tools/compliance/cmd/checkshare_test.go
+++ b/tools/compliance/cmd/checkshare_test.go
@@ -23,15 +23,12 @@
type outcome struct {
target string
- privacyOrigin string
privacyCondition string
- shareOrigin string
shareCondition string
}
func (o *outcome) String() string {
- return fmt.Sprintf("%s %s from %s and must share from %s %s",
- o.target, o.privacyCondition, o.privacyOrigin, o.shareCondition, o.shareOrigin)
+ return fmt.Sprintf("%s %s and must share from %s", o.target, o.privacyCondition, o.shareCondition)
}
type outcomeList []*outcome
@@ -180,9 +177,7 @@
expectedOutcomes: outcomeList{
&outcome{
target: "testdata/proprietary/bin/bin2.meta_lic",
- privacyOrigin: "testdata/proprietary/bin/bin2.meta_lic",
privacyCondition: "proprietary",
- shareOrigin: "testdata/proprietary/lib/libb.so.meta_lic",
shareCondition: "restricted",
},
},
@@ -195,9 +190,7 @@
expectedOutcomes: outcomeList{
&outcome{
target: "testdata/proprietary/bin/bin2.meta_lic",
- privacyOrigin: "testdata/proprietary/bin/bin2.meta_lic",
privacyCondition: "proprietary",
- shareOrigin: "testdata/proprietary/lib/libb.so.meta_lic",
shareCondition: "restricted",
},
},
@@ -210,9 +203,7 @@
expectedOutcomes: outcomeList{
&outcome{
target: "testdata/proprietary/lib/liba.so.meta_lic",
- privacyOrigin: "testdata/proprietary/lib/liba.so.meta_lic",
privacyCondition: "proprietary",
- shareOrigin: "testdata/proprietary/lib/libb.so.meta_lic",
shareCondition: "restricted",
},
},
@@ -225,9 +216,7 @@
expectedOutcomes: outcomeList{
&outcome{
target: "testdata/proprietary/bin/bin2.meta_lic",
- privacyOrigin: "testdata/proprietary/bin/bin2.meta_lic",
privacyCondition: "proprietary",
- shareOrigin: "testdata/proprietary/lib/libb.so.meta_lic",
shareCondition: "restricted",
},
},
@@ -277,10 +266,8 @@
cFields := strings.Split(ts, " ")
actualOutcomes = append(actualOutcomes, &outcome{
target: cFields[0],
- privacyOrigin: cFields[3],
privacyCondition: cFields[1],
- shareOrigin: cFields[9],
- shareCondition: cFields[8],
+ shareCondition: cFields[6],
})
}
if len(actualOutcomes) != len(tt.expectedOutcomes) {
diff --git a/tools/compliance/cmd/dumpgraph_test.go b/tools/compliance/cmd/dumpgraph_test.go
index b7d66f7..3055022 100644
--- a/tools/compliance/cmd/dumpgraph_test.go
+++ b/tools/compliance/cmd/dumpgraph_test.go
@@ -327,13 +327,13 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/restricted/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted static",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
"bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal static",
"bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted dynamic",
"bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
"highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
"highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted static",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
"highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted static",
},
},
@@ -996,7 +996,7 @@
matchTarget("bin/bin1.meta_lic", "notice"),
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
- matchTarget("lib/liba.so.meta_lic", "restricted"),
+ matchTarget("lib/liba.so.meta_lic", "restricted_allows_dynamic_linking"),
matchTarget("lib/libb.so.meta_lic", "restricted"),
matchTarget("lib/libc.a.meta_lic", "reciprocal"),
matchTarget("lib/libd.so.meta_lic", "notice"),
diff --git a/tools/compliance/cmd/dumpresolutions.go b/tools/compliance/cmd/dumpresolutions.go
index 36fbb7d..318cd91 100644
--- a/tools/compliance/cmd/dumpresolutions.go
+++ b/tools/compliance/cmd/dumpresolutions.go
@@ -36,7 +36,7 @@
)
type context struct {
- conditions []string
+ conditions []compliance.LicenseCondition
graphViz bool
labelConditions bool
stripPrefix string
@@ -50,9 +50,9 @@
resolution in the graph. When -dot flag given, outputs nodes and edges
in graphviz directed graph format.
-If one or more '-c condition' conditions are given, outputs the joined
-set of resolutions for all of the conditions. Otherwise, outputs the
-result of the bottom-up and top-down resolve only.
+If one or more '-c condition' conditions are given, outputs the
+resolution for the union of the conditions. Otherwise, outputs the
+resolution for all conditions.
In plain text mode, when '-label_conditions' is requested, the Target
and Origin have colon-separated license conditions appended:
@@ -86,13 +86,17 @@
os.Exit(2)
}
+ lcs := make([]compliance.LicenseCondition, 0, len(*conditions))
+ for _, name := range *conditions {
+ lcs = append(lcs, compliance.RecognizedConditionNames[name])
+ }
ctx := &context{
- conditions: append([]string{}, *conditions...),
+ conditions: lcs,
graphViz: *graphViz,
labelConditions: *labelConditions,
stripPrefix: *stripPrefix,
}
- err := dumpResolutions(ctx, os.Stdout, os.Stderr, flag.Args()...)
+ _, err := dumpResolutions(ctx, os.Stdout, os.Stderr, flag.Args()...)
if err != nil {
if err == failNoneRequested {
flag.Usage()
@@ -104,36 +108,31 @@
}
// dumpResolutions implements the dumpresolutions utility.
-func dumpResolutions(ctx *context, stdout, stderr io.Writer, files ...string) error {
+func dumpResolutions(ctx *context, stdout, stderr io.Writer, files ...string) (*compliance.LicenseGraph, error) {
if len(files) < 1 {
- return failNoneRequested
+ return nil, failNoneRequested
}
// Read the license graph from the license metadata files (*.meta_lic).
licenseGraph, err := compliance.ReadLicenseGraph(os.DirFS("."), stderr, files)
if err != nil {
- return fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
+ return nil, fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
}
if licenseGraph == nil {
- return failNoLicenses
+ return nil, failNoLicenses
}
- // resolutions will contain the requested set of resolutions.
- var resolutions *compliance.ResolutionSet
-
- resolutions = compliance.ResolveTopDownConditions(licenseGraph)
+ compliance.ResolveTopDownConditions(licenseGraph)
+ cs := compliance.AllLicenseConditions
if len(ctx.conditions) > 0 {
- rlist := make([]*compliance.ResolutionSet, 0, len(ctx.conditions))
+ cs = compliance.NewLicenseConditionSet()
for _, c := range ctx.conditions {
- rlist = append(rlist, compliance.WalkResolutionsForCondition(licenseGraph, resolutions, compliance.ConditionNames{c}))
- }
- if len(rlist) == 1 {
- resolutions = rlist[0]
- } else {
- resolutions = compliance.JoinResolutionSets(rlist...)
+ cs = cs.Plus(c)
}
}
+ resolutions := compliance.WalkResolutionsForCondition(licenseGraph, cs)
+
// nodes maps license metadata file names to graphViz node names when graphViz requested.
nodes := make(map[string]string)
n := 0
@@ -142,11 +141,7 @@
targetOut := func(target *compliance.TargetNode, sep string) string {
tOut := strings.TrimPrefix(target.Name(), ctx.stripPrefix)
if ctx.labelConditions {
- conditions := make([]string, 0, target.LicenseConditions().Count())
- for _, lc := range target.LicenseConditions().AsList() {
- conditions = append(conditions, lc.Name())
- }
- sort.Strings(conditions)
+ conditions := target.LicenseConditions().Names()
if len(conditions) > 0 {
tOut += sep + strings.Join(conditions, sep)
}
@@ -168,26 +163,16 @@
// outputResolution prints a resolution in the requested format to `stdout`, where one can read
// a resolution as `tname` resolves `oname`'s conditions named in `cnames`.
// `tname` is the name of the target the resolution applies to.
- // `oname` is the name of the target where the conditions originate.
// `cnames` is the list of conditions to resolve.
- outputResolution := func(tname, aname, oname string, cnames []string) {
+ outputResolution := func(tname, aname string, cnames []string) {
if ctx.graphViz {
// ... one edge per line labelled with \\n-separated annotations.
tNode := nodes[tname]
aNode := nodes[aname]
- oNode := nodes[oname]
- fmt.Fprintf(stdout, "\t%s -> %s; %s -> %s [label=\"%s\"];\n", tNode, aNode, aNode, oNode, strings.Join(cnames, "\\n"))
+ fmt.Fprintf(stdout, "\t%s -> %s [label=\"%s\"];\n", tNode, aNode, strings.Join(cnames, "\\n"))
} else {
// ... one edge per line with names in a colon-separated tuple.
- fmt.Fprintf(stdout, "%s %s %s %s\n", tname, aname, oname, strings.Join(cnames, ":"))
- }
- }
-
- // outputSingleton prints `tname` to plain text in the unexpected event that `tname` is the name of
- // a target in `resolutions.AppliesTo()` but has no conditions to resolve.
- outputSingleton := func(tname, aname string) {
- if !ctx.graphViz {
- fmt.Fprintf(stdout, "%s %s\n", tname, aname)
+ fmt.Fprintf(stdout, "%s %s %s\n", tname, aname, strings.Join(cnames, ":"))
}
}
@@ -200,16 +185,11 @@
fmt.Fprintf(stdout, "strict digraph {\n\trankdir=LR;\n")
for _, target := range targets {
makeNode(target)
- rl := compliance.ResolutionList(resolutions.Resolutions(target))
+ rl := resolutions.Resolutions(target)
sort.Sort(rl)
for _, r := range rl {
makeNode(r.ActsOn())
}
- conditions := rl.AllConditions().AsList()
- sort.Sort(conditions)
- for _, lc := range conditions {
- makeNode(lc.Origin())
- }
}
}
@@ -222,7 +202,7 @@
tname = targetOut(target, ":")
}
- rl := compliance.ResolutionList(resolutions.Resolutions(target))
+ rl := resolutions.Resolutions(target)
sort.Sort(rl)
for _, r := range rl {
var aname string
@@ -232,38 +212,11 @@
aname = targetOut(r.ActsOn(), ":")
}
- conditions := r.Resolves().AsList()
- sort.Sort(conditions)
-
- // poname is the previous origin name or "" if no previous
- poname := ""
-
// cnames accumulates the list of condition names originating at a single origin that apply to `target`.
- cnames := make([]string, 0, len(conditions))
+ cnames := r.Resolves().Names()
- // Output 1 line for each attachesTo+actsOn+origin combination.
- for _, condition := range conditions {
- var oname string
- if ctx.graphViz {
- oname = condition.Origin().Name()
- } else {
- oname = targetOut(condition.Origin(), ":")
- }
-
- // Detect when origin changes and output prior origin's conditions.
- if poname != oname && poname != "" {
- outputResolution(tname, aname, poname, cnames)
- cnames = cnames[:0]
- }
- poname = oname
- cnames = append(cnames, condition.Name())
- }
- // Output last origin's conditions or a singleton if no origins.
- if poname == "" {
- outputSingleton(tname, aname)
- } else {
- outputResolution(tname, aname, poname, cnames)
- }
+ // Output 1 line for each attachesTo+actsOn combination.
+ outputResolution(tname, aname, cnames)
}
}
// If graphViz output, rank the root nodes together, and complete the directed graph.
@@ -280,5 +233,5 @@
}
fmt.Fprintf(stdout, "}\n}\n")
}
- return nil
+ return licenseGraph, nil
}
diff --git a/tools/compliance/cmd/dumpresolutions_test.go b/tools/compliance/cmd/dumpresolutions_test.go
index cab1cc8..d904671 100644
--- a/tools/compliance/cmd/dumpresolutions_test.go
+++ b/tools/compliance/cmd/dumpresolutions_test.go
@@ -16,6 +16,7 @@
import (
"bytes"
+ "compliance"
"fmt"
"strings"
"testing"
@@ -34,20 +35,18 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/highest.apex.meta_lic testdata/firstparty/highest.apex.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
- "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
- "testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
+ "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/highest.apex.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
+ "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
+ "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
},
},
{
@@ -56,20 +55,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/firstparty/"},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic notice",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/liba.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libc.a.meta_lic notice",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -77,22 +74,22 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/firstparty/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic notice",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/liba.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libc.a.meta_lic notice",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -100,7 +97,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []string{},
@@ -110,7 +107,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []string{},
@@ -120,7 +117,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: append(compliance.ImpliesPrivate.AsList(),compliance.ImpliesShared.AsList()...),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []string{},
@@ -131,20 +128,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/firstparty/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice notice",
+ "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:notice notice",
+ "lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
},
},
{
@@ -152,20 +147,18 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/container.zip.meta_lic testdata/firstparty/container.zip.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
- "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
- "testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
+ "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin2.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/container.zip.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
+ "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
+ "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
},
},
{
@@ -173,11 +166,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/firstparty/application.meta_lic testdata/firstparty/application.meta_lic testdata/firstparty/application.meta_lic notice",
- "testdata/firstparty/application.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/bin/bin3.meta_lic testdata/firstparty/bin/bin3.meta_lic testdata/firstparty/bin/bin3.meta_lic notice",
- "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic testdata/firstparty/lib/libb.so.meta_lic notice",
+ "testdata/firstparty/application.meta_lic testdata/firstparty/application.meta_lic notice",
+ "testdata/firstparty/application.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
},
},
{
@@ -185,11 +175,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
- "testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
- "testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/bin/bin1.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic notice",
+ "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic notice",
},
},
{
@@ -197,7 +185,7 @@
name: "library",
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{
- "testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic notice",
+ "testdata/firstparty/lib/libd.so.meta_lic testdata/firstparty/lib/libd.so.meta_lic notice",
},
},
{
@@ -205,20 +193,18 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/highest.apex.meta_lic testdata/notice/highest.apex.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
- "testdata/notice/highest.apex.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
- "testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
+ "testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin1.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin2.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/highest.apex.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
+ "testdata/notice/highest.apex.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
+ "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
},
},
{
@@ -227,20 +213,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/notice/"},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic notice",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/liba.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libc.a.meta_lic notice",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -248,22 +232,22 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/notice/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic notice",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic notice",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/liba.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libc.a.meta_lic notice",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic notice",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -271,7 +255,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/notice/",
},
expectedOut: []string{},
@@ -281,7 +265,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/notice/",
},
expectedOut: []string{},
@@ -291,7 +275,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: append(compliance.ImpliesShared.AsList(),compliance.ImpliesPrivate.AsList()...),
stripPrefix: "testdata/notice/",
},
expectedOut: []string{},
@@ -302,20 +286,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/notice/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
- "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice lib/libc.a.meta_lic:notice notice",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice notice",
+ "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:notice notice",
+ "lib/liba.so.meta_lic:notice lib/liba.so.meta_lic:notice notice",
+ "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
},
},
{
@@ -323,20 +305,18 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/container.zip.meta_lic testdata/notice/container.zip.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
- "testdata/notice/container.zip.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
- "testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
+ "testdata/notice/bin/bin2.meta_lic testdata/notice/bin/bin2.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin1.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin2.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/container.zip.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
+ "testdata/notice/container.zip.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
+ "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
},
},
{
@@ -344,11 +324,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/notice/application.meta_lic testdata/notice/application.meta_lic testdata/notice/application.meta_lic notice",
- "testdata/notice/application.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/bin/bin3.meta_lic testdata/notice/bin/bin3.meta_lic testdata/notice/bin/bin3.meta_lic notice",
- "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic testdata/notice/lib/libb.so.meta_lic notice",
+ "testdata/notice/application.meta_lic testdata/notice/application.meta_lic notice",
+ "testdata/notice/application.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
},
},
{
@@ -356,11 +333,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
- "testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
- "testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/bin/bin1.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic notice",
+ "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic notice",
},
},
{
@@ -368,7 +343,7 @@
name: "library",
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{
- "testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic notice",
+ "testdata/notice/lib/libd.so.meta_lic testdata/notice/lib/libd.so.meta_lic notice",
},
},
{
@@ -376,20 +351,18 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/highest.apex.meta_lic notice",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
- "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
- "testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic notice",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/highest.apex.meta_lic notice",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
+ "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
+ "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
},
},
{
@@ -398,20 +371,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/reciprocal/"},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic reciprocal",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/liba.so.meta_lic reciprocal",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -419,17 +390,17 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
+ "highest.apex.meta_lic lib/libb.so.meta_lic notice",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic notice",
},
},
{
@@ -437,15 +408,15 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []string{
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic reciprocal",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal",
+ "highest.apex.meta_lic lib/liba.so.meta_lic reciprocal",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
},
},
{
@@ -453,7 +424,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []string{},
@@ -463,15 +434,15 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: append(compliance.ImpliesShared.AsList(),compliance.ImpliesPrivate.AsList()...),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []string{
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic reciprocal",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal",
+ "highest.apex.meta_lic lib/liba.so.meta_lic reciprocal",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic reciprocal",
},
},
{
@@ -480,20 +451,18 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/reciprocal/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:reciprocal lib/liba.so.meta_lic:reciprocal reciprocal",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:reciprocal lib/liba.so.meta_lic:reciprocal reciprocal",
- "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "lib/liba.so.meta_lic:reciprocal lib/liba.so.meta_lic:reciprocal lib/liba.so.meta_lic:reciprocal reciprocal",
- "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
- "lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:reciprocal reciprocal",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal",
+ "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:reciprocal reciprocal",
+ "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal",
+ "lib/liba.so.meta_lic:reciprocal lib/liba.so.meta_lic:reciprocal reciprocal",
+ "lib/libb.so.meta_lic:notice lib/libb.so.meta_lic:notice notice",
},
},
{
@@ -501,20 +470,18 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/container.zip.meta_lic notice",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
- "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
- "testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic notice",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin2.meta_lic notice",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/container.zip.meta_lic notice",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
+ "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
+ "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
},
},
{
@@ -522,11 +489,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/reciprocal/application.meta_lic testdata/reciprocal/application.meta_lic testdata/reciprocal/application.meta_lic notice",
- "testdata/reciprocal/application.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin3.meta_lic testdata/reciprocal/bin/bin3.meta_lic testdata/reciprocal/bin/bin3.meta_lic notice",
- "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic testdata/reciprocal/lib/libb.so.meta_lic notice",
+ "testdata/reciprocal/application.meta_lic testdata/reciprocal/application.meta_lic notice",
+ "testdata/reciprocal/application.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
},
},
{
@@ -534,11 +498,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
- "testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
- "testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/bin/bin1.meta_lic notice",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic reciprocal",
+ "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic reciprocal",
},
},
{
@@ -546,7 +508,7 @@
name: "library",
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{
- "testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic notice",
+ "testdata/reciprocal/lib/libd.so.meta_lic testdata/reciprocal/lib/libd.so.meta_lic notice",
},
},
{
@@ -554,33 +516,19 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic notice",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
+ "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/highest.apex.meta_lic notice:restricted:restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+ "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
{
@@ -589,33 +537,19 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/restricted/"},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "highest.apex.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice:restricted",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice:restricted",
+ "highest.apex.meta_lic highest.apex.meta_lic notice:restricted:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -623,15 +557,15 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/restricted/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin2.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
},
},
{
@@ -639,26 +573,23 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/restricted/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
+ "bin/bin1.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin2.meta_lic bin/bin2.meta_lic restricted",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin2.meta_lic restricted",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -666,7 +597,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/restricted/",
},
expectedOut: []string{},
@@ -676,26 +607,23 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: append(compliance.ImpliesShared.AsList(),compliance.ImpliesPrivate.AsList()...),
stripPrefix: "testdata/restricted/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/liba.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic reciprocal",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic restricted",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
+ "bin/bin1.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin2.meta_lic bin/bin2.meta_lic restricted",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin1.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic bin/bin2.meta_lic restricted",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -704,33 +632,19 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/restricted/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted restricted",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted restricted",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/liba.so.meta_lic:restricted restricted",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/liba.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "highest.apex.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted lib/liba.so.meta_lic:restricted restricted",
- "lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal lib/liba.so.meta_lic:restricted restricted",
- "lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal lib/libc.a.meta_lic:reciprocal reciprocal",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_allows_dynamic_linking",
+ "bin/bin2.meta_lic:notice bin/bin2.meta_lic:notice notice:restricted",
+ "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice notice:restricted",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice:restricted:restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
+ "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:reciprocal reciprocal:restricted_allows_dynamic_linking",
+ "lib/liba.so.meta_lic:restricted_allows_dynamic_linking lib/liba.so.meta_lic:restricted_allows_dynamic_linking restricted_allows_dynamic_linking",
+ "lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
},
},
{
@@ -738,33 +652,19 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic notice",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin2.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
+ "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin2.meta_lic notice:restricted",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/container.zip.meta_lic notice:restricted:restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+ "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
},
},
{
@@ -772,16 +672,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic notice",
- "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/application.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/bin/bin3.meta_lic testdata/restricted/bin/bin3.meta_lic testdata/restricted/bin/bin3.meta_lic restricted",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
- "testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic testdata/restricted/lib/libb.so.meta_lic restricted",
+ "testdata/restricted/application.meta_lic testdata/restricted/application.meta_lic notice:restricted:restricted_allows_dynamic_linking",
+ "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted:restricted_allows_dynamic_linking",
},
},
{
@@ -789,14 +681,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
- "testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted",
- "testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/bin/bin1.meta_lic notice:restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic restricted_allows_dynamic_linking",
+ "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic reciprocal:restricted_allows_dynamic_linking",
},
},
{
@@ -804,7 +691,7 @@
name: "library",
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{
- "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
+ "testdata/restricted/lib/libd.so.meta_lic testdata/restricted/lib/libd.so.meta_lic notice",
},
},
{
@@ -812,27 +699,19 @@
name: "apex",
roots: []string{"highest.apex.meta_lic"},
expectedOut: []string{
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/highest.apex.meta_lic testdata/proprietary/highest.apex.meta_lic notice",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/highest.apex.meta_lic notice:restricted",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
+ "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libc.a.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
},
},
{
@@ -841,27 +720,19 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/proprietary/"},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic by_exception_only:proprietary",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic by_exception_only:proprietary",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic by_exception_only:proprietary",
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic by_exception_only:proprietary",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic by_exception_only:proprietary",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic by_exception_only:proprietary",
- "highest.apex.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic by_exception_only:proprietary",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/libc.a.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic by_exception_only:proprietary",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/libd.so.meta_lic lib/libd.so.meta_lic lib/libd.so.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic proprietary:by_exception_only",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic proprietary:by_exception_only",
+ "bin/bin2.meta_lic bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "highest.apex.meta_lic highest.apex.meta_lic notice:restricted",
+ "highest.apex.meta_lic lib/liba.so.meta_lic proprietary:by_exception_only",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic lib/libc.a.meta_lic proprietary:by_exception_only",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary:by_exception_only",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -869,13 +740,13 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/proprietary/",
},
expectedOut: []string{
- "bin/bin1.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic bin/bin1.meta_lic bin/bin1.meta_lic notice",
- "highest.apex.meta_lic highest.apex.meta_lic highest.apex.meta_lic notice",
+ "bin/bin1.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic bin/bin1.meta_lic notice",
+ "highest.apex.meta_lic highest.apex.meta_lic notice",
},
},
{
@@ -883,16 +754,16 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []string{
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
+ "bin/bin2.meta_lic bin/bin2.meta_lic restricted",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin2.meta_lic restricted",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -900,17 +771,17 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []string{
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic proprietary",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic proprietary",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic proprietary",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic proprietary",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic proprietary",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic proprietary",
+ "bin/bin2.meta_lic bin/bin2.meta_lic proprietary",
+ "highest.apex.meta_lic bin/bin2.meta_lic proprietary",
+ "highest.apex.meta_lic lib/liba.so.meta_lic proprietary",
+ "highest.apex.meta_lic lib/libc.a.meta_lic proprietary",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
},
},
{
@@ -918,23 +789,21 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: append(compliance.ImpliesShared.AsList(),compliance.ImpliesPrivate.AsList()...),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []string{
- "bin/bin1.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
- "bin/bin1.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic proprietary",
- "bin/bin2.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic proprietary",
- "bin/bin2.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "bin/bin2.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic bin/bin2.meta_lic bin/bin2.meta_lic proprietary",
- "highest.apex.meta_lic bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic highest.apex.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
- "highest.apex.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
- "highest.apex.meta_lic lib/libc.a.meta_lic lib/libc.a.meta_lic proprietary",
- "lib/liba.so.meta_lic lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
- "lib/libb.so.meta_lic lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
+ "bin/bin1.meta_lic lib/liba.so.meta_lic proprietary",
+ "bin/bin1.meta_lic lib/libc.a.meta_lic proprietary",
+ "bin/bin2.meta_lic bin/bin2.meta_lic restricted:proprietary",
+ "bin/bin2.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic bin/bin2.meta_lic restricted:proprietary",
+ "highest.apex.meta_lic highest.apex.meta_lic restricted",
+ "highest.apex.meta_lic lib/liba.so.meta_lic proprietary",
+ "highest.apex.meta_lic lib/libb.so.meta_lic restricted",
+ "highest.apex.meta_lic lib/libc.a.meta_lic proprietary",
+ "lib/liba.so.meta_lic lib/liba.so.meta_lic proprietary",
+ "lib/libb.so.meta_lic lib/libb.so.meta_lic restricted",
},
},
{
@@ -943,27 +812,19 @@
roots: []string{"highest.apex.meta_lic"},
ctx: context{stripPrefix: "testdata/proprietary/", labelConditions: true},
expectedOut: []string{
- "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "bin/bin2.meta_lic:by_exception_only:proprietary bin/bin2.meta_lic:by_exception_only:proprietary bin/bin2.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "bin/bin2.meta_lic:by_exception_only:proprietary bin/bin2.meta_lic:by_exception_only:proprietary lib/libb.so.meta_lic:restricted restricted",
- "bin/bin2.meta_lic:by_exception_only:proprietary lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "bin/bin2.meta_lic:by_exception_only:proprietary lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:by_exception_only:proprietary bin/bin2.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "highest.apex.meta_lic:notice bin/bin2.meta_lic:by_exception_only:proprietary lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice",
- "highest.apex.meta_lic:notice highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "highest.apex.meta_lic:notice lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "highest.apex.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary lib/liba.so.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
- "lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary lib/libc.a.meta_lic:by_exception_only:proprietary by_exception_only:proprietary",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
- "lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice lib/libd.so.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:proprietary:by_exception_only proprietary:by_exception_only",
+ "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:proprietary:by_exception_only proprietary:by_exception_only",
+ "bin/bin2.meta_lic:proprietary:by_exception_only bin/bin2.meta_lic:proprietary:by_exception_only restricted:proprietary:by_exception_only",
+ "bin/bin2.meta_lic:proprietary:by_exception_only lib/libb.so.meta_lic:restricted restricted",
+ "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice notice",
+ "highest.apex.meta_lic:notice bin/bin2.meta_lic:proprietary:by_exception_only restricted:proprietary:by_exception_only",
+ "highest.apex.meta_lic:notice highest.apex.meta_lic:notice notice:restricted",
+ "highest.apex.meta_lic:notice lib/liba.so.meta_lic:proprietary:by_exception_only proprietary:by_exception_only",
+ "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted restricted",
+ "highest.apex.meta_lic:notice lib/libc.a.meta_lic:proprietary:by_exception_only proprietary:by_exception_only",
+ "lib/liba.so.meta_lic:proprietary:by_exception_only lib/liba.so.meta_lic:proprietary:by_exception_only proprietary:by_exception_only",
+ "lib/libb.so.meta_lic:restricted lib/libb.so.meta_lic:restricted restricted",
},
},
{
@@ -971,27 +832,19 @@
name: "container",
roots: []string{"container.zip.meta_lic"},
expectedOut: []string{
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/container.zip.meta_lic testdata/proprietary/container.zip.meta_lic notice",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin2.meta_lic restricted:proprietary:by_exception_only",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/container.zip.meta_lic notice:restricted",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
+ "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libc.a.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
},
},
{
@@ -999,15 +852,8 @@
name: "application",
roots: []string{"application.meta_lic"},
expectedOut: []string{
- "testdata/proprietary/application.meta_lic testdata/proprietary/application.meta_lic testdata/proprietary/application.meta_lic notice",
- "testdata/proprietary/application.meta_lic testdata/proprietary/application.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/application.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/application.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/application.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/bin/bin3.meta_lic testdata/proprietary/bin/bin3.meta_lic testdata/proprietary/bin/bin3.meta_lic restricted",
- "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
- "testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic testdata/proprietary/lib/libb.so.meta_lic restricted",
+ "testdata/proprietary/application.meta_lic testdata/proprietary/application.meta_lic notice:restricted",
+ "testdata/proprietary/application.meta_lic testdata/proprietary/lib/liba.so.meta_lic restricted:proprietary:by_exception_only",
},
},
{
@@ -1015,11 +861,9 @@
name: "binary",
roots: []string{"bin/bin1.meta_lic"},
expectedOut: []string{
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic testdata/proprietary/lib/liba.so.meta_lic by_exception_only:proprietary",
- "testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic testdata/proprietary/lib/libc.a.meta_lic by_exception_only:proprietary",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/bin/bin1.meta_lic notice",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic proprietary:by_exception_only",
+ "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic proprietary:by_exception_only",
},
},
{
@@ -1027,7 +871,7 @@
name: "library",
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []string{
- "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
+ "testdata/proprietary/lib/libd.so.meta_lic testdata/proprietary/lib/libd.so.meta_lic notice",
},
},
}
@@ -1046,7 +890,7 @@
for _, r := range tt.roots {
rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
}
- err := dumpResolutions(&tt.ctx, stdout, stderr, rootFiles...)
+ _, err := dumpResolutions(&tt.ctx, stdout, stderr, rootFiles...)
if err != nil {
t.Fatalf("dumpresolutions: error = %v, stderr = %v", err, stderr)
return
@@ -1076,7 +920,7 @@
}
type matcher interface {
- matchString(*testContext) string
+ matchString(*testContext, *compliance.LicenseGraph) string
typeString() string
}
@@ -1085,10 +929,23 @@
conditions []string
}
-func (tm *targetMatcher) matchString(ctx *testContext) string {
+// newTestCondition constructs a test license condition in the license graph.
+func newTestCondition(lg *compliance.LicenseGraph, conditionName... string) compliance.LicenseConditionSet {
+ cs := compliance.NewLicenseConditionSet()
+ for _, name := range conditionName {
+ cs = cs.Plus(compliance.RecognizedConditionNames[name])
+ }
+ if cs.IsEmpty() && len(conditionName) != 0 {
+ panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
+ }
+ return cs
+}
+
+func (tm *targetMatcher) matchString(ctx *testContext, lg *compliance.LicenseGraph) string {
+ cs := newTestCondition(lg, tm.conditions...)
m := tm.target
- if len(tm.conditions) > 0 {
- m += "\\n" + strings.Join(tm.conditions, "\\n")
+ if !cs.IsEmpty() {
+ m += "\\n" + strings.Join(cs.Names(), "\\n")
}
m = ctx.nodes[tm.target] + " [label=\"" + m + "\"];"
return m
@@ -1101,14 +958,13 @@
type resolutionMatcher struct {
appliesTo string
actsOn string
- origin string
conditions []string
}
-func (rm *resolutionMatcher) matchString(ctx *testContext) string {
- return ctx.nodes[rm.appliesTo] + " -> " + ctx.nodes[rm.actsOn] + "; " +
- ctx.nodes[rm.actsOn] + " -> " + ctx.nodes[rm.origin] +
- " [label=\"" + strings.Join(rm.conditions, "\\n") + "\"];"
+func (rm *resolutionMatcher) matchString(ctx *testContext, lg *compliance.LicenseGraph) string {
+ cs := newTestCondition(lg, rm.conditions...)
+ return ctx.nodes[rm.appliesTo] + " -> " + ctx.nodes[rm.actsOn] +
+ " [label=\"" + strings.Join(cs.Names(), "\\n") + "\"];"
}
func (rm *resolutionMatcher) typeString() string {
@@ -1125,7 +981,7 @@
}
}
-func matchResolution(appliesTo, actsOn, origin string, conditions ...string) getMatcher {
+func matchResolution(appliesTo, actsOn string, conditions ...string) getMatcher {
return func(ctx *testContext) matcher {
if _, ok := ctx.nodes[appliesTo]; !ok {
ctx.nodes[appliesTo] = fmt.Sprintf("unknown%d", ctx.nextNode)
@@ -1135,11 +991,7 @@
ctx.nodes[actsOn] = fmt.Sprintf("unknown%d", ctx.nextNode)
ctx.nextNode++
}
- if _, ok := ctx.nodes[origin]; !ok {
- ctx.nodes[origin] = fmt.Sprintf("unknown%d", ctx.nextNode)
- ctx.nextNode++
- }
- return &resolutionMatcher{appliesTo, actsOn, origin, append([]string{}, conditions...)}
+ return &resolutionMatcher{appliesTo, actsOn, append([]string{}, conditions...)}
}
}
@@ -1162,76 +1014,53 @@
matchTarget("testdata/firstparty/bin/bin2.meta_lic"),
matchTarget("testdata/firstparty/highest.apex.meta_lic"),
matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
- matchTarget("testdata/firstparty/lib/libd.so.meta_lic"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin2.meta_lic",
"testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/highest.apex.meta_lic",
- "testdata/firstparty/highest.apex.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/highest.apex.meta_lic",
"testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/lib/liba.so.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/lib/libb.so.meta_lic",
"testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libd.so.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1247,76 +1076,53 @@
matchTarget("bin/bin2.meta_lic"),
matchTarget("highest.apex.meta_lic"),
matchTarget("lib/libb.so.meta_lic"),
- matchTarget("lib/libd.so.meta_lic"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1325,7 +1131,7 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/firstparty/",
},
expectedOut: []getMatcher{
@@ -1338,62 +1144,50 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
},
},
@@ -1402,7 +1196,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []getMatcher{},
@@ -1412,7 +1206,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []getMatcher{},
@@ -1422,7 +1216,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: compliance.ImpliesShared.Union(compliance.ImpliesPrivate).AsList(),
stripPrefix: "testdata/firstparty/",
},
expectedOut: []getMatcher{},
@@ -1439,76 +1233,53 @@
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
matchTarget("lib/libb.so.meta_lic", "notice"),
- matchTarget("lib/libd.so.meta_lic", "notice"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1523,76 +1294,53 @@
matchTarget("testdata/firstparty/bin/bin2.meta_lic"),
matchTarget("testdata/firstparty/container.zip.meta_lic"),
matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
- matchTarget("testdata/firstparty/lib/libd.so.meta_lic"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin2.meta_lic",
"testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/bin/bin2.meta_lic",
- "testdata/firstparty/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/container.zip.meta_lic",
- "testdata/firstparty/container.zip.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/container.zip.meta_lic",
"testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/lib/liba.so.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/lib/libb.so.meta_lic",
"testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libd.so.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1603,32 +1351,13 @@
expectedOut: []getMatcher{
matchTarget("testdata/firstparty/application.meta_lic"),
matchTarget("testdata/firstparty/lib/liba.so.meta_lic"),
- matchTarget("testdata/firstparty/bin/bin3.meta_lic"),
- matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
matchResolution(
"testdata/firstparty/application.meta_lic",
"testdata/firstparty/application.meta_lic",
- "testdata/firstparty/application.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/application.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/bin/bin3.meta_lic",
- "testdata/firstparty/bin/bin3.meta_lic",
- "testdata/firstparty/bin/bin3.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
- "testdata/firstparty/lib/libb.so.meta_lic",
"notice"),
},
},
@@ -1643,27 +1372,14 @@
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/bin/bin1.meta_lic",
- "testdata/firstparty/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/firstparty/bin/bin1.meta_lic",
"testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "testdata/firstparty/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
- "testdata/firstparty/lib/libc.a.meta_lic",
"notice"),
},
},
@@ -1676,7 +1392,6 @@
matchResolution(
"testdata/firstparty/lib/libd.so.meta_lic",
"testdata/firstparty/lib/libd.so.meta_lic",
- "testdata/firstparty/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1691,76 +1406,53 @@
matchTarget("testdata/notice/bin/bin2.meta_lic"),
matchTarget("testdata/notice/highest.apex.meta_lic"),
matchTarget("testdata/notice/lib/libb.so.meta_lic"),
- matchTarget("testdata/notice/lib/libd.so.meta_lic"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin2.meta_lic",
"testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/highest.apex.meta_lic",
- "testdata/notice/highest.apex.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/highest.apex.meta_lic",
"testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/notice/lib/liba.so.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/lib/libb.so.meta_lic",
"testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libd.so.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1776,76 +1468,53 @@
matchTarget("bin/bin2.meta_lic"),
matchTarget("highest.apex.meta_lic"),
matchTarget("lib/libb.so.meta_lic"),
- matchTarget("lib/libd.so.meta_lic"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -1854,7 +1523,7 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/notice/",
},
expectedOut: []getMatcher{
@@ -1867,62 +1536,50 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
},
},
@@ -1931,7 +1588,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/notice/",
},
expectedOut: []getMatcher{},
@@ -1941,7 +1598,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/notice/",
},
expectedOut: []getMatcher{},
@@ -1951,7 +1608,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: compliance.ImpliesShared.Union(compliance.ImpliesPrivate).AsList(),
stripPrefix: "testdata/notice/",
},
expectedOut: []getMatcher{},
@@ -1968,76 +1625,53 @@
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
matchTarget("lib/libb.so.meta_lic", "notice"),
- matchTarget("lib/libd.so.meta_lic", "notice"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"notice"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2052,76 +1686,53 @@
matchTarget("testdata/notice/bin/bin2.meta_lic"),
matchTarget("testdata/notice/container.zip.meta_lic"),
matchTarget("testdata/notice/lib/libb.so.meta_lic"),
- matchTarget("testdata/notice/lib/libd.so.meta_lic"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin2.meta_lic",
"testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/bin/bin2.meta_lic",
- "testdata/notice/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/container.zip.meta_lic",
- "testdata/notice/container.zip.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/container.zip.meta_lic",
"testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
"notice"),
matchResolution(
"testdata/notice/lib/liba.so.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/lib/libb.so.meta_lic",
"testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libd.so.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2132,32 +1743,13 @@
expectedOut: []getMatcher{
matchTarget("testdata/notice/application.meta_lic"),
matchTarget("testdata/notice/lib/liba.so.meta_lic"),
- matchTarget("testdata/notice/bin/bin3.meta_lic"),
- matchTarget("testdata/notice/lib/libb.so.meta_lic"),
matchResolution(
"testdata/notice/application.meta_lic",
"testdata/notice/application.meta_lic",
- "testdata/notice/application.meta_lic",
"notice"),
matchResolution(
"testdata/notice/application.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/bin/bin3.meta_lic",
- "testdata/notice/bin/bin3.meta_lic",
- "testdata/notice/bin/bin3.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
- "testdata/notice/lib/libb.so.meta_lic",
"notice"),
},
},
@@ -2172,27 +1764,14 @@
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/bin/bin1.meta_lic",
- "testdata/notice/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
"notice"),
matchResolution(
"testdata/notice/bin/bin1.meta_lic",
"testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "testdata/notice/lib/liba.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
- "testdata/notice/lib/libc.a.meta_lic",
"notice"),
},
},
@@ -2205,7 +1784,6 @@
matchResolution(
"testdata/notice/lib/libd.so.meta_lic",
"testdata/notice/lib/libd.so.meta_lic",
- "testdata/notice/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2220,76 +1798,53 @@
matchTarget("testdata/reciprocal/bin/bin2.meta_lic"),
matchTarget("testdata/reciprocal/highest.apex.meta_lic"),
matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
- matchTarget("testdata/reciprocal/lib/libd.so.meta_lic"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/bin/bin2.meta_lic",
"testdata/reciprocal/bin/bin2.meta_lic",
- "testdata/reciprocal/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/bin/bin2.meta_lic",
- "testdata/reciprocal/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/highest.apex.meta_lic",
- "testdata/reciprocal/highest.apex.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/highest.apex.meta_lic",
"testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/lib/liba.so.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/lib/libb.so.meta_lic",
"testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/reciprocal/lib/libd.so.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2305,76 +1860,53 @@
matchTarget("bin/bin2.meta_lic"),
matchTarget("highest.apex.meta_lic"),
matchTarget("lib/libb.so.meta_lic"),
- matchTarget("lib/libd.so.meta_lic"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2383,7 +1915,7 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []getMatcher{
@@ -2394,37 +1926,30 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
},
},
@@ -2433,7 +1958,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []getMatcher{
@@ -2444,27 +1969,22 @@
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
},
},
@@ -2473,7 +1993,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []getMatcher{},
@@ -2483,7 +2003,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: compliance.ImpliesShared.Union(compliance.ImpliesPrivate).AsList(),
stripPrefix: "testdata/reciprocal/",
},
expectedOut: []getMatcher{
@@ -2494,27 +2014,22 @@
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
},
},
@@ -2530,76 +2045,53 @@
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
matchTarget("lib/libb.so.meta_lic", "notice"),
- matchTarget("lib/libd.so.meta_lic", "notice"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2614,76 +2106,53 @@
matchTarget("testdata/reciprocal/bin/bin2.meta_lic"),
matchTarget("testdata/reciprocal/container.zip.meta_lic"),
matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
- matchTarget("testdata/reciprocal/lib/libd.so.meta_lic"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/bin/bin2.meta_lic",
"testdata/reciprocal/bin/bin2.meta_lic",
- "testdata/reciprocal/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/bin/bin2.meta_lic",
- "testdata/reciprocal/bin/bin2.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/container.zip.meta_lic",
- "testdata/reciprocal/container.zip.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/container.zip.meta_lic",
"testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/lib/liba.so.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/lib/libb.so.meta_lic",
"testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "notice"),
- matchResolution(
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/reciprocal/lib/libd.so.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2694,33 +2163,14 @@
expectedOut: []getMatcher{
matchTarget("testdata/reciprocal/application.meta_lic"),
matchTarget("testdata/reciprocal/lib/liba.so.meta_lic"),
- matchTarget("testdata/reciprocal/bin/bin3.meta_lic"),
- matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
matchResolution(
"testdata/reciprocal/application.meta_lic",
"testdata/reciprocal/application.meta_lic",
- "testdata/reciprocal/application.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/application.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
- matchResolution(
- "testdata/reciprocal/bin/bin3.meta_lic",
- "testdata/reciprocal/bin/bin3.meta_lic",
- "testdata/reciprocal/bin/bin3.meta_lic",
- "notice"),
- matchResolution(
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "testdata/reciprocal/lib/libb.so.meta_lic",
- "notice"),
},
},
{
@@ -2734,27 +2184,14 @@
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/bin/bin1.meta_lic",
- "testdata/reciprocal/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
"reciprocal"),
matchResolution(
"testdata/reciprocal/bin/bin1.meta_lic",
"testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "testdata/reciprocal/lib/liba.so.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
- "testdata/reciprocal/lib/libc.a.meta_lic",
"reciprocal"),
},
},
@@ -2767,7 +2204,6 @@
matchResolution(
"testdata/reciprocal/lib/libd.so.meta_lic",
"testdata/reciprocal/lib/libd.so.meta_lic",
- "testdata/reciprocal/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -2781,143 +2217,67 @@
matchTarget("testdata/restricted/lib/libc.a.meta_lic"),
matchTarget("testdata/restricted/bin/bin2.meta_lic"),
matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
- matchTarget("testdata/restricted/lib/libd.so.meta_lic"),
matchTarget("testdata/restricted/highest.apex.meta_lic"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
- "notice"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/restricted/highest.apex.meta_lic",
"testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/restricted/highest.apex.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
+ "restricted",
+ "restricted_allows_dynamic_linking",
"notice"),
+ matchResolution(
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "restricted"),
+ matchResolution(
+ "testdata/restricted/highest.apex.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "restricted"),
},
},
{
@@ -2931,143 +2291,67 @@
matchTarget("lib/libc.a.meta_lic"),
matchTarget("bin/bin2.meta_lic"),
matchTarget("lib/libb.so.meta_lic"),
- matchTarget("lib/libd.so.meta_lic"),
matchTarget("highest.apex.meta_lic"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libd.so.meta_lic",
"lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
- "notice"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
+ "restricted",
+ "restricted_allows_dynamic_linking",
"notice"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/libb.so.meta_lic",
+ "restricted"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/libc.a.meta_lic",
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "lib/liba.so.meta_lic",
+ "lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "lib/libb.so.meta_lic",
+ "lib/libb.so.meta_lic",
+ "restricted"),
},
},
{
@@ -3075,7 +2359,7 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/restricted/",
},
expectedOut: []getMatcher{
@@ -3085,27 +2369,22 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
},
},
@@ -3114,7 +2393,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/restricted/",
},
expectedOut: []getMatcher{
@@ -3127,82 +2406,57 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"bin/bin2.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
+ "bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
"highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
+ "bin/bin2.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
+ "restricted",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
},
},
@@ -3211,7 +2465,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/restricted/",
},
expectedOut: []getMatcher{},
@@ -3221,7 +2475,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: compliance.ImpliesShared.Union(compliance.ImpliesPrivate).AsList(),
stripPrefix: "testdata/restricted/",
},
expectedOut: []getMatcher{
@@ -3234,82 +2488,57 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"bin/bin2.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
+ "bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
"highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
+ "bin/bin2.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
+ "restricted",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
},
},
@@ -3320,147 +2549,71 @@
ctx: context{stripPrefix: "testdata/restricted/", labelConditions: true},
expectedOut: []getMatcher{
matchTarget("bin/bin1.meta_lic", "notice"),
- matchTarget("lib/liba.so.meta_lic", "restricted"),
+ matchTarget("lib/liba.so.meta_lic", "restricted_allows_dynamic_linking"),
matchTarget("lib/libc.a.meta_lic", "reciprocal"),
matchTarget("bin/bin2.meta_lic", "notice"),
matchTarget("lib/libb.so.meta_lic", "restricted"),
- matchTarget("lib/libd.so.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin1.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libd.so.meta_lic",
"lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
- "notice"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin1.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
+ "restricted",
+ "restricted_allows_dynamic_linking",
"notice"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/libb.so.meta_lic",
+ "restricted"),
+ matchResolution(
+ "highest.apex.meta_lic",
+ "lib/libc.a.meta_lic",
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "lib/liba.so.meta_lic",
+ "lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "lib/libb.so.meta_lic",
+ "lib/libb.so.meta_lic",
+ "restricted"),
},
},
{
@@ -3473,143 +2626,67 @@
matchTarget("testdata/restricted/lib/libc.a.meta_lic"),
matchTarget("testdata/restricted/bin/bin2.meta_lic"),
matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
- matchTarget("testdata/restricted/lib/libd.so.meta_lic"),
matchTarget("testdata/restricted/container.zip.meta_lic"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
"testdata/restricted/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
- "notice"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/bin/bin2.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/bin/bin2.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/container.zip.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/restricted/container.zip.meta_lic",
"testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/restricted/container.zip.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
+ "restricted",
+ "restricted_allows_dynamic_linking",
"notice"),
+ matchResolution(
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "restricted"),
+ matchResolution(
+ "testdata/restricted/container.zip.meta_lic",
+ "testdata/restricted/lib/libc.a.meta_lic",
+ "reciprocal",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "testdata/restricted/lib/liba.so.meta_lic",
+ "restricted_allows_dynamic_linking"),
+ matchResolution(
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "testdata/restricted/lib/libb.so.meta_lic",
+ "restricted"),
},
},
{
@@ -3619,57 +2696,16 @@
expectedOut: []getMatcher{
matchTarget("testdata/restricted/application.meta_lic"),
matchTarget("testdata/restricted/lib/liba.so.meta_lic"),
- matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
- matchTarget("testdata/restricted/bin/bin3.meta_lic"),
matchResolution(
"testdata/restricted/application.meta_lic",
"testdata/restricted/application.meta_lic",
- "testdata/restricted/application.meta_lic",
+ "restricted",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/application.meta_lic",
- "testdata/restricted/application.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/application.meta_lic",
- "testdata/restricted/application.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/application.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/application.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/application.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin3.meta_lic",
- "testdata/restricted/bin/bin3.meta_lic",
- "testdata/restricted/bin/bin3.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
- "testdata/restricted/lib/libb.so.meta_lic",
+ "restricted_allows_dynamic_linking",
"restricted"),
},
},
@@ -3684,42 +2720,16 @@
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
+ "restricted_allows_dynamic_linking",
"notice"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
+ "restricted_allows_dynamic_linking"),
matchResolution(
"testdata/restricted/bin/bin1.meta_lic",
"testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/bin/bin1.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "reciprocal"),
- matchResolution(
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/liba.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
- "testdata/restricted/lib/libc.a.meta_lic",
+ "restricted_allows_dynamic_linking",
"reciprocal"),
},
},
@@ -3732,7 +2742,6 @@
matchResolution(
"testdata/restricted/lib/libd.so.meta_lic",
"testdata/restricted/lib/libd.so.meta_lic",
- "testdata/restricted/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -3746,96 +2755,61 @@
matchTarget("testdata/proprietary/lib/libc.a.meta_lic"),
matchTarget("testdata/proprietary/bin/bin2.meta_lic"),
matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
- matchTarget("testdata/proprietary/lib/libd.so.meta_lic"),
matchTarget("testdata/proprietary/highest.apex.meta_lic"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin2.meta_lic",
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
"testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/proprietary/highest.apex.meta_lic",
"testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
- "testdata/proprietary/highest.apex.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
@@ -3843,24 +2817,7 @@
matchResolution(
"testdata/proprietary/lib/libb.so.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
- matchResolution(
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "notice"),
},
},
{
@@ -3874,96 +2831,61 @@
matchTarget("lib/libc.a.meta_lic"),
matchTarget("bin/bin2.meta_lic"),
matchTarget("lib/libb.so.meta_lic"),
- matchTarget("lib/libd.so.meta_lic"),
matchTarget("highest.apex.meta_lic"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"by_exception_only",
+ "restricted",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libd.so.meta_lic",
"lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
- "highest.apex.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"by_exception_only",
@@ -3971,24 +2893,7 @@
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "notice"),
},
},
{
@@ -3996,7 +2901,7 @@
name: "apex_trimmed_notice",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"notice"},
+ conditions: []compliance.LicenseCondition{compliance.NoticeCondition},
stripPrefix: "testdata/proprietary/",
},
expectedOut: []getMatcher{
@@ -4005,17 +2910,14 @@
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
"notice"),
},
},
@@ -4024,7 +2926,7 @@
name: "apex_trimmed_share",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted"},
+ conditions: compliance.ImpliesShared.AsList(),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []getMatcher{
@@ -4034,32 +2936,26 @@
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"bin/bin2.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
},
},
@@ -4068,7 +2964,7 @@
name: "apex_trimmed_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"proprietary"},
+ conditions: compliance.ImpliesPrivate.AsList(),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []getMatcher{
@@ -4080,37 +2976,30 @@
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"proprietary"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
},
},
@@ -4119,7 +3008,7 @@
name: "apex_trimmed_share_private",
roots: []string{"highest.apex.meta_lic"},
ctx: context{
- conditions: []string{"reciprocal", "restricted", "proprietary"},
+ conditions: compliance.ImpliesShared.Union(compliance.ImpliesPrivate).AsList(),
stripPrefix: "testdata/proprietary/",
},
expectedOut: []getMatcher{
@@ -4132,67 +3021,48 @@
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"proprietary"),
matchResolution(
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"proprietary"),
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
},
},
@@ -4207,96 +3077,61 @@
matchTarget("lib/libc.a.meta_lic", "by_exception_only", "proprietary"),
matchTarget("bin/bin2.meta_lic", "by_exception_only", "proprietary"),
matchTarget("lib/libb.so.meta_lic", "restricted"),
- matchTarget("lib/libd.so.meta_lic", "notice"),
matchTarget("highest.apex.meta_lic", "notice"),
matchResolution(
"bin/bin1.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"bin/bin1.meta_lic",
"lib/liba.so.meta_lic",
- "lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"bin/bin1.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "bin/bin2.meta_lic",
- "lib/libd.so.meta_lic",
"lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin1.meta_lic",
- "bin/bin1.meta_lic",
"notice"),
matchResolution(
"highest.apex.meta_lic",
"bin/bin2.meta_lic",
- "bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
- "bin/bin2.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "highest.apex.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"highest.apex.meta_lic",
- "highest.apex.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "highest.apex.meta_lic",
- "lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"highest.apex.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"highest.apex.meta_lic",
"lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
- "highest.apex.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"lib/liba.so.meta_lic",
"by_exception_only",
@@ -4304,24 +3139,7 @@
matchResolution(
"lib/libb.so.meta_lic",
"lib/libb.so.meta_lic",
- "lib/libb.so.meta_lic",
"restricted"),
- matchResolution(
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "lib/libc.a.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "lib/libd.so.meta_lic",
- "notice"),
},
},
{
@@ -4334,96 +3152,61 @@
matchTarget("testdata/proprietary/lib/libc.a.meta_lic"),
matchTarget("testdata/proprietary/bin/bin2.meta_lic"),
matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
- matchTarget("testdata/proprietary/lib/libd.so.meta_lic"),
matchTarget("testdata/proprietary/container.zip.meta_lic"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin2.meta_lic",
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
"testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
"testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/bin/bin2.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
"testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/container.zip.meta_lic",
+ "restricted",
"notice"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
matchResolution(
"testdata/proprietary/container.zip.meta_lic",
"testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
- "testdata/proprietary/container.zip.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
@@ -4431,24 +3214,7 @@
matchResolution(
"testdata/proprietary/lib/libb.so.meta_lic",
"testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
"restricted"),
- matchResolution(
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
- "notice"),
},
},
{
@@ -4458,55 +3224,17 @@
expectedOut: []getMatcher{
matchTarget("testdata/proprietary/application.meta_lic"),
matchTarget("testdata/proprietary/lib/liba.so.meta_lic"),
- matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
- matchTarget("testdata/proprietary/bin/bin3.meta_lic"),
matchResolution(
"testdata/proprietary/application.meta_lic",
"testdata/proprietary/application.meta_lic",
- "testdata/proprietary/application.meta_lic",
- "notice"),
- matchResolution(
- "testdata/proprietary/application.meta_lic",
- "testdata/proprietary/application.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
+ "notice",
"restricted"),
matchResolution(
"testdata/proprietary/application.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
+ "restricted",
"by_exception_only",
"proprietary"),
- matchResolution(
- "testdata/proprietary/application.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/application.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/bin/bin3.meta_lic",
- "testdata/proprietary/bin/bin3.meta_lic",
- "testdata/proprietary/bin/bin3.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
- matchResolution(
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "testdata/proprietary/lib/libb.so.meta_lic",
- "restricted"),
},
},
{
@@ -4520,30 +3248,15 @@
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/bin/bin1.meta_lic",
- "testdata/proprietary/bin/bin1.meta_lic",
"notice"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
"by_exception_only",
"proprietary"),
matchResolution(
"testdata/proprietary/bin/bin1.meta_lic",
"testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "testdata/proprietary/lib/liba.so.meta_lic",
- "by_exception_only",
- "proprietary"),
- matchResolution(
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
- "testdata/proprietary/lib/libc.a.meta_lic",
"by_exception_only",
"proprietary"),
},
@@ -4557,7 +3270,6 @@
matchResolution(
"testdata/proprietary/lib/libd.so.meta_lic",
"testdata/proprietary/lib/libd.so.meta_lic",
- "testdata/proprietary/lib/libd.so.meta_lic",
"notice"),
},
},
@@ -4566,13 +3278,6 @@
t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
ctx := &testContext{0, make(map[string]string)}
- expectedOut := &bytes.Buffer{}
- for _, eo := range tt.expectedOut {
- m := eo(ctx)
- expectedOut.WriteString(m.matchString(ctx))
- expectedOut.WriteString("\n")
- }
-
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
@@ -4581,8 +3286,7 @@
rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
}
tt.ctx.graphViz = true
- err := dumpResolutions(&tt.ctx, stdout, stderr, rootFiles...)
-
+ lg, err := dumpResolutions(&tt.ctx, stdout, stderr, rootFiles...)
if err != nil {
t.Fatalf("dumpresolutions: error = %v, stderr = %v", err, stderr)
return
@@ -4590,6 +3294,14 @@
if stderr.Len() > 0 {
t.Errorf("dumpresolutions: gotStderr = %v, want none", stderr)
}
+
+ expectedOut := &bytes.Buffer{}
+ for _, eo := range tt.expectedOut {
+ m := eo(ctx)
+ expectedOut.WriteString(m.matchString(ctx, lg))
+ expectedOut.WriteString("\n")
+ }
+
outList := strings.Split(stdout.String(), "\n")
outLine := 0
if outList[outLine] != "strict digraph {" {
diff --git a/tools/compliance/cmd/listshare.go b/tools/compliance/cmd/listshare.go
index bba2308..5c58dc4 100644
--- a/tools/compliance/cmd/listshare.go
+++ b/tools/compliance/cmd/listshare.go
@@ -22,6 +22,7 @@
"os"
"path/filepath"
"sort"
+ "strings"
)
func init() {
@@ -83,17 +84,17 @@
shareSource := compliance.ResolveSourceSharing(licenseGraph)
// Group the resolutions by project.
- presolution := make(map[string]*compliance.LicenseConditionSet)
+ presolution := make(map[string]compliance.LicenseConditionSet)
for _, target := range shareSource.AttachesTo() {
rl := shareSource.Resolutions(target)
sort.Sort(rl)
for _, r := range rl {
for _, p := range r.ActsOn().Projects() {
if _, ok := presolution[p]; !ok {
- presolution[p] = r.Resolves().Copy()
+ presolution[p] = r.Resolves()
continue
}
- presolution[p].AddSet(r.Resolves())
+ presolution[p] = presolution[p].Union(r.Resolves())
}
}
}
@@ -107,17 +108,11 @@
// Output the sorted projects and the source-sharing license conditions that each project resolves.
for _, p := range projects {
- fmt.Fprintf(stdout, "%s", p)
-
- // Sort the conditions for repeatability/stability.
- conditions := presolution[p].AsList()
- sort.Sort(conditions)
-
- // Output the sorted origin:condition pairs.
- for _, lc := range conditions {
- fmt.Fprintf(stdout, ",%s:%s", lc.Origin().Name(), lc.Name())
+ if presolution[p].IsEmpty() {
+ fmt.Fprintf(stdout, "%s\n", p)
+ } else {
+ fmt.Fprintf(stdout, "%s,%s\n", p, strings.Join(presolution[p].Names(), ","))
}
- fmt.Fprintf(stdout, "\n")
}
return nil
diff --git a/tools/compliance/cmd/listshare_test.go b/tools/compliance/cmd/listshare_test.go
index b4847e3..71a0be6 100644
--- a/tools/compliance/cmd/listshare_test.go
+++ b/tools/compliance/cmd/listshare_test.go
@@ -98,12 +98,12 @@
expectedOut: []projectShare{
{
project: "device/library",
- conditions: []string{"lib/liba.so.meta_lic:reciprocal"},
+ conditions: []string{"reciprocal"},
},
{
project: "static/library",
conditions: []string{
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
},
},
},
@@ -115,12 +115,12 @@
expectedOut: []projectShare{
{
project: "device/library",
- conditions: []string{"lib/liba.so.meta_lic:reciprocal"},
+ conditions: []string{"reciprocal"},
},
{
project: "static/library",
conditions: []string{
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
},
},
},
@@ -132,7 +132,7 @@
expectedOut: []projectShare{
{
project: "device/library",
- conditions: []string{"lib/liba.so.meta_lic:reciprocal"},
+ conditions: []string{"reciprocal"},
},
},
},
@@ -144,13 +144,13 @@
{
project: "device/library",
conditions: []string{
- "lib/liba.so.meta_lic:reciprocal",
+ "reciprocal",
},
},
{
project: "static/library",
conditions: []string{
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
},
},
},
@@ -168,34 +168,34 @@
expectedOut: []projectShare{
{
project: "base/library",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "device/library",
- conditions: []string{"lib/liba.so.meta_lic:restricted"},
+ conditions: []string{"restricted_allows_dynamic_linking"},
},
{
project: "dynamic/binary",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "highest/apex",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libb.so.meta_lic:restricted",
+ "restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "static/binary",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "static/library",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
+ "restricted_allows_dynamic_linking",
},
},
},
@@ -207,34 +207,34 @@
expectedOut: []projectShare{
{
project: "base/library",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "container/zip",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libb.so.meta_lic:restricted",
+ "restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "device/library",
- conditions: []string{"lib/liba.so.meta_lic:restricted"},
+ conditions: []string{"restricted_allows_dynamic_linking"},
},
{
project: "dynamic/binary",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "static/binary",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "static/library",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
+ "restricted_allows_dynamic_linking",
},
},
},
@@ -247,15 +247,15 @@
{
project: "device/library",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libb.so.meta_lic:restricted",
+ "restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "distributable/application",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libb.so.meta_lic:restricted",
+ "restricted",
+ "restricted_allows_dynamic_linking",
},
},
},
@@ -268,20 +268,20 @@
{
project: "device/library",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "static/binary",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
+ "restricted_allows_dynamic_linking",
},
},
{
project: "static/library",
conditions: []string{
- "lib/liba.so.meta_lic:restricted",
- "lib/libc.a.meta_lic:reciprocal",
+ "reciprocal",
+ "restricted_allows_dynamic_linking",
},
},
},
@@ -299,15 +299,15 @@
expectedOut: []projectShare{
{
project: "base/library",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "dynamic/binary",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "highest/apex",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
},
},
@@ -318,15 +318,15 @@
expectedOut: []projectShare{
{
project: "base/library",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "container/zip",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "dynamic/binary",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
},
},
@@ -337,11 +337,11 @@
expectedOut: []projectShare{
{
project: "device/library",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
{
project: "distributable/application",
- conditions: []string{"lib/libb.so.meta_lic:restricted"},
+ conditions: []string{"restricted"},
},
},
},
@@ -357,6 +357,98 @@
roots: []string{"lib/libd.so.meta_lic"},
expectedOut: []projectShare{},
},
+ {
+ condition: "regressgpl1",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []projectShare{
+ {
+ project: "bin/threelibraries",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "container/zip",
+ conditions: []string{"restricted"},
+ },
+ },
+ },
+ {
+ condition: "regressgpl1",
+ name: "containerplus",
+ roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
+ expectedOut: []projectShare{
+ {
+ project: "bin/threelibraries",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "container/zip",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/apache",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/c++",
+ conditions: []string{"restricted"},
+ },
+ },
+ },
+ {
+ condition: "regressgpl2",
+ name: "container",
+ roots: []string{"container.zip.meta_lic"},
+ expectedOut: []projectShare{
+ {
+ project: "bin/threelibraries",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "container/zip",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/apache",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/c++",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/gpl",
+ conditions: []string{"restricted"},
+ },
+ },
+ },
+ {
+ condition: "regressgpl2",
+ name: "containerplus",
+ roots: []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
+ expectedOut: []projectShare{
+ {
+ project: "bin/threelibraries",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "container/zip",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/apache",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/c++",
+ conditions: []string{"restricted"},
+ },
+ {
+ project: "lib/gpl",
+ conditions: []string{"restricted"},
+ },
+ },
+ },
}
for _, tt := range tests {
t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
@@ -365,9 +457,6 @@
expectedOut.WriteString(p.project)
for _, lc := range p.conditions {
expectedOut.WriteString(",")
- expectedOut.WriteString("testdata/")
- expectedOut.WriteString(tt.condition)
- expectedOut.WriteString("/")
expectedOut.WriteString(lc)
}
expectedOut.WriteString("\n")
diff --git a/tools/compliance/cmd/testdata/README.md b/tools/compliance/cmd/testdata/README.md
index 9872c04..07564c2 100644
--- a/tools/compliance/cmd/testdata/README.md
+++ b/tools/compliance/cmd/testdata/README.md
@@ -1,9 +1,12 @@
## Test data
-Each directory under testdata/ defines a similar build graph.
+Each non-regression directory under testdata/ defines a similar build graph.
All have the same structure, but different versions of the graph have different
license metadata.
+The regression* directories can have whatever structure is required for the
+specific test case.
+
### Testdata build graph structure:
The structure is meant to simulate some common scenarios:
@@ -70,6 +73,7 @@
#### a pure aggregation `container.zip` that merely bundles files together
+```dot
strict digraph {
rankdir=LR;
bin1 [label="bin/bin1.meta_lic"];
@@ -89,6 +93,7 @@
container -> libb [label="static"];
{rank=same; container}
}
+```
#### an apex file (more like an apk file) with some binaries and libraries
diff --git a/tools/compliance/cmd/testdata/regressgpl1/README.md b/tools/compliance/cmd/testdata/regressgpl1/README.md
new file mode 100644
index 0000000..6ab872d
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/README.md
@@ -0,0 +1,32 @@
+## Shipped versus non-shipped libraries with restricted license
+
+### Testdata build graph structure:
+
+A restricted licensed library sandwiched between a notice library and a notice
+binary. The source-code for the libraries only needs to be shared if shipped
+alongside the container with the binaries.
+
+```dot
+strict digraph {
+ rankdir=LR;
+ bin1 [label="bin/bin1.meta_lic\nnotice"];
+ bin2 [label="bin/bin2.meta_lic\nnotice"];
+ bin3 [label="bin/bin3.meta_lic\nnotice"];
+ container [label="container.zip.meta_lic\nnotice"];
+ libapache [label="lib/libapache.so.meta_lic\nnotice"];
+ libcxx [label="lib/libc++.so.meta_lic\nnotice"];
+ libgpl [label="lib/libgpl.so.meta_lic\nrestricted"];
+ container -> bin1[label="static"];
+ container -> bin2 [label="static"];
+ container -> bin3 [label="static"];
+ bin1 -> libcxx [label="dynamic"];
+ bin2 -> libapache [label="dynamic"];
+ bin2 -> libcxx [label="dynamic"];
+ bin3 -> libapache [label="dynamic"];
+ bin3 -> libcxx [label="dynamic"];
+ bin3 -> libgpl [label="dynamic"];
+ libapache -> libcxx [label="dynamic"];
+ libgpl -> libcxx [label="dynamic"];
+ {rank=same; container}
+}
+```
diff --git a/tools/compliance/cmd/testdata/regressgpl1/bin/bin1.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/bin/bin1.meta_lic
new file mode 100644
index 0000000..4afd240
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/bin/bin1.meta_lic
@@ -0,0 +1,14 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin1"
+installed: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl1/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl1/bin/bin2.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/bin/bin2.meta_lic
new file mode 100644
index 0000000..4e56fa3
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/bin/bin2.meta_lic
@@ -0,0 +1,19 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/twolibraries"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin2"
+installed: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+deps: {
+ file: "testdata/regressgpl1/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl1/lib/libapache.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl1/bin/bin3.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/bin/bin3.meta_lic
new file mode 100644
index 0000000..16290d3
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/bin/bin3.meta_lic
@@ -0,0 +1,23 @@
+package_name: "Compiler"
+module_classes: "EXECUTABLES"
+projects: "bin/threelibraries"
+license_kinds: "SPDX-license-identifier-NCSA"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin3"
+installed: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+sources: "out/target/product/fictional/system/lib/libgpl.so"
+deps: {
+ file: "testdata/regressgpl1/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl1/lib/libapache.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl1/lib/libgpl.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl1/container.zip.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/container.zip.meta_lic
new file mode 100644
index 0000000..295bcdb
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/container.zip.meta_lic
@@ -0,0 +1,32 @@
+package_name: "Android"
+projects: "container/zip"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: true
+built: "out/target/product/fictional/obj/ETC/container_intermediates/container.zip"
+installed: "out/target/product/fictional/data/container.zip"
+install_map {
+ from_path: "out/target/product/fictional/system/lib/"
+ container_path: ""
+}
+install_map {
+ from_path: "out/target/product/fictional/system/bin/"
+ container_path: ""
+}
+sources: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+deps: {
+ file: "testdata/regressgpl1/bin/bin1.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl1/bin/bin2.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl1/bin/bin3.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl1/lib/libapache.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/lib/libapache.so.meta_lic
new file mode 100644
index 0000000..9184501
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/lib/libapache.so.meta_lic
@@ -0,0 +1,14 @@
+package_name: "Android"
+projects: "lib/apache"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libapache.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libapache.a"
+installed: "out/target/product/fictional/system/lib/libapache.so"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl1/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl1/lib/libc++.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/lib/libc++.so.meta_lic
new file mode 100644
index 0000000..b789377
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/lib/libc++.so.meta_lic
@@ -0,0 +1,8 @@
+package_name: "Device"
+projects: "lib/c++"
+license_kinds: "SPDX-license-identifier-BSD"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libc++.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libc++.a"
+installed: "out/target/product/fictional/system/lib/libc++.so"
diff --git a/tools/compliance/cmd/testdata/regressgpl1/lib/libgpl.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl1/lib/libgpl.so.meta_lic
new file mode 100644
index 0000000..a3afa2b
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl1/lib/libgpl.so.meta_lic
@@ -0,0 +1,12 @@
+package_name: "External"
+projects: "lib/gpl"
+license_kinds: "SPDX-license-identifier-GPL-2.0"
+license_conditions: "restricted"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libgpl.so"
+installed: "out/target/product/fictional/system/lib/libgpl.so"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl1/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/README.md b/tools/compliance/cmd/testdata/regressgpl2/README.md
new file mode 100644
index 0000000..9da0f4d
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/README.md
@@ -0,0 +1,35 @@
+## Libraries shipped inside container with restricted license
+
+### Testdata build graph structure:
+
+A restricted licensed library sandwiched between a notice library and a notice
+binary. The source-code for the libraries needs to be shared when shipped as
+part of the container with the binaries.
+
+```dot
+strict digraph {
+ rankdir=LR;
+ bin1 [label="bin/bin1.meta_lic\nnotice"];
+ bin2 [label="bin/bin2.meta_lic\nnotice"];
+ bin3 [label="bin/bin3.meta_lic\nnotice"];
+ container [label="container.zip.meta_lic\nnotice"];
+ libapache [label="lib/libapache.so.meta_lic\nnotice"];
+ libcxx [label="lib/libc++.so.meta_lic\nnotice"];
+ libgpl [label="lib/libgpl.so.meta_lic\nrestricted"];
+ container -> bin1[label="static"];
+ container -> bin2 [label="static"];
+ container -> bin3 [label="static"];
+ container -> libapache [label="static"];
+ container -> libcxx [label="static"];
+ container -> libgpl [label="static"];
+ bin1 -> libcxx [label="dynamic"];
+ bin2 -> libapache [label="dynamic"];
+ bin2 -> libcxx [label="dynamic"];
+ bin3 -> libapache [label="dynamic"];
+ bin3 -> libcxx [label="dynamic"];
+ bin3 -> libgpl [label="dynamic"];
+ libapache -> libcxx [label="dynamic"];
+ libgpl -> libcxx [label="dynamic"];
+ {rank=same; container}
+}
+```
diff --git a/tools/compliance/cmd/testdata/regressgpl2/bin/bin1.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/bin/bin1.meta_lic
new file mode 100644
index 0000000..839fd9c
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/bin/bin1.meta_lic
@@ -0,0 +1,14 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/onelibrary"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin1"
+installed: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/bin/bin2.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/bin/bin2.meta_lic
new file mode 100644
index 0000000..96baaae
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/bin/bin2.meta_lic
@@ -0,0 +1,19 @@
+package_name: "Android"
+module_classes: "EXECUTABLES"
+projects: "bin/twolibraries"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin2"
+installed: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libapache.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/bin/bin3.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/bin/bin3.meta_lic
new file mode 100644
index 0000000..3cd8602
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/bin/bin3.meta_lic
@@ -0,0 +1,23 @@
+package_name: "Compiler"
+module_classes: "EXECUTABLES"
+projects: "bin/threelibraries"
+license_kinds: "SPDX-license-identifier-NCSA"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/EXECUTABLES/bin_intermediates/bin3"
+installed: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+sources: "out/target/product/fictional/system/lib/libgpl.so"
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libapache.so.meta_lic"
+ annotations: "dynamic"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libgpl.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/container.zip.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/container.zip.meta_lic
new file mode 100644
index 0000000..71b68cd
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/container.zip.meta_lic
@@ -0,0 +1,44 @@
+package_name: "Android"
+projects: "container/zip"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: true
+built: "out/target/product/fictional/obj/ETC/container_intermediates/container.zip"
+installed: "out/target/product/fictional/data/container.zip"
+install_map {
+ from_path: "out/target/product/fictional/system/lib/"
+ container_path: ""
+}
+install_map {
+ from_path: "out/target/product/fictional/system/bin/"
+ container_path: ""
+}
+sources: "out/target/product/fictional/system/bin/bin1"
+sources: "out/target/product/fictional/system/bin/bin2"
+sources: "out/target/product/fictional/system/bin/bin3"
+sources: "out/target/product/fictional/system/lib/libapache.so"
+deps: {
+ file: "testdata/regressgpl2/bin/bin1.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl2/bin/bin2.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl2/bin/bin3.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libapache.so.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "static"
+}
+deps: {
+ file: "testdata/regressgpl2/lib/libgpl.so.meta_lic"
+ annotations: "static"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/lib/libapache.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/lib/libapache.so.meta_lic
new file mode 100644
index 0000000..ae47340
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/lib/libapache.so.meta_lic
@@ -0,0 +1,14 @@
+package_name: "Android"
+projects: "lib/apache"
+license_kinds: "SPDX-license-identifier-Apache-2.0"
+license_conditions: "notice"
+license_texts: "build/soong/licenses/LICENSE"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libapache.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libapache.a"
+installed: "out/target/product/fictional/system/lib/libapache.so"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/cmd/testdata/regressgpl2/lib/libc++.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/lib/libc++.so.meta_lic
new file mode 100644
index 0000000..b789377
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/lib/libc++.so.meta_lic
@@ -0,0 +1,8 @@
+package_name: "Device"
+projects: "lib/c++"
+license_kinds: "SPDX-license-identifier-BSD"
+license_conditions: "notice"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libc++.so"
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libc++.a"
+installed: "out/target/product/fictional/system/lib/libc++.so"
diff --git a/tools/compliance/cmd/testdata/regressgpl2/lib/libgpl.so.meta_lic b/tools/compliance/cmd/testdata/regressgpl2/lib/libgpl.so.meta_lic
new file mode 100644
index 0000000..4e78697
--- /dev/null
+++ b/tools/compliance/cmd/testdata/regressgpl2/lib/libgpl.so.meta_lic
@@ -0,0 +1,12 @@
+package_name: "External"
+projects: "lib/gpl"
+license_kinds: "SPDX-license-identifier-GPL-2.0"
+license_conditions: "restricted"
+is_container: false
+built: "out/target/product/fictional/obj/SHARED_LIBRARIES/lib_intermediates/libgpl.so"
+installed: "out/target/product/fictional/system/lib/libgpl.so"
+sources: "out/target/product/fictional/system/lib/libc++.so"
+deps: {
+ file: "testdata/regressgpl2/lib/libc++.so.meta_lic"
+ annotations: "dynamic"
+}
diff --git a/tools/compliance/condition.go b/tools/compliance/condition.go
index b5c8cec..26b91ca 100644
--- a/tools/compliance/condition.go
+++ b/tools/compliance/condition.go
@@ -16,150 +16,87 @@
import (
"fmt"
- "strings"
)
-// LicenseCondition describes an individual license condition or requirement
-// originating at a specific target node. (immutable)
-//
-// e.g. A module licensed under GPL terms would originate a `restricted` condition.
-type LicenseCondition struct {
- name string
- origin *TargetNode
-}
+// LicenseCondition identifies a recognized license condition by setting the
+// corresponding bit.
+type LicenseCondition uint16
-// Name returns the name of the condition. e.g. "restricted" or "notice"
+// LicenseConditionMask is a bitmask for the recognized license conditions.
+const LicenseConditionMask = LicenseCondition(0x3ff)
+
+const (
+ // UnencumberedCondition identifies public domain or public domain-
+ // like license that disclaims copyright.
+ UnencumberedCondition = LicenseCondition(0x0001)
+ // PermissiveCondition identifies a license without notice or other
+ // significant requirements.
+ PermissiveCondition = LicenseCondition(0x0002)
+ // NoticeCondition identifies a typical open-source license with only
+ // notice or attribution requirements.
+ NoticeCondition = LicenseCondition(0x0004)
+ // ReciprocalCondition identifies a license with requirement to share
+ // the module's source only.
+ ReciprocalCondition = LicenseCondition(0x0008)
+ // RestrictedCondition identifies a license with requirement to share
+ // all source code linked to the module's source.
+ RestrictedCondition = LicenseCondition(0x0010)
+ // RestrictedClasspathExceptionCondition identifies RestrictedCondition
+ // waived for dynamic linking from independent modules.
+ RestrictedClasspathExceptionCondition = LicenseCondition(0x0020)
+ // WeaklyRestrictedCondition identifies a RestrictedCondition waived
+ // for dynamic linking.
+ WeaklyRestrictedCondition = LicenseCondition(0x0040)
+ // ProprietaryCondition identifies a license with source privacy
+ // requirements.
+ ProprietaryCondition = LicenseCondition(0x0080)
+ // ByExceptionOnly identifies a license where policy requires product
+ // counsel review prior to use.
+ ByExceptionOnlyCondition = LicenseCondition(0x0100)
+ // NotAllowedCondition identifies a license with onerous conditions
+ // where policy prohibits use.
+ NotAllowedCondition = LicenseCondition(0x0200)
+)
+
+var (
+ // RecognizedConditionNames maps condition strings to LicenseCondition.
+ RecognizedConditionNames = map[string]LicenseCondition{
+ "unencumbered": UnencumberedCondition,
+ "permissive": PermissiveCondition,
+ "notice": NoticeCondition,
+ "reciprocal": ReciprocalCondition,
+ "restricted": RestrictedCondition,
+ "restricted_with_classpath_exception": RestrictedClasspathExceptionCondition,
+ "restricted_allows_dynamic_linking": WeaklyRestrictedCondition,
+ "proprietary": ProprietaryCondition,
+ "by_exception_only": ByExceptionOnlyCondition,
+ "not_allowed": NotAllowedCondition,
+ }
+)
+
+// Name returns the condition string corresponding to the LicenseCondition.
func (lc LicenseCondition) Name() string {
- return lc.name
-}
-
-// Origin identifies the TargetNode where the condition originates.
-func (lc LicenseCondition) Origin() *TargetNode {
- return lc.origin
-}
-
-// asString returns a string representation of a license condition:
-// origin+separator+condition.
-func (lc LicenseCondition) asString(separator string) string {
- return lc.origin.name + separator + lc.name
-}
-
-// ConditionList implements introspection methods to arrays of LicenseCondition.
-type ConditionList []LicenseCondition
-
-
-// ConditionList orders arrays of LicenseCondition by Origin and Name.
-
-// Len returns the length of the list.
-func (l ConditionList) Len() int { return len(l) }
-
-// Swap rearranges 2 elements in the list so each occupies the other's former position.
-func (l ConditionList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-
-// Less returns true when the `i`th element is lexicographically less than tht `j`th element.
-func (l ConditionList) Less(i, j int) bool {
- if l[i].origin.name == l[j].origin.name {
- return l[i].name < l[j].name
+ switch lc {
+ case UnencumberedCondition:
+ return "unencumbered"
+ case PermissiveCondition:
+ return "permissive"
+ case NoticeCondition:
+ return "notice"
+ case ReciprocalCondition:
+ return "reciprocal"
+ case RestrictedCondition:
+ return "restricted"
+ case RestrictedClasspathExceptionCondition:
+ return "restricted_with_classpath_exception"
+ case WeaklyRestrictedCondition:
+ return "restricted_allows_dynamic_linking"
+ case ProprietaryCondition:
+ return "proprietary"
+ case ByExceptionOnlyCondition:
+ return "by_exception_only"
+ case NotAllowedCondition:
+ return "not_allowed"
}
- return l[i].origin.name < l[j].origin.name
-}
-
-// String returns a string representation of the set.
-func (cl ConditionList) String() string {
- var sb strings.Builder
- fmt.Fprintf(&sb, "[")
- sep := ""
- for _, lc := range cl {
- fmt.Fprintf(&sb, "%s%s:%s", sep, lc.origin.name, lc.name)
- sep = ", "
- }
- fmt.Fprintf(&sb, "]")
- return sb.String()
-}
-
-// Names returns the list of the conditions' names.
-func (cl ConditionList) Names() []string {
- result := make([]string, 0, len(cl))
- for _, lc := range cl {
- result = append(result, lc.name)
- }
- return result
-}
-
-// HasByName returns true if the list contains any condition matching `name`.
-func (cl ConditionList) HasByName(name ConditionNames) bool {
- for _, lc := range cl {
- if name.Contains(lc.name) {
- return true
- }
- }
- return false
-}
-
-// ByName returns the sublist of conditions that match `name`.
-func (cl ConditionList) ByName(name ConditionNames) ConditionList {
- result := make(ConditionList, 0, cl.CountByName(name))
- for _, lc := range cl {
- if name.Contains(lc.name) {
- result = append(result, lc)
- }
- }
- return result
-}
-
-// CountByName returns the size of the sublist of conditions that match `name`.
-func (cl ConditionList) CountByName(name ConditionNames) int {
- size := 0
- for _, lc := range cl {
- if name.Contains(lc.name) {
- size++
- }
- }
- return size
-}
-
-// HasByOrigin returns true if the list contains any condition originating at `origin`.
-func (cl ConditionList) HasByOrigin(origin *TargetNode) bool {
- for _, lc := range cl {
- if lc.origin.name == origin.name {
- return true
- }
- }
- return false
-}
-
-// ByOrigin returns the sublist of conditions that originate at `origin`.
-func (cl ConditionList) ByOrigin(origin *TargetNode) ConditionList {
- result := make(ConditionList, 0, cl.CountByOrigin(origin))
- for _, lc := range cl {
- if lc.origin.name == origin.name {
- result = append(result, lc)
- }
- }
- return result
-}
-
-// CountByOrigin returns the size of the sublist of conditions that originate at `origin`.
-func (cl ConditionList) CountByOrigin(origin *TargetNode) int {
- size := 0
- for _, lc := range cl {
- if lc.origin.name == origin.name {
- size++
- }
- }
- return size
-}
-
-// ConditionNames implements the Contains predicate for slices of condition
-// name strings.
-type ConditionNames []string
-
-// Contains returns true if the name matches one of the ConditionNames.
-func (cn ConditionNames) Contains(name string) bool {
- for _, cname := range cn {
- if cname == name {
- return true
- }
- }
- return false
+ panic(fmt.Errorf("unrecognized license condition: %04x", lc))
}
diff --git a/tools/compliance/condition_test.go b/tools/compliance/condition_test.go
index 0507469..778ce4a 100644
--- a/tools/compliance/condition_test.go
+++ b/tools/compliance/condition_test.go
@@ -15,204 +15,53 @@
package compliance
import (
- "sort"
- "strings"
"testing"
)
-func TestConditionNames(t *testing.T) {
- impliesShare := ConditionNames([]string{"restricted", "reciprocal"})
+func TestConditionSetHas(t *testing.T) {
+ impliesShare := ImpliesShared
- if impliesShare.Contains("notice") {
- t.Errorf("impliesShare.Contains(\"notice\") got true, want false")
+ t.Logf("testing with imliesShare=%04x", impliesShare)
+
+ if impliesShare.HasAny(NoticeCondition) {
+ t.Errorf("impliesShare.HasAny(\"notice\"=%04x) got true, want false", NoticeCondition)
}
- if !impliesShare.Contains("restricted") {
- t.Errorf("impliesShare.Contains(\"restricted\") got false, want true")
+ if !impliesShare.HasAny(RestrictedCondition) {
+ t.Errorf("impliesShare.HasAny(\"restricted\"=%04x) got false, want true", RestrictedCondition)
}
- if !impliesShare.Contains("reciprocal") {
- t.Errorf("impliesShare.Contains(\"reciprocal\") got false, want true")
+ if !impliesShare.HasAny(ReciprocalCondition) {
+ t.Errorf("impliesShare.HasAny(\"reciprocal\"=%04x) got false, want true", ReciprocalCondition)
}
- if impliesShare.Contains("") {
- t.Errorf("impliesShare.Contains(\"\") got true, want false")
+ if impliesShare.HasAny(LicenseCondition(0x0000)) {
+ t.Errorf("impliesShare.HasAny(nil=%04x) got true, want false", LicenseCondition(0x0000))
}
}
-func TestConditionList(t *testing.T) {
- tests := []struct {
- name string
- conditions map[string][]string
- byName map[string][]string
- byOrigin map[string][]string
- }{
- {
- name: "noticeonly",
- conditions: map[string][]string{
- "notice": []string{"bin1", "lib1"},
- },
- byName: map[string][]string{
- "notice": []string{"bin1", "lib1"},
- "restricted": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "lib1": []string{"notice"},
- "bin2": []string{},
- "lib2": []string{},
- },
- },
- {
- name: "empty",
- conditions: map[string][]string{},
- byName: map[string][]string{
- "notice": []string{},
- "restricted": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{},
- "lib1": []string{},
- "bin2": []string{},
- "lib2": []string{},
- },
- },
- {
- name: "everything",
- conditions: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "other": []string{},
- },
- },
- {
- name: "allbutoneeach",
- conditions: map[string][]string{
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted"},
- "other": []string{},
- },
- },
- {
- name: "oneeach",
- conditions: map[string][]string{
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "bin2": []string{"reciprocal"},
- "lib1": []string{"restricted"},
- "lib2": []string{"by_exception_only"},
- "other": []string{},
- },
- },
+func TestConditionName(t *testing.T) {
+ for expected, condition := range RecognizedConditionNames {
+ actual := condition.Name()
+ if expected != actual {
+ t.Errorf("unexpected name for condition %04x: got %s, want %s", condition, actual, expected)
+ }
}
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- lg := newLicenseGraph()
- cl := toConditionList(lg, tt.conditions)
- for names, expected := range tt.byName {
- name := ConditionNames(strings.Split(names, ":"))
- if cl.HasByName(name) {
- if len(expected) == 0 {
- t.Errorf("unexpected ConditionList.HasByName(%q): got true, want false", name)
- }
- } else {
- if len(expected) != 0 {
- t.Errorf("unexpected ConditionList.HasByName(%q): got false, want true", name)
- }
- }
- if len(expected) != cl.CountByName(name) {
- t.Errorf("unexpected ConditionList.CountByName(%q): got %d, want %d", name, cl.CountByName(name), len(expected))
- }
- byName := cl.ByName(name)
- if len(expected) != len(byName) {
- t.Errorf("unexpected ConditionList.ByName(%q): got %v, want %v", name, byName, expected)
- } else {
- sort.Strings(expected)
- actual := make([]string, 0, len(byName))
- for _, lc := range byName {
- actual = append(actual, lc.Origin().Name())
- }
- sort.Strings(actual)
- for i := 0; i < len(expected); i++ {
- if expected[i] != actual[i] {
- t.Errorf("unexpected ConditionList.ByName(%q) index %d in %v: got %s, want %s", name, i, actual, actual[i], expected[i])
- }
- }
- }
+}
+
+func TestConditionName_InvalidCondition(t *testing.T) {
+ panicked := false
+ var lc LicenseCondition
+ func() {
+ defer func() {
+ if err := recover(); err != nil {
+ panicked = true
}
- for origin, expected := range tt.byOrigin {
- onode := newTestNode(lg, origin)
- if cl.HasByOrigin(onode) {
- if len(expected) == 0 {
- t.Errorf("unexpected ConditionList.HasByOrigin(%q): got true, want false", origin)
- }
- } else {
- if len(expected) != 0 {
- t.Errorf("unexpected ConditionList.HasByOrigin(%q): got false, want true", origin)
- }
- }
- if len(expected) != cl.CountByOrigin(onode) {
- t.Errorf("unexpected ConditionList.CountByOrigin(%q): got %d, want %d", origin, cl.CountByOrigin(onode), len(expected))
- }
- byOrigin := cl.ByOrigin(onode)
- if len(expected) != len(byOrigin) {
- t.Errorf("unexpected ConditionList.ByOrigin(%q): got %v, want %v", origin, byOrigin, expected)
- } else {
- sort.Strings(expected)
- actual := make([]string, 0, len(byOrigin))
- for _, lc := range byOrigin {
- actual = append(actual, lc.Name())
- }
- sort.Strings(actual)
- for i := 0; i < len(expected); i++ {
- if expected[i] != actual[i] {
- t.Errorf("unexpected ConditionList.ByOrigin(%q) index %d in %v: got %s, want %s", origin, i, actual, actual[i], expected[i])
- }
- }
- }
- }
- })
+ }()
+ name := lc.Name()
+ t.Errorf("invalid condition unexpected name: got %s, wanted panic", name)
+ }()
+ if !panicked {
+ t.Errorf("no expected panic for %04x.Name(): got no panic, wanted panic", lc)
}
}
diff --git a/tools/compliance/conditionset.go b/tools/compliance/conditionset.go
index 1ad15ca..7a12ddc 100644
--- a/tools/compliance/conditionset.go
+++ b/tools/compliance/conditionset.go
@@ -16,263 +16,174 @@
import (
"fmt"
+ "strings"
)
-// NewLicenseConditionSet creates a new instance or variable of *LicenseConditionSet.
-func NewLicenseConditionSet(conditions ...LicenseCondition) *LicenseConditionSet {
- cs := newLicenseConditionSet()
- cs.Add(conditions...)
+// LicenseConditionSet identifies sets of license conditions.
+type LicenseConditionSet LicenseCondition
+
+// AllLicenseConditions is the set of all recognized license conditions.
+const AllLicenseConditions = LicenseConditionSet(LicenseConditionMask)
+
+// NewLicenseConditionSet returns a set containing exactly the elements of
+// `conditions`.
+func NewLicenseConditionSet(conditions ...LicenseCondition) LicenseConditionSet {
+ cs := LicenseConditionSet(0x00)
+ for _, lc := range conditions {
+ cs |= LicenseConditionSet(lc)
+ }
return cs
}
-// LicenseConditionSet describes a mutable set of immutable license conditions.
-type LicenseConditionSet struct {
- // conditions describes the set of license conditions i.e. (condition name, origin target) pairs
- // by mapping condition name -> origin target -> true.
- conditions map[string]map[*TargetNode]bool
-}
-
-// Add makes all `conditions` members of the set if they were not previously.
-func (cs *LicenseConditionSet) Add(conditions ...LicenseCondition) {
- if len(conditions) == 0 {
- return
- }
+// Plus returns a new set containing all of the elements of `cs` and all of the
+// `conditions`.
+func (cs LicenseConditionSet) Plus(conditions ...LicenseCondition) LicenseConditionSet {
+ result := cs
for _, lc := range conditions {
- if _, ok := cs.conditions[lc.name]; !ok {
- cs.conditions[lc.name] = make(map[*TargetNode]bool)
- }
- cs.conditions[lc.name][lc.origin] = true
+ result |= LicenseConditionSet(lc)
}
+ return result
}
-// AddSet makes all elements of `conditions` members of the set if they were not previously.
-func (cs *LicenseConditionSet) AddSet(other *LicenseConditionSet) {
- if len(other.conditions) == 0 {
- return
+// Union returns a new set containing all of the elements of `cs` and all of the
+// elements of the `other` sets.
+func (cs LicenseConditionSet) Union(other ...LicenseConditionSet) LicenseConditionSet {
+ result := cs
+ for _, ls := range other {
+ result |= ls
}
- for name, origins := range other.conditions {
- if len(origins) == 0 {
- continue
- }
- if _, ok := cs.conditions[name]; !ok {
- cs.conditions[name] = make(map[*TargetNode]bool)
- }
- for origin := range origins {
- cs.conditions[name][origin] = other.conditions[name][origin]
- }
- }
+ return result
}
-// ByName returns a list of the conditions in the set matching `names`.
-func (cs *LicenseConditionSet) ByName(names ...ConditionNames) *LicenseConditionSet {
- other := newLicenseConditionSet()
- for _, cn := range names {
- for _, name := range cn {
- if origins, ok := cs.conditions[name]; ok {
- other.conditions[name] = make(map[*TargetNode]bool)
- for origin := range origins {
- other.conditions[name][origin] = true
- }
- }
- }
+// MatchingAny returns the subset of `cs` equal to any of the `conditions`.
+func (cs LicenseConditionSet) MatchingAny(conditions ...LicenseCondition) LicenseConditionSet {
+ result := LicenseConditionSet(0x00)
+ for _, lc := range conditions {
+ result |= cs & LicenseConditionSet(lc)
}
- return other
+ return result
}
-// HasAnyByName returns true if the set contains any conditions matching `names` originating at any target.
-func (cs *LicenseConditionSet) HasAnyByName(names ...ConditionNames) bool {
- for _, cn := range names {
- for _, name := range cn {
- if origins, ok := cs.conditions[name]; ok {
- if len(origins) > 0 {
- return true
- }
- }
- }
+// MatchingAnySet returns the subset of `cs` that are members of any of the
+// `other` sets.
+func (cs LicenseConditionSet) MatchingAnySet(other ...LicenseConditionSet) LicenseConditionSet {
+ result := LicenseConditionSet(0x00)
+ for _, ls := range other {
+ result |= cs & ls
}
- return false
+ return result
}
-// CountByName returns the number of conditions matching `names` originating at any target.
-func (cs *LicenseConditionSet) CountByName(names ...ConditionNames) int {
- size := 0
- for _, cn := range names {
- for _, name := range cn {
- if origins, ok := cs.conditions[name]; ok {
- size += len(origins)
- }
- }
- }
- return size
-}
-
-// ByOrigin returns all of the conditions that originate at `origin` regardless of name.
-func (cs *LicenseConditionSet) ByOrigin(origin *TargetNode) *LicenseConditionSet {
- other := newLicenseConditionSet()
- for name, origins := range cs.conditions {
- if _, ok := origins[origin]; ok {
- other.conditions[name] = make(map[*TargetNode]bool)
- other.conditions[name][origin] = true
- }
- }
- return other
-}
-
-// HasAnyByOrigin returns true if the set contains any conditions originating at `origin` regardless of condition name.
-func (cs *LicenseConditionSet) HasAnyByOrigin(origin *TargetNode) bool {
- for _, origins := range cs.conditions {
- if _, ok := origins[origin]; ok {
+// HasAny returns true when `cs` contains at least one of the `conditions`.
+func (cs LicenseConditionSet) HasAny(conditions ...LicenseCondition) bool {
+ for _, lc := range conditions {
+ if 0x0000 != (cs & LicenseConditionSet(lc)) {
return true
}
}
return false
}
-// CountByOrigin returns the number of conditions originating at `origin` regardless of condition name.
-func (cs *LicenseConditionSet) CountByOrigin(origin *TargetNode) int {
- size := 0
- for _, origins := range cs.conditions {
- if _, ok := origins[origin]; ok {
- size++
- }
- }
- return size
-}
-
-// AsList returns a list of all the conditions in the set.
-func (cs *LicenseConditionSet) AsList() ConditionList {
- result := make(ConditionList, 0, cs.Count())
- for name, origins := range cs.conditions {
- for origin := range origins {
- result = append(result, LicenseCondition{name, origin})
- }
- }
- return result
-}
-
-// Names returns a list of the names of the conditions in the set.
-func (cs *LicenseConditionSet) Names() []string {
- result := make([]string, 0, len(cs.conditions))
- for name := range cs.conditions {
- result = append(result, name)
- }
- return result
-}
-
-// Count returns the number of conditions in the set.
-func (cs *LicenseConditionSet) Count() int {
- size := 0
- for _, origins := range cs.conditions {
- size += len(origins)
- }
- return size
-}
-
-// Copy creates a new LicenseCondition variable with the same value.
-func (cs *LicenseConditionSet) Copy() *LicenseConditionSet {
- other := newLicenseConditionSet()
- for name := range cs.conditions {
- other.conditions[name] = make(map[*TargetNode]bool)
- for origin := range cs.conditions[name] {
- other.conditions[name][origin] = cs.conditions[name][origin]
- }
- }
- return other
-}
-
-// HasCondition returns true if the set contains any condition matching both `names` and `origin`.
-func (cs *LicenseConditionSet) HasCondition(names ConditionNames, origin *TargetNode) bool {
- for _, name := range names {
- if origins, ok := cs.conditions[name]; ok {
- _, isPresent := origins[origin]
- if isPresent {
- return true
- }
+// MatchesAnySet returns true when `cs` has a non-empty intersection with at
+// least one of the `other` condition sets.
+func (cs LicenseConditionSet) MatchesAnySet(other ...LicenseConditionSet) bool {
+ for _, ls := range other {
+ if 0x0000 != (cs & ls) {
+ return true
}
}
return false
}
-// IsEmpty returns true when the set of conditions contains zero elements.
-func (cs *LicenseConditionSet) IsEmpty() bool {
- for _, origins := range cs.conditions {
- if 0 < len(origins) {
+// HasAll returns true when `cs` contains every one of the `conditions`.
+func (cs LicenseConditionSet) HasAll(conditions ...LicenseCondition) bool {
+ for _, lc := range conditions {
+ if 0x0000 == (cs & LicenseConditionSet(lc)) {
return false
}
}
return true
}
-// RemoveAllByName changes the set to delete all conditions matching `names`.
-func (cs *LicenseConditionSet) RemoveAllByName(names ...ConditionNames) {
- for _, cn := range names {
- for _, name := range cn {
- delete(cs.conditions, name)
+// MatchesEverySet returns true when `cs` has a non-empty intersection with
+// each of the `other` condition sets.
+func (cs LicenseConditionSet) MatchesEverySet(other ...LicenseConditionSet) bool {
+ for _, ls := range other {
+ if 0x0000 == (cs & ls) {
+ return false
}
}
+ return true
}
-// Remove changes the set to delete `conditions`.
-func (cs *LicenseConditionSet) Remove(conditions ...LicenseCondition) {
+// Intersection returns the subset of `cs` that are members of every `other`
+// set.
+func (cs LicenseConditionSet) Intersection(other ...LicenseConditionSet) LicenseConditionSet {
+ result := cs
+ for _, ls := range other {
+ result &= ls
+ }
+ return result
+}
+
+// Minus returns the subset of `cs` that are not equaal to any `conditions`.
+func (cs LicenseConditionSet) Minus(conditions ...LicenseCondition) LicenseConditionSet {
+ result := cs
for _, lc := range conditions {
- if _, isPresent := cs.conditions[lc.name]; !isPresent {
- panic(fmt.Errorf("attempt to remove non-existent condition: %q", lc.asString(":")))
- }
- if _, isPresent := cs.conditions[lc.name][lc.origin]; !isPresent {
- panic(fmt.Errorf("attempt to remove non-existent origin: %q", lc.asString(":")))
- }
- delete(cs.conditions[lc.name], lc.origin)
+ result &^= LicenseConditionSet(lc)
}
+ return result
}
-// removeSet changes the set to delete all conditions also present in `other`.
-func (cs *LicenseConditionSet) RemoveSet(other *LicenseConditionSet) {
- for name, origins := range other.conditions {
- if _, isPresent := cs.conditions[name]; !isPresent {
- continue
- }
- for origin := range origins {
- delete(cs.conditions[name], origin)
+// Difference returns the subset of `cs` that are not members of any `other`
+// set.
+func (cs LicenseConditionSet) Difference(other ...LicenseConditionSet) LicenseConditionSet {
+ result := cs
+ for _, ls := range other {
+ result &^= ls
+ }
+ return result
+}
+
+// Len returns the number of license conditions in the set.
+func (cs LicenseConditionSet) Len() int {
+ size := 0
+ for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 {
+ if 0x00 != (cs & lc) {
+ size++
}
}
+ return size
}
-// compliance-only LicenseConditionSet methods
-
-// newLicenseConditionSet constructs a set of `conditions`.
-func newLicenseConditionSet() *LicenseConditionSet {
- return &LicenseConditionSet{make(map[string]map[*TargetNode]bool)}
-}
-
-// add changes the set to include each element of `conditions` originating at `origin`.
-func (cs *LicenseConditionSet) add(origin *TargetNode, conditions ...string) {
- for _, name := range conditions {
- if _, ok := cs.conditions[name]; !ok {
- cs.conditions[name] = make(map[*TargetNode]bool)
- }
- cs.conditions[name][origin] = true
- }
-}
-
-// asStringList returns the conditions in the set as `separator`-separated (origin, condition-name) pair strings.
-func (cs *LicenseConditionSet) asStringList(separator string) []string {
- result := make([]string, 0, cs.Count())
- for name, origins := range cs.conditions {
- for origin := range origins {
- result = append(result, origin.name+separator+name)
+// AsList returns an array of the license conditions in the set.
+func (cs LicenseConditionSet) AsList() []LicenseCondition {
+ result := make([]LicenseCondition, 0, cs.Len())
+ for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 {
+ if 0x00 != (cs & lc) {
+ result = append(result, LicenseCondition(lc))
}
}
return result
}
-// conditionNamesArray implements a `contains` predicate for arrays of ConditionNames
-type conditionNamesArray []ConditionNames
-
-func (cn conditionNamesArray) contains(name string) bool {
- for _, names := range cn {
- if names.Contains(name) {
- return true
+// Names returns an array of the names of the license conditions in the set.
+func (cs LicenseConditionSet) Names() []string {
+ result := make([]string, 0, cs.Len())
+ for lc := LicenseConditionSet(0x01); 0x00 != (AllLicenseConditions & lc); lc <<= 1 {
+ if 0x00 != (cs & lc) {
+ result = append(result, LicenseCondition(lc).Name())
}
}
- return false
+ return result
+}
+
+// IsEmpty returns true when the set contains no license conditions.
+func (cs LicenseConditionSet) IsEmpty() bool {
+ return 0x00 == (cs & AllLicenseConditions)
+}
+
+// String returns a human-readable string representation of the set.
+func (cs LicenseConditionSet) String() string {
+ return fmt.Sprintf("{%s}", strings.Join(cs.Names(), "|"))
}
diff --git a/tools/compliance/conditionset_test.go b/tools/compliance/conditionset_test.go
index eac0680..c7306e7 100644
--- a/tools/compliance/conditionset_test.go
+++ b/tools/compliance/conditionset_test.go
@@ -15,576 +15,643 @@
package compliance
import (
- "sort"
"strings"
"testing"
)
-type byName map[string][]string
-
-func (bn byName) checkPublic(ls *LicenseConditionSet, t *testing.T) {
- for names, expected := range bn {
- name := ConditionNames(strings.Split(names, ":"))
- if ls.HasAnyByName(name) {
- if len(expected) == 0 {
- t.Errorf("unexpected LicenseConditionSet.HasAnyByName(%q): got true, want false", name)
- }
- } else {
- if len(expected) != 0 {
- t.Errorf("unexpected LicenseConditionSet.HasAnyByName(%q): got false, want true", name)
- }
- }
- if len(expected) != ls.CountByName(name) {
- t.Errorf("unexpected LicenseConditionSet.CountByName(%q): got %d, want %d", name, ls.CountByName(name), len(expected))
- }
- byName := ls.ByName(name).AsList()
- if len(expected) != len(byName) {
- t.Errorf("unexpected LicenseConditionSet.ByName(%q): got %v, want %v", name, byName, expected)
- } else {
- sort.Strings(expected)
- actual := make([]string, 0, len(byName))
- for _, lc := range byName {
- actual = append(actual, lc.Origin().Name())
- }
- sort.Strings(actual)
- for i := 0; i < len(expected); i++ {
- if expected[i] != actual[i] {
- t.Errorf("unexpected LicenseConditionSet.ByName(%q) index %d in %v: got %s, want %s", name, i, actual, actual[i], expected[i])
- }
- }
- }
- }
-}
-
-type byOrigin map[string][]string
-
-func (bo byOrigin) checkPublic(lg *LicenseGraph, ls *LicenseConditionSet, t *testing.T) {
- expectedCount := 0
- for origin, expected := range bo {
- expectedCount += len(expected)
- onode := newTestNode(lg, origin)
- if ls.HasAnyByOrigin(onode) {
- if len(expected) == 0 {
- t.Errorf("unexpected LicenseConditionSet.HasAnyByOrigin(%q): got true, want false", origin)
- }
- } else {
- if len(expected) != 0 {
- t.Errorf("unexpected LicenseConditionSet.HasAnyByOrigin(%q): got false, want true", origin)
- }
- }
- if len(expected) != ls.CountByOrigin(onode) {
- t.Errorf("unexpected LicenseConditionSet.CountByOrigin(%q): got %d, want %d", origin, ls.CountByOrigin(onode), len(expected))
- }
- byOrigin := ls.ByOrigin(onode).AsList()
- if len(expected) != len(byOrigin) {
- t.Errorf("unexpected LicenseConditionSet.ByOrigin(%q): got %v, want %v", origin, byOrigin, expected)
- } else {
- sort.Strings(expected)
- actual := make([]string, 0, len(byOrigin))
- for _, lc := range byOrigin {
- actual = append(actual, lc.Name())
- }
- sort.Strings(actual)
- for i := 0; i < len(expected); i++ {
- if expected[i] != actual[i] {
- t.Errorf("unexpected LicenseConditionSet.ByOrigin(%q) index %d in %v: got %s, want %s", origin, i, actual, actual[i], expected[i])
- }
- }
- }
- }
- if expectedCount != ls.Count() {
- t.Errorf("unexpected LicenseConditionSet.Count(): got %d, want %d", ls.Count(), expectedCount)
- }
- if ls.IsEmpty() {
- if expectedCount != 0 {
- t.Errorf("unexpected LicenseConditionSet.IsEmpty(): got true, want false")
- }
- } else {
- if expectedCount == 0 {
- t.Errorf("unexpected LicenseConditionSet.IsEmpty(): got false, want true")
- }
- }
-}
-
func TestConditionSet(t *testing.T) {
tests := []struct {
- name string
- conditions map[string][]string
- add map[string][]string
- byName map[string][]string
- byOrigin map[string][]string
+ name string
+ conditions []string
+ plus *[]string
+ minus *[]string
+ matchingAny map[string][]string
+ expected []string
}{
{
name: "empty",
- conditions: map[string][]string{},
- add: map[string][]string{},
- byName: map[string][]string{
+ conditions: []string{},
+ plus: &[]string{},
+ matchingAny: map[string][]string{
"notice": []string{},
"restricted": []string{},
+ "restricted|reciprocal": []string{},
},
- byOrigin: map[string][]string{
- "bin1": []string{},
- "lib1": []string{},
- "bin2": []string{},
- "lib2": []string{},
+ expected: []string{},
+ },
+ {
+ name: "emptyminusnothing",
+ conditions: []string{},
+ minus: &[]string{},
+ matchingAny: map[string][]string{
+ "notice": []string{},
+ "restricted": []string{},
+ "restricted|reciprocal": []string{},
},
+ expected: []string{},
+ },
+ {
+ name: "emptyminusnotice",
+ conditions: []string{},
+ minus: &[]string{"notice"},
+ matchingAny: map[string][]string{
+ "notice": []string{},
+ "restricted": []string{},
+ "restricted|reciprocal": []string{},
+ },
+ expected: []string{},
},
{
name: "noticeonly",
- conditions: map[string][]string{
- "notice": []string{"bin1", "lib1"},
- },
- byName: map[string][]string{
- "notice": []string{"bin1", "lib1"},
+ conditions: []string{"notice"},
+ matchingAny: map[string][]string{
+ "notice": []string{"notice"},
+ "notice|proprietary": []string{"notice"},
"restricted": []string{},
},
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "lib1": []string{"notice"},
- "bin2": []string{},
- "lib2": []string{},
- },
+ expected: []string{"notice"},
},
{
- name: "noticeonlyadded",
- conditions: map[string][]string{
- "notice": []string{"bin1", "lib1"},
- },
- add: map[string][]string{
- "notice": []string{"bin1", "bin2"},
- },
- byName: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1"},
+ name: "allnoticeonly",
+ conditions: []string{"notice"},
+ plus: &[]string{"notice"},
+ matchingAny: map[string][]string{
+ "notice": []string{"notice"},
+ "notice|proprietary": []string{"notice"},
"restricted": []string{},
},
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "lib1": []string{"notice"},
- "bin2": []string{"notice"},
- "lib2": []string{},
+ expected: []string{"notice"},
+ },
+ {
+ name: "emptyplusnotice",
+ conditions: []string{},
+ plus: &[]string{"notice"},
+ matchingAny: map[string][]string{
+ "notice": []string{"notice"},
+ "notice|proprietary": []string{"notice"},
+ "restricted": []string{},
},
+ expected: []string{"notice"},
},
{
name: "everything",
- conditions: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
+ conditions: []string{"unencumbered", "permissive", "notice", "reciprocal", "restricted", "proprietary"},
+ plus: &[]string{"restricted_with_classpath_exception", "restricted_allows_dynamic_linking", "by_exception_only", "not_allowed"},
+ matchingAny: map[string][]string{
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_with_classpath_exception": []string{"restricted_with_classpath_exception"},
+ "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "notice|proprietary": []string{"notice", "proprietary"},
},
- add: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "other": []string{},
+ expected: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
},
{
- name: "allbutoneeach",
- conditions: map[string][]string{
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
+ name: "everythingplusminusnothing",
+ conditions: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
+ plus: &[]string{},
+ minus: &[]string{},
+ matchingAny: map[string][]string{
+ "unencumbered|permissive|notice": []string{"unencumbered", "permissive", "notice"},
+ "restricted|reciprocal": []string{"reciprocal", "restricted"},
+ "proprietary|by_exception_only": []string{"proprietary", "by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
},
- byOrigin: map[string][]string{
- "bin1": []string{"reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted"},
- "other": []string{},
+ expected: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
},
{
- name: "allbutoneeachadded",
- conditions: map[string][]string{
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
+ name: "allbutone",
+ conditions: []string{"unencumbered", "permissive", "notice", "reciprocal", "restricted", "proprietary"},
+ plus: &[]string{"restricted_allows_dynamic_linking", "by_exception_only", "not_allowed"},
+ matchingAny: map[string][]string{
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_with_classpath_exception": []string{},
+ "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "notice|proprietary": []string{"notice", "proprietary"},
},
- add: map[string][]string{
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted"},
- "other": []string{},
+ expected: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
},
{
- name: "allbutoneeachfilled",
- conditions: map[string][]string{
- "notice": []string{"bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1"},
+ name: "everythingminusone",
+ conditions: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
- add: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1"},
- "reciprocal": []string{"bin1", "bin2", "lib2"},
- "restricted": []string{"bin1", "lib1", "lib2"},
- "by_exception_only": []string{"bin2", "lib1", "lib2"},
+ minus: &[]string{"restricted_allows_dynamic_linking"},
+ matchingAny: map[string][]string{
+ "unencumbered": []string{"unencumbered"},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "reciprocal": []string{"reciprocal"},
+ "restricted": []string{"restricted"},
+ "restricted_with_classpath_exception": []string{"restricted_with_classpath_exception"},
+ "restricted_allows_dynamic_linking": []string{},
+ "proprietary": []string{"proprietary"},
+ "by_exception_only": []string{"by_exception_only"},
+ "not_allowed": []string{"not_allowed"},
+ "restricted|proprietary": []string{"restricted", "proprietary"},
},
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "other": []string{},
+ expected: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
},
{
- name: "oneeach",
- conditions: map[string][]string{
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
+ name: "everythingminuseverything",
+ conditions: []string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
+ minus: &[]string{
+ "unencumbered",
+ "permissive",
+ "notice",
+ "reciprocal",
+ "restricted",
+ "restricted_with_classpath_exception",
+ "restricted_allows_dynamic_linking",
+ "proprietary",
+ "by_exception_only",
+ "not_allowed",
},
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "bin2": []string{"reciprocal"},
- "lib1": []string{"restricted"},
- "lib2": []string{"by_exception_only"},
- "other": []string{},
+ matchingAny: map[string][]string{
+ "unencumbered": []string{},
+ "permissive": []string{},
+ "notice": []string{},
+ "reciprocal": []string{},
+ "restricted": []string{},
+ "restricted_with_classpath_exception": []string{},
+ "restricted_allows_dynamic_linking": []string{},
+ "proprietary": []string{},
+ "by_exception_only": []string{},
+ "not_allowed": []string{},
+ "restricted|proprietary": []string{},
},
+ expected: []string{},
},
{
- name: "oneeachoverlap",
- conditions: map[string][]string{
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
+ name: "restrictedplus",
+ conditions: []string{"restricted", "restricted_with_classpath_exception", "restricted_allows_dynamic_linking"},
+ plus: &[]string{"permissive", "notice", "restricted", "proprietary"},
+ matchingAny: map[string][]string{
+ "unencumbered": []string{},
+ "permissive": []string{"permissive"},
+ "notice": []string{"notice"},
+ "restricted": []string{"restricted"},
+ "restricted_with_classpath_exception": []string{"restricted_with_classpath_exception"},
+ "restricted_allows_dynamic_linking": []string{"restricted_allows_dynamic_linking"},
+ "proprietary": []string{"proprietary"},
+ "restricted|proprietary": []string{"restricted", "proprietary"},
+ "by_exception_only": []string{},
+ "proprietary|by_exception_only": []string{"proprietary"},
},
- add: map[string][]string{
- "notice": []string{"lib2"},
- "reciprocal": []string{"lib1"},
- "restricted": []string{"bin2"},
- "by_exception_only": []string{"bin1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "lib2"},
- "reciprocal": []string{"bin2", "lib1"},
- "restricted": []string{"bin2", "lib1"},
- "by_exception_only": []string{"bin1", "lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"by_exception_only", "notice"},
- "bin2": []string{"reciprocal", "restricted"},
- "lib1": []string{"reciprocal", "restricted"},
- "lib2": []string{"by_exception_only", "notice"},
- "other": []string{},
- },
- },
- {
- name: "oneeachadded",
- conditions: map[string][]string{
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
- },
- add: map[string][]string{
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1"},
- "reciprocal": []string{"bin2"},
- "restricted": []string{"lib1"},
- "by_exception_only": []string{"lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice"},
- "bin2": []string{"reciprocal"},
- "lib1": []string{"restricted"},
- "lib2": []string{"by_exception_only"},
- "other": []string{},
- },
+ expected: []string{"permissive", "notice", "restricted", "restricted_with_classpath_exception", "restricted_allows_dynamic_linking", "proprietary"},
},
}
for _, tt := range tests {
- testPublicInterface := func(lg *LicenseGraph, cs *LicenseConditionSet, t *testing.T) {
- byName(tt.byName).checkPublic(cs, t)
- byOrigin(tt.byOrigin).checkPublic(lg, cs, t)
+ toConditions := func(names []string) []LicenseCondition {
+ result := make([]LicenseCondition, 0, len(names))
+ for _, name := range names {
+ result = append(result, RecognizedConditionNames[name])
+ }
+ return result
}
- t.Run(tt.name+"_public_interface", func(t *testing.T) {
- lg := newLicenseGraph()
- cs := NewLicenseConditionSet(toConditionList(lg, tt.conditions)...)
- if tt.add != nil {
- cs.Add(toConditionList(lg, tt.add)...)
+ populate := func() LicenseConditionSet {
+ testSet := NewLicenseConditionSet(toConditions(tt.conditions)...)
+ if tt.plus != nil {
+ testSet = testSet.Plus(toConditions(*tt.plus)...)
}
- testPublicInterface(lg, cs, t)
- })
-
- t.Run("Copy() of "+tt.name+"_public_interface", func(t *testing.T) {
- lg := newLicenseGraph()
- cs := NewLicenseConditionSet(toConditionList(lg, tt.conditions)...)
- if tt.add != nil {
- cs.Add(toConditionList(lg, tt.add)...)
+ if tt.minus != nil {
+ testSet = testSet.Minus(toConditions(*tt.minus)...)
}
- testPublicInterface(lg, cs.Copy(), t)
- })
+ return testSet
+ }
+ populateSet := func() LicenseConditionSet {
+ testSet := NewLicenseConditionSet(toConditions(tt.conditions)...)
+ if tt.plus != nil {
+ testSet = testSet.Union(NewLicenseConditionSet(toConditions(*tt.plus)...))
+ }
+ if tt.minus != nil {
+ testSet = testSet.Difference(NewLicenseConditionSet(toConditions(*tt.minus)...))
+ }
+ return testSet
+ }
+ populatePlusSet := func() LicenseConditionSet {
+ testSet := NewLicenseConditionSet(toConditions(tt.conditions)...)
+ if tt.plus != nil {
+ testSet = testSet.Union(NewLicenseConditionSet(toConditions(*tt.plus)...))
+ }
+ if tt.minus != nil {
+ testSet = testSet.Minus(toConditions(*tt.minus)...)
+ }
+ return testSet
+ }
+ populateMinusSet := func() LicenseConditionSet {
+ testSet := NewLicenseConditionSet(toConditions(tt.conditions)...)
+ if tt.plus != nil {
+ testSet = testSet.Plus(toConditions(*tt.plus)...)
+ }
+ if tt.minus != nil {
+ testSet = testSet.Difference(NewLicenseConditionSet(toConditions(*tt.minus)...))
+ }
+ return testSet
+ }
+ checkMatching := func(cs LicenseConditionSet, t *testing.T) {
+ for data, expectedNames := range tt.matchingAny {
+ expectedConditions := toConditions(expectedNames)
+ expected := NewLicenseConditionSet(expectedConditions...)
+ actual := cs.MatchingAny(toConditions(strings.Split(data, "|"))...)
+ actualNames := actual.Names()
- testPrivateInterface := func(lg *LicenseGraph, cs *LicenseConditionSet, t *testing.T) {
- slist := make([]string, 0, cs.Count())
- for origin, expected := range tt.byOrigin {
- for _, name := range expected {
- slist = append(slist, origin+";"+name)
+ t.Logf("MatchingAny(%s): actual set %04x %s", data, actual, actual.String())
+ t.Logf("MatchingAny(%s): expected set %04x %s", data, expected, expected.String())
+
+ if actual != expected {
+ t.Errorf("MatchingAny(%s): got %04x, want %04x", data, actual, expected)
+ continue
+ }
+ if len(actualNames) != len(expectedNames) {
+ t.Errorf("len(MatchinAny(%s).Names()): got %d, want %d",
+ data, len(actualNames), len(expectedNames))
+ } else {
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != expectedNames[i] {
+ t.Errorf("MatchingAny(%s).Names()[%d]: got %s, want %s",
+ data, i, actualNames[i], expectedNames[i])
+ break
+ }
+ }
+ }
+ actualConditions := actual.AsList()
+ if len(actualConditions) != len(expectedConditions) {
+ t.Errorf("len(MatchingAny(%d).AsList()): got %d, want %d",
+ data, len(actualNames), len(expectedNames))
+ } else {
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != expectedNames[i] {
+ t.Errorf("MatchingAny(%s).AsList()[%d]: got %s, want %s",
+ data, i, actualNames[i], expectedNames[i])
+ break
+ }
+ }
}
}
- actualSlist := cs.asStringList(";")
- if len(slist) != len(actualSlist) {
- t.Errorf("unexpected LicenseConditionSet.asStringList(\";\"): got %v, want %v", actualSlist, slist)
+ }
+ checkMatchingSet := func(cs LicenseConditionSet, t *testing.T) {
+ for data, expectedNames := range tt.matchingAny {
+ expected := NewLicenseConditionSet(toConditions(expectedNames)...)
+ actual := cs.MatchingAnySet(NewLicenseConditionSet(toConditions(strings.Split(data, "|"))...))
+ actualNames := actual.Names()
+
+ t.Logf("MatchingAnySet(%s): actual set %04x %s", data, actual, actual.String())
+ t.Logf("MatchingAnySet(%s): expected set %04x %s", data, expected, expected.String())
+
+ if actual != expected {
+ t.Errorf("MatchingAnySet(%s): got %04x, want %04x", data, actual, expected)
+ continue
+ }
+ if len(actualNames) != len(expectedNames) {
+ t.Errorf("len(MatchingAnySet(%s).Names()): got %d, want %d",
+ data, len(actualNames), len(expectedNames))
+ } else {
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != expectedNames[i] {
+ t.Errorf("MatchingAnySet(%s).Names()[%d]: got %s, want %s",
+ data, i, actualNames[i], expectedNames[i])
+ break
+ }
+ }
+ }
+ expectedConditions := toConditions(expectedNames)
+ actualConditions := actual.AsList()
+ if len(actualConditions) != len(expectedConditions) {
+ t.Errorf("len(MatchingAnySet(%s).AsList()): got %d, want %d",
+ data, len(actualNames), len(expectedNames))
+ } else {
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != expectedNames[i] {
+ t.Errorf("MatchingAnySet(%s).AsList()[%d]: got %s, want %s",
+ data, i, actualNames[i], expectedNames[i])
+ break
+ }
+ }
+ }
+ }
+ }
+
+ checkExpected := func(actual LicenseConditionSet, t *testing.T) bool {
+ t.Logf("checkExpected{%s}", strings.Join(tt.expected, ", "))
+
+ expectedConditions := toConditions(tt.expected)
+ expected := NewLicenseConditionSet(expectedConditions...)
+
+ actualNames := actual.Names()
+
+ t.Logf("actual license condition set: %04x %s", actual, actual.String())
+ t.Logf("expected license condition set: %04x %s", expected, expected.String())
+
+ if actual != expected {
+ t.Errorf("checkExpected: got %04x, want %04x", actual, expected)
+ return false
+ }
+
+ if len(actualNames) != len(tt.expected) {
+ t.Errorf("len(actual.Names()): got %d, want %d", len(actualNames), len(tt.expected))
} else {
- sort.Strings(slist)
- sort.Strings(actualSlist)
- for i := 0; i < len(slist); i++ {
- if slist[i] != actualSlist[i] {
- t.Errorf("unexpected LicenseConditionSet.asStringList(\";\") index %d in %v: got %s, want %s", i, actualSlist, actualSlist[i], slist[i])
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != tt.expected[i] {
+ t.Errorf("actual.Names()[%d]: got %s, want %s", i, actualNames[i], tt.expected[i])
+ break
}
}
}
+
+ actualConditions := actual.AsList()
+ if len(actualConditions) != len(expectedConditions) {
+ t.Errorf("len(actual.AsList()): got %d, want %d", len(actualConditions), len(expectedConditions))
+ } else {
+ for i := 0; i < len(actualConditions); i++ {
+ if actualConditions[i] != expectedConditions[i] {
+ t.Errorf("actual.AsList()[%d]: got %s, want %s",
+ i, actualConditions[i], expectedConditions[i])
+ break
+ }
+ }
+ }
+
+ if len(tt.expected) == 0 {
+ if !actual.IsEmpty() {
+ t.Errorf("actual.IsEmpty(): got false, want true")
+ }
+ if actual.HasAny(expectedConditions...) {
+ t.Errorf("actual.HasAny(): got true, want false")
+ }
+ } else {
+ if actual.IsEmpty() {
+ t.Errorf("actual.IsEmpty(): got true, want false")
+ }
+ if !actual.HasAny(expectedConditions...) {
+ t.Errorf("actual.HasAny(all expected): got false, want true")
+ }
+ }
+ if !actual.HasAll(expectedConditions...) {
+ t.Errorf("actual.Hasll(all expected): want true, got false")
+ }
+ for _, expectedCondition := range expectedConditions {
+ if !actual.HasAny(expectedCondition) {
+ t.Errorf("actual.HasAny(%q): got false, want true", expectedCondition.Name())
+ }
+ if !actual.HasAll(expectedCondition) {
+ t.Errorf("actual.HasAll(%q): got false, want true", expectedCondition.Name())
+ }
+ }
+
+ notExpected := (AllLicenseConditions &^ expected)
+ notExpectedList := notExpected.AsList()
+ t.Logf("not expected license condition set: %04x %s", notExpected, notExpected.String())
+
+ if len(tt.expected) == 0 {
+ if actual.HasAny(append(expectedConditions, notExpectedList...)...) {
+ t.Errorf("actual.HasAny(all conditions): want false, got true")
+ }
+ } else {
+ if !actual.HasAny(append(expectedConditions, notExpectedList...)...) {
+ t.Errorf("actual.HasAny(all conditions): want true, got false")
+ }
+ }
+ if len(notExpectedList) == 0 {
+ if !actual.HasAll(append(expectedConditions, notExpectedList...)...) {
+ t.Errorf("actual.HasAll(all conditions): want true, got false")
+ }
+ } else {
+ if actual.HasAll(append(expectedConditions, notExpectedList...)...) {
+ t.Errorf("actual.HasAll(all conditions): want false, got true")
+ }
+ }
+ for _, unexpectedCondition := range notExpectedList {
+ if actual.HasAny(unexpectedCondition) {
+ t.Errorf("actual.HasAny(%q): got true, want false", unexpectedCondition.Name())
+ }
+ if actual.HasAll(unexpectedCondition) {
+ t.Errorf("actual.HasAll(%q): got true, want false", unexpectedCondition.Name())
+ }
+ }
+ return true
}
- t.Run(tt.name+"_private_list_interface", func(t *testing.T) {
- lg := newLicenseGraph()
- cs := newLicenseConditionSet()
- for name, origins := range tt.conditions {
- for _, origin := range origins {
- cs.add(newTestNode(lg, origin), name)
- }
- }
- if tt.add != nil {
- cs.Add(toConditionList(lg, tt.add)...)
- }
- testPrivateInterface(lg, cs, t)
- })
+ checkExpectedSet := func(actual LicenseConditionSet, t *testing.T) bool {
+ t.Logf("checkExpectedSet{%s}", strings.Join(tt.expected, ", "))
- t.Run(tt.name+"_private_set_interface", func(t *testing.T) {
- lg := newLicenseGraph()
- cs := newLicenseConditionSet()
- for name, origins := range tt.conditions {
- for _, origin := range origins {
- cs.add(newTestNode(lg, origin), name)
- }
+ expectedConditions := toConditions(tt.expected)
+ expected := NewLicenseConditionSet(expectedConditions...)
+
+ actualNames := actual.Names()
+
+ t.Logf("actual license condition set: %04x %s", actual, actual.String())
+ t.Logf("expected license condition set: %04x %s", expected, expected.String())
+
+ if actual != expected {
+ t.Errorf("checkExpectedSet: got %04x, want %04x", actual, expected)
+ return false
}
- if tt.add != nil {
- other := newLicenseConditionSet()
- for name, origins := range tt.add {
- for _, origin := range origins {
- other.add(newTestNode(lg, origin), name)
+
+ if len(actualNames) != len(tt.expected) {
+ t.Errorf("len(actual.Names()): got %d, want %d", len(actualNames), len(tt.expected))
+ } else {
+ for i := 0; i < len(actualNames); i++ {
+ if actualNames[i] != tt.expected[i] {
+ t.Errorf("actual.Names()[%d]: got %s, want %s", i, actualNames[i], tt.expected[i])
+ break
}
}
- cs.AddSet(other)
}
- testPrivateInterface(lg, cs, t)
- })
- }
-}
-func TestConditionSet_Removals(t *testing.T) {
- tests := []struct {
- name string
- conditions map[string][]string
- removeByName []ConditionNames
- removeSet map[string][]string
- byName map[string][]string
- byOrigin map[string][]string
- }{
- {
- name: "emptybyname",
- conditions: map[string][]string{},
- removeByName: []ConditionNames{{"reciprocal", "restricted"}},
- byName: map[string][]string{
- "notice": []string{},
- "restricted": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{},
- "lib1": []string{},
- "bin2": []string{},
- "lib2": []string{},
- },
- },
- {
- name: "emptybyset",
- conditions: map[string][]string{},
- removeSet: map[string][]string{
- "notice": []string{"bin1", "bin2"},
- "restricted": []string{"lib1", "lib2"},
- },
- byName: map[string][]string{
- "notice": []string{},
- "restricted": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{},
- "lib1": []string{},
- "bin2": []string{},
- "lib2": []string{},
- },
- },
- {
- name: "everythingremovenone",
- conditions: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- removeByName: []ConditionNames{{"permissive", "unencumbered"}},
- removeSet: map[string][]string{
- "notice": []string{"apk1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "bin2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib1": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "lib2": []string{"notice", "reciprocal", "restricted", "by_exception_only"},
- "other": []string{},
- },
- },
- {
- name: "everythingremovesome",
- conditions: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- removeByName: []ConditionNames{{"restricted", "by_exception_only"}},
- removeSet: map[string][]string{
- "notice": []string{"lib1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{"bin1", "bin2", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{},
- "by_exception_only": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{"notice", "reciprocal"},
- "bin2": []string{"notice", "reciprocal"},
- "lib1": []string{"reciprocal"},
- "lib2": []string{"notice", "reciprocal"},
- "other": []string{},
- },
- },
- {
- name: "everythingremoveall",
- conditions: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1", "bin2", "lib1", "lib2"},
- "by_exception_only": []string{"bin1", "bin2", "lib1", "lib2"},
- },
- removeByName: []ConditionNames{{"restricted", "by_exception_only"}},
- removeSet: map[string][]string{
- "notice": []string{"bin1", "bin2", "lib1", "lib2"},
- "reciprocal": []string{"bin1", "bin2", "lib1", "lib2"},
- "restricted": []string{"bin1"},
- },
- byName: map[string][]string{
- "permissive": []string{},
- "notice": []string{},
- "reciprocal": []string{},
- "restricted": []string{},
- "by_exception_only": []string{},
- },
- byOrigin: map[string][]string{
- "bin1": []string{},
- "bin2": []string{},
- "lib1": []string{},
- "lib2": []string{},
- "other": []string{},
- },
- },
- }
- for _, tt := range tests {
+ actualConditions := actual.AsList()
+ if len(actualConditions) != len(expectedConditions) {
+ t.Errorf("len(actual.AsList()): got %d, want %d", len(actualConditions), len(expectedConditions))
+ } else {
+ for i := 0; i < len(actualConditions); i++ {
+ if actualConditions[i] != expectedConditions[i] {
+ t.Errorf("actual.AsList()[%d}: got %s, want %s",
+ i, actualConditions[i], expectedConditions[i])
+ break
+ }
+ }
+ }
+
+ if len(tt.expected) == 0 {
+ if !actual.IsEmpty() {
+ t.Errorf("actual.IsEmpty(): got false, want true")
+ }
+ if actual.MatchesAnySet(expected) {
+ t.Errorf("actual.MatchesAnySet({}): got true, want false")
+ }
+ if actual.MatchesEverySet(expected, expected) {
+ t.Errorf("actual.MatchesEverySet({}, {}): want false, got true")
+ }
+ } else {
+ if actual.IsEmpty() {
+ t.Errorf("actual.IsEmpty(): got true, want false")
+ }
+ if !actual.MatchesAnySet(expected) {
+ t.Errorf("actual.MatchesAnySet({all expected}): want true, got false")
+ }
+ if !actual.MatchesEverySet(expected, expected) {
+ t.Errorf("actual.MatchesEverySet({all expected}, {all expected}): want true, got false")
+ }
+ }
+
+ notExpected := (AllLicenseConditions &^ expected)
+ t.Logf("not expected license condition set: %04x %s", notExpected, notExpected.String())
+
+ if len(tt.expected) == 0 {
+ if actual.MatchesAnySet(expected, notExpected) {
+ t.Errorf("empty actual.MatchesAnySet({expected}, {not expected}): want false, got true")
+ }
+ } else {
+ if !actual.MatchesAnySet(expected, notExpected) {
+ t.Errorf("actual.MatchesAnySet({expected}, {not expected}): want true, got false")
+ }
+ }
+ if actual.MatchesAnySet(notExpected) {
+ t.Errorf("actual.MatchesAnySet({not expected}): want false, got true")
+ }
+ if actual.MatchesEverySet(notExpected) {
+ t.Errorf("actual.MatchesEverySet({not expected}): want false, got true")
+ }
+ if actual.MatchesEverySet(expected, notExpected) {
+ t.Errorf("actual.MatchesEverySet({expected}, {not expected}): want false, got true")
+ }
+
+ if !actual.Difference(expected).IsEmpty() {
+ t.Errorf("actual.Difference({expected}).IsEmpty(): want true, got false")
+ }
+ if expected != actual.Intersection(expected) {
+ t.Errorf("expected == actual.Intersection({expected}): want true, got false (%04x != %04x)", expected, actual.Intersection(expected))
+ }
+ if actual != actual.Intersection(expected) {
+ t.Errorf("actual == actual.Intersection({expected}): want true, got false (%04x != %04x)", actual, actual.Intersection(expected))
+ }
+ return true
+ }
+
t.Run(tt.name, func(t *testing.T) {
- lg := newLicenseGraph()
- cs := newLicenseConditionSet()
- for name, origins := range tt.conditions {
- for _, origin := range origins {
- cs.add(newTestNode(lg, origin), name)
- }
+ cs := populate()
+ if checkExpected(cs, t) {
+ checkMatching(cs, t)
}
- if tt.removeByName != nil {
- cs.RemoveAllByName(tt.removeByName...)
+ if checkExpectedSet(cs, t) {
+ checkMatchingSet(cs, t)
}
- if tt.removeSet != nil {
- other := newLicenseConditionSet()
- for name, origins := range tt.removeSet {
- for _, origin := range origins {
- other.add(newTestNode(lg, origin), name)
- }
- }
- cs.RemoveSet(other)
+ })
+
+ t.Run(tt.name+"_sets", func(t *testing.T) {
+ cs := populateSet()
+ if checkExpected(cs, t) {
+ checkMatching(cs, t)
}
- byName(tt.byName).checkPublic(cs, t)
- byOrigin(tt.byOrigin).checkPublic(lg, cs, t)
+ if checkExpectedSet(cs, t){
+ checkMatchingSet(cs, t)
+ }
+ })
+
+ t.Run(tt.name+"_plusset", func(t *testing.T) {
+ cs := populatePlusSet()
+ if checkExpected(cs, t) {
+ checkMatching(cs, t)
+ }
+ if checkExpectedSet(cs, t){
+ checkMatchingSet(cs, t)
+ }
+ })
+
+ t.Run(tt.name+"_minusset", func(t *testing.T) {
+ cs := populateMinusSet()
+ if checkExpected(cs, t) {
+ checkMatching(cs, t)
+ }
+ if checkExpectedSet(cs, t){
+ checkMatchingSet(cs, t)
+ }
})
}
}
diff --git a/tools/compliance/graph.go b/tools/compliance/graph.go
index 9dcfa66..97fa657 100644
--- a/tools/compliance/graph.go
+++ b/tools/compliance/graph.go
@@ -52,30 +52,19 @@
// edges lists the directed edges in the graph from target to dependency. (guarded by mu)
//
// Alternatively, the graph is the set of `edges`.
- edges []*dependencyEdge
+ edges TargetEdgeList
- // targets identifies, indexes by name, and describes the entire set of target node files.
+ // targets identifies, indexes, and describes the entire set of target node files.
/// (guarded by mu)
targets map[string]*TargetNode
- // index facilitates looking up edges from targets. (creation guarded by my)
- //
- // This is a forward index from target to dependencies. i.e. "top-down"
- index map[string][]*dependencyEdge
+ // wgBU becomes non-nil when the bottom-up resolve begins and reaches 0
+ // (i.e. Wait() proceeds) when the bottom-up resolve completes. (guarded by mu)
+ wgBU *sync.WaitGroup
- // rsBU caches the results of a full bottom-up resolve. (creation guarded by mu)
- //
- // A bottom-up resolve is a prerequisite for all of the top-down resolves so caching
- // the result is a performance win.
- rsBU *ResolutionSet
-
- // rsTD caches the results of a full top-down resolve. (creation guarded by mu)
- //
- // A top-down resolve is a prerequisite for final resolutions.
- // e.g. a shipped node inheriting a `restricted` condition from a parent through a
- // dynamic dependency implies a notice dependency on the parent; even though, the
- // distribution does not happen as a result of the dynamic dependency itself.
- rsTD *ResolutionSet
+ // wgTD becomes non-nil when the top-down resolve begins and reaches 0 (i.e. Wait()
+ // proceeds) when the top-down resolve completes. (guarded by mu)
+ wgTD *sync.WaitGroup
// shippedNodes caches the results of a full walk of nodes identifying targets
// distributed either directly or as derivative works. (creation guarded by mu)
@@ -85,35 +74,18 @@
mu sync.Mutex
}
-// TargetNode returns the target node identified by `name`.
-func (lg *LicenseGraph) TargetNode(name string) *TargetNode {
- if _, ok := lg.targets[name]; !ok {
- panic(fmt.Errorf("target node %q missing from graph", name))
- }
- return lg.targets[name]
-}
-
-// HasTargetNode returns true if a target node identified by `name` appears in
-// the graph.
-func (lg *LicenseGraph) HasTargetNode(name string) bool {
- _, isPresent := lg.targets[name]
- return isPresent
-}
-
// Edges returns the list of edges in the graph. (unordered)
func (lg *LicenseGraph) Edges() TargetEdgeList {
edges := make(TargetEdgeList, 0, len(lg.edges))
- for _, e := range lg.edges {
- edges = append(edges, TargetEdge{lg, e})
- }
+ edges = append(edges, lg.edges...)
return edges
}
// Targets returns the list of target nodes in the graph. (unordered)
func (lg *LicenseGraph) Targets() TargetNodeList {
targets := make(TargetNodeList, 0, len(lg.targets))
- for target := range lg.targets {
- targets = append(targets, lg.targets[target])
+ for _, target := range lg.targets {
+ targets = append(targets, target)
}
return targets
}
@@ -124,33 +96,10 @@
func newLicenseGraph() *LicenseGraph {
return &LicenseGraph{
rootFiles: []string{},
- edges: make([]*dependencyEdge, 0, 1000),
targets: make(map[string]*TargetNode),
}
}
-// indexForward guarantees the `index` map is populated to look up edges by
-// `target`.
-func (lg *LicenseGraph) indexForward() {
- lg.mu.Lock()
- defer func() {
- lg.mu.Unlock()
- }()
-
- if lg.index != nil {
- return
- }
-
- lg.index = make(map[string][]*dependencyEdge)
- for _, e := range lg.edges {
- if _, ok := lg.index[e.target]; ok {
- lg.index[e.target] = append(lg.index[e.target], e)
- } else {
- lg.index[e.target] = []*dependencyEdge{e}
- }
- }
-}
-
// TargetEdge describes a directed, annotated edge from a target to a
// dependency. (immutable)
//
@@ -159,25 +108,25 @@
// i.e. `Target` depends on `Dependency` in the manner described by
// `Annotations`.
type TargetEdge struct {
- // lg identifies the scope, i.e. license graph, in which the edge appears.
- lg *LicenseGraph
+ // target and dependency identify the nodes connected by the edge.
+ target, dependency *TargetNode
- // e identifies describes the target, dependency, and annotations of the edge.
- e *dependencyEdge
+ // annotations identifies the set of compliance-relevant annotations describing the edge.
+ annotations TargetEdgeAnnotations
}
// Target identifies the target that depends on the dependency.
//
// Target needs Dependency to build.
-func (e TargetEdge) Target() *TargetNode {
- return e.lg.targets[e.e.target]
+func (e *TargetEdge) Target() *TargetNode {
+ return e.target
}
// Dependency identifies the target depended on by the target.
//
// Dependency builds without Target, but Target needs Dependency to build.
-func (e TargetEdge) Dependency() *TargetNode {
- return e.lg.targets[e.e.dependency]
+func (e *TargetEdge) Dependency() *TargetNode {
+ return e.dependency
}
// Annotations describes the type of edge by the set of annotations attached to
@@ -186,12 +135,17 @@
// Only annotations prescribed by policy have any meaning for licensing, and
// the meaning for licensing is likewise prescribed by policy. Other annotations
// are preserved and ignored by policy.
-func (e TargetEdge) Annotations() TargetEdgeAnnotations {
- return e.e.annotations
+func (e *TargetEdge) Annotations() TargetEdgeAnnotations {
+ return e.annotations
+}
+
+// String returns a human-readable string representation of the edge.
+func (e *TargetEdge) String() string {
+ return fmt.Sprintf("%s -[%s]> %s", e.target.name, strings.Join(e.annotations.AsList(), ", "), e.dependency.name)
}
// TargetEdgeList orders lists of edges by target then dependency then annotations.
-type TargetEdgeList []TargetEdge
+type TargetEdgeList []*TargetEdge
// Len returns the count of the elmements in the list.
func (l TargetEdgeList) Len() int { return len(l) }
@@ -201,18 +155,63 @@
// Less returns true when the `i`th element is lexicographically less than the `j`th.
func (l TargetEdgeList) Less(i, j int) bool {
- if l[i].e.target == l[j].e.target {
- if l[i].e.dependency == l[j].e.dependency {
- return l[i].e.annotations.Compare(l[j].e.annotations) < 0
- }
- return l[i].e.dependency < l[j].e.dependency
+ namei := l[i].target.name
+ namej := l[j].target.name
+ if namei == namej {
+ namei = l[i].dependency.name
+ namej = l[j].dependency.name
}
- return l[i].e.target < l[j].e.target
+ if namei == namej {
+ return l[i].annotations.Compare(l[j].annotations) < 0
+ }
+ return namei < namej
+}
+
+// TargetEdgePathSegment describes a single arc in a TargetPath associating the
+// edge with a context `ctx` defined by whatever process is creating the path.
+type TargetEdgePathSegment struct {
+ edge *TargetEdge
+ ctx interface{}
+}
+
+// Target identifies the target that depends on the dependency.
+//
+// Target needs Dependency to build.
+func (s TargetEdgePathSegment) Target() *TargetNode {
+ return s.edge.target
+}
+
+// Dependency identifies the target depended on by the target.
+//
+// Dependency builds without Target, but Target needs Dependency to build.
+func (s TargetEdgePathSegment) Dependency() *TargetNode {
+ return s.edge.dependency
+}
+
+// Annotations describes the type of edge by the set of annotations attached to
+// it.
+//
+// Only annotations prescribed by policy have any meaning for licensing, and
+// the meaning for licensing is likewise prescribed by policy. Other annotations
+// are preserved and ignored by policy.
+func (s TargetEdgePathSegment) Annotations() TargetEdgeAnnotations {
+ return s.edge.annotations
+}
+
+// Context returns the context associated with the path segment. The type and
+// value of the context defined by the process creating the path.
+func (s TargetEdgePathSegment) Context() interface{} {
+ return s.ctx
+}
+
+// String returns a human-readable string representation of the edge.
+func (s TargetEdgePathSegment) String() string {
+ return fmt.Sprintf("%s -[%s]> %s", s.edge.target.name, strings.Join(s.edge.annotations.AsList(), ", "), s.edge.dependency.name)
}
// TargetEdgePath describes a sequence of edges starting at a root and ending
// at some final dependency.
-type TargetEdgePath []TargetEdge
+type TargetEdgePath []TargetEdgePathSegment
// NewTargetEdgePath creates a new, empty path with capacity `cap`.
func NewTargetEdgePath(cap int) *TargetEdgePath {
@@ -222,15 +221,15 @@
// Push appends a new edge to the list verifying that the target of the new
// edge is the dependency of the prior.
-func (p *TargetEdgePath) Push(edge TargetEdge) {
+func (p *TargetEdgePath) Push(edge *TargetEdge, ctx interface{}) {
if len(*p) == 0 {
- *p = append(*p, edge)
+ *p = append(*p, TargetEdgePathSegment{edge, ctx})
return
}
- if (*p)[len(*p)-1].e.dependency != edge.e.target {
- panic(fmt.Errorf("disjoint path %s does not end at %s", p.String(), edge.e.target))
+ if (*p)[len(*p)-1].edge.dependency != edge.target {
+ panic(fmt.Errorf("disjoint path %s does not end at %s", p.String(), edge.target.name))
}
- *p = append(*p, edge)
+ *p = append(*p, TargetEdgePathSegment{edge, ctx})
}
// Pop shortens the path by 1 edge.
@@ -256,10 +255,11 @@
}
var sb strings.Builder
fmt.Fprintf(&sb, "[")
- for _, e := range *p {
- fmt.Fprintf(&sb, "%s -> ", e.e.target)
+ for _, s := range *p {
+ fmt.Fprintf(&sb, "%s -> ", s.edge.target.name)
}
- fmt.Fprintf(&sb, "%s]", (*p)[len(*p)-1].e.dependency)
+ lastSegment := (*p)[len(*p)-1]
+ fmt.Fprintf(&sb, "%s]", lastSegment.edge.dependency.name)
return sb.String()
}
@@ -279,6 +279,13 @@
return tn.name
}
+// Dependencies returns the list of edges to dependencies of `tn`.
+func (tn *TargetNode) Dependencies() TargetEdgeList {
+ edges := make(TargetEdgeList, 0, len(tn.edges))
+ edges = append(edges, tn.edges...)
+ return edges
+}
+
// PackageName returns the string that identifes the package for the target.
func (tn *TargetNode) PackageName() string {
return tn.proto.GetPackageName()
@@ -323,10 +330,8 @@
// is a matter of policy. (unordered)
//
// e.g. notice or proprietary
-func (tn *TargetNode) LicenseConditions() *LicenseConditionSet {
- result := newLicenseConditionSet()
- result.add(tn, tn.proto.LicenseConditions...)
- return result
+func (tn *TargetNode) LicenseConditions() LicenseConditionSet {
+ return tn.licenseConditions
}
// LicenseTexts returns the paths to the files containing the license texts for
@@ -387,12 +392,12 @@
// Annotations typically distinguish between static linkage versus dynamic
// versus tools that are used at build time but are not linked in any way.
type TargetEdgeAnnotations struct {
- annotations map[string]bool
+ annotations map[string]struct{}
}
// newEdgeAnnotations creates a new instance of TargetEdgeAnnotations.
func newEdgeAnnotations() TargetEdgeAnnotations {
- return TargetEdgeAnnotations{make(map[string]bool)}
+ return TargetEdgeAnnotations{make(map[string]struct{})}
}
// HasAnnotation returns true if an annotation `ann` is in the set.
@@ -439,7 +444,7 @@
// TargetNodeSet describes a set of distinct nodes in a license graph.
type TargetNodeSet struct {
- nodes map[*TargetNode]bool
+ nodes map[*TargetNode]struct{}
}
// Contains returns true when `target` is an element of the set.
@@ -466,6 +471,11 @@
return result
}
+// String returns a human-readable string representation of the set.
+func (ts *TargetNodeSet) String() string {
+ return fmt.Sprintf("{%s}", strings.Join(ts.Names(), ", "))
+}
+
// TargetNodeList orders a list of targets by name.
type TargetNodeList []*TargetNode
diff --git a/tools/compliance/policy/policy.go b/tools/compliance/policy/policy.go
index 9dab05b..581912a 100644
--- a/tools/compliance/policy/policy.go
+++ b/tools/compliance/policy/policy.go
@@ -20,32 +20,43 @@
)
var (
+ // RecognizedAnnotations identifies the set of annotations that have
+ // meaning for compliance policy.
+ RecognizedAnnotations = map[string]string{
+ // used in readgraph.go to avoid creating 1000's of copies of the below 3 strings.
+ "static": "static",
+ "dynamic": "dynamic",
+ "toolchain": "toolchain",
+ }
+
// ImpliesUnencumbered lists the condition names representing an author attempt to disclaim copyright.
- ImpliesUnencumbered = ConditionNames{"unencumbered"}
+ ImpliesUnencumbered = LicenseConditionSet(UnencumberedCondition)
// ImpliesPermissive lists the condition names representing copyrighted but "licensed without policy requirements".
- ImpliesPermissive = ConditionNames{"permissive"}
+ ImpliesPermissive = LicenseConditionSet(PermissiveCondition)
// ImpliesNotice lists the condition names implying a notice or attribution policy.
- ImpliesNotice = ConditionNames{"unencumbered", "permissive", "notice", "reciprocal", "restricted", "proprietary", "by_exception_only"}
+ ImpliesNotice = LicenseConditionSet(UnencumberedCondition | PermissiveCondition | NoticeCondition | ReciprocalCondition |
+ RestrictedCondition | RestrictedClasspathExceptionCondition | WeaklyRestrictedCondition |
+ ProprietaryCondition | ByExceptionOnlyCondition)
// ImpliesReciprocal lists the condition names implying a local source-sharing policy.
- ImpliesReciprocal = ConditionNames{"reciprocal"}
+ ImpliesReciprocal = LicenseConditionSet(ReciprocalCondition)
// Restricted lists the condition names implying an infectious source-sharing policy.
- ImpliesRestricted = ConditionNames{"restricted"}
+ ImpliesRestricted = LicenseConditionSet(RestrictedCondition | RestrictedClasspathExceptionCondition | WeaklyRestrictedCondition)
// ImpliesProprietary lists the condition names implying a confidentiality policy.
- ImpliesProprietary = ConditionNames{"proprietary"}
+ ImpliesProprietary = LicenseConditionSet(ProprietaryCondition)
// ImpliesByExceptionOnly lists the condition names implying a policy for "license review and approval before use".
- ImpliesByExceptionOnly = ConditionNames{"proprietary", "by_exception_only"}
+ ImpliesByExceptionOnly = LicenseConditionSet(ProprietaryCondition | ByExceptionOnlyCondition)
// ImpliesPrivate lists the condition names implying a source-code privacy policy.
- ImpliesPrivate = ConditionNames{"proprietary"}
+ ImpliesPrivate = LicenseConditionSet(ProprietaryCondition)
// ImpliesShared lists the condition names implying a source-code sharing policy.
- ImpliesShared = ConditionNames{"reciprocal", "restricted"}
+ ImpliesShared = LicenseConditionSet(ReciprocalCondition | RestrictedCondition | RestrictedClasspathExceptionCondition | WeaklyRestrictedCondition)
)
var (
@@ -55,100 +66,117 @@
ccBySa = regexp.MustCompile(`^SPDX-license-identifier-CC-BY.*-SA.*`)
)
-// Resolution happens in two passes:
+
+// LicenseConditionSetFromNames returns a set containing the recognized `names` and
+// silently ignoring or discarding the unrecognized `names`.
+func LicenseConditionSetFromNames(tn *TargetNode, names ...string) LicenseConditionSet {
+ cs := NewLicenseConditionSet()
+ for _, name := range names {
+ if name == "restricted" {
+ if 0 == len(tn.LicenseKinds()) {
+ cs = cs.Plus(RestrictedCondition)
+ continue
+ }
+ hasLgpl := false
+ hasClasspath := false
+ hasGeneric := false
+ for _, kind := range tn.LicenseKinds() {
+ if strings.HasSuffix(kind, "-with-classpath-exception") {
+ cs = cs.Plus(RestrictedClasspathExceptionCondition)
+ hasClasspath = true
+ } else if anyLgpl.MatchString(kind) {
+ cs = cs.Plus(WeaklyRestrictedCondition)
+ hasLgpl = true
+ } else if versionedGpl.MatchString(kind) {
+ cs = cs.Plus(RestrictedCondition)
+ } else if genericGpl.MatchString(kind) {
+ hasGeneric = true
+ } else if kind == "legacy_restricted" || ccBySa.MatchString(kind) {
+ cs = cs.Plus(RestrictedCondition)
+ } else {
+ cs = cs.Plus(RestrictedCondition)
+ }
+ }
+ if hasGeneric && !hasLgpl && !hasClasspath {
+ cs = cs.Plus(RestrictedCondition)
+ }
+ continue
+ }
+ if lc, ok := RecognizedConditionNames[name]; ok {
+ cs |= LicenseConditionSet(lc)
+ }
+ }
+ return cs
+}
+
+
+// Resolution happens in three phases:
//
-// 1. A bottom-up traversal propagates license conditions up to targets from
-// dendencies as needed.
+// 1. A bottom-up traversal propagates (restricted) license conditions up to
+// targets from dendencies as needed.
//
-// 2. For each condition of interest, a top-down traversal adjusts the attached
-// conditions pushing restricted down from targets into linked dependencies.
+// 2. For each condition of interest, a top-down traversal propagates
+// (restricted) conditions down from targets into linked dependencies.
//
-// The behavior of the 2 passes gets controlled by the 2 functions below.
+// 3. Finally, a walk of the shipped target nodes attaches resolutions to the
+// ancestor nodes from the root down to and including the first non-container.
//
-// The first function controls what happens during the bottom-up traversal. In
-// general conditions flow up through static links but not other dependencies;
-// except, restricted sometimes flows up through dynamic links.
+// e.g. If a disk image contains a binary bin1 that links a library liba, the
+// notice requirement for liba gets attached to the disk image and to bin1.
+// Because liba doesn't actually get shipped as a separate artifact, but only
+// as bits in bin1, it has no actions 'attached' to it. The actions attached
+// to the image and to bin1 'act on' liba by providing notice.
//
-// In general, too, the originating target gets acted on to resolve the
-// condition (e.g. providing notice), but again restricted is special in that
-// it requires acting on (i.e. sharing source of) both the originating module
-// and the target using the module.
+// The behavior of the 3 phases gets controlled by the 3 functions below.
//
-// The latter function controls what happens during the top-down traversal. In
-// general, only restricted conditions flow down at all, and only through
-// static links.
+// The first function controls what happens during the bottom-up propagation.
+// Restricted conditions propagate up all non-toolchain dependencies; except,
+// some do not propagate up dynamic links, which may depend on whether the
+// modules are independent.
+//
+// The second function controls what happens during the top-down propagation.
+// Restricted conditions propagate down as above with the added caveat that
+// inherited restricted conditions do not propagate from pure aggregates to
+// their dependencies.
+//
+// The final function controls which conditions apply/get attached to ancestors
+// depending on the types of dependencies involved. All conditions apply across
+// normal derivation dependencies. No conditions apply across toolchain
+// dependencies. Some restricted conditions apply across dynamic link
+// dependencies.
//
// Not all restricted licenses are create equal. Some have special rules or
// exceptions. e.g. LGPL or "with classpath excption".
-// depActionsApplicableToTarget returns the actions which propagate up an
+
+// depConditionsPropagatingToTarget returns the conditions which propagate up an
// edge from dependency to target.
//
-// This function sets the policy for the bottom-up traversal and how conditions
+// This function sets the policy for the bottom-up propagation and how conditions
// flow up the graph from dependencies to targets.
//
// If a pure aggregation is built into a derivative work that is not a pure
// aggregation, per policy it ceases to be a pure aggregation in the context of
// that derivative work. The `treatAsAggregate` parameter will be false for
// non-aggregates and for aggregates in non-aggregate contexts.
-func depActionsApplicableToTarget(e TargetEdge, depActions actionSet, treatAsAggregate bool) actionSet {
- result := make(actionSet)
+func depConditionsPropagatingToTarget(lg *LicenseGraph, e *TargetEdge, depConditions LicenseConditionSet, treatAsAggregate bool) LicenseConditionSet {
+ result := LicenseConditionSet(0x0000)
if edgeIsDerivation(e) {
- result.addSet(depActions)
- for _, cs := range depActions.byName(ImpliesRestricted) {
- result.add(e.Target(), cs)
- }
+ result |= depConditions & ImpliesRestricted
return result
}
if !edgeIsDynamicLink(e) {
return result
}
- restricted := depActions.byName(ImpliesRestricted)
- for actsOn, cs := range restricted {
- for _, lc := range cs.AsList() {
- hasGpl := false
- hasLgpl := false
- hasClasspath := false
- hasGeneric := false
- hasOther := false
- for _, kind := range lc.origin.LicenseKinds() {
- if strings.HasSuffix(kind, "-with-classpath-exception") {
- hasClasspath = true
- } else if anyLgpl.MatchString(kind) {
- hasLgpl = true
- } else if versionedGpl.MatchString(kind) {
- hasGpl = true
- } else if genericGpl.MatchString(kind) {
- hasGeneric = true
- } else if kind == "legacy_restricted" || ccBySa.MatchString(kind) {
- hasOther = true
- }
- }
- if hasOther || hasGpl {
- result.addCondition(actsOn, lc)
- result.addCondition(e.Target(), lc)
- continue
- }
- if hasClasspath && !edgeNodesAreIndependentModules(e) {
- result.addCondition(actsOn, lc)
- result.addCondition(e.Target(), lc)
- continue
- }
- if hasLgpl || hasClasspath {
- continue
- }
- if !hasGeneric {
- continue
- }
- result.addCondition(actsOn, lc)
- result.addCondition(e.Target(), lc)
- }
+ result |= depConditions & LicenseConditionSet(RestrictedCondition)
+ if 0 != (depConditions & LicenseConditionSet(RestrictedClasspathExceptionCondition)) && !edgeNodesAreIndependentModules(e) {
+ result |= LicenseConditionSet(RestrictedClasspathExceptionCondition)
}
return result
}
-// targetConditionsApplicableToDep returns the conditions which propagate down
+// targetConditionsPropagatingToDep returns the conditions which propagate down
// an edge from target to dependency.
//
// This function sets the policy for the top-down traversal and how conditions
@@ -158,81 +186,73 @@
// aggregation, per policy it ceases to be a pure aggregation in the context of
// that derivative work. The `treatAsAggregate` parameter will be false for
// non-aggregates and for aggregates in non-aggregate contexts.
-func targetConditionsApplicableToDep(e TargetEdge, targetConditions *LicenseConditionSet, treatAsAggregate bool) *LicenseConditionSet {
- result := targetConditions.Copy()
+func targetConditionsPropagatingToDep(lg *LicenseGraph, e *TargetEdge, targetConditions LicenseConditionSet, treatAsAggregate bool) LicenseConditionSet {
+ result := targetConditions
// reverse direction -- none of these apply to things depended-on, only to targets depending-on.
- result.RemoveAllByName(ConditionNames{"unencumbered", "permissive", "notice", "reciprocal", "proprietary", "by_exception_only"})
+ result = result.Minus(UnencumberedCondition, PermissiveCondition, NoticeCondition, ReciprocalCondition, ProprietaryCondition, ByExceptionOnlyCondition)
if !edgeIsDerivation(e) && !edgeIsDynamicLink(e) {
// target is not a derivative work of dependency and is not linked to dependency
- result.RemoveAllByName(ImpliesRestricted)
+ result = result.Difference(ImpliesRestricted)
return result
}
if treatAsAggregate {
// If the author of a pure aggregate licenses it restricted, apply restricted to immediate dependencies.
// Otherwise, restricted does not propagate back down to dependencies.
- restricted := result.ByName(ImpliesRestricted).AsList()
- for _, lc := range restricted {
- if lc.origin.name != e.e.target {
- result.Remove(lc)
- }
+ if !LicenseConditionSetFromNames(e.target, e.target.proto.LicenseConditions...).MatchesAnySet(ImpliesRestricted) {
+ result = result.Difference(ImpliesRestricted)
}
return result
}
if edgeIsDerivation(e) {
return result
}
- restricted := result.ByName(ImpliesRestricted).AsList()
- for _, lc := range restricted {
- hasGpl := false
- hasLgpl := false
- hasClasspath := false
- hasGeneric := false
- hasOther := false
- for _, kind := range lc.origin.LicenseKinds() {
- if strings.HasSuffix(kind, "-with-classpath-exception") {
- hasClasspath = true
- } else if anyLgpl.MatchString(kind) {
- hasLgpl = true
- } else if versionedGpl.MatchString(kind) {
- hasGpl = true
- } else if genericGpl.MatchString(kind) {
- hasGeneric = true
- } else if kind == "legacy_restricted" || ccBySa.MatchString(kind) {
- hasOther = true
- }
- }
- if hasOther || hasGpl {
- continue
- }
- if hasClasspath && !edgeNodesAreIndependentModules(e) {
- continue
- }
- if hasGeneric && !hasLgpl && !hasClasspath {
- continue
- }
- result.Remove(lc)
+ result = result.Minus(WeaklyRestrictedCondition)
+ if edgeNodesAreIndependentModules(e) {
+ result = result.Minus(RestrictedClasspathExceptionCondition)
}
return result
}
+// conditionsAttachingAcrossEdge returns the subset of conditions in `universe`
+// that apply across edge `e`.
+//
+// This function sets the policy for attaching actions to ancestor nodes in the
+// final resolution walk.
+func conditionsAttachingAcrossEdge(lg *LicenseGraph, e *TargetEdge, universe LicenseConditionSet) LicenseConditionSet {
+ result := universe
+ if edgeIsDerivation(e) {
+ return result
+ }
+ if !edgeIsDynamicLink(e) {
+ return NewLicenseConditionSet()
+ }
+
+ result &= LicenseConditionSet(RestrictedCondition | RestrictedClasspathExceptionCondition)
+ if 0 != (result & LicenseConditionSet(RestrictedClasspathExceptionCondition)) && edgeNodesAreIndependentModules(e) {
+ result &= LicenseConditionSet(RestrictedCondition)
+ }
+ return result
+}
+
+
// edgeIsDynamicLink returns true for edges representing shared libraries
// linked dynamically at runtime.
-func edgeIsDynamicLink(e TargetEdge) bool {
- return e.e.annotations.HasAnnotation("dynamic")
+func edgeIsDynamicLink(e *TargetEdge) bool {
+ return e.annotations.HasAnnotation("dynamic")
}
// edgeIsDerivation returns true for edges where the target is a derivative
// work of dependency.
-func edgeIsDerivation(e TargetEdge) bool {
- isDynamic := e.e.annotations.HasAnnotation("dynamic")
- isToolchain := e.e.annotations.HasAnnotation("toolchain")
+func edgeIsDerivation(e *TargetEdge) bool {
+ isDynamic := e.annotations.HasAnnotation("dynamic")
+ isToolchain := e.annotations.HasAnnotation("toolchain")
return !isDynamic && !isToolchain
}
// edgeNodesAreIndependentModules returns true for edges where the target and
// dependency are independent modules.
-func edgeNodesAreIndependentModules(e TargetEdge) bool {
- return e.Target().PackageName() != e.Dependency().PackageName()
+func edgeNodesAreIndependentModules(e *TargetEdge) bool {
+ return e.target.PackageName() != e.dependency.PackageName()
}
diff --git a/tools/compliance/policy/policy_test.go b/tools/compliance/policy/policy_test.go
index aea307f..09e831c 100644
--- a/tools/compliance/policy/policy_test.go
+++ b/tools/compliance/policy/policy_test.go
@@ -34,21 +34,21 @@
{
name: "firstparty",
edge: annotated{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"apacheLib.meta_lic:apacheLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
name: "notice",
edge: annotated{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"mitLib.meta_lic:mitLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
name: "fponlgpl",
edge: annotated{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
expectedDepActions: []string{
- "apacheBin.meta_lic:lgplLib.meta_lic:restricted",
- "lgplLib.meta_lic:lgplLib.meta_lic:restricted",
+ "apacheBin.meta_lic:lgplLib.meta_lic:restricted_allows_dynamic_linking",
+ "lgplLib.meta_lic:lgplLib.meta_lic:restricted_allows_dynamic_linking",
},
expectedTargetConditions: []string{},
},
@@ -86,8 +86,8 @@
name: "independentmodulestatic",
edge: annotated{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
expectedDepActions: []string{
- "apacheBin.meta_lic:gplWithClasspathException.meta_lic:restricted",
- "gplWithClasspathException.meta_lic:gplWithClasspathException.meta_lic:restricted",
+ "apacheBin.meta_lic:gplWithClasspathException.meta_lic:restricted_with_classpath_exception",
+ "gplWithClasspathException.meta_lic:gplWithClasspathException.meta_lic:restricted_with_classpath_exception",
},
expectedTargetConditions: []string{},
},
@@ -95,8 +95,8 @@
name: "dependentmodule",
edge: annotated{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
expectedDepActions: []string{
- "dependentModule.meta_lic:gplWithClasspathException.meta_lic:restricted",
- "gplWithClasspathException.meta_lic:gplWithClasspathException.meta_lic:restricted",
+ "dependentModule.meta_lic:gplWithClasspathException.meta_lic:restricted_with_classpath_exception",
+ "gplWithClasspathException.meta_lic:gplWithClasspathException.meta_lic:restricted_with_classpath_exception",
},
expectedTargetConditions: []string{},
},
@@ -104,8 +104,8 @@
{
name: "lgplonfp",
edge: annotated{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"apacheLib.meta_lic:apacheLib.meta_lic:notice"},
- expectedTargetConditions: []string{"lgplBin.meta_lic:restricted"},
+ expectedDepActions: []string{},
+ expectedTargetConditions: []string{"lgplBin.meta_lic:restricted_allows_dynamic_linking"},
},
{
name: "lgplonfpdynamic",
@@ -116,14 +116,14 @@
{
name: "gplonfp",
edge: annotated{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"apacheLib.meta_lic:apacheLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{"gplBin.meta_lic:restricted"},
},
{
name: "gplcontainer",
edge: annotated{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
treatAsAggregate: true,
- expectedDepActions: []string{"apacheLib.meta_lic:apacheLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{"gplContainer.meta_lic:restricted"},
},
{
@@ -133,7 +133,6 @@
otherCondition: "gplLib.meta_lic:restricted",
expectedDepActions: []string{
"apacheContainer.meta_lic:gplLib.meta_lic:restricted",
- "apacheLib.meta_lic:apacheLib.meta_lic:notice",
"apacheLib.meta_lic:gplLib.meta_lic:restricted",
"gplLib.meta_lic:gplLib.meta_lic:restricted",
},
@@ -146,7 +145,6 @@
otherCondition: "gplLib.meta_lic:restricted",
expectedDepActions: []string{
"apacheBin.meta_lic:gplLib.meta_lic:restricted",
- "apacheLib.meta_lic:apacheLib.meta_lic:notice",
"apacheLib.meta_lic:gplLib.meta_lic:restricted",
"gplLib.meta_lic:gplLib.meta_lic:restricted",
},
@@ -167,14 +165,14 @@
{
name: "independentmodulereversestatic",
edge: annotated{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
- expectedDepActions: []string{"apacheBin.meta_lic:apacheBin.meta_lic:notice"},
- expectedTargetConditions: []string{"gplWithClasspathException.meta_lic:restricted"},
+ expectedDepActions: []string{},
+ expectedTargetConditions: []string{"gplWithClasspathException.meta_lic:restricted_with_classpath_exception"},
},
{
name: "dependentmodulereverse",
edge: annotated{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
expectedDepActions: []string{},
- expectedTargetConditions: []string{"gplWithClasspathException.meta_lic:restricted"},
+ expectedTargetConditions: []string{"gplWithClasspathException.meta_lic:restricted_with_classpath_exception"},
},
{
name: "ponr",
@@ -188,31 +186,31 @@
{
name: "ronp",
edge: annotated{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
- expectedDepActions: []string{"proprietary.meta_lic:proprietary.meta_lic:proprietary"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{"gplBin.meta_lic:restricted"},
},
{
name: "noticeonb_e_o",
edge: annotated{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
- expectedDepActions: []string{"by_exception.meta_lic:by_exception.meta_lic:by_exception_only"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
name: "b_e_oonnotice",
edge: annotated{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"mitLib.meta_lic:mitLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
name: "noticeonrecip",
edge: annotated{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"mplLib.meta_lic:mplLib.meta_lic:reciprocal"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
{
name: "reciponnotice",
edge: annotated{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
- expectedDepActions: []string{"mitLib.meta_lic:mitLib.meta_lic:notice"},
+ expectedDepActions: []string{},
expectedTargetConditions: []string{},
},
}
@@ -231,69 +229,80 @@
t.Errorf("unexpected error reading graph: %w", err)
return
}
+ edge := lg.Edges()[0]
// simulate a condition inherited from another edge/dependency.
otherTarget := ""
otherCondition := ""
+ var otn *TargetNode
if len(tt.otherCondition) > 0 {
fields := strings.Split(tt.otherCondition, ":")
otherTarget = fields[0]
otherCondition = fields[1]
+ otn = &TargetNode{name: otherTarget}
// other target must exist in graph
- lg.targets[otherTarget] = &TargetNode{name: otherTarget}
- lg.targets[otherTarget].proto.LicenseConditions = append(lg.targets[otherTarget].proto.LicenseConditions, otherCondition)
+ lg.targets[otherTarget] = otn
+ otn.licenseConditions = LicenseConditionSet(RecognizedConditionNames[otherCondition])
+ }
+ targets := make(map[string]*TargetNode)
+ targets[edge.target.name] = edge.target
+ targets[edge.dependency.name] = edge.dependency
+ if otn != nil {
+ targets[otn.name] = otn
}
if tt.expectedDepActions != nil {
- depActions := make(actionSet)
- depActions[lg.targets[tt.edge.dep]] = lg.targets[tt.edge.dep].LicenseConditions()
- if otherTarget != "" {
- // simulate a sub-dependency's condition having already propagated up to dep and about to go to target
- otherCs := lg.targets[otherTarget].LicenseConditions()
- depActions[lg.targets[tt.edge.dep]].AddSet(otherCs)
- depActions[lg.targets[otherTarget]] = otherCs
- }
- asActual := depActionsApplicableToTarget(lg.Edges()[0], depActions, tt.treatAsAggregate)
- asExpected := make(actionSet)
- for _, triple := range tt.expectedDepActions {
- fields := strings.Split(triple, ":")
- actsOn := lg.targets[fields[0]]
- origin := lg.targets[fields[1]]
- expectedConditions := newLicenseConditionSet()
- expectedConditions.add(origin, fields[2:]...)
- if _, ok := asExpected[actsOn]; ok {
- asExpected[actsOn].AddSet(expectedConditions)
- } else {
- asExpected[actsOn] = expectedConditions
+ t.Run("depConditionsPropagatingToTarget", func(t *testing.T) {
+ depConditions := edge.dependency.LicenseConditions()
+ if otherTarget != "" {
+ // simulate a sub-dependency's condition having already propagated up to dep and about to go to target
+ otherCs := otn.LicenseConditions()
+ depConditions |= otherCs
}
- }
-
- checkSameActions(lg, asActual, asExpected, t)
+ t.Logf("calculate target actions for edge=%s, dep conditions=%04x, treatAsAggregate=%v", edge.String(), depConditions, tt.treatAsAggregate)
+ csActual := depConditionsPropagatingToTarget(lg, edge, depConditions, tt.treatAsAggregate)
+ t.Logf("calculated target conditions as %04x{%s}", csActual, strings.Join(csActual.Names(), ", "))
+ csExpected := NewLicenseConditionSet()
+ for _, triple := range tt.expectedDepActions {
+ fields := strings.Split(triple, ":")
+ expectedConditions := NewLicenseConditionSet()
+ for _, cname := range fields[2:] {
+ expectedConditions = expectedConditions.Plus(RecognizedConditionNames[cname])
+ }
+ csExpected |= expectedConditions
+ }
+ t.Logf("expected target conditions as %04x{%s}", csExpected, strings.Join(csExpected.Names(), ", "))
+ if csActual != csExpected {
+ t.Errorf("unexpected license conditions: got %04x, want %04x", csActual, csExpected)
+ }
+ })
}
if tt.expectedTargetConditions != nil {
- targetConditions := lg.TargetNode(tt.edge.target).LicenseConditions()
- if otherTarget != "" {
- targetConditions.add(lg.targets[otherTarget], otherCondition)
- }
- cs := targetConditionsApplicableToDep(
- lg.Edges()[0],
- targetConditions,
- tt.treatAsAggregate)
- actual := make([]string, 0, cs.Count())
- for _, lc := range cs.AsList() {
- actual = append(actual, lc.asString(":"))
- }
- sort.Strings(actual)
- sort.Strings(tt.expectedTargetConditions)
- if len(actual) != len(tt.expectedTargetConditions) {
- t.Errorf("unexpected number of target conditions: got %v with %d conditions, want %v with %d conditions",
- actual, len(actual), tt.expectedTargetConditions, len(tt.expectedTargetConditions))
- } else {
- for i := 0; i < len(actual); i++ {
- if actual[i] != tt.expectedTargetConditions[i] {
- t.Errorf("unexpected target condition at element %d: got %q, want %q",
- i, actual[i], tt.expectedTargetConditions[i])
+ t.Run("targetConditionsPropagatingToDep", func(t *testing.T) {
+ targetConditions := edge.target.LicenseConditions()
+ if otherTarget != "" {
+ targetConditions = targetConditions.Union(otn.licenseConditions)
+ }
+ t.Logf("calculate dep conditions for edge=%s, target conditions=%v, treatAsAggregate=%v", edge.String(), targetConditions.Names(), tt.treatAsAggregate)
+ cs := targetConditionsPropagatingToDep(lg, edge, targetConditions, tt.treatAsAggregate)
+ t.Logf("calculated dep conditions as %v", cs.Names())
+ actual := cs.Names()
+ sort.Strings(actual)
+ expected := make([]string, 0)
+ for _, expectedDepCondition := range tt.expectedTargetConditions {
+ expected = append(expected, strings.Split(expectedDepCondition, ":")[1])
+ }
+ sort.Strings(expected)
+ if len(actual) != len(expected) {
+ t.Errorf("unexpected number of target conditions: got %v with %d conditions, want %v with %d conditions",
+ actual, len(actual), expected, len(expected))
+ } else {
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != expected[i] {
+ t.Errorf("unexpected target condition at element %d: got %q, want %q",
+ i, actual[i], expected[i])
+ }
}
}
- }
+ })
}
})
}
diff --git a/tools/compliance/policy/resolve.go b/tools/compliance/policy/resolve.go
index 58547f8..336894a 100644
--- a/tools/compliance/policy/resolve.go
+++ b/tools/compliance/policy/resolve.go
@@ -14,228 +14,196 @@
package compliance
+import (
+ "sync"
+)
+
// ResolveBottomUpConditions performs a bottom-up walk of the LicenseGraph
// propagating conditions up the graph as necessary according to the properties
// of each edge and according to each license condition in question.
//
-// Subsequent top-down walks of the graph will filter some resolutions and may
-// introduce new resolutions.
-//
// e.g. if a "restricted" condition applies to a binary, it also applies to all
// of the statically-linked libraries and the transitive closure of their static
// dependencies; even if neither they nor the transitive closure of their
// dependencies originate any "restricted" conditions. The bottom-up walk will
// not resolve the library and its transitive closure, but the later top-down
// walk will.
-func ResolveBottomUpConditions(lg *LicenseGraph) *ResolutionSet {
+func ResolveBottomUpConditions(lg *LicenseGraph) {
// short-cut if already walked and cached
lg.mu.Lock()
- rs := lg.rsBU
+ wg := lg.wgBU
+
+ if wg != nil {
+ lg.mu.Unlock()
+ wg.Wait()
+ return
+ }
+ wg = &sync.WaitGroup{}
+ wg.Add(1)
+ lg.wgBU = wg
lg.mu.Unlock()
- if rs != nil {
- return rs
+ // amap identifes targets previously walked. (guarded by mu)
+ amap := make(map[*TargetNode]struct{})
+
+ // cmap identifies targets previously walked as pure aggregates. i.e. as containers
+ // (guarded by mu)
+ cmap := make(map[*TargetNode]struct{})
+ var mu sync.Mutex
+
+ var walk func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet
+
+ walk = func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet {
+ priorWalkResults := func() (LicenseConditionSet, bool) {
+ mu.Lock()
+ defer mu.Unlock()
+
+ if _, alreadyWalked := amap[target]; alreadyWalked {
+ if treatAsAggregate {
+ return target.resolution, true
+ }
+ if _, asAggregate := cmap[target]; !asAggregate {
+ return target.resolution, true
+ }
+ // previously walked in a pure aggregate context,
+ // needs to walk again in non-aggregate context
+ delete(cmap, target)
+ } else {
+ target.resolution |= target.licenseConditions
+ amap[target] = struct{}{}
+ }
+ if treatAsAggregate {
+ cmap[target] = struct{}{}
+ }
+ return target.resolution, false
+ }
+ cs, alreadyWalked := priorWalkResults()
+ if alreadyWalked {
+ return cs
+ }
+
+ c := make(chan LicenseConditionSet, len(target.edges))
+ // add all the conditions from all the dependencies
+ for _, edge := range target.edges {
+ go func(edge *TargetEdge) {
+ // walk dependency to get its conditions
+ cs := walk(edge.dependency, treatAsAggregate && edge.dependency.IsContainer())
+
+ // turn those into the conditions that apply to the target
+ cs = depConditionsPropagatingToTarget(lg, edge, cs, treatAsAggregate)
+
+ c <- cs
+ }(edge)
+ }
+ for i := 0; i < len(target.edges); i++ {
+ cs |= <-c
+ }
+ mu.Lock()
+ target.resolution |= cs
+ mu.Unlock()
+
+ // return conditions up the tree
+ return cs
}
- // must be indexed for fast lookup
- lg.indexForward()
-
- rs = resolveBottomUp(lg, make(map[*TargetNode]actionSet) /* empty map; no prior resolves */)
-
- // if not yet cached, save the result
- lg.mu.Lock()
- if lg.rsBU == nil {
- lg.rsBU = rs
- } else {
- // if we end up with 2, release the later for garbage collection
- rs = lg.rsBU
+ // walk each of the roots
+ for _, rname := range lg.rootFiles {
+ rnode := lg.targets[rname]
+ _ = walk(rnode, rnode.IsContainer())
}
- lg.mu.Unlock()
- return rs
+ wg.Done()
}
// ResolveTopDownCondtions performs a top-down walk of the LicenseGraph
-// resolving all reachable nodes for `condition`. Policy establishes the rules
-// for transforming and propagating resolutions down the graph.
+// propagating conditions from target to dependency.
//
// e.g. For current policy, none of the conditions propagate from target to
// dependency except restricted. For restricted, the policy is to share the
// source of any libraries linked to restricted code and to provide notice.
-func ResolveTopDownConditions(lg *LicenseGraph) *ResolutionSet {
+func ResolveTopDownConditions(lg *LicenseGraph) {
// short-cut if already walked and cached
lg.mu.Lock()
- rs := lg.rsTD
- lg.mu.Unlock()
+ wg := lg.wgTD
- if rs != nil {
- return rs
+ if wg != nil {
+ lg.mu.Unlock()
+ wg.Wait()
+ return
}
+ wg = &sync.WaitGroup{}
+ wg.Add(1)
+ lg.wgTD = wg
+ lg.mu.Unlock()
// start with the conditions propagated up the graph
- rs = ResolveBottomUpConditions(lg)
+ ResolveBottomUpConditions(lg)
- // rmap maps 'appliesTo' targets to their applicable conditions
- //
- // rmap is the resulting ResolutionSet
- rmap := make(map[*TargetNode]actionSet)
+ // amap contains the set of targets already walked. (guarded by mu)
+ amap := make(map[*TargetNode]struct{})
// cmap contains the set of targets walked as pure aggregates. i.e. containers
- cmap := make(map[*TargetNode]bool)
+ // (guarded by mu)
+ cmap := make(map[*TargetNode]struct{})
- var walk func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool)
+ // mu guards concurrent access to cmap
+ var mu sync.Mutex
- walk = func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool) {
- if _, ok := rmap[fnode]; !ok {
- rmap[fnode] = make(actionSet)
- }
- rmap[fnode].add(fnode, cs)
+ var walk func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool)
+
+ walk = func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool) {
+ defer wg.Done()
+ mu.Lock()
+ fnode.resolution |= fnode.licenseConditions
+ fnode.resolution |= cs
+ amap[fnode] = struct{}{}
if treatAsAggregate {
- cmap[fnode] = true
+ cmap[fnode] = struct{}{}
}
- // add conditions attached to `fnode`
- cs = cs.Copy()
- for _, fcs := range rs.resolutions[fnode] {
- cs.AddSet(fcs)
- }
+ cs = fnode.resolution
+ mu.Unlock()
// for each dependency
- for _, edge := range lg.index[fnode.name] {
- e := TargetEdge{lg, edge}
- // dcs holds the dpendency conditions inherited from the target
- dcs := targetConditionsApplicableToDep(e, cs, treatAsAggregate)
- if dcs.IsEmpty() && !treatAsAggregate {
- continue
- }
- dnode := lg.targets[edge.dependency]
- if as, alreadyWalked := rmap[dnode]; alreadyWalked {
- diff := dcs.Copy()
- diff.RemoveSet(as.conditions())
- if diff.IsEmpty() {
- // no new conditions
+ for _, edge := range fnode.edges {
+ func(edge *TargetEdge) {
+ // dcs holds the dpendency conditions inherited from the target
+ dcs := targetConditionsPropagatingToDep(lg, edge, cs, treatAsAggregate)
+ dnode := edge.dependency
+ mu.Lock()
+ defer mu.Unlock()
+ depcs := dnode.resolution
+ _, alreadyWalked := amap[dnode]
+ if !dcs.IsEmpty() && alreadyWalked {
+ if dcs.Difference(depcs).IsEmpty() {
+ // no new conditions
- // pure aggregates never need walking a 2nd time with same conditions
- if treatAsAggregate {
- continue
+ // pure aggregates never need walking a 2nd time with same conditions
+ if treatAsAggregate {
+ return
+ }
+ // non-aggregates don't need walking as non-aggregate a 2nd time
+ if _, asAggregate := cmap[dnode]; !asAggregate {
+ return
+ }
+ // previously walked as pure aggregate; need to re-walk as non-aggregate
+ delete(cmap, dnode)
}
- // non-aggregates don't need walking as non-aggregate a 2nd time
- if _, asAggregate := cmap[dnode]; !asAggregate {
- continue
- }
- // previously walked as pure aggregate; need to re-walk as non-aggregate
- delete(cmap, dnode)
}
- }
- // add the conditions to the dependency
- walk(dnode, dcs, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
+ // add the conditions to the dependency
+ wg.Add(1)
+ go walk(dnode, dcs, treatAsAggregate && dnode.IsContainer())
+ }(edge)
}
}
// walk each of the roots
- for _, r := range lg.rootFiles {
- rnode := lg.targets[r]
- as, ok := rs.resolutions[rnode]
- if !ok {
- // no conditions in root or transitive closure of dependencies
- continue
- }
- if as.isEmpty() {
- continue
- }
-
+ for _, rname := range lg.rootFiles {
+ rnode := lg.targets[rname]
+ wg.Add(1)
// add the conditions to the root and its transitive closure
- walk(rnode, newLicenseConditionSet(), lg.targets[r].IsContainer())
+ go walk(rnode, NewLicenseConditionSet(), rnode.IsContainer())
}
-
- // back-fill any bottom-up conditions on targets missed by top-down walk
- for attachesTo, as := range rs.resolutions {
- if _, ok := rmap[attachesTo]; !ok {
- rmap[attachesTo] = as.copy()
- } else {
- rmap[attachesTo].addSet(as)
- }
- }
-
- // propagate any new conditions back up the graph
- rs = resolveBottomUp(lg, rmap)
-
- // if not yet cached, save the result
- lg.mu.Lock()
- if lg.rsTD == nil {
- lg.rsTD = rs
- } else {
- // if we end up with 2, release the later for garbage collection
- rs = lg.rsTD
- }
- lg.mu.Unlock()
-
- return rs
-}
-
-// resolveBottomUp implements a bottom-up resolve propagating conditions both
-// from the graph, and from a `priors` map of resolutions.
-func resolveBottomUp(lg *LicenseGraph, priors map[*TargetNode]actionSet) *ResolutionSet {
- rs := newResolutionSet()
-
- // cmap contains an entry for every target that was previously walked as a pure aggregate only.
- cmap := make(map[string]bool)
-
- var walk func(f string, treatAsAggregate bool) actionSet
-
- walk = func(f string, treatAsAggregate bool) actionSet {
- target := lg.targets[f]
- result := make(actionSet)
- result[target] = newLicenseConditionSet()
- result[target].add(target, target.proto.LicenseConditions...)
- if pas, ok := priors[target]; ok {
- result.addSet(pas)
- }
- if preresolved, ok := rs.resolutions[target]; ok {
- if treatAsAggregate {
- result.addSet(preresolved)
- return result
- }
- if _, asAggregate := cmap[f]; !asAggregate {
- result.addSet(preresolved)
- return result
- }
- // previously walked in a pure aggregate context,
- // needs to walk again in non-aggregate context
- delete(cmap, f)
- }
- if treatAsAggregate {
- cmap[f] = true
- }
-
- // add all the conditions from all the dependencies
- for _, edge := range lg.index[f] {
- // walk dependency to get its conditions
- as := walk(edge.dependency, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
-
- // turn those into the conditions that apply to the target
- as = depActionsApplicableToTarget(TargetEdge{lg, edge}, as, treatAsAggregate)
-
- // add them to the result
- result.addSet(as)
- }
-
- // record these conditions as applicable to the target
- rs.addConditions(target, result)
- if len(priors) == 0 {
- // on the first bottom-up resolve, parents have their own sharing and notice needs
- // on the later resolve, if priors is empty, there will be nothing new to add
- rs.addSelf(target, result.byName(ImpliesRestricted))
- }
-
- // return this up the tree
- return result
- }
-
- // walk each of the roots
- for _, r := range lg.rootFiles {
- _ = walk(r, lg.targets[r].IsContainer())
- }
-
- return rs
+ wg.Done()
+ wg.Wait()
}
diff --git a/tools/compliance/policy/resolve_test.go b/tools/compliance/policy/resolve_test.go
index 4c99d35..09dd7dd 100644
--- a/tools/compliance/policy/resolve_test.go
+++ b/tools/compliance/policy/resolve_test.go
@@ -16,15 +16,16 @@
import (
"bytes"
+ "sort"
"testing"
)
func TestResolveBottomUpConditions(t *testing.T) {
tests := []struct {
- name string
- roots []string
- edges []annotated
- expectedResolutions []res
+ name string
+ roots []string
+ edges []annotated
+ expectedActions []tcond
}{
{
name: "firstparty",
@@ -32,10 +33,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -44,9 +44,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"toolchain"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -56,13 +56,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -72,12 +69,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -86,9 +81,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -98,11 +93,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -112,11 +106,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -125,11 +118,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -138,9 +129,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"toolchain"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -150,16 +141,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -169,13 +154,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -184,11 +166,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -198,16 +178,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -217,13 +191,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -232,11 +203,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -245,9 +214,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"toolchain"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -257,16 +226,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -276,13 +239,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -291,9 +251,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -303,11 +263,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -317,11 +276,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -330,11 +288,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
},
},
{
@@ -343,11 +299,9 @@
edges: []annotated{
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"dependentModule.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
},
},
{
@@ -356,9 +310,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
},
},
{
@@ -367,11 +321,9 @@
edges: []annotated{
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"dependentModule.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
},
},
}
@@ -383,19 +335,37 @@
t.Errorf("unexpected test data error: got %w, want no error", err)
return
}
- expectedRs := toResolutionSet(lg, tt.expectedResolutions)
- actualRs := ResolveBottomUpConditions(lg)
- checkSame(actualRs, expectedRs, t)
+
+ logGraph(lg, t)
+
+ ResolveBottomUpConditions(lg)
+ actual := asActionList(lg)
+ sort.Sort(actual)
+ t.Logf("actual: %s", actual.String())
+
+ expected := toActionList(lg, tt.expectedActions)
+ sort.Sort(expected)
+ t.Logf("expected: %s", expected.String())
+
+ if len(actual) != len(expected) {
+ t.Errorf("unexpected number of actions: got %d, want %d", len(actual), len(expected))
+ return
+ }
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != expected[i] {
+ t.Errorf("unexpected action at index %d: got %s, want %s", i, actual[i].String(), expected[i].String())
+ }
+ }
})
}
}
func TestResolveTopDownConditions(t *testing.T) {
tests := []struct {
- name string
- roots []string
- edges []annotated
- expectedResolutions []res
+ name string
+ roots []string
+ edges []annotated
+ expectedActions []tcond
}{
{
name: "firstparty",
@@ -403,10 +373,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -415,9 +384,9 @@
edges: []annotated{
{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheLib.meta_lic", "apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "notice"},
},
},
{
@@ -427,15 +396,10 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"mitLib.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -445,11 +409,10 @@
{"apacheBin.meta_lic", "gplBin.meta_lic", []string{"toolchain"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"gplBin.meta_lic", "gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"mitLib.meta_lic", "notice"},
+ {"gplBin.meta_lic", "restricted"},
},
},
{
@@ -462,27 +425,13 @@
{"apacheBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"mplLib.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mplLib.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"mitBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
+ {"mplLib.meta_lic", "reciprocal|restricted"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -492,13 +441,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -508,14 +454,10 @@
{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"gplLib.meta_lic", "restricted"},
+ {"mitLib.meta_lic", "notice|restricted"},
},
},
{
@@ -528,23 +470,13 @@
{"apacheBin.meta_lic", "mplLib.meta_lic", []string{"dynamic"}},
{"mitBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mitBin.meta_lic", "mitBin.meta_lic", "mitBin.meta_lic", "notice"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"mplLib.meta_lic", "mplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"mplLib.meta_lic", "mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice|restricted"},
+ {"mitBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
+ {"mplLib.meta_lic", "reciprocal|restricted"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -554,13 +486,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"gplLib.meta_lic", "gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted"},
+ {"apacheBin.meta_lic", "notice"},
+ {"gplLib.meta_lic", "restricted"},
},
},
{
@@ -570,15 +499,10 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"mitLib.meta_lic", "notice|restricted_allows_dynamic_linking"},
},
},
{
@@ -588,11 +512,10 @@
{"apacheBin.meta_lic", "lgplBin.meta_lic", []string{"toolchain"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"lgplBin.meta_lic", "lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplBin.meta_lic", "restricted_allows_dynamic_linking"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -603,22 +526,11 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"mitLib.meta_lic", "notice|restricted_allows_dynamic_linking"},
},
},
{
@@ -628,13 +540,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice|restricted_allows_dynamic_linking"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -644,11 +553,10 @@
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -658,11 +566,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -672,11 +579,10 @@
{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
},
- expectedResolutions: []res{
- {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
- {"apacheContainer.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"lgplLib.meta_lic", "lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ expectedActions: []tcond{
+ {"apacheContainer.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "notice"},
+ {"lgplLib.meta_lic", "restricted_allows_dynamic_linking"},
},
},
{
@@ -686,15 +592,10 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
+ {"mitLib.meta_lic", "notice|restricted_with_classpath_exception"},
},
},
{
@@ -704,15 +605,10 @@
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"dependentModule.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
+ {"mitLib.meta_lic", "notice|restricted_with_classpath_exception"},
},
},
{
@@ -722,11 +618,10 @@
{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"apacheBin.meta_lic", "apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
- {"apacheBin.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"apacheBin.meta_lic", "notice"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
+ {"mitLib.meta_lic", "notice"},
},
},
{
@@ -736,15 +631,10 @@
{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
},
- expectedResolutions: []res{
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
- {"dependentModule.meta_lic", "dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
- {"dependentModule.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
- {"mitLib.meta_lic", "mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ expectedActions: []tcond{
+ {"dependentModule.meta_lic", "notice|restricted_with_classpath_exception"},
+ {"gplWithClasspathException.meta_lic", "restricted_with_classpath_exception"},
+ {"mitLib.meta_lic", "notice|restricted_with_classpath_exception"},
},
},
}
@@ -756,9 +646,27 @@
t.Errorf("unexpected test data error: got %w, want no error", err)
return
}
- expectedRs := toResolutionSet(lg, tt.expectedResolutions)
- actualRs := ResolveTopDownConditions(lg)
- checkSame(actualRs, expectedRs, t)
+
+ logGraph(lg, t)
+
+ ResolveTopDownConditions(lg)
+ actual := asActionList(lg)
+ sort.Sort(actual)
+ t.Logf("actual: %s", actual.String())
+
+ expected := toActionList(lg, tt.expectedActions)
+ sort.Sort(expected)
+ t.Logf("expected: %s", expected.String())
+
+ if len(actual) != len(expected) {
+ t.Errorf("unexpected number of actions: got %d, want %d", len(actual), len(expected))
+ return
+ }
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != expected[i] {
+ t.Errorf("unexpected action at index %d: got %s, want %s", i, actual[i].String(), expected[i].String())
+ }
+ }
})
}
}
diff --git a/tools/compliance/policy/resolvenotices.go b/tools/compliance/policy/resolvenotices.go
index 80b5e02..99f6d42 100644
--- a/tools/compliance/policy/resolvenotices.go
+++ b/tools/compliance/policy/resolvenotices.go
@@ -15,7 +15,7 @@
package compliance
// ResolveNotices implements the policy for notices.
-func ResolveNotices(lg *LicenseGraph) *ResolutionSet {
- rs := ResolveTopDownConditions(lg)
- return WalkResolutionsForCondition(lg, rs, ImpliesNotice)
+func ResolveNotices(lg *LicenseGraph) ResolutionSet {
+ ResolveTopDownConditions(lg)
+ return WalkResolutionsForCondition(lg, ImpliesNotice)
}
diff --git a/tools/compliance/policy/resolveprivacy.go b/tools/compliance/policy/resolveprivacy.go
index dabbc62..2a7992e 100644
--- a/tools/compliance/policy/resolveprivacy.go
+++ b/tools/compliance/policy/resolveprivacy.go
@@ -15,7 +15,7 @@
package compliance
// ResolveSourcePrivacy implements the policy for source privacy.
-func ResolveSourcePrivacy(lg *LicenseGraph) *ResolutionSet {
- rs := ResolveTopDownConditions(lg)
- return WalkResolutionsForCondition(lg, rs, ImpliesPrivate)
+func ResolveSourcePrivacy(lg *LicenseGraph) ResolutionSet {
+ ResolveTopDownConditions(lg)
+ return WalkResolutionsForCondition(lg, ImpliesPrivate)
}
diff --git a/tools/compliance/policy/resolveprivacy_test.go b/tools/compliance/policy/resolveprivacy_test.go
index 25772bb..2072d22 100644
--- a/tools/compliance/policy/resolveprivacy_test.go
+++ b/tools/compliance/policy/resolveprivacy_test.go
@@ -81,7 +81,7 @@
}
expectedRs := toResolutionSet(lg, tt.expectedResolutions)
actualRs := ResolveSourcePrivacy(lg)
- checkSame(actualRs, expectedRs, t)
+ checkResolves(actualRs, expectedRs, t)
})
}
}
diff --git a/tools/compliance/policy/resolveshare.go b/tools/compliance/policy/resolveshare.go
index 24efd28..9b6a8bb 100644
--- a/tools/compliance/policy/resolveshare.go
+++ b/tools/compliance/policy/resolveshare.go
@@ -15,7 +15,7 @@
package compliance
// ResolveSourceSharing implements the policy for source-sharing.
-func ResolveSourceSharing(lg *LicenseGraph) *ResolutionSet {
- rs := ResolveTopDownConditions(lg)
- return WalkResolutionsForCondition(lg, rs, ImpliesShared)
+func ResolveSourceSharing(lg *LicenseGraph) ResolutionSet {
+ ResolveTopDownConditions(lg)
+ return WalkResolutionsForCondition(lg, ImpliesShared)
}
diff --git a/tools/compliance/policy/resolveshare_test.go b/tools/compliance/policy/resolveshare_test.go
index ad3630d..f73888d 100644
--- a/tools/compliance/policy/resolveshare_test.go
+++ b/tools/compliance/policy/resolveshare_test.go
@@ -291,7 +291,7 @@
}
expectedRs := toResolutionSet(lg, tt.expectedResolutions)
actualRs := ResolveSourceSharing(lg)
- checkSame(actualRs, expectedRs, t)
+ checkResolves(actualRs, expectedRs, t)
})
}
}
diff --git a/tools/compliance/policy/shareprivacyconflicts.go b/tools/compliance/policy/shareprivacyconflicts.go
index dabdff5..279e179 100644
--- a/tools/compliance/policy/shareprivacyconflicts.go
+++ b/tools/compliance/policy/shareprivacyconflicts.go
@@ -28,57 +28,37 @@
// Error returns a string describing the conflict.
func (conflict SourceSharePrivacyConflict) Error() string {
- return fmt.Sprintf("%s %s from %s and must share from %s %s\n",
- conflict.SourceNode.name,
- conflict.PrivacyCondition.name, conflict.PrivacyCondition.origin.name,
- conflict.ShareCondition.name, conflict.ShareCondition.origin.name)
+ return fmt.Sprintf("%s %s and must share from %s condition\n", conflict.SourceNode.name,
+ conflict.PrivacyCondition.Name(), conflict.ShareCondition.Name())
}
// IsEqualTo returns true when `conflict` and `other` describe the same conflict.
func (conflict SourceSharePrivacyConflict) IsEqualTo(other SourceSharePrivacyConflict) bool {
return conflict.SourceNode.name == other.SourceNode.name &&
- conflict.ShareCondition.name == other.ShareCondition.name &&
- conflict.ShareCondition.origin.name == other.ShareCondition.origin.name &&
- conflict.PrivacyCondition.name == other.PrivacyCondition.name &&
- conflict.PrivacyCondition.origin.name == other.PrivacyCondition.origin.name
+ conflict.ShareCondition == other.ShareCondition &&
+ conflict.PrivacyCondition == other.PrivacyCondition
}
// ConflictingSharedPrivateSource lists all of the targets where conflicting conditions to
// share the source and to keep the source private apply to the target.
func ConflictingSharedPrivateSource(lg *LicenseGraph) []SourceSharePrivacyConflict {
- // shareSource is the set of all source-sharing resolutions.
- shareSource := ResolveSourceSharing(lg)
- if shareSource.IsEmpty() {
- return []SourceSharePrivacyConflict{}
- }
- // privateSource is the set of all source privacy resolutions.
- privateSource := ResolveSourcePrivacy(lg)
- if privateSource.IsEmpty() {
- return []SourceSharePrivacyConflict{}
- }
-
+ ResolveTopDownConditions(lg)
// combined is the combination of source-sharing and source privacy.
- combined := JoinResolutionSets(shareSource, privateSource)
+ combined := WalkActionsForCondition(lg, ImpliesShared.Union(ImpliesPrivate))
// size is the size of the result
size := 0
- for _, actsOn := range combined.ActsOn() {
- rl := combined.ResolutionsByActsOn(actsOn)
- size += rl.CountConditionsByName(ImpliesShared) * rl.CountConditionsByName(ImpliesPrivate)
+ for _, cs := range combined {
+ size += cs.Intersection(ImpliesShared).Len() * cs.Intersection(ImpliesPrivate).Len()
}
if size == 0 {
- return []SourceSharePrivacyConflict{}
+ return nil
}
result := make([]SourceSharePrivacyConflict, 0, size)
- for _, actsOn := range combined.ActsOn() {
- rl := combined.ResolutionsByActsOn(actsOn)
- if len(rl) == 0 {
- continue
- }
-
- pconditions := rl.ByName(ImpliesPrivate).AllConditions().AsList()
- ssconditions := rl.ByName(ImpliesShared).AllConditions().AsList()
+ for actsOn, cs := range combined {
+ pconditions := cs.Intersection(ImpliesPrivate).AsList()
+ ssconditions := cs.Intersection(ImpliesShared).AsList()
// report all conflicting condition combinations
for _, p := range pconditions {
diff --git a/tools/compliance/policy/shareprivacyconflicts_test.go b/tools/compliance/policy/shareprivacyconflicts_test.go
index 162c1fe..ad3f3f4 100644
--- a/tools/compliance/policy/shareprivacyconflicts_test.go
+++ b/tools/compliance/policy/shareprivacyconflicts_test.go
@@ -33,19 +33,13 @@
// Less returns true when the `i`th element is lexicographically less than
// the `j`th element.
func (l byConflict) Less(i, j int) bool {
- if l[i].SourceNode.name == l[j].SourceNode.name {
- if l[i].ShareCondition.origin.name == l[j].ShareCondition.origin.name {
- if l[i].ShareCondition.name == l[j].ShareCondition.name {
- if l[i].PrivacyCondition.origin.name == l[j].PrivacyCondition.origin.name {
- return l[i].PrivacyCondition.name < l[j].PrivacyCondition.name
- }
- return l[i].PrivacyCondition.origin.name < l[j].PrivacyCondition.origin.name
- }
- return l[i].ShareCondition.name < l[j].ShareCondition.name
+ if l[i].SourceNode.Name() == l[j].SourceNode.Name() {
+ if l[i].ShareCondition.Name() == l[j].ShareCondition.Name() {
+ return l[i].PrivacyCondition.Name() < l[j].PrivacyCondition.Name()
}
- return l[i].ShareCondition.origin.name < l[j].ShareCondition.origin.name
+ return l[i].ShareCondition.Name() < l[j].ShareCondition.Name()
}
- return l[i].SourceNode.name < l[j].SourceNode.name
+ return l[i].SourceNode.Name() < l[j].SourceNode.Name()
}
func TestConflictingSharedPrivateSource(t *testing.T) {
diff --git a/tools/compliance/policy/shipped.go b/tools/compliance/policy/shipped.go
index 74eb343..75c8399 100644
--- a/tools/compliance/policy/shipped.go
+++ b/tools/compliance/policy/shipped.go
@@ -24,18 +24,18 @@
return shipped
}
- tset := make(map[*TargetNode]bool)
+ tset := make(map[*TargetNode]struct{})
- WalkTopDown(lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
+ WalkTopDown(NoEdgeContext{}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
if _, alreadyWalked := tset[tn]; alreadyWalked {
return false
}
if len(path) > 0 {
- if !edgeIsDerivation(path[len(path)-1]) {
+ if !edgeIsDerivation(path[len(path)-1].edge) {
return false
}
}
- tset[tn] = true
+ tset[tn] = struct{}{}
return true
})
diff --git a/tools/compliance/policy/shipped_test.go b/tools/compliance/policy/shipped_test.go
index 53a8469..718e56f 100644
--- a/tools/compliance/policy/shipped_test.go
+++ b/tools/compliance/policy/shipped_test.go
@@ -17,6 +17,7 @@
import (
"bytes"
"sort"
+ "strings"
"testing"
)
@@ -110,19 +111,31 @@
t.Errorf("unexpected test data error: got %w, want no error", err)
return
}
+ t.Logf("graph:")
+ for _, edge := range lg.Edges() {
+ t.Logf(" %s", edge.String())
+ }
expectedNodes := append([]string{}, tt.expectedNodes...)
- actualNodes := ShippedNodes(lg).Names()
+ nodeset := ShippedNodes(lg)
+ t.Logf("shipped node set: %s", nodeset.String())
+
+ actualNodes := nodeset.Names()
+ t.Logf("shipped nodes: [%s]", strings.Join(actualNodes, ", "))
+
sort.Strings(expectedNodes)
sort.Strings(actualNodes)
+
+ t.Logf("sorted nodes: [%s]", strings.Join(actualNodes, ", "))
+ t.Logf("expected nodes: [%s]", strings.Join(expectedNodes, ", "))
if len(expectedNodes) != len(actualNodes) {
- t.Errorf("unexpected number of shipped nodes: got %v with %d nodes, want %v with %d nodes",
- actualNodes, len(actualNodes), expectedNodes, len(expectedNodes))
+ t.Errorf("unexpected number of shipped nodes: %d nodes, want %d nodes",
+ len(actualNodes), len(expectedNodes))
return
}
for i := 0; i < len(actualNodes); i++ {
if expectedNodes[i] != actualNodes[i] {
- t.Errorf("unexpected node at index %d: got %q in %v, want %q in %v",
- i, actualNodes[i], actualNodes, expectedNodes[i], expectedNodes)
+ t.Errorf("unexpected node at index %d: got %q, want %q",
+ i, actualNodes[i], expectedNodes[i])
}
}
})
diff --git a/tools/compliance/policy/walk.go b/tools/compliance/policy/walk.go
index 8b6737d..3e73088 100644
--- a/tools/compliance/policy/walk.go
+++ b/tools/compliance/policy/walk.go
@@ -14,27 +14,60 @@
package compliance
+// EdgeContextProvider is an interface for injecting edge-specific context
+// into walk paths.
+type EdgeContextProvider interface {
+ // Context returns the context for `edge` when added to `path`.
+ Context(lg *LicenseGraph, path TargetEdgePath, edge *TargetEdge) interface{}
+}
+
+// NoEdgeContext implements EdgeContextProvider for walks that use no context.
+type NoEdgeContext struct{}
+
+// Context returns nil.
+func (ctx NoEdgeContext) Context(lg *LicenseGraph, path TargetEdgePath, edge *TargetEdge) interface{} {
+ return nil
+}
+
+// ApplicableConditionsContext provides the subset of conditions in `universe`
+// that apply to each edge in a path.
+type ApplicableConditionsContext struct {
+ universe LicenseConditionSet
+}
+
+// Context returns the LicenseConditionSet applicable to the edge.
+func (ctx ApplicableConditionsContext) Context(lg *LicenseGraph, path TargetEdgePath, edge *TargetEdge) interface{} {
+ universe := ctx.universe
+ if len(path) > 0 {
+ universe = path[len(path)-1].ctx.(LicenseConditionSet)
+ }
+ return conditionsAttachingAcrossEdge(lg, edge, universe)
+}
+
// VisitNode is called for each root and for each walked dependency node by
// WalkTopDown. When VisitNode returns true, WalkTopDown will proceed to walk
// down the dependences of the node
-type VisitNode func(*LicenseGraph, *TargetNode, TargetEdgePath) bool
+type VisitNode func(lg *LicenseGraph, target *TargetNode, path TargetEdgePath) bool
// WalkTopDown does a top-down walk of `lg` calling `visit` and descending
// into depenencies when `visit` returns true.
-func WalkTopDown(lg *LicenseGraph, visit VisitNode) {
+func WalkTopDown(ctx EdgeContextProvider, lg *LicenseGraph, visit VisitNode) {
path := NewTargetEdgePath(32)
- // must be indexed for fast lookup
- lg.indexForward()
-
- var walk func(f string)
- walk = func(f string) {
- visitChildren := visit(lg, lg.targets[f], *path)
+ var walk func(fnode *TargetNode)
+ walk = func(fnode *TargetNode) {
+ visitChildren := visit(lg, fnode, *path)
if !visitChildren {
return
}
- for _, edge := range lg.index[f] {
- path.Push(TargetEdge{lg, edge})
+ for _, edge := range fnode.edges {
+ var edgeContext interface{}
+ if ctx == nil {
+ edgeContext = nil
+ } else {
+ edgeContext = ctx.Context(lg, *path, edge)
+ }
+ path.Push(edge, edgeContext)
walk(edge.dependency)
path.Pop()
}
@@ -42,35 +75,164 @@
for _, r := range lg.rootFiles {
path.Clear()
- walk(r)
+ walk(lg.targets[r])
}
}
+// resolutionKey identifies results from walking a specific target for a
+// specific set of conditions.
+type resolutionKey struct {
+ target *TargetNode
+ cs LicenseConditionSet
+}
+
// WalkResolutionsForCondition performs a top-down walk of the LicenseGraph
-// resolving all distributed works for condition `names`.
-func WalkResolutionsForCondition(lg *LicenseGraph, rs *ResolutionSet, names ConditionNames) *ResolutionSet {
+// resolving all distributed works for `conditions`.
+func WalkResolutionsForCondition(lg *LicenseGraph, conditions LicenseConditionSet) ResolutionSet {
shipped := ShippedNodes(lg)
// rmap maps 'attachesTo' targets to the `actsOn` targets and applicable conditions
- //
- // rmap is the resulting ResolutionSet
- rmap := make(map[*TargetNode]actionSet)
+ rmap := make(map[resolutionKey]ActionSet)
- WalkTopDown(lg, func(lg *LicenseGraph, tn *TargetNode, _ TargetEdgePath) bool {
- if _, ok := rmap[tn]; ok {
+ // cmap identifies previously walked target/condition pairs.
+ cmap := make(map[resolutionKey]struct{})
+
+ // result accumulates the resolutions to return.
+ result := make(ResolutionSet)
+ WalkTopDown(ApplicableConditionsContext{conditions}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
+ universe := conditions
+ if len(path) > 0 {
+ universe = path[len(path)-1].ctx.(LicenseConditionSet)
+ }
+
+ if universe.IsEmpty() {
+ return false
+ }
+ key := resolutionKey{tn, universe}
+
+ if _, alreadyWalked := cmap[key]; alreadyWalked {
+ pure := true
+ for _, p := range path {
+ target := p.Target()
+ tkey := resolutionKey{target, universe}
+ if _, ok := rmap[tkey]; !ok {
+ rmap[tkey] = make(ActionSet)
+ }
+ // attach prior walk outcome to ancestor
+ for actsOn, cs := range rmap[key] {
+ rmap[tkey][actsOn] = cs
+ }
+ // if prior walk produced results, copy results
+ // to ancestor.
+ if _, ok := result[tn]; ok && pure {
+ if _, ok := result[target]; !ok {
+ result[target] = make(ActionSet)
+ }
+ for actsOn, cs := range result[tn] {
+ result[target][actsOn] = cs
+ }
+ pure = target.IsContainer()
+ }
+ }
+ // if all ancestors are pure aggregates, attach
+ // matching prior walk conditions to self. Prior walk
+ // will not have done so if any ancestor was not an
+ // aggregate.
+ if pure {
+ match := rmap[key][tn].Intersection(universe)
+ if !match.IsEmpty() {
+ if _, ok := result[tn]; !ok {
+ result[tn] = make(ActionSet)
+ }
+ result[tn][tn] = match
+ }
+ }
+ return false
+ }
+ // no need to walk node or dependencies if not shipped
+ if !shipped.Contains(tn) {
+ return false
+ }
+ if _, ok := rmap[key]; !ok {
+ rmap[key] = make(ActionSet)
+ }
+ // add self to walk outcome
+ rmap[key][tn] = tn.resolution
+ cmap[key] = struct{}{}
+ cs := tn.resolution
+ if !cs.IsEmpty() {
+ cs = cs.Intersection(universe)
+ pure := true
+ for _, p := range path {
+ target := p.Target()
+ tkey := resolutionKey{target, universe}
+ if _, ok := rmap[tkey]; !ok {
+ rmap[tkey] = make(ActionSet)
+ }
+ // copy current node's action into ancestor
+ rmap[tkey][tn] = tn.resolution
+ // conditionally put matching conditions into
+ // result
+ if pure && !cs.IsEmpty() {
+ if _, ok := result[target]; !ok {
+ result[target] = make(ActionSet)
+ }
+ result[target][tn] = cs
+ pure = target.IsContainer()
+ }
+ }
+ // if all ancestors are pure aggregates, attach
+ // matching conditions to self.
+ if pure && !cs.IsEmpty() {
+ if _, ok := result[tn]; !ok {
+ result[tn] = make(ActionSet)
+ }
+ result[tn][tn] = cs
+ }
+ }
+ return true
+ })
+
+ return result
+}
+
+// WalkActionsForCondition performs a top-down walk of the LicenseGraph
+// resolving all distributed works for `conditions`.
+func WalkActionsForCondition(lg *LicenseGraph, conditions LicenseConditionSet) ActionSet {
+ shipped := ShippedNodes(lg)
+
+ // cmap identifies previously walked target/condition pairs.
+ cmap := make(map[resolutionKey]struct{})
+
+ // amap maps 'actsOn' targets to the applicable conditions
+ //
+ // amap is the resulting ActionSet
+ amap := make(ActionSet)
+ WalkTopDown(ApplicableConditionsContext{conditions}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool {
+ universe := conditions
+ if len(path) > 0 {
+ universe = path[len(path)-1].ctx.(LicenseConditionSet)
+ }
+ if universe.IsEmpty() {
+ return false
+ }
+ key := resolutionKey{tn, universe}
+ if _, ok := cmap[key]; ok {
return false
}
if !shipped.Contains(tn) {
return false
}
- if as, ok := rs.resolutions[tn]; ok {
- fas := as.byActsOn(shipped).byName(names)
- if !fas.isEmpty() {
- rmap[tn] = fas
+ cs := universe.Intersection(tn.resolution)
+ if !cs.IsEmpty() {
+ if _, ok := amap[tn]; ok {
+ amap[tn] = cs
+ } else {
+ amap[tn] = amap[tn].Union(cs)
}
}
- return tn.IsContainer() // descend into containers
+ return true
})
- return &ResolutionSet{rmap}
+ return amap
}
diff --git a/tools/compliance/policy/walk_test.go b/tools/compliance/policy/walk_test.go
index 07710aa..a2ec6e7 100644
--- a/tools/compliance/policy/walk_test.go
+++ b/tools/compliance/policy/walk_test.go
@@ -22,7 +22,7 @@
func TestWalkResolutionsForCondition(t *testing.T) {
tests := []struct {
name string
- condition ConditionNames
+ condition LicenseConditionSet
roots []string
edges []annotated
expectedResolutions []res
@@ -624,8 +624,617 @@
return
}
expectedRs := toResolutionSet(lg, tt.expectedResolutions)
- actualRs := WalkResolutionsForCondition(lg, ResolveTopDownConditions(lg), tt.condition)
- checkSame(actualRs, expectedRs, t)
+ ResolveTopDownConditions(lg)
+ actualRs := WalkResolutionsForCondition(lg, tt.condition)
+ checkResolves(actualRs, expectedRs, t)
+ })
+ }
+}
+
+func TestWalkActionsForCondition(t *testing.T) {
+ tests := []struct {
+ name string
+ condition LicenseConditionSet
+ roots []string
+ edges []annotated
+ expectedActions []act
+ }{
+ {
+ name: "firstparty",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "notice",
+ condition: ImpliesNotice,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "fponlgplnotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", "restricted"},
+ {"lgplLib.meta_lic", "lgplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "fponlgpldynamicnotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "independentmodulenotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "independentmodulerestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{},
+ },
+ {
+ name: "independentmodulestaticnotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulestaticrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "dependentmodulenotice",
+ condition: ImpliesNotice,
+ roots: []string{"dependentModule.meta_lic"},
+ edges: []annotated{
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"dependentModule.meta_lic", "dependentModule.meta_lic", "notice"},
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "dependentmodulerestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"dependentModule.meta_lic"},
+ edges: []annotated{
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "lgplonfpnotice",
+ condition: ImpliesNotice,
+ roots: []string{"lgplBin.meta_lic"},
+ edges: []annotated{
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "lgplonfprestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"lgplBin.meta_lic"},
+ edges: []annotated{
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "lgplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "lgplonfpdynamicnotice",
+ condition: ImpliesNotice,
+ roots: []string{"lgplBin.meta_lic"},
+ edges: []annotated{
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "lgplonfpdynamicrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"lgplBin.meta_lic"},
+ edges: []annotated{
+ {"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonfpnotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonfprestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplcontainernotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplContainer.meta_lic"},
+ edges: []annotated{
+ {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplcontainerrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplContainer.meta_lic"},
+ edges: []annotated{
+ {"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "gplContainer.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gploncontainernotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheContainer.meta_lic"},
+ edges: []annotated{
+ {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheContainer.meta_lic", "apacheContainer.meta_lic", "notice"},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gploncontainerrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"apacheContainer.meta_lic"},
+ edges: []annotated{
+ {"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonbinnotice",
+ condition: ImpliesNotice,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "apacheLib.meta_lic", "notice"},
+ {"apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonbinrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"apacheBin.meta_lic"},
+ edges: []annotated{
+ {"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
+ {"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonfpdynamicnotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonfpdynamicrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "gplonfpdynamicrestrictedshipped",
+ condition: ImpliesRestricted,
+ roots: []string{"gplBin.meta_lic", "apacheLib.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"apacheLib.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulereversenotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulereverserestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulereverserestrictedshipped",
+ condition: ImpliesRestricted,
+ roots: []string{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulereversestaticnotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "apacheBin.meta_lic", "notice"},
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "independentmodulereversestaticrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ {"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "dependentmodulereversenotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "dependentmodulereverserestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplWithClasspathException.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "dependentmodulereverserestrictedshipped",
+ condition: ImpliesRestricted,
+ roots: []string{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic"},
+ edges: []annotated{
+ {"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
+ },
+ expectedActions: []act{
+ {"gplWithClasspathException.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ {"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "ponrnotice",
+ condition: ImpliesNotice,
+ roots: []string{"proprietary.meta_lic"},
+ edges: []annotated{
+ {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "ponrrestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"proprietary.meta_lic"},
+ edges: []annotated{
+ {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "ponrproprietary",
+ condition: ImpliesProprietary,
+ roots: []string{"proprietary.meta_lic"},
+ edges: []annotated{
+ {"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ },
+ },
+ {
+ name: "ronpnotice",
+ condition: ImpliesNotice,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ {"proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "ronprestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
+ {"proprietary.meta_lic", "gplBin.meta_lic", "restricted"},
+ },
+ },
+ {
+ name: "ronpproprietary",
+ condition: ImpliesProprietary,
+ roots: []string{"gplBin.meta_lic"},
+ edges: []annotated{
+ {"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"proprietary.meta_lic", "proprietary.meta_lic", "proprietary"},
+ },
+ },
+ {
+ name: "noticeonb_e_onotice",
+ condition: ImpliesNotice,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ },
+ },
+ {
+ name: "noticeonb_e_orestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{},
+ },
+ {
+ name: "noticeonb_e_ob_e_o",
+ condition: ImpliesByExceptionOnly,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ },
+ },
+ {
+ name: "b_e_oonnoticenotice",
+ condition: ImpliesNotice,
+ roots: []string{"by_exception.meta_lic"},
+ edges: []annotated{
+ {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "b_e_oonnoticerestricted",
+ condition: ImpliesRestricted,
+ roots: []string{"by_exception.meta_lic"},
+ edges: []annotated{
+ {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{},
+ },
+ {
+ name: "b_e_oonnoticeb_e_o",
+ condition: ImpliesByExceptionOnly,
+ roots: []string{"by_exception.meta_lic"},
+ edges: []annotated{
+ {"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"by_exception.meta_lic", "by_exception.meta_lic", "by_exception_only"},
+ },
+ },
+ {
+ name: "noticeonrecipnotice",
+ condition: ImpliesNotice,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mitBin.meta_lic", "mitBin.meta_lic", "notice"},
+ {"mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ },
+ },
+ {
+ name: "noticeonreciprecip",
+ condition: ImpliesReciprocal,
+ roots: []string{"mitBin.meta_lic"},
+ edges: []annotated{
+ {"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mplLib.meta_lic", "mplLib.meta_lic", "reciprocal"},
+ },
+ },
+ {
+ name: "reciponnoticenotice",
+ condition: ImpliesNotice,
+ roots: []string{"mplBin.meta_lic"},
+ edges: []annotated{
+ {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ {"mitLib.meta_lic", "mitLib.meta_lic", "notice"},
+ },
+ },
+ {
+ name: "reciponnoticerecip",
+ condition: ImpliesReciprocal,
+ roots: []string{"mplBin.meta_lic"},
+ edges: []annotated{
+ {"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
+ },
+ expectedActions: []act{
+ {"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ stderr := &bytes.Buffer{}
+ lg, err := toGraph(stderr, tt.roots, tt.edges)
+ if err != nil {
+ t.Errorf("unexpected test data error: got %w, want no error", err)
+ return
+ }
+ expectedAs := toActionSet(lg, tt.expectedActions)
+ ResolveTopDownConditions(lg)
+ actualAs := WalkActionsForCondition(lg, tt.condition)
+ checkResolvesActions(lg, actualAs, expectedAs, t)
})
}
}
diff --git a/tools/compliance/readgraph.go b/tools/compliance/readgraph.go
index 0b5ebfe..c809a96 100644
--- a/tools/compliance/readgraph.go
+++ b/tools/compliance/readgraph.go
@@ -39,16 +39,13 @@
// target contains the parsed metadata or nil if an error
target *TargetNode
- // edges contains the parsed dependencies
- edges []*dependencyEdge
-
// err is nil unless an error occurs
err error
}
// receiver coordinates the tasks for reading and parsing license metadata files.
type receiver struct {
- // lg accumulates the read metadata and becomes the final resulting LicensGraph.
+ // lg accumulates the read metadata and becomes the final resulting LicenseGraph.
lg *LicenseGraph
// rootFS locates the root of the file system from which to read the files.
@@ -80,7 +77,7 @@
lg := newLicenseGraph()
for _, f := range files {
- if strings.HasSuffix(f, ".meta_lic") {
+ if strings.HasSuffix(f, "meta_lic") {
lg.rootFiles = append(lg.rootFiles, f)
} else {
lg.rootFiles = append(lg.rootFiles, f+".meta_lic")
@@ -138,10 +135,7 @@
// record the parsed metadata (guarded by mutex)
recv.lg.mu.Lock()
- recv.lg.targets[r.file] = r.target
- if len(r.edges) > 0 {
- recv.lg.edges = append(recv.lg.edges, r.edges...)
- }
+ lg.targets[r.target.name] = r.target
recv.lg.mu.Unlock()
} else {
// finished -- nil the results channel
@@ -150,6 +144,21 @@
}
}
+ if lg != nil {
+ esize := 0
+ for _, tn := range lg.targets {
+ esize += len(tn.proto.Deps)
+ }
+ lg.edges = make(TargetEdgeList, 0, esize)
+ for _, tn := range lg.targets {
+ tn.licenseConditions = LicenseConditionSetFromNames(tn, tn.proto.LicenseConditions...)
+ err = addDependencies(lg, tn)
+ if err != nil {
+ return nil, fmt.Errorf("error indexing dependencies for %q: %w", tn.name, err)
+ }
+ tn.proto.Deps = []*license_metadata_proto.AnnotatedDependency{}
+ }
+ }
return lg, err
}
@@ -158,42 +167,48 @@
type targetNode struct {
proto license_metadata_proto.LicenseMetadata
- // name is the path to the metadata file
+ // name is the path to the metadata file.
name string
-}
-// dependencyEdge describes a single edge in the license graph.
-type dependencyEdge struct {
- // target identifies the target node being built and/or installed.
- target string
+ // lg is the license graph the node belongs to.
+ lg *LicenseGraph
- // dependency identifies the target node being depended on.
- //
- // i.e. `dependency` is necessary to build `target`.
- dependency string
+ // edges identifies the dependencies of the target.
+ edges TargetEdgeList
- // annotations are a set of text attributes attached to the edge.
- //
- // Policy prescribes meaning to a limited set of annotations; others
- // are preserved and ignored.
- annotations TargetEdgeAnnotations
+ // licenseConditions identifies the set of license conditions originating at the target node.
+ licenseConditions LicenseConditionSet
+
+ // resolution identifies the set of conditions resolved by acting on the target node.
+ resolution LicenseConditionSet
}
// addDependencies converts the proto AnnotatedDependencies into `edges`
-func addDependencies(edges *[]*dependencyEdge, target string, dependencies []*license_metadata_proto.AnnotatedDependency) error {
- for _, ad := range dependencies {
+func addDependencies(lg *LicenseGraph, tn *TargetNode) error {
+ tn.edges = make(TargetEdgeList, 0,len(tn.proto.Deps))
+ for _, ad := range tn.proto.Deps {
dependency := ad.GetFile()
if len(dependency) == 0 {
return fmt.Errorf("missing dependency name")
}
+ dtn, ok := lg.targets[dependency]
+ if !ok {
+ return fmt.Errorf("unknown dependency name %q", dependency)
+ }
+ if dtn == nil {
+ return fmt.Errorf("nil dependency for name %q", dependency)
+ }
annotations := newEdgeAnnotations()
for _, a := range ad.Annotations {
- if len(a) == 0 {
- continue
+ // look up a common constant annotation string from a small map
+ // instead of creating 1000's of copies of the same 3 strings.
+ if ann, ok := RecognizedAnnotations[a]; ok {
+ annotations.annotations[ann] = struct{}{}
}
- annotations.annotations[a] = true
}
- *edges = append(*edges, &dependencyEdge{target, dependency, annotations})
+ edge := &TargetEdge{tn, dtn, annotations}
+ lg.edges = append(lg.edges, edge)
+ tn.edges = append(tn.edges, edge)
}
return nil
}
@@ -206,50 +221,44 @@
go func() {
f, err := recv.rootFS.Open(file)
if err != nil {
- recv.results <- &result{file, nil, nil, fmt.Errorf("error opening license metadata %q: %w", file, err)}
+ recv.results <- &result{file, nil, fmt.Errorf("error opening license metadata %q: %w", file, err)}
return
}
// read the file
data, err := io.ReadAll(f)
if err != nil {
- recv.results <- &result{file, nil, nil, fmt.Errorf("error reading license metadata %q: %w", file, err)}
+ recv.results <- &result{file, nil, fmt.Errorf("error reading license metadata %q: %w", file, err)}
return
}
+ f.Close()
- tn := &TargetNode{name: file}
+ tn := &TargetNode{lg: recv.lg, name: file}
err = prototext.Unmarshal(data, &tn.proto)
if err != nil {
- recv.results <- &result{file, nil, nil, fmt.Errorf("error license metadata %q: %w", file, err)}
+ recv.results <- &result{file, nil, fmt.Errorf("error license metadata %q: %w", file, err)}
return
}
- edges := []*dependencyEdge{}
- err = addDependencies(&edges, file, tn.proto.Deps)
- if err != nil {
- recv.results <- &result{file, nil, nil, fmt.Errorf("error license metadata dependency %q: %w", file, err)}
- return
- }
- tn.proto.Deps = []*license_metadata_proto.AnnotatedDependency{}
-
// send result for this file and release task before scheduling dependencies,
// but do not signal done to WaitGroup until dependencies are scheduled.
- recv.results <- &result{file, tn, edges, nil}
+ recv.results <- &result{file, tn, nil}
recv.task <- true
// schedule tasks as necessary to read dependencies
- for _, e := range edges {
+ for _, ad := range tn.proto.Deps {
+ dependency := ad.GetFile()
// decide, signal and record whether to schedule task in critical section
recv.lg.mu.Lock()
- _, alreadyScheduled := recv.lg.targets[e.dependency]
+ _, alreadyScheduled := recv.lg.targets[dependency]
if !alreadyScheduled {
- recv.lg.targets[e.dependency] = nil
+ recv.lg.targets[dependency] = nil
}
recv.lg.mu.Unlock()
// schedule task to read dependency file outside critical section
if !alreadyScheduled {
- readFile(recv, e.dependency)
+ readFile(recv, dependency)
}
}
diff --git a/tools/compliance/readgraph_test.go b/tools/compliance/readgraph_test.go
index 6248209..6ff7a6c 100644
--- a/tools/compliance/readgraph_test.go
+++ b/tools/compliance/readgraph_test.go
@@ -108,29 +108,40 @@
}
sort.Sort(byEdge(tt.expectedEdges))
sort.Sort(byEdge(actualEdges))
+ t.Logf("actualEdges:")
+ for _, edge := range actualEdges {
+ t.Logf(" %s", edge.String())
+ }
+ t.Logf("expectedEdges:")
+ for _, edge := range actualEdges {
+ t.Logf(" %s", edge.String())
+ }
if len(tt.expectedEdges) != len(actualEdges) {
- t.Errorf("unexpected number of edges: got %v with %d elements, want %v with %d elements",
- actualEdges, len(actualEdges), tt.expectedEdges, len(tt.expectedEdges))
+ t.Errorf("len(actualEdges): got %d, want %d", len(actualEdges), len(tt.expectedEdges))
} else {
for i := 0; i < len(actualEdges); i++ {
if tt.expectedEdges[i] != actualEdges[i] {
- t.Errorf("unexpected edge at element %d: got %s, want %s", i, actualEdges[i], tt.expectedEdges[i])
+ t.Errorf("actualEdges[%d]: got %s, want %s", i, actualEdges[i], tt.expectedEdges[i])
}
}
}
+
actualTargets := make([]string, 0)
for _, t := range lg.Targets() {
actualTargets = append(actualTargets, t.Name())
}
sort.Strings(tt.expectedTargets)
sort.Strings(actualTargets)
+
+ t.Logf("actualTargets: %v", actualTargets)
+ t.Logf("expectedTargets: %v", tt.expectedTargets)
+
if len(tt.expectedTargets) != len(actualTargets) {
- t.Errorf("unexpected number of targets: got %v with %d elements, want %v with %d elements",
- actualTargets, len(actualTargets), tt.expectedTargets, len(tt.expectedTargets))
+ t.Errorf("len(actualTargets): got %d, want %d", len(actualTargets), len(tt.expectedTargets))
} else {
for i := 0; i < len(actualTargets); i++ {
if tt.expectedTargets[i] != actualTargets[i] {
- t.Errorf("unexpected target at element %d: got %s, want %s", i, actualTargets[i], tt.expectedTargets[i])
+ t.Errorf("actualTargets[%d]: got %s, want %s", i, actualTargets[i], tt.expectedTargets[i])
}
}
}
diff --git a/tools/compliance/resolution.go b/tools/compliance/resolution.go
index 0865ecd..6f15ca3 100644
--- a/tools/compliance/resolution.go
+++ b/tools/compliance/resolution.go
@@ -32,7 +32,7 @@
// resolve the restricted condition originating from the GPL code.
type Resolution struct {
attachesTo, actsOn *TargetNode
- cs *LicenseConditionSet
+ cs LicenseConditionSet
}
// AttachesTo returns the target node the resolution attaches to.
@@ -48,16 +48,16 @@
}
// Resolves returns the set of license condition the resolution satisfies.
-func (r Resolution) Resolves() *LicenseConditionSet {
- return r.cs.Copy()
+func (r Resolution) Resolves() LicenseConditionSet {
+ return r.cs
}
// asString returns a string representation of the resolution.
func (r Resolution) asString() string {
var sb strings.Builder
- cl := r.cs.AsList()
- sort.Sort(cl)
- fmt.Fprintf(&sb, "%s -> %s -> %s", r.attachesTo.name, r.actsOn.name, cl.String())
+ names := r.cs.Names()
+ sort.Strings(names)
+ fmt.Fprintf(&sb, "%s -> %s{%s}", r.attachesTo.name, r.actsOn.name, strings.Join(names, ", "))
return sb.String()
}
@@ -94,67 +94,32 @@
// AllConditions returns the union of all license conditions resolved by any
// element of the list.
-func (rl ResolutionList) AllConditions() *LicenseConditionSet {
- result := newLicenseConditionSet()
+func (rl ResolutionList) AllConditions() LicenseConditionSet {
+ result := NewLicenseConditionSet()
for _, r := range rl {
- result.AddSet(r.cs)
+ result = result.Union(r.cs)
}
return result
}
// ByName returns the sub-list of resolutions resolving conditions matching
// `names`.
-func (rl ResolutionList) ByName(names ConditionNames) ResolutionList {
- result := make(ResolutionList, 0, rl.CountByName(names))
+func (rl ResolutionList) Matching(conditions LicenseConditionSet) ResolutionList {
+ result := make(ResolutionList, 0, rl.CountMatching(conditions))
for _, r := range rl {
- if r.Resolves().HasAnyByName(names) {
- result = append(result, Resolution{r.attachesTo, r.actsOn, r.cs.ByName(names)})
+ if r.Resolves().MatchesAnySet(conditions) {
+ result = append(result, Resolution{r.attachesTo, r.actsOn, r.cs.MatchingAnySet(conditions)})
}
}
return result
}
-// CountByName returns the number of resolutions resolving conditions matching
-// `names`.
-func (rl ResolutionList) CountByName(names ConditionNames) int {
+// CountMatching returns the number of resolutions resolving conditions matching
+// `conditions`.
+func (rl ResolutionList) CountMatching(conditions LicenseConditionSet) int {
c := 0
for _, r := range rl {
- if r.Resolves().HasAnyByName(names) {
- c++
- }
- }
- return c
-}
-
-// CountConditionsByName returns a count of distinct resolution/conditions
-// pairs matching `names`.
-//
-// A single resolution might resolve multiple conditions matching `names`.
-func (rl ResolutionList) CountConditionsByName(names ConditionNames) int {
- c := 0
- for _, r := range rl {
- c += r.Resolves().CountByName(names)
- }
- return c
-}
-
-// ByAttachesTo returns the sub-list of resolutions attached to `attachesTo`.
-func (rl ResolutionList) ByAttachesTo(attachesTo *TargetNode) ResolutionList {
- result := make(ResolutionList, 0, rl.CountByActsOn(attachesTo))
- for _, r := range rl {
- if r.attachesTo == attachesTo {
- result = append(result, r)
- }
- }
- return result
-}
-
-// CountByAttachesTo returns the number of resolutions attached to
-// `attachesTo`.
-func (rl ResolutionList) CountByAttachesTo(attachesTo *TargetNode) int {
- c := 0
- for _, r := range rl {
- if r.attachesTo == attachesTo {
+ if r.Resolves().MatchesAnySet(conditions) {
c++
}
}
@@ -182,27 +147,3 @@
}
return c
}
-
-// ByOrigin returns the sub-list of resolutions resolving license conditions
-// originating at `origin`.
-func (rl ResolutionList) ByOrigin(origin *TargetNode) ResolutionList {
- result := make(ResolutionList, 0, rl.CountByOrigin(origin))
- for _, r := range rl {
- if r.Resolves().HasAnyByOrigin(origin) {
- result = append(result, Resolution{r.attachesTo, r.actsOn, r.cs.ByOrigin(origin)})
- }
- }
- return result
-}
-
-// CountByOrigin returns the number of resolutions resolving license conditions
-// originating at `origin`.
-func (rl ResolutionList) CountByOrigin(origin *TargetNode) int {
- c := 0
- for _, r := range rl {
- if r.Resolves().HasAnyByOrigin(origin) {
- c++
- }
- }
- return c
-}
diff --git a/tools/compliance/resolutionset.go b/tools/compliance/resolutionset.go
index ea49db9..893ef26 100644
--- a/tools/compliance/resolutionset.go
+++ b/tools/compliance/resolutionset.go
@@ -19,34 +19,6 @@
"strings"
)
-// JoinResolutionSets returns a new ResolutionSet combining the resolutions from
-// multiple resolution sets. All sets must be derived from the same license
-// graph.
-//
-// e.g. combine "restricted", "reciprocal", and "proprietary" resolutions.
-func JoinResolutionSets(resolutions ...*ResolutionSet) *ResolutionSet {
- if len(resolutions) < 1 {
- panic(fmt.Errorf("attempt to join 0 resolution sets"))
- }
- rmap := make(map[*TargetNode]actionSet)
- for _, r := range resolutions {
- if len(r.resolutions) < 1 {
- continue
- }
- for attachesTo, as := range r.resolutions {
- if as.isEmpty() {
- continue
- }
- if _, ok := rmap[attachesTo]; !ok {
- rmap[attachesTo] = as.copy()
- continue
- }
- rmap[attachesTo].addSet(as)
- }
- }
- return &ResolutionSet{rmap}
-}
-
// ResolutionSet describes an immutable set of targets and the license
// conditions each target must satisfy or "resolve" in a specific context.
//
@@ -68,8 +40,8 @@
//
// An "unencumbered" condition would originate from the binary, and a "notice"
// condition would originate from the .a library. A ResolutionSet for the
-// context of the Notice policy might apply both conditions to the binary while
-// preserving the origin of each condition. By applying the notice condition to
+// context of the Notice policy might attach both conditions to the binary to
+// act on the origin of each condition. By attaching the notice condition to
// the binary, the ResolutionSet stipulates the policy that the release of the
// unencumbered binary must provide suitable notice for the .a library.
//
@@ -77,228 +49,71 @@
// validating that a suitable notice has been built into the distribution, or
// for reporting what notices need to be given.
//
-// Resolutions for different contexts may be combined in a new ResolutionSet
-// using JoinResolutions(...).
-//
-// See: resolve.go for:
-// * ResolveBottomUpConditions(...)
-// * ResolveTopDownForCondition(...)
-// See also: policy.go for:
-// * ResolveSourceSharing(...)
-// * ResolveSourcePrivacy(...)
-type ResolutionSet struct {
- // resolutions maps names of target with applicable conditions to the set of conditions that apply.
- resolutions map[*TargetNode]actionSet
+// The action is defined by the context. In the above example, the action is
+// providing notice for the module acted on. In another context, the action
+// might be sharing the source-code or preserving the privacy of the module
+// acted on.
+type ResolutionSet map[*TargetNode]ActionSet
+
+// AttachesTo identifies the list of targets triggering action to resolve
+// conditions. (unordered)
+func (rs ResolutionSet) AttachesTo() TargetNodeList {
+ result := make(TargetNodeList, 0, len(rs))
+ for attachesTo := range rs {
+ result = append(result, attachesTo)
+ }
+ return result
}
-// String returns a string representation of the set.
-func (rs *ResolutionSet) String() string {
+
+// AttachesToTarget returns true if the set contains conditions that
+// are `attachedTo`.
+func (rs ResolutionSet) AttachesToTarget(target *TargetNode) bool {
+ _, isPresent := rs[target]
+ return isPresent
+}
+
+
+// Resolutions returns the list of resolutions that `attachedTo`
+// target must resolve. Returns empty list if no conditions apply.
+func (rs ResolutionSet) Resolutions(attachesTo *TargetNode) ResolutionList {
+ as, ok := rs[attachesTo]
+ if !ok {
+ return nil
+ }
+ result := make(ResolutionList, 0, len(as))
+ for actsOn, cs := range as {
+ result = append(result, Resolution{attachesTo, actsOn, cs})
+ }
+ return result
+}
+
+// String returns a human-readable string representation of the set.
+func (rs ResolutionSet) String() string {
var sb strings.Builder
fmt.Fprintf(&sb, "{")
sep := ""
- for attachesTo, as := range rs.resolutions {
- fmt.Fprintf(&sb, "%s%s -> %s", sep, attachesTo.name, as.String())
+ for attachesTo, as := range rs {
+ fmt.Fprintf(&sb, "%s%s -> %s", sep, attachesTo.Name(), as.String())
sep = ", "
}
fmt.Fprintf(&sb, "}")
return sb.String()
}
-// AttachesTo identifies the list of targets triggering action to resolve
-// conditions. (unordered)
-func (rs *ResolutionSet) AttachesTo() TargetNodeList {
- targets := make(TargetNodeList, 0, len(rs.resolutions))
- for attachesTo := range rs.resolutions {
- targets = append(targets, attachesTo)
- }
- return targets
-}
+// ActionSet identifies a set of targets to act on and the license conditions
+// the action will resolve.
+type ActionSet map[*TargetNode]LicenseConditionSet
-// ActsOn identifies the list of targets to act on (share, give notice etc.)
-// to resolve conditions. (unordered)
-func (rs *ResolutionSet) ActsOn() TargetNodeList {
- tset := make(map[*TargetNode]bool)
- for _, as := range rs.resolutions {
- for actsOn := range as {
- tset[actsOn] = true
- }
- }
- targets := make(TargetNodeList, 0, len(tset))
- for target := range tset {
- targets = append(targets, target)
- }
- return targets
-}
-
-// Origins identifies the list of targets originating conditions to resolve.
-// (unordered)
-func (rs *ResolutionSet) Origins() TargetNodeList {
- tset := make(map[*TargetNode]bool)
- for _, as := range rs.resolutions {
- for _, cs := range as {
- for _, origins := range cs.conditions {
- for origin := range origins {
- tset[origin] = true
- }
- }
- }
- }
- targets := make(TargetNodeList, 0, len(tset))
- for target := range tset {
- targets = append(targets, target)
- }
- return targets
-}
-
-// Resolutions returns the list of resolutions that `attachedTo`
-// target must resolve. Returns empty list if no conditions apply.
-//
-// Panics if `attachedTo` does not appear in the set.
-func (rs *ResolutionSet) Resolutions(attachedTo *TargetNode) ResolutionList {
- as, ok := rs.resolutions[attachedTo]
- if !ok {
- return ResolutionList{}
- }
- result := make(ResolutionList, 0, len(as))
+// String returns a human-readable string representation of the set.
+func (as ActionSet) String() string {
+ var sb strings.Builder
+ fmt.Fprintf(&sb, "{")
+ sep := ""
for actsOn, cs := range as {
- result = append(result, Resolution{attachedTo, actsOn, cs.Copy()})
+ fmt.Fprintf(&sb, "%s%s%s", sep, actsOn.Name(), cs.String())
+ sep = ", "
}
- return result
-}
-
-// ResolutionsByActsOn returns the list of resolutions that must `actOn` to
-// resolvee. Returns empty list if no conditions apply.
-//
-// Panics if `actOn` does not appear in the set.
-func (rs *ResolutionSet) ResolutionsByActsOn(actOn *TargetNode) ResolutionList {
- c := 0
- for _, as := range rs.resolutions {
- if _, ok := as[actOn]; ok {
- c++
- }
- }
- result := make(ResolutionList, 0, c)
- for attachedTo, as := range rs.resolutions {
- if cs, ok := as[actOn]; ok {
- result = append(result, Resolution{attachedTo, actOn, cs.Copy()})
- }
- }
- return result
-}
-
-// AttachesToByOrigin identifies the list of targets requiring action to
-// resolve conditions originating at `origin`. (unordered)
-func (rs *ResolutionSet) AttachesToByOrigin(origin *TargetNode) TargetNodeList {
- tset := make(map[*TargetNode]bool)
- for attachesTo, as := range rs.resolutions {
- for _, cs := range as {
- if cs.HasAnyByOrigin(origin) {
- tset[attachesTo] = true
- break
- }
- }
- }
- targets := make(TargetNodeList, 0, len(tset))
- for target := range tset {
- targets = append(targets, target)
- }
- return targets
-}
-
-// AttachesToTarget returns true if the set contains conditions that
-// are `attachedTo`.
-func (rs *ResolutionSet) AttachesToTarget(attachedTo *TargetNode) bool {
- _, isPresent := rs.resolutions[attachedTo]
- return isPresent
-}
-
-// AnyByNameAttachToTarget returns true if the set contains conditions matching
-// `names` that attach to `attachedTo`.
-func (rs *ResolutionSet) AnyByNameAttachToTarget(attachedTo *TargetNode, names ...ConditionNames) bool {
- as, isPresent := rs.resolutions[attachedTo]
- if !isPresent {
- return false
- }
- for _, cs := range as {
- for _, cn := range names {
- for _, name := range cn {
- _, isPresent = cs.conditions[name]
- if isPresent {
- return true
- }
- }
- }
- }
- return false
-}
-
-// AllByNameAttachTo returns true if the set contains at least one condition
-// matching each element of `names` for `attachedTo`.
-func (rs *ResolutionSet) AllByNameAttachToTarget(attachedTo *TargetNode, names ...ConditionNames) bool {
- as, isPresent := rs.resolutions[attachedTo]
- if !isPresent {
- return false
- }
- for _, cn := range names {
- found := false
- asloop:
- for _, cs := range as {
- for _, name := range cn {
- _, isPresent = cs.conditions[name]
- if isPresent {
- found = true
- break asloop
- }
- }
- }
- if !found {
- return false
- }
- }
- return true
-}
-
-// IsEmpty returns true if the set contains no conditions to resolve.
-func (rs *ResolutionSet) IsEmpty() bool {
- for _, as := range rs.resolutions {
- if !as.isEmpty() {
- return false
- }
- }
- return true
-}
-
-// compliance-only ResolutionSet methods
-
-// newResolutionSet constructs a new, empty instance of resolutionSetImp for graph `lg`.
-func newResolutionSet() *ResolutionSet {
- return &ResolutionSet{make(map[*TargetNode]actionSet)}
-}
-
-// addConditions attaches all of the license conditions in `as` to `attachTo` to act on the originating node if not already applied.
-func (rs *ResolutionSet) addConditions(attachTo *TargetNode, as actionSet) {
- _, ok := rs.resolutions[attachTo]
- if !ok {
- rs.resolutions[attachTo] = as.copy()
- return
- }
- rs.resolutions[attachTo].addSet(as)
-}
-
-// add attaches all of the license conditions in `as` to `attachTo` to act on `attachTo` if not already applied.
-func (rs *ResolutionSet) addSelf(attachTo *TargetNode, as actionSet) {
- for _, cs := range as {
- if cs.IsEmpty() {
- return
- }
- _, ok := rs.resolutions[attachTo]
- if !ok {
- rs.resolutions[attachTo] = make(actionSet)
- }
- _, ok = rs.resolutions[attachTo][attachTo]
- if !ok {
- rs.resolutions[attachTo][attachTo] = newLicenseConditionSet()
- }
- rs.resolutions[attachTo][attachTo].AddSet(cs)
- }
+ fmt.Fprintf(&sb, "}")
+ return sb.String()
}
diff --git a/tools/compliance/resolutionset_test.go b/tools/compliance/resolutionset_test.go
index e50e823..89cdfeb 100644
--- a/tools/compliance/resolutionset_test.go
+++ b/tools/compliance/resolutionset_test.go
@@ -77,113 +77,46 @@
proprietary = []res{}
)
-func TestResolutionSet_JoinResolutionSets(t *testing.T) {
- lg := newLicenseGraph()
-
- rsNotice := toResolutionSet(lg, notice)
- rsShare := toResolutionSet(lg, share)
- rsExpected := toResolutionSet(lg, append(notice, share...))
-
- rsActual := JoinResolutionSets(rsNotice, rsShare)
- checkSame(rsActual, rsExpected, t)
-}
-
-func TestResolutionSet_JoinResolutionsEmpty(t *testing.T) {
- lg := newLicenseGraph()
-
- rsShare := toResolutionSet(lg, share)
- rsProprietary := toResolutionSet(lg, proprietary)
- rsExpected := toResolutionSet(lg, append(share, proprietary...))
-
- rsActual := JoinResolutionSets(rsShare, rsProprietary)
- checkSame(rsActual, rsExpected, t)
-}
-
-func TestResolutionSet_Origins(t *testing.T) {
+func TestResolutionSet_AttachesTo(t *testing.T) {
lg := newLicenseGraph()
rsShare := toResolutionSet(lg, share)
- origins := make([]string, 0)
- for _, target := range rsShare.Origins() {
- origins = append(origins, target.Name())
- }
- sort.Strings(origins)
- if len(origins) != 2 {
- t.Errorf("unexpected number of origins: got %v with %d elements, want [\"bin1\", \"bin2\"] with 2 elements", origins, len(origins))
- }
- if origins[0] != "bin1" {
- t.Errorf("unexpected origin at element 0: got %s, want \"bin1\"", origins[0])
- }
- if origins[1] != "bin2" {
- t.Errorf("unexpected origin at element 0: got %s, want \"bin2\"", origins[0])
- }
-}
+ t.Logf("checking resolution set %s", rsShare.String())
-func TestResolutionSet_AttachedToTarget(t *testing.T) {
- lg := newLicenseGraph()
+ actual := rsShare.AttachesTo().Names()
+ sort.Strings(actual)
- rsShare := toResolutionSet(lg, share)
+ expected := []string{"bin1", "bin2", "image"}
- if rsShare.AttachesToTarget(newTestNode(lg, "binc")) {
- t.Errorf("unexpected AttachedToTarget(\"binc\"): got true, want false")
- }
- if !rsShare.AttachesToTarget(newTestNode(lg, "image")) {
- t.Errorf("unexpected AttachedToTarget(\"image\"): got false want true")
- }
-}
+ t.Logf("actual rsShare: %v", actual)
+ t.Logf("expected rsShare: %v", expected)
-func TestResolutionSet_AnyByNameAttachToTarget(t *testing.T) {
- lg := newLicenseGraph()
+ if len(actual) != len(expected) {
+ t.Errorf("rsShare: wrong number of targets: got %d, want %d", len(actual), len(expected))
+ return
+ }
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != expected[i] {
+ t.Errorf("rsShare: unexpected target at index %d: got %s, want %s", i, actual[i], expected[i])
+ }
+ }
- rs := toResolutionSet(lg, bottomUp)
+ rsPrivate := toResolutionSet(lg, proprietary)
+ actual = rsPrivate.AttachesTo().Names()
+ expected = []string{}
- pandp := ConditionNames{"permissive", "proprietary"}
- pandn := ConditionNames{"permissive", "notice"}
- p := ConditionNames{"proprietary"}
- r := ConditionNames{"restricted"}
+ t.Logf("actual rsPrivate: %v", actual)
+ t.Logf("expected rsPrivate: %v", expected)
- if rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), pandp, p) {
- t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"proprietary\", \"permissive\"): want false, got true")
+ if len(actual) != len(expected) {
+ t.Errorf("rsPrivate: wrong number of targets: got %d, want %d", len(actual), len(expected))
+ return
}
- if !rs.AnyByNameAttachToTarget(newTestNode(lg, "binc"), p) {
- t.Errorf("unexpected AnyByNameAttachToTarget(\"binc\", \"proprietary\"): want true, got false")
- }
- if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), pandn) {
- t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"permissive\", \"notice\"): want true, got false")
- }
- if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), r, pandn) {
- t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"restricted\", \"notice\"): want true, got false")
- }
- if !rs.AnyByNameAttachToTarget(newTestNode(lg, "image"), r, p) {
- t.Errorf("unexpected AnyByNameAttachToTarget(\"image\", \"restricted\", \"proprietary\"): want true, got false")
- }
-}
-
-func TestResolutionSet_AllByNameAttachToTarget(t *testing.T) {
- lg := newLicenseGraph()
-
- rs := toResolutionSet(lg, bottomUp)
-
- pandp := ConditionNames{"permissive", "proprietary"}
- pandn := ConditionNames{"permissive", "notice"}
- p := ConditionNames{"proprietary"}
- r := ConditionNames{"restricted"}
-
- if rs.AllByNameAttachToTarget(newTestNode(lg, "image"), pandp, p) {
- t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"proprietary\", \"permissive\"): want false, got true")
- }
- if !rs.AllByNameAttachToTarget(newTestNode(lg, "binc"), p) {
- t.Errorf("unexpected AllByNameAttachToTarget(\"binc\", \"proprietary\"): want true, got false")
- }
- if !rs.AllByNameAttachToTarget(newTestNode(lg, "image"), pandn) {
- t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"notice\"): want true, got false")
- }
- if !rs.AllByNameAttachToTarget(newTestNode(lg, "image"), r, pandn) {
- t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"restricted\", \"notice\"): want true, got false")
- }
- if rs.AllByNameAttachToTarget(newTestNode(lg, "image"), r, p) {
- t.Errorf("unexpected AllByNameAttachToTarget(\"image\", \"restricted\", \"proprietary\"): want false, got true")
+ for i := 0; i < len(actual); i++ {
+ if actual[i] != expected[i] {
+ t.Errorf("rsPrivate: unexpected target at index %d: got %s, want %s", i, actual[i], expected[i])
+ }
}
}
@@ -192,10 +125,12 @@
rsShare := toResolutionSet(lg, share)
+ t.Logf("checking resolution set %s", rsShare.String())
+
if rsShare.AttachesToTarget(newTestNode(lg, "binc")) {
- t.Errorf("unexpected hasTarget(\"binc\"): got true, want false")
+ t.Errorf("actual.AttachesToTarget(\"binc\"): got true, want false")
}
if !rsShare.AttachesToTarget(newTestNode(lg, "image")) {
- t.Errorf("unexpected AttachesToTarget(\"image\"): got false want true")
+ t.Errorf("actual.AttachesToTarget(\"image\"): got false want true")
}
}
diff --git a/tools/compliance/test_util.go b/tools/compliance/test_util.go
index a183b90..8f4088a 100644
--- a/tools/compliance/test_util.go
+++ b/tools/compliance/test_util.go
@@ -86,7 +86,6 @@
license_kinds: "legacy_by_exception_only"
license_conditions: "by_exception_only"
`
-
)
var (
@@ -111,23 +110,39 @@
}
)
-// toConditionList converts a test data map of condition name to origin names into a ConditionList.
-func toConditionList(lg *LicenseGraph, conditions map[string][]string) ConditionList {
- cl := make(ConditionList, 0)
- for name, origins := range conditions {
- for _, origin := range origins {
- cl = append(cl, LicenseCondition{name, newTestNode(lg, origin)})
- }
- }
- return cl
-}
-
// newTestNode constructs a test node in the license graph.
func newTestNode(lg *LicenseGraph, targetName string) *TargetNode {
- if _, ok := lg.targets[targetName]; !ok {
- lg.targets[targetName] = &TargetNode{name: targetName}
+ if tn, alreadyExists := lg.targets[targetName]; alreadyExists {
+ return tn
}
- return lg.targets[targetName]
+ tn := &TargetNode{name: targetName}
+ lg.targets[targetName] = tn
+ return tn
+}
+
+// newTestCondition constructs a test license condition in the license graph.
+func newTestCondition(lg *LicenseGraph, targetName string, conditionName string) LicenseCondition {
+ tn := newTestNode(lg, targetName)
+ cl := LicenseConditionSetFromNames(tn, conditionName).AsList()
+ if len(cl) == 0 {
+ panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
+ } else if len(cl) != 1 {
+ panic(fmt.Errorf("unexpected multiple conditions from condition name: %q: got %d, want 1", conditionName, len(cl)))
+ }
+ lc := cl[0]
+ tn.licenseConditions = tn.licenseConditions.Plus(lc)
+ return lc
+}
+
+// newTestConditionSet constructs a test license condition set in the license graph.
+func newTestConditionSet(lg *LicenseGraph, targetName string, conditionName []string) LicenseConditionSet {
+ tn := newTestNode(lg, targetName)
+ cs := LicenseConditionSetFromNames(tn, conditionName...)
+ if cs.IsEmpty() {
+ panic(fmt.Errorf("attempt to create unrecognized condition: %q", conditionName))
+ }
+ tn.licenseConditions = tn.licenseConditions.Union(cs)
+ return cs
}
// testFS implements a test file system (fs.FS) simulated by a map from filename to []byte content.
@@ -270,6 +285,21 @@
return ReadLicenseGraph(&fs, stderr, roots)
}
+// logGraph outputs a representation of the graph to a test log.
+func logGraph(lg *LicenseGraph, t *testing.T) {
+ t.Logf("license graph:")
+ t.Logf(" targets:")
+ for _, target := range lg.Targets() {
+ t.Logf(" %s%s in package %q", target.Name(), target.LicenseConditions().String(), target.PackageName())
+ }
+ t.Logf(" /targets")
+ t.Logf(" edges:")
+ for _, edge := range lg.Edges() {
+ t.Logf(" %s", edge.String())
+ }
+ t.Logf(" /edges")
+ t.Logf("/license graph")
+}
// byAnnotatedEdge orders edges by target then dep name then annotations.
type byAnnotatedEdge []annotated
@@ -296,33 +326,137 @@
return l[i].target < l[j].target
}
+// act describes test data resolution actions to define test action sets.
+type act struct {
+ actsOn, origin, condition string
+}
+
+// String returns a human-readable string representing the test action.
+func (a act) String() string {
+ return fmt.Sprintf("%s{%s:%s}", a.actsOn, a.origin, a.condition)
+}
+
+// toActionSet converts a list of act test data into a test action set.
+func toActionSet(lg *LicenseGraph, data []act) ActionSet {
+ as := make(ActionSet)
+ for _, a := range data {
+ actsOn := newTestNode(lg, a.actsOn)
+ cs := newTestConditionSet(lg, a.origin, strings.Split(a.condition, "|"))
+ as[actsOn] = cs
+ }
+ return as
+}
+
// res describes test data resolutions to define test resolution sets.
type res struct {
attachesTo, actsOn, origin, condition string
}
// toResolutionSet converts a list of res test data into a test resolution set.
-func toResolutionSet(lg *LicenseGraph, data []res) *ResolutionSet {
- rmap := make(map[*TargetNode]actionSet)
+func toResolutionSet(lg *LicenseGraph, data []res) ResolutionSet {
+ rmap := make(ResolutionSet)
for _, r := range data {
attachesTo := newTestNode(lg, r.attachesTo)
actsOn := newTestNode(lg, r.actsOn)
- origin := newTestNode(lg, r.origin)
if _, ok := rmap[attachesTo]; !ok {
- rmap[attachesTo] = make(actionSet)
+ rmap[attachesTo] = make(ActionSet)
}
- if _, ok := rmap[attachesTo][actsOn]; !ok {
- rmap[attachesTo][actsOn] = newLicenseConditionSet()
- }
- rmap[attachesTo][actsOn].add(origin, r.condition)
+ cs := newTestConditionSet(lg, r.origin, strings.Split(r.condition, ":"))
+ rmap[attachesTo][actsOn] |= cs
}
- return &ResolutionSet{rmap}
+ return rmap
}
+// tcond associates a target name with '|' separated string conditions.
+type tcond struct {
+ target, conditions string
+}
+
+// action represents a single element of an ActionSet for testing.
+type action struct {
+ target *TargetNode
+ cs LicenseConditionSet
+}
+
+// String returns a human-readable string representation of the action.
+func (a action) String() string {
+ return fmt.Sprintf("%s%s", a.target.Name(), a.cs.String())
+}
+
+// actionList represents an array of actions and a total order defined by
+// target name followed by license condition set.
+type actionList []action
+
+// String returns a human-readable string representation of the list.
+func (l actionList) String() string {
+ var sb strings.Builder
+ fmt.Fprintf(&sb, "[")
+ sep := ""
+ for _, a := range l {
+ fmt.Fprintf(&sb, "%s%s", sep, a.String())
+ sep = ", "
+ }
+ fmt.Fprintf(&sb, "]")
+ return sb.String()
+}
+
+// Len returns the count of elements in the slice.
+func (l actionList) Len() int { return len(l) }
+
+// Swap rearranges 2 elements of the slice so that each occupies the other's
+// former position.
+func (l actionList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+
+// Less returns true when the `i`th element is lexicographically less than
+// the `j`th element.
+func (l actionList) Less(i, j int) bool {
+ if l[i].target == l[j].target {
+ return l[i].cs < l[j].cs
+ }
+ return l[i].target.Name() < l[j].target.Name()
+}
+
+// asActionList represents the resolved license conditions in a license graph
+// as an actionList for comparison in a test.
+func asActionList(lg *LicenseGraph) actionList {
+ result := make(actionList, 0, len(lg.targets))
+ for _, target := range lg.targets {
+ cs := target.resolution
+ if cs.IsEmpty() {
+ continue
+ }
+ result = append(result, action{target, cs})
+ }
+ return result
+}
+
+// toActionList converts an array of tcond into an actionList for comparison
+// in a test.
+func toActionList(lg *LicenseGraph, actions []tcond) actionList {
+ result := make(actionList, 0, len(actions))
+ for _, actn := range actions {
+ target := newTestNode(lg, actn.target)
+ cs := NewLicenseConditionSet()
+ for _, name := range strings.Split(actn.conditions, "|") {
+ lc, ok := RecognizedConditionNames[name]
+ if !ok {
+ panic(fmt.Errorf("Unrecognized test condition name: %q", name))
+ }
+ cs = cs.Plus(lc)
+ }
+ result = append(result, action{target, cs})
+ }
+ return result
+}
+
+// confl defines test data for a SourceSharePrivacyConflict as a target name,
+// source condition name, privacy condition name triple.
type confl struct {
sourceNode, share, privacy string
}
+// toConflictList converts confl test data into an array of
+// SourceSharePrivacyConflict for comparison in a test.
func toConflictList(lg *LicenseGraph, data []confl) []SourceSharePrivacyConflict {
result := make([]SourceSharePrivacyConflict, 0, len(data))
for _, c := range data {
@@ -334,30 +468,40 @@
cprivacy := fields[1]
result = append(result, SourceSharePrivacyConflict{
newTestNode(lg, c.sourceNode),
- LicenseCondition{cshare, newTestNode(lg, oshare)},
- LicenseCondition{cprivacy, newTestNode(lg, oprivacy)},
+ newTestCondition(lg, oshare, cshare),
+ newTestCondition(lg, oprivacy, cprivacy),
})
}
return result
}
// checkSameActions compares an actual action set to an expected action set for a test.
-func checkSameActions(lg *LicenseGraph, asActual, asExpected actionSet, t *testing.T) {
- rsActual := ResolutionSet{make(map[*TargetNode]actionSet)}
- rsExpected := ResolutionSet{make(map[*TargetNode]actionSet)}
+func checkSameActions(lg *LicenseGraph, asActual, asExpected ActionSet, t *testing.T) {
+ rsActual := make(ResolutionSet)
+ rsExpected := make(ResolutionSet)
testNode := newTestNode(lg, "test")
- rsActual.resolutions[testNode] = asActual
- rsExpected.resolutions[testNode] = asExpected
- checkSame(&rsActual, &rsExpected, t)
+ rsActual[testNode] = asActual
+ rsExpected[testNode] = asExpected
+ checkSame(rsActual, rsExpected, t)
}
// checkSame compares an actual resolution set to an expected resolution set for a test.
-func checkSame(rsActual, rsExpected *ResolutionSet, t *testing.T) {
+func checkSame(rsActual, rsExpected ResolutionSet, t *testing.T) {
+ t.Logf("actual resolution set: %s", rsActual.String())
+ t.Logf("expected resolution set: %s", rsExpected.String())
+
+ actualTargets := rsActual.AttachesTo()
+ sort.Sort(actualTargets)
+
expectedTargets := rsExpected.AttachesTo()
sort.Sort(expectedTargets)
+
+ t.Logf("actual targets: %s", actualTargets.String())
+ t.Logf("expected targets: %s", expectedTargets.String())
+
for _, target := range expectedTargets {
if !rsActual.AttachesToTarget(target) {
- t.Errorf("unexpected missing target: got AttachesToTarget(%q) is false in %s, want true in %s", target.name, rsActual, rsExpected)
+ t.Errorf("unexpected missing target: got AttachesToTarget(%q) is false, want true", target.name)
continue
}
expectedRl := rsExpected.Resolutions(target)
@@ -365,8 +509,8 @@
actualRl := rsActual.Resolutions(target)
sort.Sort(actualRl)
if len(expectedRl) != len(actualRl) {
- t.Errorf("unexpected number of resolutions attach to %q: got %s with %d elements, want %s with %d elements",
- target.name, actualRl, len(actualRl), expectedRl, len(expectedRl))
+ t.Errorf("unexpected number of resolutions attach to %q: %d elements, %d elements",
+ target.name, len(actualRl), len(expectedRl))
continue
}
for i := 0; i < len(expectedRl); i++ {
@@ -375,34 +519,86 @@
target.name, i, actualRl[i].asString(), expectedRl[i].asString())
continue
}
- expectedConditions := expectedRl[i].Resolves().AsList()
- actualConditions := actualRl[i].Resolves().AsList()
- sort.Sort(expectedConditions)
- sort.Sort(actualConditions)
- if len(expectedConditions) != len(actualConditions) {
- t.Errorf("unexpected number of conditions apply to %q acting on %q: got %s with %d elements, want %s with %d elements",
+ expectedConditions := expectedRl[i].Resolves()
+ actualConditions := actualRl[i].Resolves()
+ if expectedConditions != actualConditions {
+ t.Errorf("unexpected conditions apply to %q acting on %q: got %04x with names %s, want %04x with names %s",
target.name, expectedRl[i].actsOn.name,
- actualConditions, len(actualConditions),
- expectedConditions, len(expectedConditions))
+ actualConditions, actualConditions.Names(),
+ expectedConditions, expectedConditions.Names())
continue
}
- for j := 0; j < len(expectedConditions); j++ {
- if expectedConditions[j] != actualConditions[j] {
- t.Errorf("unexpected condition attached to %q acting on %q at index %d: got %s at index %d in %s, want %s in %s",
- target.name, expectedRl[i].actsOn.name, i,
- actualConditions[j].asString(":"), j, actualConditions,
- expectedConditions[j].asString(":"), expectedConditions)
- }
- }
}
}
+ for _, target := range actualTargets {
+ if !rsExpected.AttachesToTarget(target) {
+ t.Errorf("unexpected extra target: got expected.AttachesTo(%q) is false, want true", target.name)
+ }
+ }
+}
+
+// checkResolvesActions compares an actual action set to an expected action set for a test verifying the actual set
+// resolves all of the expected conditions.
+func checkResolvesActions(lg *LicenseGraph, asActual, asExpected ActionSet, t *testing.T) {
+ rsActual := make(ResolutionSet)
+ rsExpected := make(ResolutionSet)
+ testNode := newTestNode(lg, "test")
+ rsActual[testNode] = asActual
+ rsExpected[testNode] = asExpected
+ checkResolves(rsActual, rsExpected, t)
+}
+
+// checkResolves compares an actual resolution set to an expected resolution set for a test verifying the actual set
+// resolves all of the expected conditions.
+func checkResolves(rsActual, rsExpected ResolutionSet, t *testing.T) {
+ t.Logf("actual resolution set: %s", rsActual.String())
+ t.Logf("expected resolution set: %s", rsExpected.String())
+
actualTargets := rsActual.AttachesTo()
sort.Sort(actualTargets)
- for i, target := range actualTargets {
+
+ expectedTargets := rsExpected.AttachesTo()
+ sort.Sort(expectedTargets)
+
+ t.Logf("actual targets: %s", actualTargets.String())
+ t.Logf("expected targets: %s", expectedTargets.String())
+
+ for _, target := range expectedTargets {
+ if !rsActual.AttachesToTarget(target) {
+ t.Errorf("unexpected missing target: got AttachesToTarget(%q) is false, want true", target.name)
+ continue
+ }
+ expectedRl := rsExpected.Resolutions(target)
+ sort.Sort(expectedRl)
+ actualRl := rsActual.Resolutions(target)
+ sort.Sort(actualRl)
+ if len(expectedRl) != len(actualRl) {
+ t.Errorf("unexpected number of resolutions attach to %q: %d elements, %d elements",
+ target.name, len(actualRl), len(expectedRl))
+ continue
+ }
+ for i := 0; i < len(expectedRl); i++ {
+ if expectedRl[i].attachesTo.name != actualRl[i].attachesTo.name || expectedRl[i].actsOn.name != actualRl[i].actsOn.name {
+ t.Errorf("unexpected resolution attaches to %q at index %d: got %s, want %s",
+ target.name, i, actualRl[i].asString(), expectedRl[i].asString())
+ continue
+ }
+ expectedConditions := expectedRl[i].Resolves()
+ actualConditions := actualRl[i].Resolves()
+ if expectedConditions != (expectedConditions & actualConditions) {
+ t.Errorf("expected conditions missing from %q acting on %q: got %04x with names %s, want %04x with names %s",
+ target.name, expectedRl[i].actsOn.name,
+ actualConditions, actualConditions.Names(),
+ expectedConditions, expectedConditions.Names())
+ continue
+ }
+ }
+
+ }
+ for _, target := range actualTargets {
if !rsExpected.AttachesToTarget(target) {
- t.Errorf("unexpected target: got %q element %d in AttachesTo() %s with %d elements in %s, want %s with %d elements in %s",
- target.name, i, actualTargets, len(actualTargets), rsActual, expectedTargets, len(expectedTargets), rsExpected)
+ t.Errorf("unexpected extra target: got expected.AttachesTo(%q) is false, want true", target.name)
}
}
}
diff --git a/tools/droiddoc/Android.bp b/tools/droiddoc/Android.bp
index efd30c1..71d4939 100644
--- a/tools/droiddoc/Android.bp
+++ b/tools/droiddoc/Android.bp
@@ -14,15 +14,22 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- // SPDX-license-identifier-BSD
- // SPDX-license-identifier-CC-BY
- // SPDX-license-identifier-GPL
- // SPDX-license-identifier-MIT
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ "build_make_tools_droiddoc_license",
+ ],
+}
+
+license {
+ name: "build_make_tools_droiddoc_license",
+ package_name: "Android Droiddoc Templates",
+ license_kinds: [
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-CC-BY-2.5",
+ "SPDX-license-identifier-GPL-3.0",
+ "SPDX-license-identifier-MIT",
+ ],
+ license_text: ["LICENSE"],
}
droiddoc_exported_dir {
diff --git a/tools/droiddoc/LICENSE b/tools/droiddoc/LICENSE
new file mode 100644
index 0000000..b591dde
--- /dev/null
+++ b/tools/droiddoc/LICENSE
@@ -0,0 +1,1095 @@
+-----------------------------------------------------
+microtemplate.js
+
+// Simple JavaScript Templating
+// John Resig - http://ejohn.org/ - MIT Licensed
+
+-----------------------------------------------------
+jquery-history.js
+
+/**
+ * jQuery history event v0.1
+ * Copyright (c) 2008 Tom Rodenberg <tarodenberg gmail com>
+ * Licensed under the GPL (http://www.gnu.org/licenses/gpl.html) license.
+ */
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+-----------------------------------------------------
+yui-3.3.0-reset-min.css
+
+/*
+Copyright (c) 2010, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 3.3.0
+build: 3167
+*/
+
+
+Software License Agreement (BSD License)
+Copyright (c) 2010, Yahoo! Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ Neither the name of Yahoo! Inc. nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Sources of Intellectual Property Included in the YUI Library
+
+YUI is issued by Yahoo! under the BSD license above. Below is a list of certain
+publicly available software that is the source of intellectual property in YUI,
+along with the licensing terms that pertain to thosesources of IP. This list is
+for informational purposes only and is not intended to represent an exhaustive
+list of third party contributions to the YUI.
+
+ Douglas Crockford's JSON parsing and stringifying methods: In the JSON
+ Utility, Douglas Crockford's JSON parsing and stringifying methods are
+ adapted from work published at JSON.org. The adapted work is in the public
+ domain.
+
+ Robert Penner's animation-easing algorithms: In the Animation Utility, YUI
+ makes use of Robert Penner's algorithms for easing.
+
+ Geoff Stearns's SWFObject: In the Charts Control and the Uploader versions
+ through 2.7.0, YUI makes use of Geoff Stearns's SWFObject v1.5 for Flash
+ Player detection and embedding. More information on SWFObject can be found
+ here (http://blog.deconcept.com/swfobject/). SWFObject is (c) 2007 Geoff
+ Stearns and is released under the MIT License
+ (http://www.opensource.org/licenses/mit-license.php).
+
+ Diego Perini's IEContentLoaded technique: The Event Utility employs a
+ technique developed by Diego Perini and licensed under GPL. YUI's use of
+ this technique is included under our BSD license with the author's
+ permission.
+
+
+From MIT license link above:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----------------------------------------------------
+customizations.cs
+
+ Except as noted, this content is
+ licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+ Creative Commons Attribution 2.5</a>.
+
+
+Creative Commons
+Creative Commons Legal Code
+
+Attribution 2.5
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
+SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
+RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
+CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND
+DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
+
+License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE
+BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS
+CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
+CONDITIONS.
+
+1. Definitions
+
+ "Collective Work" means a work, such as a periodical issue, anthology or
+ encyclopedia, in which the Work in its entirety in unmodified form, along
+ with a number of other contributions, constituting separate and independent
+ works in themselves, are assembled into a collective whole. A work that
+ constitutes a Collective Work will not be considered a Derivative Work (as
+ defined below) for the purposes of this License.
+
+ "Derivative Work" means a work based upon the Work or upon the Work and
+ other pre-existing works, such as a translation, musical arrangement,
+ dramatization, fictionalization, motion picture version, sound recording,
+ art reproduction, abridgment, condensation, or any other form in which the
+ Work may be recast, transformed, or adapted, except that a work that
+ constitutes a Collective Work will not be considered a Derivative Work for
+ the purpose of this License. For the avoidance of doubt, where the Work is
+ a musical composition or sound recording, the synchronization of the Work
+ in timed-relation with a moving image ("synching") will be considered a
+ Derivative Work for the purpose of this License.
+
+ "Licensor" means the individual or entity that offers the Work under the
+ terms of this License.
+
+ "Original Author" means the individual or entity who created the Work.
+
+ "Work" means the copyrightable work of authorship offered under the terms
+ of this License.
+
+ "You" means an individual or entity exercising rights under this License
+ who has not previously violated the terms of this License with respect to
+ the Work, or who has received express permission from the Licensor to
+ exercise rights under this License despite a previous violation.
+
+2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or
+restrict any rights arising from fair use, first sale or other limitations on
+the exclusive rights of the copyright owner under copyright law or other
+applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License, Licensor
+hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
+duration of the applicable copyright) license to exercise the rights in the
+Work as stated below:
+
+ to reproduce the Work, to incorporate the Work into one or more Collective
+ Works, and to reproduce the Work as incorporated in the Collective Works;
+
+ to create and reproduce Derivative Works;
+
+ to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio transmission the
+ Work including as incorporated in Collective Works;
+
+ to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio transmission
+ Derivative Works.
+
+ For the avoidance of doubt, where the work is a musical composition:
+ Performance Royalties Under Blanket Licenses. Licensor waives the
+ exclusive right to collect, whether individually or via a performance
+ rights society (e.g. ASCAP, BMI, SESAC), royalties for the public
+ performance or public digital performance (e.g. webcast) of the Work.
+
+ Mechanical Rights and Statutory Royalties. Licensor waives the
+ exclusive right to collect, whether individually or via a music rights
+ agency or designated agent (e.g. Harry Fox Agency), royalties for any
+ phonorecord You create from the Work ("cover version") and distribute,
+ subject to the compulsory license created by 17 USC Section 115 of the
+ US Copyright Act (or the equivalent in other jurisdictions).
+
+ Webcasting Rights and Statutory Royalties. For the avoidance of doubt,
+ where the Work is a sound recording, Licensor waives the exclusive right to
+ collect, whether individually or via a performance-rights society (e.g.
+ SoundExchange), royalties for the public digital performance (e.g. webcast)
+ of the Work, subject to the compulsory license created by 17 USC Section
+ 114 of the US Copyright Act (or the equivalent in other jurisdictions).
+
+The above rights may be exercised in all media and formats whether now known or
+hereafter devised. The above rights include the right to make such
+modifications as are technically necessary to exercise the rights in other
+media and formats. All rights not expressly granted by Licensor are hereby
+reserved.
+
+4. Restrictions.The license granted in Section 3 above is expressly made
+subject to and limited by the following restrictions:
+
+ You may distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work only under the terms of this License, and You
+ must include a copy of, or the Uniform Resource Identifier for, this
+ License with every copy or phonorecord of the Work You distribute, publicly
+ display, publicly perform, or publicly digitally perform. You may not offer
+ or impose any terms on the Work that alter or restrict the terms of this
+ License or the recipients' exercise of the rights granted hereunder. You
+ may not sublicense the Work. You must keep intact all notices that refer to
+ this License and to the disclaimer of warranties. You may not distribute,
+ publicly display, publicly perform, or publicly digitally perform the Work
+ with any technological measures that control access or use of the Work in a
+ manner inconsistent with the terms of this License Agreement. The above
+ applies to the Work as incorporated in a Collective Work, but this does not
+ require the Collective Work apart from the Work itself to be made subject
+ to the terms of this License. If You create a Collective Work, upon notice
+ from any Licensor You must, to the extent practicable, remove from the
+ Collective Work any credit as required by clause 4(b), as requested. If You
+ create a Derivative Work, upon notice from any Licensor You must, to the
+ extent practicable, remove from the Derivative Work any credit as required
+ by clause 4(b), as requested.
+
+ If you distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work or any Derivative Works or Collective Works, You
+ must keep intact all copyright notices for the Work and provide, reasonable
+ to the medium or means You are utilizing: (i) the name of the Original
+ Author (or pseudonym, if applicable) if supplied, and/or (ii) if the
+ Original Author and/or Licensor designate another party or parties (e.g. a
+ sponsor institute, publishing entity, journal) for attribution in
+ Licensor's copyright notice, terms of service or by other reasonable means,
+ the name of such party or parties; the title of the Work if supplied; to
+ the extent reasonably practicable, the Uniform Resource Identifier, if any,
+ that Licensor specifies to be associated with the Work, unless such URI
+ does not refer to the copyright notice or licensing information for the
+ Work; and in the case of a Derivative Work, a credit identifying the use of
+ the Work in the Derivative Work (e.g., "French translation of the Work by
+ Original Author," or "Screenplay based on original Work by Original
+ Author"). Such credit may be implemented in any reasonable manner;
+ provided, however, that in the case of a Derivative Work or Collective
+ Work, at a minimum such credit will appear where any other comparable
+ authorship credit appears and in a manner at least as prominent as such
+ other comparable authorship credit.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS
+THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
+CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING,
+WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A
+PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS,
+ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE.
+SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH
+EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN
+NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
+INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS
+LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ This License and the rights granted hereunder will terminate automatically
+ upon any breach by You of the terms of this License. Individuals or
+ entities who have received Derivative Works or Collective Works from You
+ under this License, however, will not have their licenses terminated
+ provided such individuals or entities remain in full compliance with those
+ licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of
+ this License.
+
+ Subject to the above terms and conditions, the license granted here is
+ perpetual (for the duration of the applicable copyright in the Work).
+ Notwithstanding the above, Licensor reserves the right to release the Work
+ under different license terms or to stop distributing the Work at any time;
+ provided, however that any such election will not serve to withdraw this
+ License (or any other license that has been, or is required to be, granted
+ under the terms of this License), and this License will continue in full
+ force and effect unless terminated as stated above.
+
+8. Miscellaneous
+
+ Each time You distribute or publicly digitally perform the Work or a
+ Collective Work, the Licensor offers to the recipient a license to the Work
+ on the same terms and conditions as the license granted to You under this
+ License.
+
+ Each time You distribute or publicly digitally perform a Derivative Work,
+ Licensor offers to the recipient a license to the original Work on the same
+ terms and conditions as the license granted to You under this License.
+
+ If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of the
+ remainder of the terms of this License, and without further action by the
+ parties to this agreement, such provision shall be reformed to the minimum
+ extent necessary to make such provision valid and enforceable.
+
+ No term or provision of this License shall be deemed waived and no breach
+ consented to unless such waiver or consent shall be in writing and signed
+ by the party to be charged with such waiver or consent.
+
+ This License constitutes the entire agreement between the parties with
+ respect to the Work licensed here. There are no understandings, agreements
+ or representations with respect to the Work not specified here. Licensor
+ shall not be bound by any additional provisions that may appear in any
+ communication from You. This License may not be modified without the mutual
+ written agreement of the Licensor and You.
+
+Creative Commons is not a party to this License, and makes no warranty
+whatsoever in connection with the Work. Creative Commons will not be liable to
+You or any party on any legal theory for any damages whatsoever, including
+without limitation any general, special, incidental or consequential damages
+arising in connection to this license. Notwithstanding the foregoing two (2)
+sentences, if Creative Commons has expressly identified itself as the Licensor
+hereunder, it shall have all rights and obligations of Licensor.
+
+Except for the limited purpose of indicating to the public that the Work is
+licensed under the CCPL, neither party will use the trademark "Creative
+Commons" or any related trademark or logo of Creative Commons without the prior
+written consent of Creative Commons. Any permitted use will be in compliance
+with Creative Commons' then-current trademark usage guidelines, as may be
+published on its website or otherwise made available upon request from time to
+time.
+
+Creative Commons may be contacted at https://creativecommons.org/.
+
+-----------------------------------------------------
+jquery-resizable.min.js
+
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+
+The MIT License (MIT)
+
+Copyright (c) 2009 John Resig
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----------------------------------------------------
+jquery-1.6.2.min.js
+
+/*!
+ * jQuery JavaScript Library v1.6.2
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Jun 30 14:16:56 2011 -0400
+ */
+
+The MIT License (MIT)
+
+Copyright (c) 2011 John Resig, and The Dojo Foundation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/tools/event_log_tags.py b/tools/event_log_tags.py
index 35b2de0..a6ae9f1 100644
--- a/tools/event_log_tags.py
+++ b/tools/event_log_tags.py
@@ -55,12 +55,13 @@
if file_object is None:
try:
file_object = open(filename, "rb")
- except (IOError, OSError), e:
+ except (IOError, OSError) as e:
self.AddError(str(e))
return
try:
for self.linenum, line in enumerate(file_object):
+ line = line.decode('utf-8')
self.linenum += 1
line = re.sub('#.*$', '', line) # strip trailing comments
line = line.strip()
@@ -100,7 +101,7 @@
self.tags.append(Tag(tag, tagname, description,
self.filename, self.linenum))
- except (IOError, OSError), e:
+ except (IOError, OSError) as e:
self.AddError(str(e))
@@ -128,8 +129,8 @@
output_file = "<stdout>"
else:
out = open(output_file, "wb")
- out.write(data)
+ out.write(str.encode(data))
out.close()
- except (IOError, OSError), e:
- print >> sys.stderr, "failed to write %s: %s" % (output_file, e)
+ except (IOError, OSError) as e:
+ print("failed to write %s: %s" % (output_file, e), file=sys.stderr)
sys.exit(1)
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index 4544e07..8891a0a 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -14,11 +14,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
bootstrap_go_package {
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 63cb4eb..b19a630 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -57,8 +57,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := \
fs_config_dirs_system \
fs_config_dirs_system_ext \
@@ -72,8 +73,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := \
fs_config_files_system \
fs_config_files_system_ext \
@@ -88,8 +90,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs_system_ext
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_system_ext)
include $(BUILD_PHONY_PACKAGE)
@@ -100,8 +103,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files_system_ext
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_SYSTEM_EXTIMAGE)$(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_system_ext)
include $(BUILD_PHONY_PACKAGE)
@@ -112,8 +116,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs_product
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_dirs_product)
include $(BUILD_PHONY_PACKAGE)
@@ -124,8 +129,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files_product
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(if $(BOARD_USES_PRODUCTIMAGE)$(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),_fs_config_files_product)
include $(BUILD_PHONY_PACKAGE)
@@ -136,8 +142,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs_nonsystem
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_dirs_$(t))
include $(BUILD_PHONY_PACKAGE)
@@ -148,8 +155,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files_nonsystem
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_REQUIRED_MODULES := $(foreach t,$(fs_config_generate_extra_partition_list),_fs_config_files_$(t))
include $(BUILD_PHONY_PACKAGE)
@@ -160,8 +168,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_dirs_system
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
include $(BUILD_SYSTEM)/base_rules.mk
@@ -187,8 +196,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := fs_config_files_system
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
include $(BUILD_SYSTEM)/base_rules.mk
@@ -215,8 +225,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_vendor
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
@@ -241,8 +252,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_vendor
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc
@@ -270,8 +282,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_oem
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
@@ -296,8 +309,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_oem
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/etc
@@ -325,8 +339,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_odm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
@@ -351,8 +366,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_odm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM)/etc
@@ -380,8 +396,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_vendor_dlkm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
@@ -406,8 +423,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_vendor_dlkm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
@@ -435,8 +453,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_odm_dlkm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
@@ -461,8 +480,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_odm_dlkm
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_ODM_DLKM)/etc
@@ -490,8 +510,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_product
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
@@ -516,8 +537,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_product
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/etc
@@ -544,8 +566,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_dirs_system_ext
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
@@ -570,8 +593,9 @@
include $(CLEAR_VARS)
LOCAL_MODULE := _fs_config_files_system_ext
-LOCAL_LICENSE_KINDS := legacy_restricted
-LOCAL_LICENSE_CONDITIONS := restricted
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := ETC
LOCAL_INSTALLED_MODULE_STEM := fs_config_files
LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_EXT)/etc
diff --git a/tools/fs_get_stats/Android.bp b/tools/fs_get_stats/Android.bp
index 9457de4..0697999 100644
--- a/tools/fs_get_stats/Android.bp
+++ b/tools/fs_get_stats/Android.bp
@@ -1,10 +1,6 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary_host {
diff --git a/tools/generate-self-extracting-archive.py b/tools/generate-self-extracting-archive.py
index 5b0628d..c9f56cb 100755
--- a/tools/generate-self-extracting-archive.py
+++ b/tools/generate-self-extracting-archive.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2019 The Android Open Source Project
#
@@ -120,7 +120,7 @@
def main(argv):
if len(argv) != 5:
- print 'generate-self-extracting-archive.py expects exactly 4 arguments'
+ print('generate-self-extracting-archive.py expects exactly 4 arguments')
sys.exit(1)
output_filename = argv[1]
@@ -134,11 +134,11 @@
license = license_file.read()
if not license:
- print 'License file was empty'
+ print('License file was empty')
sys.exit(1)
if 'SOFTWARE LICENSE AGREEMENT' not in license:
- print 'License does not look like a license'
+ print('License does not look like a license')
sys.exit(1)
comment_line = '# %s\n' % comment
diff --git a/tools/java-event-log-tags.py b/tools/java-event-log-tags.py
index 37cd712..4bd6d2b 100755
--- a/tools/java-event-log-tags.py
+++ b/tools/java-event-log-tags.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2009 The Android Open Source Project
#
@@ -23,7 +23,7 @@
-h to display this usage message and exit.
"""
-import cStringIO
+from io import StringIO
import getopt
import os
import os.path
@@ -36,24 +36,24 @@
try:
opts, args = getopt.getopt(sys.argv[1:], "ho:")
-except getopt.GetoptError, err:
- print str(err)
- print __doc__
+except getopt.GetoptError as err:
+ print(str(err))
+ print(__doc__)
sys.exit(2)
for o, a in opts:
if o == "-h":
- print __doc__
+ print(__doc__)
sys.exit(2)
elif o == "-o":
output_file = a
else:
- print >> sys.stderr, "unhandled option %s" % (o,)
+ print("unhandled option %s" % (o,), file=sys.stderr)
sys.exit(1)
if len(args) != 1 and len(args) != 2:
- print "need one or two input files, not %d" % (len(args),)
- print __doc__
+ print("need one or two input files, not %d" % (len(args),))
+ print(__doc__)
sys.exit(1)
fn = args[0]
@@ -92,10 +92,10 @@
if tagfile.errors:
for fn, ln, msg in tagfile.errors:
- print >> sys.stderr, "%s:%d: error: %s" % (fn, ln, msg)
+ print("%s:%d: error: %s" % (fn, ln, msg), file=sys.stderr)
sys.exit(1)
-buffer = cStringIO.StringIO()
+buffer = StringIO()
buffer.write("/* This file is auto-generated. DO NOT MODIFY.\n"
" * Source file: %s\n"
" */\n\n" % (fn,))
diff --git a/tools/libhost/Android.bp b/tools/libhost/Android.bp
index a83f2e7..cd99af8 100644
--- a/tools/libhost/Android.bp
+++ b/tools/libhost/Android.bp
@@ -1,10 +1,6 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "build_make_license"
- // to get the below license kinds:
- // legacy_restricted
- default_applicable_licenses: ["build_make_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_library_host_static {
diff --git a/tools/merge-event-log-tags.py b/tools/merge-event-log-tags.py
index 64bad3f..292604c 100755
--- a/tools/merge-event-log-tags.py
+++ b/tools/merge-event-log-tags.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2009 The Android Open Source Project
#
@@ -24,7 +24,7 @@
-h to display this usage message and exit.
"""
-import cStringIO
+from io import StringIO
import getopt
try:
import hashlib
@@ -48,21 +48,21 @@
try:
opts, args = getopt.getopt(sys.argv[1:], "ho:m:")
-except getopt.GetoptError, err:
- print str(err)
- print __doc__
+except getopt.GetoptError as err:
+ print(str(err))
+ print(__doc__)
sys.exit(2)
for o, a in opts:
if o == "-h":
- print __doc__
+ print(__doc__)
sys.exit(2)
elif o == "-o":
output_file = a
elif o == "-m":
pre_merged_file = a
else:
- print >> sys.stderr, "unhandled option %s" % (o,)
+ print("unhandled option %s" % (o,), file=sys.stderr)
sys.exit(1)
# Restrictions on tags:
@@ -133,12 +133,12 @@
if errors:
for fn, ln, msg in errors:
- print >> sys.stderr, "%s:%d: error: %s" % (fn, ln, msg)
+ print("%s:%d: error: %s" % (fn, ln, msg), file=sys.stderr)
sys.exit(1)
if warnings:
for fn, ln, msg in warnings:
- print >> sys.stderr, "%s:%d: warning: %s" % (fn, ln, msg)
+ print("%s:%d: warning: %s" % (fn, ln, msg), file=sys.stderr)
# Python's hash function (a) isn't great and (b) varies between
# versions of python. Using md5 is overkill here but is the same from
@@ -154,14 +154,14 @@
# If we were provided pre-merged tags (w/ the -m option), then don't
# ever try to allocate one, just fail if we don't have a number
-for name, t in sorted(by_tagname.iteritems()):
+for name, t in sorted(by_tagname.items()):
if t.tagnum is None:
if pre_merged_tags:
try:
t.tagnum = pre_merged_tags[t.tagname]
except KeyError:
- print >> sys.stderr, ("Error: Tag number not defined for tag `%s'."
- +" Have you done a full build?") % t.tagname
+ print("Error: Tag number not defined for tag `%s'. Have you done a full build?" % t.tagname,
+ file=sys.stderr)
sys.exit(1)
else:
while True:
@@ -174,8 +174,8 @@
# by_tagnum should be complete now; we've assigned numbers to all tags.
-buffer = cStringIO.StringIO()
-for n, t in sorted(by_tagnum.iteritems()):
+buffer = StringIO()
+for n, t in sorted(by_tagnum.items()):
if t.description:
buffer.write("%d %s %s\n" % (t.tagnum, t.tagname, t.description))
else:
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index bf7f9a0..7b2c290 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -162,6 +162,7 @@
required: [
"brillo_update_payload",
"checkvintf",
+ "generate_gki_certificate",
"minigzip",
"lz4",
"toybox",
@@ -236,6 +237,7 @@
"boot_signer",
"brotli",
"bsdiff",
+ "generate_gki_certificate",
"imgdiff",
"minigzip",
"lz4",
@@ -301,6 +303,7 @@
"brotli",
"bsdiff",
"deapexer",
+ "generate_gki_certificate",
"imgdiff",
"minigzip",
"lz4",
@@ -554,12 +557,25 @@
}
python_binary_host {
- name: "fsverity_metadata_generator",
+ name: "fsverity_manifest_generator",
srcs: [
- "fsverity_metadata_generator.py",
+ "fsverity_manifest_generator.py",
],
libs: [
"fsverity_digests_proto_python",
+ "releasetools_common",
+ ],
+ required: [
+ "aapt2",
+ "apksigner",
+ "fsverity",
+ ],
+}
+
+python_binary_host {
+ name: "fsverity_metadata_generator",
+ srcs: [
+ "fsverity_metadata_generator.py",
],
required: [
"fsverity",
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 34aa1a6..a4377c7 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -35,9 +35,6 @@
import common
import verity_utils
-from fsverity_digests_pb2 import FSVerityDigests
-from fsverity_metadata_generator import FSVerityMetadataGenerator
-
logger = logging.getLogger(__name__)
OPTIONS = common.OPTIONS
@@ -451,69 +448,6 @@
return mkfs_output
-def GenerateFSVerityMetadata(in_dir, fsverity_path, apk_key_path, apk_manifest_path, apk_out_path):
- """Generates fsverity metadata files.
-
- By setting PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA := true, fsverity
- metadata files will be generated. For the input files, see `patterns` below.
-
- One metadata file per one input file will be generated with the suffix
- .fsv_meta. e.g. system/framework/foo.jar -> system/framework/foo.jar.fsv_meta
- Also a mapping file containing fsverity digests will be generated to
- system/etc/security/fsverity/BuildManifest.apk.
-
- Args:
- in_dir: temporary working directory (same as BuildImage)
- fsverity_path: path to host tool fsverity
- apk_key_path: path to key (e.g. build/make/target/product/security/platform)
- apk_manifest_path: path to AndroidManifest.xml for APK
- apk_out_path: path to the output APK
-
- Returns:
- None. The files are generated directly under in_dir.
- """
-
- patterns = [
- "system/framework/*.jar",
- "system/framework/oat/*/*.oat",
- "system/framework/oat/*/*.vdex",
- "system/framework/oat/*/*.art",
- "system/etc/boot-image.prof",
- "system/etc/dirty-image-objects",
- ]
- files = []
- for pattern in patterns:
- files += glob.glob(os.path.join(in_dir, pattern))
- files = sorted(set(files))
-
- generator = FSVerityMetadataGenerator(fsverity_path)
- generator.set_hash_alg("sha256")
-
- digests = FSVerityDigests()
- for f in files:
- generator.generate(f)
- # f is a full path for now; make it relative so it starts with {mount_point}/
- digest = digests.digests[os.path.relpath(f, in_dir)]
- digest.digest = generator.digest(f)
- digest.hash_alg = "sha256"
-
- temp_dir = common.MakeTempDir()
-
- os.mkdir(os.path.join(temp_dir, "assets"))
- metadata_path = os.path.join(temp_dir, "assets", "build_manifest")
- with open(metadata_path, "wb") as f:
- f.write(digests.SerializeToString())
-
- apk_path = os.path.join(in_dir, apk_out_path)
-
- common.RunAndCheckOutput(["aapt2", "link",
- "-A", os.path.join(temp_dir, "assets"),
- "-o", apk_path,
- "--manifest", apk_manifest_path])
- common.RunAndCheckOutput(["apksigner", "sign", "--in", apk_path,
- "--cert", apk_key_path + ".x509.pem",
- "--key", apk_key_path + ".pk8"])
-
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
"""Builds an image for the files under in_dir and writes it to out_file.
@@ -541,13 +475,6 @@
elif fs_type.startswith("f2fs") and prop_dict.get("f2fs_compress") == "true":
fs_spans_partition = False
- if "fsverity_generate_metadata" in prop_dict:
- GenerateFSVerityMetadata(in_dir,
- fsverity_path=prop_dict["fsverity"],
- apk_key_path=prop_dict["fsverity_apk_key"],
- apk_manifest_path=prop_dict["fsverity_apk_manifest"],
- apk_out_path=prop_dict["fsverity_apk_out"])
-
# Get a builder for creating an image that's to be verified by Verified Boot,
# or None if not applicable.
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
@@ -801,11 +728,6 @@
copy_prop("system_root_image", "system_root_image")
copy_prop("root_dir", "root_dir")
copy_prop("root_fs_config", "root_fs_config")
- copy_prop("fsverity", "fsverity")
- copy_prop("fsverity_generate_metadata", "fsverity_generate_metadata")
- copy_prop("fsverity_apk_key","fsverity_apk_key")
- copy_prop("fsverity_apk_manifest","fsverity_apk_manifest")
- copy_prop("fsverity_apk_out","fsverity_apk_out")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("flash_logical_block_size", "flash_logical_block_size")
diff --git a/tools/releasetools/check_target_files_signatures.py b/tools/releasetools/check_target_files_signatures.py
index 6e02e4d..0f56fb9 100755
--- a/tools/releasetools/check_target_files_signatures.py
+++ b/tools/releasetools/check_target_files_signatures.py
@@ -65,10 +65,13 @@
# extra field anyway).
# Issue #14315: https://bugs.python.org/issue14315, fixed in Python 2.7.8 and
# Python 3.5.0 alpha 1.
+
+
class MyZipInfo(zipfile.ZipInfo):
def _decodeExtra(self):
pass
+
zipfile.ZipInfo = MyZipInfo
@@ -83,6 +86,7 @@
def AddProblem(msg):
+ logger.error(msg)
PROBLEMS.append(" ".join(PROBLEM_PREFIX) + " " + msg)
@@ -204,7 +208,7 @@
for info in apk.infolist():
filename = info.filename
if (filename.startswith("META-INF/") and
- info.filename.endswith((".DSA", ".RSA"))):
+ info.filename.endswith((".DSA", ".RSA"))):
pkcs7 = apk.read(filename)
cert = CertFromPKCS7(pkcs7, filename)
if not cert:
@@ -266,7 +270,7 @@
stdout=subprocess.PIPE)
manifest, err = p.communicate()
if err:
- AddProblem("failed to read manifest")
+ AddProblem("failed to read manifest " + full_filename)
return
self.shared_uid = None
@@ -279,15 +283,15 @@
name = m.group(1)
if name == "android:sharedUserId":
if self.shared_uid is not None:
- AddProblem("multiple sharedUserId declarations")
+ AddProblem("multiple sharedUserId declarations " + full_filename)
self.shared_uid = m.group(2)
elif name == "package":
if self.package is not None:
- AddProblem("multiple package declarations")
+ AddProblem("multiple package declarations " + full_filename)
self.package = m.group(2)
if self.package is None:
- AddProblem("no package declaration")
+ AddProblem("no package declaration " + full_filename)
class TargetFiles(object):
@@ -400,7 +404,12 @@
for _, digest in order:
print("%s:" % (ALL_CERTS.Get(digest),))
apks = by_digest[digest]
- apks.sort()
+ apks.sort(key=lambda x: x[0])
+ for i in range(1, len(apks)):
+ pkgname, apk = apks[i]
+ if pkgname == apks[i-1][0]:
+ print("Both {} and {} have same package name {}".format(
+ apk.filename, apks[i-1][1].filename, pkgname))
for _, apk in apks:
if apk.shared_uid:
print(" %-*s %-*s [%s]" % (self.max_fn_len, apk.filename,
@@ -527,8 +536,5 @@
try:
r = main(sys.argv[1:])
sys.exit(r)
- except common.ExternalError as e:
- print("\n ERROR: %s\n" % (e,))
- sys.exit(1)
finally:
common.Cleanup()
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 6ec1b94..e5c68bc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -73,6 +73,7 @@
self.search_path = os.environ["ANDROID_HOST_OUT"]
self.signapk_shared_library_path = "lib64" # Relative to search_path
self.extra_signapk_args = []
+ self.aapt2_path = "aapt2"
self.java_path = "java" # Use the one on the path by default.
self.java_args = ["-Xmx2048m"] # The default JVM args.
self.android_jar_path = None
@@ -1395,34 +1396,52 @@
return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
-def AppendGkiSigningArgs(cmd):
- """Append GKI signing arguments for mkbootimg."""
- # e.g., --gki_signing_key path/to/signing_key
- # --gki_signing_algorithm SHA256_RSA4096"
+def _HasGkiCertificationArgs():
+ return ("gki_signing_key_path" in OPTIONS.info_dict and
+ "gki_signing_algorithm" in OPTIONS.info_dict)
+
+def _GenerateGkiCertificate(image, image_name, partition_name):
key_path = OPTIONS.info_dict.get("gki_signing_key_path")
- # It's fine that a non-GKI boot.img has no gki_signing_key_path.
- if not key_path:
- return
+ algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")
if not os.path.exists(key_path) and OPTIONS.search_path:
new_key_path = os.path.join(OPTIONS.search_path, key_path)
if os.path.exists(new_key_path):
key_path = new_key_path
- # Checks key_path exists, before appending --gki_signing_* args.
+ # Checks key_path exists, before processing --gki_signing_* args.
if not os.path.exists(key_path):
raise ExternalError(
'gki_signing_key_path: "{}" not found'.format(key_path))
- algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")
- if key_path and algorithm:
- cmd.extend(["--gki_signing_key", key_path,
- "--gki_signing_algorithm", algorithm])
+ output_certificate = tempfile.NamedTemporaryFile()
+ cmd = [
+ "generate_gki_certificate",
+ "--name", image_name,
+ "--algorithm", algorithm,
+ "--key", key_path,
+ "--output", output_certificate.name,
+ image,
+ ]
- signature_args = OPTIONS.info_dict.get("gki_signing_signature_args")
- if signature_args:
- cmd.extend(["--gki_signing_signature_args", signature_args])
+ signature_args = OPTIONS.info_dict.get("gki_signing_signature_args", "")
+ signature_args = signature_args.strip()
+ if signature_args:
+ cmd.extend(["--additional_avb_args", signature_args])
+
+ args = OPTIONS.info_dict.get(
+ "avb_" + partition_name + "_add_hash_footer_args", "")
+ args = args.strip()
+ if args:
+ cmd.extend(["--additional_avb_args", args])
+
+ RunAndCheckOutput(cmd)
+
+ output_certificate.seek(os.SEEK_SET, 0)
+ data = output_certificate.read()
+ output_certificate.close()
+ return data
def BuildVBMeta(image_path, partitions, name, needed_partitions):
@@ -1548,6 +1567,8 @@
if kernel and not os.access(os.path.join(sourcedir, kernel), os.F_OK):
return None
+ kernel_path = os.path.join(sourcedir, kernel) if kernel else None
+
if has_ramdisk and not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK):
return None
@@ -1562,8 +1583,8 @@
mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"
cmd = [mkbootimg]
- if kernel:
- cmd += ["--kernel", os.path.join(sourcedir, kernel)]
+ if kernel_path is not None:
+ cmd.extend(["--kernel", kernel_path])
fn = os.path.join(sourcedir, "second")
if os.access(fn, os.F_OK):
@@ -1603,15 +1624,31 @@
if args and args.strip():
cmd.extend(shlex.split(args))
- args = info_dict.get("mkbootimg_version_args")
- if args and args.strip():
- cmd.extend(shlex.split(args))
+ boot_signature = None
+ if _HasGkiCertificationArgs():
+ # Certify GKI images.
+ boot_signature_bytes = b''
+ if kernel_path is not None:
+ boot_signature_bytes += _GenerateGkiCertificate(
+ kernel_path, "generic_kernel", "boot")
+ if has_ramdisk:
+ boot_signature_bytes += _GenerateGkiCertificate(
+ ramdisk_img.name, "generic_ramdisk", "init_boot")
+
+ if len(boot_signature_bytes) > 0:
+ boot_signature = tempfile.NamedTemporaryFile()
+ boot_signature.write(boot_signature_bytes)
+ boot_signature.flush()
+ cmd.extend(["--boot_signature", boot_signature.name])
+ else:
+ # Certified GKI boot/init_boot image mustn't set 'mkbootimg_version_args'.
+ args = info_dict.get("mkbootimg_version_args")
+ if args and args.strip():
+ cmd.extend(shlex.split(args))
if has_ramdisk:
cmd.extend(["--ramdisk", ramdisk_img.name])
- AppendGkiSigningArgs(cmd)
-
img_unsigned = None
if info_dict.get("vboot"):
img_unsigned = tempfile.NamedTemporaryFile()
@@ -1689,6 +1726,9 @@
ramdisk_img.close()
img.close()
+ if boot_signature is not None:
+ boot_signature.close()
+
return data
@@ -1699,8 +1739,8 @@
Args:
image_path: The full path of the image, e.g., /path/to/boot.img.
prebuilt_name: The prebuilt image name, e.g., boot.img, boot-5.4-gz.img,
- boot-5.10.img, recovery.img.
- partition_name: The partition name, e.g., 'boot' or 'recovery'.
+ boot-5.10.img, recovery.img or init_boot.img.
+ partition_name: The partition name, e.g., 'boot', 'init_boot' or 'recovery'.
info_dict: The information dict read from misc_info.txt.
"""
if info_dict is None:
@@ -1724,6 +1764,35 @@
RunAndCheckOutput(cmd)
+def HasRamdisk(partition_name, info_dict=None):
+ """Returns true/false to see if a bootable image should have a ramdisk.
+
+ Args:
+ partition_name: The partition name, e.g., 'boot', 'init_boot' or 'recovery'.
+ info_dict: The information dict read from misc_info.txt.
+ """
+ if info_dict is None:
+ info_dict = OPTIONS.info_dict
+
+ if partition_name != "boot":
+ return True # init_boot.img or recovery.img has a ramdisk.
+
+ if info_dict.get("recovery_as_boot") == "true":
+ return True # the recovery-as-boot boot.img has a RECOVERY ramdisk.
+
+ if info_dict.get("system_root_image") == "true":
+ # The ramdisk content is merged into the system.img, so there is NO
+ # ramdisk in the boot.img or boot-<kernel version>.img.
+ return False
+
+ if info_dict.get("init_boot") == "true":
+ # The ramdisk is moved to the init_boot.img, so there is NO
+ # ramdisk in the boot.img or boot-<kernel version>.img.
+ return False
+
+ return True
+
+
def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
info_dict=None, two_step_image=False):
"""Return a File object with the desired bootable image.
@@ -1745,25 +1814,18 @@
logger.info("using prebuilt %s from IMAGES...", prebuilt_name)
return File.FromLocalFile(name, prebuilt_path)
+ partition_name = tree_subdir.lower()
prebuilt_path = os.path.join(unpack_dir, "PREBUILT_IMAGES", prebuilt_name)
if os.path.exists(prebuilt_path):
logger.info("Re-signing prebuilt %s from PREBUILT_IMAGES...", prebuilt_name)
signed_img = MakeTempFile()
shutil.copy(prebuilt_path, signed_img)
- partition_name = tree_subdir.lower()
_SignBootableImage(signed_img, prebuilt_name, partition_name, info_dict)
return File.FromLocalFile(name, signed_img)
logger.info("building image from target_files %s...", tree_subdir)
- # With system_root_image == "true", we don't pack ramdisk into the boot image.
- # With init_boot == "true", we don't pack the ramdisk into boot.img.
- # Unless "recovery_as_boot" is specified, in which case we carry the ramdisk
- # for recovery.
- has_ramdisk = ((info_dict.get("system_root_image") != "true" and
- info_dict.get("init_boot") != "true") or
- prebuilt_name != "boot.img" or
- info_dict.get("recovery_as_boot") == "true")
+ has_ramdisk = HasRamdisk(partition_name, info_dict)
fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
data = _BuildBootableImage(prebuilt_name, os.path.join(unpack_dir, tree_subdir),
@@ -2162,8 +2224,8 @@
def GetMinSdkVersion(apk_name):
"""Gets the minSdkVersion declared in the APK.
- It calls 'aapt2' to query the embedded minSdkVersion from the given APK file.
- This can be both a decimal number (API Level) or a codename.
+ It calls OPTIONS.aapt2_path to query the embedded minSdkVersion from the given
+ APK file. This can be both a decimal number (API Level) or a codename.
Args:
apk_name: The APK filename.
@@ -2175,7 +2237,7 @@
ExternalError: On failing to obtain the min SDK version.
"""
proc = Run(
- ["aapt2", "dump", "badging", apk_name], stdout=subprocess.PIPE,
+ [OPTIONS.aapt2_path, "dump", "badging", apk_name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdoutdata, stderrdata = proc.communicate()
if proc.returncode != 0:
@@ -2451,7 +2513,7 @@
opts, args = getopt.getopt(
argv, "hvp:s:x:" + extra_opts,
["help", "verbose", "path=", "signapk_path=",
- "signapk_shared_library_path=", "extra_signapk_args=",
+ "signapk_shared_library_path=", "extra_signapk_args=", "aapt2_path=",
"java_path=", "java_args=", "android_jar_path=", "public_key_suffix=",
"private_key_suffix=", "boot_signer_path=", "boot_signer_args=",
"verity_signer_path=", "verity_signer_args=", "device_specific=",
@@ -2475,6 +2537,8 @@
OPTIONS.signapk_shared_library_path = a
elif o in ("--extra_signapk_args",):
OPTIONS.extra_signapk_args = shlex.split(a)
+ elif o in ("--aapt2_path",):
+ OPTIONS.aapt2_path = a
elif o in ("--java_path",):
OPTIONS.java_path = a
elif o in ("--java_args",):
@@ -3870,7 +3934,10 @@
disable_sparse = OPTIONS.info_dict.get(which + "_disable_sparse")
image_blocks = int(image_size) // 4096 - 1
- assert image_blocks > 0, "blocks for {} must be positive".format(which)
+ # It's OK for image_blocks to be 0, because care map ranges are inclusive.
+ # So 0-0 means "just block 0", which is valid.
+ assert image_blocks >= 0, "blocks for {} must be non-negative, image size: {}".format(
+ which, image_size)
# For sparse images, we will only check the blocks that are listed in the care
# map, i.e. the ones with meaningful data.
diff --git a/tools/releasetools/fsverity_manifest_generator.py b/tools/releasetools/fsverity_manifest_generator.py
new file mode 100644
index 0000000..527cddb
--- /dev/null
+++ b/tools/releasetools/fsverity_manifest_generator.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+`fsverity_manifest_generator` generates build manifest APK file containing
+digests of target files. The APK file is signed so the manifest inside the APK
+can be trusted.
+"""
+
+import argparse
+import common
+import os
+import subprocess
+import sys
+from fsverity_digests_pb2 import FSVerityDigests
+
+HASH_ALGORITHM = 'sha256'
+
+def _digest(fsverity_path, input_file):
+ cmd = [fsverity_path, 'digest', input_file]
+ cmd.extend(['--compact'])
+ cmd.extend(['--hash-alg', HASH_ALGORITHM])
+ out = subprocess.check_output(cmd, universal_newlines=True).strip()
+ return bytes(bytearray.fromhex(out))
+
+if __name__ == '__main__':
+ p = argparse.ArgumentParser()
+ p.add_argument(
+ '--output',
+ help='Path to the output manifest APK',
+ required=True)
+ p.add_argument(
+ '--fsverity-path',
+ help='path to the fsverity program',
+ required=True)
+ p.add_argument(
+ '--aapt2-path',
+ help='path to the aapt2 program',
+ required=True)
+ p.add_argument(
+ '--min-sdk-version',
+ help='minimum supported sdk version of the generated manifest apk',
+ required=True)
+ p.add_argument(
+ '--framework-res',
+ help='path to framework-res.apk',
+ required=True)
+ p.add_argument(
+ '--apksigner-path',
+ help='path to the apksigner program',
+ required=True)
+ p.add_argument(
+ '--apk-key-path',
+ help='path to the apk key',
+ required=True)
+ p.add_argument(
+ '--apk-manifest-path',
+ help='path to AndroidManifest.xml',
+ required=True)
+ p.add_argument(
+ '--base-dir',
+ help='directory to use as a relative root for the inputs',
+ required=True)
+ p.add_argument(
+ 'inputs',
+ nargs='+',
+ help='input file for the build manifest')
+ args = p.parse_args(sys.argv[1:])
+
+ digests = FSVerityDigests()
+ for f in sorted(args.inputs):
+ # f is a full path for now; make it relative so it starts with {mount_point}/
+ digest = digests.digests[os.path.relpath(f, args.base_dir)]
+ digest.digest = _digest(args.fsverity_path, f)
+ digest.hash_alg = HASH_ALGORITHM
+
+ temp_dir = common.MakeTempDir()
+
+ os.mkdir(os.path.join(temp_dir, "assets"))
+ metadata_path = os.path.join(temp_dir, "assets", "build_manifest.pb")
+ with open(metadata_path, "wb") as f:
+ f.write(digests.SerializeToString())
+
+ common.RunAndCheckOutput([args.aapt2_path, "link",
+ "-A", os.path.join(temp_dir, "assets"),
+ "-o", args.output,
+ "--min-sdk-version", args.min_sdk_version,
+ "-I", args.framework_res,
+ "--manifest", args.apk_manifest_path])
+ common.RunAndCheckOutput([args.apksigner_path, "sign", "--in", args.output,
+ "--cert", args.apk_key_path + ".x509.pem",
+ "--key", args.apk_key_path + ".pk8"])
diff --git a/tools/releasetools/fsverity_metadata_generator.py b/tools/releasetools/fsverity_metadata_generator.py
index a300d2e..fa7cd39 100644
--- a/tools/releasetools/fsverity_metadata_generator.py
+++ b/tools/releasetools/fsverity_metadata_generator.py
@@ -178,6 +178,7 @@
out.write(sig)
else:
out.write(pack('<I', SIG_TYPE_NONE))
+ out.write(pack('<I', 0))
# 4. merkle tree
with open(merkletree_file, 'rb') as f:
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index c21de14..9b9422c 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -230,6 +230,13 @@
--compressor_types
A colon ':' separated list of compressors. Allowed values are bz2 and brotli.
+
+ --enable_zucchini
+ Whether to enable to zucchini feature. Will generate smaller OTA but uses more memory.
+
+ --enable_lz4diff
+ Whether to enable lz4diff feature. Will generate smaller OTA for EROFS but
+ uses more memory.
"""
from __future__ import print_function
@@ -299,6 +306,8 @@
OPTIONS.enable_vabc_xor = True
OPTIONS.force_minor_version = None
OPTIONS.compressor_types = None
+OPTIONS.enable_zucchini = True
+OPTIONS.enable_lz4diff = False
POSTINSTALL_CONFIG = 'META/postinstall_config.txt'
DYNAMIC_PARTITION_INFO = 'META/dynamic_partitions_info.txt'
@@ -1141,6 +1150,32 @@
partition_timestamps_flags = GeneratePartitionTimestampFlags(
metadata.postcondition.partition_state)
+ if not ota_utils.IsZucchiniCompatible(source_file, target_file):
+ OPTIONS.enable_zucchini = False
+
+ additional_args += ["--enable_zucchini",
+ str(OPTIONS.enable_zucchini).lower()]
+
+ if not ota_utils.IsLz4diffCompatible(source_file, target_file):
+ logger.warn(
+ "Source build doesn't support lz4diff, or source/target don't have compatible lz4diff versions. Disabling lz4diff.")
+ OPTIONS.enable_lz4diff = False
+
+ additional_args += ["--enable_lz4diff",
+ str(OPTIONS.enable_lz4diff).lower()]
+
+ if source_file and OPTIONS.enable_lz4diff:
+ input_tmp = common.UnzipTemp(source_file, ["META/liblz4.so"])
+ liblz4_path = os.path.join(input_tmp, "META", "liblz4.so")
+ assert os.path.exists(
+ liblz4_path), "liblz4.so not found in META/ dir of target file {}".format(liblz4_path)
+ logger.info("Enabling lz4diff %s", liblz4_path)
+ additional_args += ["--liblz4_path", liblz4_path]
+ erofs_compression_param = OPTIONS.target_info_dict.get(
+ "erofs_default_compressor")
+ assert erofs_compression_param is not None, "'erofs_default_compressor' not found in META/misc_info.txt of target build. This is required to enable lz4diff."
+ additional_args += ["--erofs_compression_param", erofs_compression_param]
+
if OPTIONS.disable_vabc:
additional_args += ["--disable_vabc", "true"]
if OPTIONS.enable_vabc_xor:
@@ -1321,11 +1356,18 @@
elif o == "--vabc_downgrade":
OPTIONS.vabc_downgrade = True
elif o == "--enable_vabc_xor":
+ assert a.lower() in ["true", "false"]
OPTIONS.enable_vabc_xor = a.lower() != "false"
elif o == "--force_minor_version":
OPTIONS.force_minor_version = a
elif o == "--compressor_types":
OPTIONS.compressor_types = a
+ elif o == "--enable_zucchini":
+ assert a.lower() in ["true", "false"]
+ OPTIONS.enable_zucchini = a.lower() != "false"
+ elif o == "--enable_lz4diff":
+ assert a.lower() in ["true", "false"]
+ OPTIONS.enable_lz4diff = a.lower() != "false"
else:
return False
return True
@@ -1373,6 +1415,8 @@
"enable_vabc_xor=",
"force_minor_version=",
"compressor_types=",
+ "enable_zucchin=",
+ "enable_lz4diff=",
], extra_option_handler=option_handler)
if len(args) != 2:
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index 6c5fc05..6896f83 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -638,3 +638,60 @@
target_apex.source_version = source_apex_versions[name]
return target_apex_proto.SerializeToString()
+
+
+def IsLz4diffCompatible(source_file: str, target_file: str):
+ """Check whether lz4diff versions in two builds are compatible
+
+ Args:
+ source_file: Path to source build's target_file.zip
+ target_file: Path to target build's target_file.zip
+
+ Returns:
+ bool true if and only if lz4diff versions are compatible
+ """
+ if source_file is None or target_file is None:
+ return False
+ # Right now we enable lz4diff as long as source build has liblz4.so.
+ # In the future we might introduce version system to lz4diff as well.
+ if zipfile.is_zipfile(source_file):
+ with zipfile.ZipFile(source_file, "r") as zfp:
+ return "META/liblz4.so" in zfp.namelist()
+ else:
+ assert os.path.isdir(source_file)
+ return os.path.exists(os.path.join(source_file, "META", "liblz4.so"))
+
+
+def IsZucchiniCompatible(source_file: str, target_file: str):
+ """Check whether zucchini versions in two builds are compatible
+
+ Args:
+ source_file: Path to source build's target_file.zip
+ target_file: Path to target build's target_file.zip
+
+ Returns:
+ bool true if and only if zucchini versions are compatible
+ """
+ if source_file is None or target_file is None:
+ return False
+ assert os.path.exists(source_file)
+ assert os.path.exists(target_file)
+
+ assert zipfile.is_zipfile(source_file) or os.path.isdir(source_file)
+ assert zipfile.is_zipfile(target_file) or os.path.isdir(target_file)
+ _ZUCCHINI_CONFIG_ENTRY_NAME = "META/zucchini_config.txt"
+
+ def ReadEntry(path, entry):
+ # Read an entry inside a .zip file or extracted dir of .zip file
+ if zipfile.is_zipfile(path):
+ with zipfile.ZipFile(path, "r", allowZip64=True) as zfp:
+ if entry in zfp.namelist():
+ return zfp.read(entry).decode()
+ else:
+ entry_path = os.path.join(entry, path)
+ if os.path.exists(entry_path):
+ with open(entry_path, "r") as fp:
+ return fp.read()
+ else:
+ return ""
+ return ReadEntry(source_file, _ZUCCHINI_CONFIG_ENTRY_NAME) == ReadEntry(target_file, _ZUCCHINI_CONFIG_ENTRY_NAME)
diff --git a/tools/releasetools/sign_apex.py b/tools/releasetools/sign_apex.py
index 679f57a..66f5e05 100755
--- a/tools/releasetools/sign_apex.py
+++ b/tools/releasetools/sign_apex.py
@@ -141,7 +141,7 @@
signing_args=options.get('payload_extra_args'),
codename_to_api_level_map=options.get(
'codename_to_api_level_map', {}),
- sign_tool=options['sign_tool'])
+ sign_tool=options.get('sign_tool', None))
shutil.copyfile(signed_apex, args[1])
logger.info("done.")
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 3f65df1..c615b84 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -520,9 +520,14 @@
compressed_extension):
# maxsize measures the maximum filename length, including the ones to be
# skipped.
- maxsize = max(
- [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
- if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
+ try:
+ maxsize = max(
+ [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
+ if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
+ except ValueError:
+ # Sets this to zero for targets without APK files, e.g., gki_arm64.
+ maxsize = 0
+
system_root_image = misc_info.get("system_root_image") == "true"
for info in input_tf_zip.infolist():
@@ -883,14 +888,27 @@
except KeyError:
raise common.ExternalError("can't read META/otakeys.txt from input")
- extra_recovery_keys = misc_info.get("extra_recovery_keys")
- if extra_recovery_keys:
+ extra_ota_keys_info = misc_info.get("extra_ota_keys")
+ if extra_ota_keys_info:
+ extra_ota_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
+ for k in extra_ota_keys_info.split()]
+ print("extra ota key(s): " + ", ".join(extra_ota_keys))
+ else:
+ extra_ota_keys = []
+ for k in extra_ota_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
+
+ extra_recovery_keys_info = misc_info.get("extra_recovery_keys")
+ if extra_recovery_keys_info:
extra_recovery_keys = [OPTIONS.key_map.get(k, k) + ".x509.pem"
- for k in extra_recovery_keys.split()]
- if extra_recovery_keys:
- print("extra recovery-only key(s): " + ", ".join(extra_recovery_keys))
+ for k in extra_recovery_keys_info.split()]
+ print("extra recovery-only key(s): " + ", ".join(extra_recovery_keys))
else:
extra_recovery_keys = []
+ for k in extra_recovery_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
mapped_keys = []
for k in keylist:
@@ -913,13 +931,20 @@
mapped_keys.append(mapped_devkey + ".x509.pem")
print("META/otakeys.txt has no keys; using %s for OTA package"
" verification." % (mapped_keys[0],))
+ for k in mapped_keys:
+ if not os.path.isfile(k):
+ raise common.ExternalError(k + " does not exist or is not a file")
otacerts = [info
for info in input_tf_zip.infolist()
if info.filename.endswith("/otacerts.zip")]
for info in otacerts:
- print("Rewriting OTA key:", info.filename, mapped_keys)
- WriteOtacerts(output_tf_zip, info.filename, mapped_keys)
+ if info.filename.startswith(("BOOT/", "RECOVERY/", "VENDOR_BOOT/")):
+ extra_keys = extra_recovery_keys
+ else:
+ extra_keys = extra_ota_keys
+ print("Rewriting OTA key:", info.filename, mapped_keys + extra_keys)
+ WriteOtacerts(output_tf_zip, info.filename, mapped_keys + extra_keys)
def ReplaceVerityPublicKey(output_zip, filename, key_path):
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index e42d417..7dd365f 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -1631,66 +1631,7 @@
self.assertEqual('3', chained_partition_args[1])
self.assertTrue(os.path.exists(chained_partition_args[2]))
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_NoSigningKeyPath(self):
- # A non-GKI boot.img has no gki_signing_key_path.
- common.OPTIONS.info_dict = {
- # 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
-
- # Tests no --gki_signing_* args are appended if there is no
- # gki_signing_key_path.
- cmd = ['mkbootimg', '--header_version', '4']
- expected_cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
- self.assertEqual(cmd, expected_cmd)
-
- def test_AppendGkiSigningArgs_NoSigningAlgorithm(self):
- pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
- with open(pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(pubkey))
-
- # Tests no --gki_signing_* args are appended if there is no
- # gki_signing_algorithm.
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- # 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
-
- cmd = ['mkbootimg', '--header_version', '4']
- expected_cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs(self):
- pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
- with open(pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(pubkey))
-
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
- cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
-
- expected_cmd = [
- 'mkbootimg', '--header_version', '4',
- '--gki_signing_key', pubkey,
- '--gki_signing_algorithm', 'SHA256_RSA4096',
- '--gki_signing_signature_args', '--prop foo:bar'
- ]
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_KeyPathNotFound(self):
+ def test_GenerateGkiCertificate_KeyPathNotFound(self):
pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem')
self.assertFalse(os.path.exists(pubkey))
@@ -1699,41 +1640,11 @@
'gki_signing_algorithm': 'SHA256_RSA4096',
'gki_signing_signature_args': '--prop foo:bar',
}
- cmd = ['mkbootimg', '--header_version', '4']
- self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
+ test_file = tempfile.NamedTemporaryFile()
+ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
+ test_file.name, 'generic_kernel', 'boot')
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_SearchKeyPath(self):
- pubkey = 'testkey_gki.pem'
- self.assertFalse(os.path.exists(pubkey))
-
- # Tests it should replace the pubkey with an existed key under
- # OPTIONS.search_path, i.e., os.path.join(OPTIONS.search_path, pubkey).
- search_path_dir = common.MakeTempDir()
- search_pubkey = os.path.join(search_path_dir, pubkey)
- with open(search_pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(search_pubkey))
-
- common.OPTIONS.search_path = search_path_dir
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
- cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
-
- expected_cmd = [
- 'mkbootimg', '--header_version', '4',
- '--gki_signing_key', search_pubkey,
- '--gki_signing_algorithm', 'SHA256_RSA4096',
- '--gki_signing_signature_args', '--prop foo:bar'
- ]
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_SearchKeyPathNotFound(self):
+ def test_GenerateGkiCertificate_SearchKeyPathNotFound(self):
pubkey = 'no_testkey_gki.pem'
self.assertFalse(os.path.exists(pubkey))
@@ -1749,9 +1660,9 @@
'gki_signing_algorithm': 'SHA256_RSA4096',
'gki_signing_signature_args': '--prop foo:bar',
}
- cmd = ['mkbootimg', '--header_version', '4']
- self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
-
+ test_file = tempfile.NamedTemporaryFile()
+ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
+ test_file.name, 'generic_kernel', 'boot')
class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
"""Checks the format of install-recovery.sh.
diff --git a/tools/warn/html_writer.py b/tools/warn/html_writer.py
index ef173bc..3fa822a 100644
--- a/tools/warn/html_writer.py
+++ b/tools/warn/html_writer.py
@@ -63,6 +63,11 @@
from .severity import Severity
+# Report files with this number of warnings or more.
+LIMIT_WARNINGS_PER_FILE = 100
+# Report files/directories with this percentage of total warnings or more.
+LIMIT_PERCENT_WARNINGS = 1
+
HTML_HEAD_SCRIPTS = """\
<script type="text/javascript">
function expand(id) {
@@ -89,12 +94,13 @@
</script>
<style type="text/css">
th,td{border-collapse:collapse; border:1px solid black;}
- .button{color:blue;font-size:110%;font-weight:bolder;}
+ .button{color:blue;font-size:100%;font-weight:bolder;}
.bt{color:black;background-color:transparent;border:none;outline:none;
font-size:140%;font-weight:bolder;}
.c0{background-color:#e0e0e0;}
.c1{background-color:#d0d0d0;}
.t1{border-collapse:collapse; width:100%; border:1px solid black;}
+ .box{margin:5pt; padding:5pt; border:1px solid;}
</style>
<script src="https://www.gstatic.com/charts/loader.js"></script>
"""
@@ -287,14 +293,14 @@
# sort by project, severity, warn_id, warning_message
def emit_buttons(writer):
"""Write the button elements in HTML."""
- writer('<button class="button" onclick="expandCollapse(1);">'
+ writer('<p><button class="button" onclick="expandCollapse(1);">'
'Expand all warnings</button>\n'
'<button class="button" onclick="expandCollapse(0);">'
'Collapse all warnings</button>\n'
- '<button class="button" onclick="groupBySeverity();">'
+ '<p><button class="button" onclick="groupBySeverity();">'
'Group warnings by severity</button>\n'
'<button class="button" onclick="groupByProject();">'
- 'Group warnings by project</button><br>')
+ 'Group warnings by project</button>')
def all_patterns(category):
@@ -559,6 +565,11 @@
"""
+# Emit a JavaScript const number
+def emit_const_number(name, value, writer):
+ writer('const ' + name + ' = ' + str(value) + ';')
+
+
# Emit a JavaScript const string
def emit_const_string(name, value, writer):
writer('const ' + name + ' = "' + escape_string(value) + '";')
@@ -602,6 +613,8 @@
emit_const_string('FlagPlatform', flags.platform, writer)
emit_const_string('FlagURL', flags.url, writer)
emit_const_string('FlagSeparator', flags.separator, writer)
+ emit_const_number('LimitWarningsPerFile', LIMIT_WARNINGS_PER_FILE, writer)
+ emit_const_number('LimitPercentWarnings', LIMIT_PERCENT_WARNINGS, writer)
emit_const_string_array('SeverityColors', [s.color for s in Severity.levels],
writer)
emit_const_string_array('SeverityHeaders',
@@ -624,8 +637,8 @@
DRAW_TABLE_JAVASCRIPT = """
google.charts.load('current', {'packages':['table']});
-google.charts.setOnLoadCallback(drawTable);
-function drawTable() {
+google.charts.setOnLoadCallback(genTables);
+function genSelectedProjectsTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', StatsHeader[0]);
for (var i=1; i<StatsHeader.length; i++) {
@@ -638,12 +651,167 @@
}
}
var table = new google.visualization.Table(
- document.getElementById('stats_table'));
+ document.getElementById('selected_projects_section'));
table.draw(data, {allowHtml: true, alternatingRowStyle: true});
}
+// Global TopDirs and TopFiles are computed later by genTables.
+window.TopDirs = [];
+window.TopFiles = [];
+function computeTopDirsFiles() {
+ var numWarnings = WarningMessages.length;
+ var warningsOfFiles = {};
+ var warningsOfDirs = {};
+ var subDirs = {};
+ function addOneWarning(map, key) {
+ map[key] = 1 + ((key in map) ? map[key] : 0);
+ }
+ for (var i = 0; i < numWarnings; i++) {
+ var file = WarningMessages[i].replace(/:.*/, "");
+ addOneWarning(warningsOfFiles, file);
+ var dirs = file.split("/");
+ var dir = dirs[0];
+ addOneWarning(warningsOfDirs, dir);
+ for (var d = 1; d < dirs.length - 1; d++) {
+ var subDir = dir + "/" + dirs[d];
+ if (!(dir in subDirs)) {
+ subDirs[dir] = {};
+ }
+ subDirs[dir][subDir] = 1;
+ dir = subDir;
+ addOneWarning(warningsOfDirs, dir);
+ }
+ }
+ var minDirWarnings = numWarnings*(LimitPercentWarnings/100);
+ var minFileWarnings = Math.min(LimitWarningsPerFile, minDirWarnings);
+ // Each row in TopDirs and TopFiles has
+ // [index, {v:<num_of_warnings>, f:<percent>}, file_or_dir_name]
+ function countWarnings(minWarnings, warningsOf, isDir) {
+ var rows = [];
+ for (var name in warningsOf) {
+ if (isDir && name in subDirs && Object.keys(subDirs[name]).length < 2) {
+ continue; // skip a directory if it has only one subdir
+ }
+ var count = warningsOf[name];
+ if (count >= minWarnings) {
+ name = isDir ? (name + "/...") : name;
+ var percent = (100*count/numWarnings).toFixed(1);
+ var countFormat = count + ' (' + percent + '%)';
+ rows.push([0, {v:count, f:countFormat}, name]);
+ }
+ }
+ rows.sort((a,b) => b[1].v - a[1].v);
+ for (var i=0; i<rows.length; i++) {
+ rows[i][0] = i;
+ }
+ return rows;
+ }
+ TopDirs = countWarnings(minDirWarnings, warningsOfDirs, true);
+ TopFiles = countWarnings(minFileWarnings, warningsOfFiles, false);
+}
+function genTopDirsFilesTables() {
+ computeTopDirsFiles();
+ function addTable(name, divName, rows, clickFunction) {
+ var data = new google.visualization.DataTable();
+ data.addColumn("number", "index"); // not shown in view
+ data.addColumn("number", "# of warnings");
+ data.addColumn("string", name);
+ data.addRows(rows);
+ var formatter = new google.visualization.PatternFormat(
+ '<p onclick="' + clickFunction + '({0})">{2}</p>');
+ formatter.format(data, [0, 1, 2], 2);
+ var view = new google.visualization.DataView(data);
+ view.setColumns([1,2]); // hide the index column
+ var table = new google.visualization.Table(
+ document.getElementById(divName));
+ table.draw(view, {allowHtml: true, alternatingRowStyle: true});
+ }
+ addTable("Directory", "top_dirs_table", TopDirs, "selectDir");
+ addTable("File", "top_files_table", TopFiles, "selectFile");
+}
+function selectDirFile(idx, rows, dirFile) {
+ if (rows.length <= idx) {
+ return;
+ }
+ var name = rows[idx][2];
+ var spanName = "selected_" + dirFile + "_name";
+ document.getElementById(spanName).innerHTML = name;
+ var divName = "selected_" + dirFile + "_warnings";
+ var numWarnings = rows[idx][1].v;
+ var prefix = name.replace(/\\.\\.\\.$/, "");
+ var data = new google.visualization.DataTable();
+ data.addColumn('string', numWarnings + ' warnings in ' + name);
+ var getWarningMessage = (FlagPlatform == "chrome")
+ ? ((x) => addURLToLine(WarningMessages[Warnings[x][2]],
+ WarningLinks[Warnings[x][3]]))
+ : ((x) => addURL(WarningMessages[Warnings[x][2]]));
+ for (var i = 0; i < Warnings.length; i++) {
+ if (WarningMessages[Warnings[i][2]].startsWith(prefix)) {
+ data.addRow([getWarningMessage(i)]);
+ }
+ }
+ var table = new google.visualization.Table(
+ document.getElementById(divName));
+ table.draw(data, {allowHtml: true, alternatingRowStyle: true});
+}
+function selectDir(idx) {
+ selectDirFile(idx, TopDirs, "directory")
+}
+function selectFile(idx) {
+ selectDirFile(idx, TopFiles, "file");
+}
+function genTables() {
+ genSelectedProjectsTable();
+ if (WarningMessages.length > 1) {
+ genTopDirsFilesTables();
+ }
+}
"""
+def dump_boxed_section(writer, func):
+ writer('<div class="box">')
+ func()
+ writer('</div>')
+
+
+def dump_section_header(writer, table_name, section_title):
+ writer('<h3><b><button id="' + table_name + '_mark" class="bt"\n' +
+ ' onclick="expand(\'' + table_name + '\');">⊕</button></b>\n' +
+ section_title + '</h3>')
+
+
+def dump_table_section(writer, table_name, section_title):
+ dump_section_header(writer, table_name, section_title)
+ writer('<div id="' + table_name + '" style="display:none;"></div>')
+
+
+def dump_dir_file_section(writer, dir_file, table_name, section_title):
+ section_name = 'top_' + dir_file + '_section'
+ dump_section_header(writer, section_name, section_title)
+ writer('<div id="' + section_name + '" style="display:none;">')
+ writer('<div id="' + table_name + '"></div>')
+ def subsection():
+ subsection_name = 'selected_' + dir_file + '_warnings'
+ subsection_title = ('Warnings in <span id="selected_' + dir_file +
+ '_name">(click a ' + dir_file +
+ ' in the above table)</span>')
+ dump_section_header(writer, subsection_name, subsection_title)
+ writer('<div id="' + subsection_name + '" style="display:none;"></div>')
+ dump_boxed_section(writer, subsection)
+ writer('</div>')
+
+
+# HTML output has the following major div elements:
+# selected_projects_section
+# top_directory_section
+# top_dirs_table
+# selected_directory_warnings
+# top_file_section
+# top_files_table
+# selected_file_warnings
+# all_warnings_section
+# warning_groups
+# fixed_warnings
def dump_html(flags, output_stream, warning_messages, warning_links,
warning_records, header_str, warn_patterns, project_names):
"""Dump the flags output to output_stream."""
@@ -651,20 +819,44 @@
dump_html_prologue('Warnings for ' + header_str, writer, warn_patterns,
project_names)
dump_stats(writer, warn_patterns)
- writer('<br><div id="stats_table"></div><br>')
- writer('\n<script>')
- emit_js_data(writer, flags, warning_messages, warning_links, warning_records,
- warn_patterns, project_names)
- writer(SCRIPTS_FOR_WARNING_GROUPS)
- writer('</script>')
- emit_buttons(writer)
- # Warning messages are grouped by severities or project names.
- writer('<br><div id="warning_groups"></div>')
- if flags.byproject:
- writer('<script>groupByProject();</script>')
- else:
- writer('<script>groupBySeverity();</script>')
- dump_fixed(writer, warn_patterns)
+ writer('<br><br>Press ⊕ to show section content,'
+ ' and ⊖ to hide the content.')
+ def section1():
+ dump_table_section(writer, 'selected_projects_section',
+ 'Number of warnings in preselected project directories')
+ def section2():
+ dump_dir_file_section(
+ writer, 'directory', 'top_dirs_table',
+ 'Directories with at least ' +
+ str(LIMIT_PERCENT_WARNINGS) + '% warnings')
+ def section3():
+ dump_dir_file_section(
+ writer, 'file', 'top_files_table',
+ 'Files with at least ' +
+ str(LIMIT_PERCENT_WARNINGS) + '% or ' +
+ str(LIMIT_WARNINGS_PER_FILE) + ' warnings')
+ def section4():
+ writer('<script>')
+ emit_js_data(writer, flags, warning_messages, warning_links,
+ warning_records, warn_patterns, project_names)
+ writer(SCRIPTS_FOR_WARNING_GROUPS)
+ writer('</script>')
+ dump_section_header(writer, 'all_warnings_section',
+ 'All warnings grouped by severities or projects')
+ writer('<div id="all_warnings_section" style="display:none;">')
+ emit_buttons(writer)
+ # Warning messages are grouped by severities or project names.
+ writer('<br><div id="warning_groups"></div>')
+ if flags.byproject:
+ writer('<script>groupByProject();</script>')
+ else:
+ writer('<script>groupBySeverity();</script>')
+ dump_fixed(writer, warn_patterns)
+ writer('</div>')
+ dump_boxed_section(writer, section1)
+ dump_boxed_section(writer, section2)
+ dump_boxed_section(writer, section3)
+ dump_boxed_section(writer, section4)
dump_html_epilogue(writer)
diff --git a/tools/warn/tidy_warn_patterns.py b/tools/warn/tidy_warn_patterns.py
index a5842ea..c138f1c 100644
--- a/tools/warn/tidy_warn_patterns.py
+++ b/tools/warn/tidy_warn_patterns.py
@@ -224,6 +224,9 @@
analyzer_warn_check('clang-analyzer-valist.Unterminated'),
analyzer_group_check('clang-analyzer-core.uninitialized'),
analyzer_group_check('clang-analyzer-deadcode'),
+ analyzer_warn_check('clang-analyzer-security.insecureAPI.bcmp'),
+ analyzer_warn_check('clang-analyzer-security.insecureAPI.bcopy'),
+ analyzer_warn_check('clang-analyzer-security.insecureAPI.bzero'),
analyzer_warn_check('clang-analyzer-security.insecureAPI.strcpy'),
analyzer_group_high('clang-analyzer-security.insecureAPI'),
analyzer_group_high('clang-analyzer-security'),
diff --git a/tools/zipalign/tests/src/align_test.cpp b/tools/zipalign/tests/src/align_test.cpp
index 96d4f73..ff45187 100644
--- a/tools/zipalign/tests/src/align_test.cpp
+++ b/tools/zipalign/tests/src/align_test.cpp
@@ -3,6 +3,7 @@
#include "ZipAlign.h"
+#include <filesystem>
#include <stdio.h>
#include <string>
@@ -16,9 +17,15 @@
return test_data_dir + filename;
}
+static std::string GetTempPath(const std::string& filename) {
+ std::filesystem::path temp_path = std::filesystem::path(testing::TempDir());
+ temp_path += filename;
+ return temp_path.string();
+}
+
TEST(Align, Unaligned) {
const std::string src = GetTestPath("unaligned.zip");
- const std::string dst = GetTestPath("unaligned_out.zip");
+ const std::string dst = GetTempPath("unaligned_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -29,8 +36,8 @@
TEST(Align, DoubleAligment) {
const std::string src = GetTestPath("unaligned.zip");
- const std::string tmp = GetTestPath("da_aligned.zip");
- const std::string dst = GetTestPath("da_d_aligner.zip");
+ const std::string tmp = GetTempPath("da_aligned.zip");
+ const std::string dst = GetTempPath("da_d_aligner.zip");
int processed = process(src.c_str(), tmp.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -60,7 +67,7 @@
// Directory.
TEST(Align, Holes) {
const std::string src = GetTestPath("holes.zip");
- const std::string dst = GetTestPath("holes_out.zip");
+ const std::string dst = GetTempPath("holes_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);
@@ -72,7 +79,7 @@
// Align a zip where LFH order and CD entries differ.
TEST(Align, DifferenteOrders) {
const std::string src = GetTestPath("diffOrders.zip");
- const std::string dst = GetTestPath("diffOrders_out.zip");
+ const std::string dst = GetTempPath("diffOrders_out.zip");
int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
ASSERT_EQ(0, processed);