Date: Sat, 15 Aug 2009 01:16:11 GMT From: Alejandro Pulver <alepulver@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 167348 for review Message-ID: <200908150116.n7F1GB7v075555@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167348 Change 167348 by alepulver@alepulver_deimos on 2009/08/15 01:16:05 - Move ask-license to _PATCH_SEQ, and add private cookie to avoid asking twice if patch target fails. - Rework bsd.licenses.mk to include dual/multiple licenses support. - Add dialog based GUI interface, and text interface (similar to NetBSD). - Remove inheritance from groups and leave them as tags for now (otherwise it overcomplicates things unnecessarily) - No more saving for now (there were 3 sources of configuration before). - Rename "redist" to "mirror" to avoid confusing with "dist" (of distfiles). - Add reports with an option to disable. - Replace current bsd.port.mk section for restricted files removal if LICENSE is defined (some clean-* targets). - Some minor changes and fixes. Affected files ... .. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.db.mk#4 edit .. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.mk#9 edit .. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.port.mk#8 edit .. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/test-license-1/Makefile#4 edit Differences ... ==== //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.db.mk#4 (text+ko) ==== @@ -18,6 +18,12 @@ # http://en.wikipedia.org/wiki/Comparison_of_free_software_licences # # Probably will be automatically incorporated from FOSSology's software. +# +# IMPORTANT: as this file is going to be included by most ports, we may +# consider having licenses here only as "tags" as most of them will be free, +# to remove some loops and additional variables here. This will not affect the +# rest of bsd.licenses.mk, and anyways restricted licenses that aren't used by +# many ports should be defined in each one's Makefile. # XXX Start of editable section @@ -30,68 +36,60 @@ _LICENSE_LIST= ASL BSD BSL CDDL GPLv2 GPLv3 LGPL MIT MPL _LICENSE_LIST_GROUPS= FSF GPL OSI -# Properties of license/group "xxx" (similar to port's variables, but single) +# List of groups (only names must be present) + +_LICENSE_NAME_FSF= Free Software Foundation Approved + +_LICENSE_NAME_GPL= GPL Compatible + +_LICENSE_NAME_OSI= OSI Approved + +# Default permissions for licenses here, if not defined + +_LICENSE_PERMS_DEFAULT= dist-mirror dist-sell pkg-mirror pkg-sell auto-accept + +# Properties of license "xxx" (similar to port variables, but single) +# # _LICENSE_NAME_xxx - Full name/description of license/group -# _LICENSE_PERMS_xxx - Permissions -# _LICENSE_COMPAT_xxx - Compatibility -# _LICENSE_INCOMPAT_xxx - Incompatibility +# _LICENSE_PERMS_xxx - Permissions (if not defined defaults to +# ${_LICENSE_PERMS_DEFAULT}. +# _LICENSE_GROUPS_xxx - Groups (optional) +# +# Notes: +# - General permissions from groups are added to each license, if not defined. +# -# List of licenses - _LICENSE_NAME_ASL= Apache License +_LICENSE_GROUPS_ASL= FSF OSI _LICENSE_NAME_BSD= BSD license +_LICENSE_GROUPS_BSD= FSF OSI _LICENSE_NAME_BSL= Boost Software License +_LICENSE_GROUPS_BSL= FSF OSI _LICENSE_NAME_CDDL= Common Development and Distribution License +_LICENSE_GROUPS_CDDL= FSF OSI _LICENSE_NAME_GPLv2= GNU General Public License version 2 +_LICENSE_NAME_GPLv2= FSF GPL OSI _LICENSE_NAME_GPLv3= GNU General Public License version 3 -_LICENSE_PERMS_GPLv3= no-pkg +_LICENSE_GROUPS_GPLv3= FSF GPL OSI _LICENSE_NAME_LGPL= GNU Lesser General Public License +_LICENSE_GROUPS_LGPL= FSF GPL OSI _LICENSE_NAME_MIT= MIT license / X11 license +_LICENSE_GROUPS_MIT= FSF GPL OSI _LICENSE_NAME_MPL= Mozilla Public License +_LICENSE_GROUPS_MPL= FSF OSI -# List of groups +# Set default permissions if not defined -_LICENSE_NAME_FSF= Free Software Foundation Approved -_LICENSE_PERMS_FSF= pkg-redist dist-redist pkg-sell dist-sell auto-accept - -_LICENSE_NAME_GPL= GPL Compatible -_LICENSE_PERMS_GPL= pkg-redist dist-redist pkg-sell dist-sell auto-accept - -_LICENSE_NAME_OSI= OSI Approved -_LICENSE_PERMS_OSI= pkg-redist dist-redist pkg-sell dist-sell auto-accept - -# Grouping -# -# - Method 1: -# _LICENSE_LIST_GROUP_xxx - List of licenses under the "xxx" group - -_LICENSE_LIST_GROUP_FSF= ASL BSD BSL CDDL GPLv2 GPLv3 LGPL MIT MPL - -_LICENSE_LIST_GROUP_GPL= GPLv2 GPLv3 LGPL MIT - -_LICENSE_LIST_GROUP_OSI= ASL BSD BSL CDDL GPLv2 GPLv3 LGPL MIT MPL - -# - Method 2: -# _LICENSE_GROUPS_xxx - Groups the license/group belongs to - -# empty - -# XXX End of editable section - -# Method 1 expands to method 2 -.for group in ${_LICENSE_LIST_GROUPS} -. for lic in ${_LICENSE_LIST_GROUP_${group}} -_LICENSE_GROUPS_${lic}?= # -. if ${_LICENSE_GROUPS_${lic}:M${group}} == "" -_LICENSE_GROUPS_${lic}+= ${group} -. endif -. endfor +.for lic in ${_LICENSE_LIST} +. if !defined(_LICENSE_PERMS_${lic}) +_LICENSE_PERMS_${lic}= ${_LICENSE_PERMS_DEFAULT} +. endif .endfor ==== //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.mk#9 (text+ko) ==== @@ -10,108 +10,117 @@ # Please view me with 4 column tabs! # +# TODO: +# - Bring back save and checksum with new dialog interface (only offers to do +# so if ran by root, otherwise silently remove the options). Also only allow +# saving per-port options (known or unknown), and only when accepted. +# - Add custom restriction targets for better integration (now some files are +# removed from FTP if restricted for CDROM for example, as the old +# behavior). + # The following cases are not considered: # -# - Redistribution of modified distfiles, because is never been done. +# - Redistribution of modified distfiles, because is never done. # - Creating binaries from modified sources, because packages almost always -# contain modifications to the source, and can not be autodetected (i.e. +# contain modifications to the source, can not be autodetected (i.e. # patch-* in ${FILESDIR}, post-* targets, etc), and these licenses tend to -# have more restrictions. +# have more restrictions anyways. # # Integration with target sequences # # _SANITY_SEQ+= check-license (after check-vulnerable) -# _EXTRACT_SEQ+= ask-license (after post-extract-script) +# _PATCH_SEQ+= ask-license (before any other targets) # _INSTALL_SUSEQ+= install-license (after install-desktop-entries) # -# The 'check-license' target will determine if the license was rejected or has -# to be asked later in 'ask-license' (by then LICENSE_FILE should be available -# for presenting to the user). -# The 'install-license' target installs both the application's license and a -# restriction report (to be used by ports scripts and similar tools). +# The 'check-license' target will determine if the license was accepted, +# rejected or has to be asked later to the user in 'ask-license' (by then +# licenses should be extracted). The 'install-license' target installs the +# applications' licenses, a general package license mentioning them, and a +# restriction report (to be used by ports, scripts and similar tools). -# Variables provided to users +# Variables provided to the ports system and users in general, to modify the +# behavior of the framework # -# LICENSES_ACCEPTED - Accepted licenses and groups. -# LICENSES_REJECTED - Rejected licenses and groups. -# LICENSE_ASK - Require explicit user approval for all licenses not -# present in configuration nor LICENSES_ACCEPTED. -# LICENSES_CONFIG - If defined, will ask again when already saved +# NO_LICENSES_INSTALL - Do not install catalog, report and licenses. +# NO_LICENSES_DIALOGS - Disable interactive menus for asking licenses. + +#NO_LICENSES_INSTALL= yes +#NO_LICENSES_DIALOGS= yes + +# Variables provided to users (can be passed to make or set in /etc/make.conf) # -# The components of LICENSES_{ACCEPTED,REJECTED} can be one of: -# - A license code (like "GPLv2"). -# - A license group prefixed by '@' (like "@OSI"). +# LICENSES_ACCEPTED - Accepted licenses. +# LICENSES_REJECTED - Rejected licenses. +# LICENSES_GROUPS_ACCEPTED - Accepted license groups. +# LICENSES_GROUPS_REJECTED - Rejected license groups. +# LICENSES_ASK - Require explicit user approval for all licenses not +# present in previous variables (for example, stock +# accepted licenses will ask confirmation). # -# Note that the framework configuration format is the same (without groups -# syntax), but stored in ${LICENSE_CFG} or ${LICENSE_CFG_PORT}. The user -# variables take precedence (anyways the other configuration is also made by -# the user). -# # Variables provided to ports # # LICENSE - Code of license (short name). # LICENSE_PERMS - Permissions; use "none" if empty. # LICENSE_GROUPS - Groups the license belongs. -# LICENSE_COMPAT - Compatibility with other licenses/groups (default: all). -# LICENSE_INCOMPAT - Incompatibility with other licenses/groups (default: none). # LICENSE_NAME - Full license name (for the reports). -# LICENSE_NOTES - A note about restrictions (not needed), to replace -# RESTRICTED and ports/LEGAL. # LICENSE_FILE - Full path to license (or use LICENSE_TEXT). # LICENSE_TEXT - Text to use as a license, useful when referencing to # another place if it's not in the distfile. -# LICENSE_DISTFILE - Name of licensed files (defaults to ${DISTFILES}). +# LICENSE_DISTFILES - Name of licensed files (defaults to ${_DISTFILES}). +# LICENSE_COMB - Set to "dual" or "multi", for OR/AND behavior +# (defaults to "single" if undefined, the common case) # -# The following cases are supported (see _LICENSE_TYPE): +# The following cases are supported after defining LICENSE: # # Case 1: license defined in the framework (aka "known"). -# Define LICENSE; framework defines license variables, by redefining any of -# them the port falls in Case 2. # -# Case 2: license is based on a defined one (aka "variant"). -# All license variables must be defined by the port (but LICENSE is set to -# a known value). -# XXX This case is being considered, and if it has to inherit properties from -# its base license or just let it fall in Case 3 (as now). +# In this case the only allowed variables to set are LICENSE_FILE and +# LICENSE_DISTFILES. The rest are managed by the framework and are not allowed +# to change. # -# Case 3: license only known by the port (aka "unknown"). -# All license variables must be defined by the port. +# Case 2: license only known by the port (aka "unknown"). # -# Notes: -# - Permissions use a default-deny policy (that's why groups are there). -# - Adding a license to a group makes it inherit their properties (PERMS, -# GROUPS and COMPAT/INCOMPAT). -# - Components can be negated by prefixing them with "no-" (like -# "no-pkg-sell"). Useful for exceptions. -# - For multiple licenses components can be grouped, for example: -# LICENSE= GPLv2 BSD -# LICENSE_PERMS= GPLv2:no-pkg-sell,pkg-redist BSD:no-pkg-sell,pkg-redist -# LICENSE_NOTES= GPLv2:"No sell" BSD:"Allows everything" +# In this case LICENSE_{PERMS,NAME} are mandatory, in addition to +# either LICENSE_FILE or LICENSE_TEXT. Optional variables are +# LICENSE_{GROUPS,NOTES}. # # Available components for LICENSE_PERMS: -# dist-redist - No free redistribution of distfile (like FTP mirroring; RESTRICTED). +# dist-mirror - No free redistribution of distfile (like FTP mirroring; RESTRICTED). # dist-sell - No selling of distfile (like in CD-ROM; NO_CDROM). -# pkg-redist - No free redistribution of package (like FTP upload; NO_PACKAGE). +# pkg-mirror - No free redistribution of package (like FTP upload; NO_PACKAGE). # pkg-sell - No selling of package (like in CD-ROM; NO_CDROM). -# auto-accept - If license is accepted by default, without presented agreement. -# none - Explicit universal restriction (to make sure that is the intention). -# And the following aliases (can also be negated): pkg, dist, sell and redist. +# auto-accept - If license is accepted by default, without presented +# agreement, at least the user defines LICENSES_ASK. +# +# Notes about permissions: +# - Permissions use a default-deny policy. +# - Components can be negated by prefixing them with "no-" (like +# "no-pkg-sell"). +# - In case a component is present and also excluded (i.e. no-dist-sell and +# dist-sell together in LICENSE_PERMS), it will be excluded. +# - XXX Currently there is no point in "no-" prefixes, as permissions are not +# inherited from groups. Maybe it looks more clear that way than leaving the +# variable empty? +# +# Dual/multiple licenses: +# +# If LICENSE_COMB is set to "dual", then LICENSE can (must, actually) have +# more than one component. After that each license "lic" in LICENSE falls in +# previous cases (known or unknown), but their variables are prefixed by +# _LICENSE_ and suffixed by _lic. The main license name, perms and groups will +# be set automatically (following appropiate logic). The idea is that any +# license from LICENSE can be chosen to use the package. +# +# The case when LICENSE_COMB is set to "multi" is similar. But the idea is +# that all of the licenses in LICENSE must be agreed to use the package. # .if defined(_POSTMKINCLUDED) && !defined(BEFOREPORTMK) .if defined(LICENSE) -# Organization -# - Define common license properties. -# - Define internal variables. -# - Check for single or multiple port licenses. -# - Check defined properties and compare with database. -# - Check user and framework configuration. -# - Define targets. - # Include known licenses from database .include "${PORTSDIR}/Mk/bsd.licenses.db.mk" @@ -120,244 +129,418 @@ # # _LICENSE_LIST_PERMS - Valid permission components # _LICENSE_LIST_PORT_VARS - License variables defined by the port -# _LICENSE_LIST_GROUP_VARS - License variables inherited from groups -# _LICENSE_LIST_SAVE_VARS - License variables present in the report -_LICENSE_LIST_PERMS= dist-redist dist-sell pkg-redist pkg-sell auto-accept none -_LICENSE_LIST_PORT_VARS= PERMS GROUPS NAME COMPAT INCOMPAT -_LICENSE_LIST_GROUP_VARS= PERMS COMPAT INCOMPAT -_LICENSE_LIST_SAVE_VARS= _LICENSE _LICENSE_NOTES _LICENSE_DISTFILES \ - _LICENSE_COMPAT _LICENSE_INCOMPAT ${_LICENSE_LIST_PORT_VARS:S/^/_LICENSE_/} - -# Defaults +_LICENSE_LIST_PERMS= dist-mirror dist-sell pkg-mirror pkg-sell auto-accept none +_LICENSE_LIST_PORT_VARS= PERMS NAME GROUPS -LICENSE_DISTFILE?= ${DISTFILES} -# XXX internal variables will be useful for multiple licenses -_LICENSE= ${LICENSE} -_LICENSE_NOTES= ${LICENSE_NOTES} -_LICENSE_DISTFILE= ${LICENSE_DISTFILE} - # Path variables # # _LICENSE_DIR - Directory to install licenses # _LICENSE_DIR_REL - Same as above, without ${PREFIX} -# _LICENSE_CFG_GLOB - Global license configuration file -# _LICENSE_CFG_PORT - Per port license configuration file -# _LICENSE_REPORT - License report to be created (under ${LICENSE_DIR}) +# _LICENSE_CATALOG - License catalog (make include file) to be created (dst) +# _LICENSE_CATALOG_TMP - Same as above, but in WRKDIR (src) +# _LICENSE_REPORT - License summary, shows licenses and how they are combined (dst) +# _LICENSE_REPORT_TMP - Same as above, but in WRKDIR (src) +# _LICENSE_COOKIE - Set when license is accepted, it is not present in +# bsd.port.mk to avoid creating LICENSE_{REQ,SEQ} for a +# few more targets only. + +_LICENSE_DIR?= ${PREFIX}/share/licenses/${PKGNAME} +_LICENSE_DIR_REL?= share/licenses/${PKGNAME} +_LICENSE_CATALOG?= ${_LICENSE_DIR}/catalog.mk +_LICENSE_CATALOG_TMP?= ${WRKDIR}/.license-catalog.mk +_LICENSE_REPORT?= ${_LICENSE_DIR}/LICENSE +_LICENSE_REPORT_TMP?= ${WRKDIR}/.license-report +_LICENSE_COOKIE?= ${WRKDIR}/.license_done.${PORTNAME}.${PREFIX:S/\//_/g} + +# Defaults (never overriden for now) +# +# _LICENSE - Copy of LICENSE (for now) +# _LICENSE_COMB - Copy of LICENSE_COMB (but "single" instead of empty) -_LICENSE_DIR?= ${PREFIX}/share/licenses/${UNIQUENAME} -_LICENSE_DIR_REL?= share/licenses/${UNIQUENAME} -_LICENSE_CFG_GLOB?= ${PORT_DBDIR}/license-config -_LICENSE_CFG_PORT?= ${PORT_DBDIR}/${UNIQUENAME}/license -_LICENSE_REPORT?= ${_LICENSE_DIR}/report +_LICENSE?= ${LICENSE} +.if !defined(LICENSE_COMB) +_LICENSE_COMB= single +.else +_LICENSE_COMB= ${LICENSE_COMB} +.endif # Check if single or dual/multiple license # -# _LICENSE_SINGLE - Defined for a single license -# _LICENSE_MULTI - Set to "and"/"or"? (XXX Not implemented) +# Make sure LICENSE_COMB is only used with more than one license. + +.if ${_LICENSE_COMB} != "single" && ${_LICENSE_COMB} != "dual" && ${_LICENSE_COMB} != "multi" +_LICENSE_ERROR?= invalid value for LICENSE_COMB: "${_LICENSE_COMB}" (should be "single", "dual" or "multi") +.endif -#.for lic in ${_LICENSE} -#. if defined(_LICENSE_DEFINED) -#_LICENSE_MULTI= yes -#. else -#_LICENSE_DEFINED?= ${lic} -#. endif -#.endfor -#.if !defined(_LICENSE_MULTI) -#_LICENSE_SINGLE= yes -#.endif -#.undef _LICENSE_DEFINED +.for lic in ${_LICENSE} +. if defined(_LICENSE_DEFINED) +. if ${_LICENSE_COMB} == "single" +_LICENSE_ERROR?= multiple licenses in LICENSE, but LICENSE_COMB is set to "single" (or undefined) +. else +_LICENSE_MULTI= yes +. endif +. else +_LICENSE_DEFINED= yes +. endif +.endfor +.if ${_LICENSE_COMB} != "single" && !defined(_LICENSE_MULTI) +_LICENSE_ERROR?= single license in LICENSE, but LICENSE_COMB is set to "${_LICENSE_COMB}" (requires more than one) +.endif +.if !defined(_LICENSE_DEFINED) +_LICENSE_ERROR?= no licenses present in LICENSE (empty string) +.endif +.undef _LICENSE_DEFINED +.undef _LICENSE_MULTI # Evaluate port license groups and permissions # # Available values for _LICENSE_TYPE: +# # Case 1: "known" (license info taken from internal database) -# Case 2: "variant" (LICENSE is known, but info taken from port) -# Case 3: "unknown" (LICENSE is not known, and info taken from port) -# # Make sure required variables are defined, and remove conflicting (positive -# and negative) and duplicated components. +# Case 2: "unknown" (LICENSE is not known, and info taken from port) +# +# Make sure required variables are defined, and remove conflicting (positive +# and negative) duplicated components. -#.if defined(_LICENSE_SINGLE) +.if ${_LICENSE_COMB} == "single" +# Defaults to empty +_LICENSE_GROUPS?= # +# Start . for lic in ${_LICENSE} . if ${_LICENSE_LIST:M${lic}} != "" +# Case 1: license defined in the framework. +_LICENSE_TYPE= known . for var in ${_LICENSE_LIST_PORT_VARS} . if defined(LICENSE_${var}) -_LICENSE_TYPE= variant +_LICENSE_ERROR?= redefining LICENSE_${var} is not allowed for known licenses, to define a custom license try another LICENSE name like ${_LICENSE}-variant . endif -. endfor -_LICENSE_TYPE?= known -. for var in ${_LICENSE_LIST_PORT_VARS} -# Case 1: license defined in the framework. -. if ${_LICENSE_TYPE} == "known" +. if !defined(_LICENSE_${var}_${lic}) +_LICENGE_ERROR?= ERROR: missing _LICENSE_${var}_${lic} in bsd.licenses.db.mk +. else _LICENSE_${var}= ${_LICENSE_${var}_${lic}} -# Case 2: license is based on a defined one. -# XXX Should here be inheritance of non defined values? -. elif ${_LICENSE_TYPE} == "variant" && defined(LICENSE_${var}) -_LICENSE_${var}= ${LICENSE_${var}} . endif . endfor -# Case 3: license only known by the port. +# Check for LICENSE_FILE or at least LICENSE_TEXT (which simulates it) +. if !defined(LICENSE_FILE) +. if !defined(LICENSE_TEXT) +# XXX Until we have a license pool under /usr/ports/Licenses use this +_LICENSE_TEXT= The license: ${_LICENSE} (${_LICENSE_NAME}) is standard, please read from the web. +_LICENSE_FILE= ${WRKDIR}/${lic} +. else +_LICENSE_ERROR?= defining LICENSE_TEXT is not allowed for known licenses +. endif +. else +_LICENSE_FILE= ${LICENSE_FILE} +. endif + . else -_LICENSE_TYPE?= unknown +# Case 2: license only known by the port. +_LICENSE_TYPE= unknown . for var in ${_LICENSE_LIST_PORT_VARS} . if defined(LICENSE_${var}) _LICENSE_${var}= ${LICENSE_${var}} +. else +_LICENSE_ERROR?= for a new/unknown license, defining LICENSE_${var} is mandatory (otherwise use a known LICENSE) . endif . endfor +# Check LICENSE_PERMS for invalid, ambiguous and duplicate components +__LICENSE_PERMS:= # +. for comp in ${_LICENSE_PERMS} +. if ${_LICENSE_LIST_PERMS:M${comp:C/^no-//}} == "" +_LICENSE_ERROR?= invalid LICENSE_PERMS component "${comp}" +. elif ${__LICENSE_PERMS:M${comp}} == "" && \ + ${_LICENSE_PERMS:Mno-${comp:C/^no-//}} == "" +__LICENSE_PERMS+= ${comp} +. endif +. endfor +_LICENSE_PERMS:= ${__LICENSE_PERMS} +. undef __LICENSE_PERMS +# Check for LICENSE_FILE or at least LICENSE_TEXT (which simulates it) +. if !defined(LICENSE_FILE) +. if !defined(LICENSE_TEXT) +_LICENSE_ERROR?= either LICENSE_FILE or LICENSE_TEXT must be defined +. else +_LICENSE_TEXT= ${LICENSE_TEXT} +_LICENSE_FILE= ${WRKDIR}/${lic} +. endif +. else +_LICENSE_FILE= ${LICENSE_FILE} +. endif +. endif + +# Only one is allowed +. if defined(LICENSE_FILE) && defined(LICENSE_TEXT) +_LICENSE_ERROR?= defining both LICENSE_FILE and LICENSE_TEXT is not allowed . endif -# XXX Some defaults (here they do not affect _LICENSE_TYPE). -_LICENSE_COMPAT?= # -_LICENSE_INCOMPAT?= # -_LICENSE_GROUPS?= # -# Check everything needed is defined. -. for var in ${_LICENSE_LIST_PORT_VARS} -. if !defined(_LICENSE_${var}) -. if ${_LICENSE_TYPE} == "variant" -_LICENSE_ERROR?= for a modified license, defining LICENSE_${var} is mandatory (otherwise define LICENSE alone) -. elif ${_LICENSE_TYPE} == "unknown" -_LICENSE_ERROR?= for a new/unknown license, defining LICENSE_${var} is mandatory (otherwise use a known LICENSE) +# Distfiles +. if !defined(LICENSE_DISTFILES) +_LICENSE_DISTFILES= ${_DISTFILES} +. else +_LICENSE_DISTFILES= ${LICENSE_DISTFILES} +. endif +. endfor + +.else +. for lic in ${_LICENSE} +# Defaults to empty +_LICENSE_GROUPS_${lic}?=# +. if ${_LICENSE_LIST:M${lic}} != "" +# Case 1: license defined in the framework. +_LICENSE_TYPE_${lic}= known +. for var in ${_LICENSE_LIST_PORT_VARS} +. if defined(LICENSE_${var}_${lic}) +_LICENSE_ERROR?= redefining LICENSE_${var}_${lic} is not allowed for known licenses, to define a custom license try another LICENSE name for ${lic} like ${lic}-variant +. endif +. if !defined(_LICENSE_${var}_${lic}) +_LICENGE_ERROR?= ERROR: missing _LICENSE_${var}_${lic} in bsd.licenses.db.mk +. endif +. endfor +# Check for LICENSE_FILE or at least LICENSE_TEXT (which simulates it) +. if !defined(LICENSE_FILE_${lic}) +. if !defined(LICENSE_TEXT_${lic}) +# XXX Until we have a license pool under /usr/ports/Licenses use this +_LICENSE_TEXT_${lic}= The license: ${lic} (${_LICENSE_NAME_${lic}}) is standard, please read from the web. +_LICENSE_FILE_${lic}= ${WRKDIR}/${lic} +. else +_LICENSE_ERROR?= defining LICENSE_TEXT_${lic} is not allowed for known licenses . endif +. else +_LICENSE_FILE_${lic}= ${LICENSE_FILE_${lic}} . endif -. endfor -# Groups are always inherited (and were expanded so no recursion) -. for group in ${_LICENSE_LIST_GROUPS} -. for var in ${_LICENSE_LIST_GROUP_VARS} -_LICENSE_${var}+= ${_LICENSE_${var}_${group}} + +. else +# Case 2: license only known by the port. +_LICENSE_TYPE_${lic}= unknown +. for var in ${_LICENSE_LIST_PORT_VARS} +. if defined(LICENSE_${var}_${lic}) +_LICENSE_${var}_${lic}= ${LICENSE_${var}_${lic}} +. else +_LICENSE_ERROR?= for a new/unknown license, defining LICENSE_${var}_${lic} is mandatory (otherwise use a known LICENSE) +. endif . endfor -. endfor -# Expand LICENSE_PERMS aliases -# pkg -> pkg-redist pkg-sell -# dist -> dist-redist dist-sell -# redist -> pkg-redist dist-redist -# sell -> pkg-sell dist-sell -_LICENSE_PERMS:= ${_LICENSE_PERMS:Nno-*:C/^(pkg|dist)$/\1-redist \1-sell/:C/^(sell|redist)$/dist-\1 pkg-\1/} \ - ${_LICENSE_PERMS:Mno-*:C/^(no-)(pkg|dist)$/\1\2-redist \1\2-sell/:C/^(no-)(sell|redist)$/\1dist-\2 \1pkg-\2/} -# XXX Cleaner, but outputs an error when (no-)? is not found but referenced later by \1 -#_LICENSE_PERMS:= ${_LICENSE_PERMS:C/^(no-)?(pkg|dist)$/\1\2-redist \1\2-sell/:C/^(no-)?(sell|redist)$/\1dist-\2 \1pkg-\2/} # Check LICENSE_PERMS for invalid, ambiguous and duplicate components __LICENSE_PERMS:= # -. for comp in ${_LICENSE_PERMS} -. if ${_LICENSE_LIST_PERMS:M${comp:C/^no-//}} == "" -_LICENSE_ERROR?= invalid LICENSE_PERMS component "${comp}" -. elif ${__LICENSE_PERMS:M${comp}} == "" && \ - ${_LICENSE_PERMS:Mno-${comp:C/^no-//}} == "" -__LICENSE_PERMS+= ${comp} -. endif -. endfor -_LICENSE_PERMS:= ${__LICENSE_PERMS} -. undef __LICENSE_PERMS +. for comp in ${_LICENSE_PERMS_${lic}} +. if ${_LICENSE_LIST_PERMS:M${comp:C/^no-//}} == "" +_LICENSE_ERROR?= invalid LICENSE_PERMS_${var} component "${comp}" +. elif ${__LICENSE_PERMS:M${comp}} == "" && \ + ${_LICENSE_PERMS_${lic}:Mno-${comp:C/^no-//}} == "" +__LICENSE_PERMS+= ${comp} +. endif +. endfor +_LICENSE_PERMS_${lic}:= ${__LICENSE_PERMS} +. undef __LICENSE_PERMS # Check for LICENSE_FILE or at least LICENSE_TEXT (which simulates it) -# XXX License file is optional for licenses present in database, maybe an option -# could be added to avoid installing licenses present in the database -. if !defined(LICENSE_FILE) -. if !defined(LICENSE_TEXT) -. if ${_LICENSE_TYPE} == "known" -LICENSE_TEXT= License ${lic} is in internal database, check repository. +. if !defined(LICENSE_FILE_${lic}) +. if !defined(LICENSE_TEXT_${lic}) +_LICENSE_ERROR?= either LICENSE_FILE_${lic} or LICENSE_TEXT_${lic} must be defined . else -_LICENSE_ERROR?= LICENSE_FILE or LICENSE_TEXT must be defined for unknown licenses +_LICENSE_TEXT_${lic}= ${LICENSE_TEXT_${lic}} +_LICENSE_FILE_${lic}= ${WRKDIR}/${lic} . endif +. else +_LICENSE_FILE_${lic}= ${LICENSE_FILE_${lic}} . endif -_LICENSE_FILE= ${WRKDIR}/License-freebsd-port +. endif + +# Only one is allowed +. if defined(LICENSE_FILE_${lic}) && defined(LICENSE_TEXT_${lic}) +_LICENSE_ERROR?= defining both LICENSE_FILE_${lic} and LICENSE_TEXT_${lic}is not allowed +. endif +# Distfiles +. if !defined(LICENSE_DISTFILES_${lic}) +_LICENSE_DISTFILES_${lic}= ${_DISTFILES} . else -_LICENSE_FILE= ${LICENSE_FILE} +_LICENSE_DISTFILES_${lic}= ${LICENSE_DISTFILES_${lic}} . endif . endfor -#.else -# XXX dual/multiple licenses -#.endif +.endif # Check if the user agrees with the license -# -# _LICENSE_CFG - Path to cfg file (either global or per port) -# _LICENSE_CFG_TYPE - "global" or "port", according to the previous -# -# LICENSES_ACCEPTED - List of accepted licenses (user version) -# LICENSES_REJECTED - List of rejected licenses (user version) -# _LICENSES_ACCEPTED - List of accepted licenses (configuration file) -# _LICENSES_REJECTED - List of rejected licenses (configuration file) + +# Make sure these are defined + +LICENSES_ACCEPTED?= # +LICENSES_REJECTED?= # +LICENSES_GROUPS_ACCEPTED?= # +LICENSES_GROUPS_REJECTED?= # + +# Evaluate per-license status -# If _LICENSE_TYPE is "known", configuration is global, otherwise per port. +.if ${_LICENSE_COMB} == "single" +. for lic in ${_LICENSE} +. if ${LICENSES_REJECTED:M${lic}} != "" +_LICENSE_STATUS?= rejected +. endif +. for group in ${_LICENSE_GROUPS} +. if ${LICENSES_GROUPS_REJECTED:M${group}} != "" +_LICENSE_STATUS?= rejected +. endif +. if ${LICENSES_GROUPS_ACCEPTED:M${group}} != "" +_LICENSE_STATUS?= accepted +. endif +. endfor +. if ${LICENSES_ACCEPTED:M${lic}} != "" +_LICENSE_STATUS?= accepted +. endif +. if ${_LICENSE_PERMS:Mauto-accept} != "" && !defined(LICENSES_ASK) +_LICENSE_STATUS?= accepted +. endif +_LICENSE_STATUS?= ask +. endfor -.if ${_LICENSE_TYPE} == "known" -_LICENSE_CFG= ${_LICENSE_CFG_GLOB} -_LICENSE_CFG_TYPE= global .else -_LICENSE_CFG= ${_LICENSE_CFG_PORT} -_LICENSE_CFG_TYPE= port +. for lic in ${_LICENSE} +. if ${LICENSES_REJECTED:M${lic}} != "" +_LICENSE_STATUS_${lic}?= rejected +. endif +. for group in ${_LICENSE_GROUPS_${lic}} +. if ${LICENSES_GROUPS_REJECTED:M${group}} != "" +_LICENSE_STATUS_${lic}?= rejected +. endif +. if ${LICENSES_GROUPS_ACCEPTED:M${group}} != "" +_LICENSE_STATUS_${lic}?= accepted +. endif +. endfor +. if ${LICENSES_ACCEPTED:M${lic}} != "" +_LICENSE_STATUS_${lic}?= accepted +. endif +. if ${_LICENSE_PERMS_${lic}:Mauto-accept} != "" && !defined(LICENSES_ASK) +_LICENSE_STATUS_${lic}?= accepted +. endif +_LICENSE_STATUS_${lic}?= ask +. endfor .endif -.if exists(${_LICENSE_CFG}) -. include "${_LICENSE_CFG}" -.endif +# Evaluate general status -# Make sure these are defined -LICENSES_ACCEPTED?= # -LICENSES_REJECTED?= # -_LICENSES_ACCEPTED?= # -_LICENSES_REJECTED?= # +.if ${_LICENSE_COMB} == "dual" +. for lic in ${_LICENSE} +. if ${_LICENSE_STATUS_${lic}} == "accepted" +_LICENSE_STATUS= accepted +. elif ${_LICENSE_STATUS_${lic}} == "ask" +_LICENSE_STATUS?= ask +_LICENSE_TO_ASK+= ${lic} +. endif +_LICENSE_STATUS?= rejected +. endfor -# Evaluate status (accepted, rejected or ask) -# -# _LICENSE_STATUS - Status: "accepted", "rejected" or "ask" -# _LICENSE_STATUS_FROM - Status origin: "user", "config" or "default" -# _LICENSE_STATUS_REASON - Text reason of license status (XXX Required?) +.elif ${_LICENSE_COMB} == "multi" +. for lic in ${_LICENSE} +. if ${_LICENSE_STATUS_${lic}} == "rejected" +_LICENSE_STATUS= rejected +. elif ${_LICENSE_STATUS_${lic}} == "ask" +_LICENSE_STATUS?= ask +_LICENSE_TO_ASK+= ${lic} +. endif +. endfor +_LICENSE_STATUS?= accepted +.endif -_LICENSE_TYPE_PAIRS_known= LICENSES,user _LICENSES,config -_LICENSE_TYPE_PAIRS_variant= _LICENSES,config -_LICENSE_TYPE_PAIRS_unknown= _LICENSES,config +# For dual/multi licenses, after processing all sub-licenses, the following +# must be determined: _LICENSE_NAME, _LICENSE_PERMS and _LICENSE_GROUPS. -#.if defined(_LICENSE_SINGLE) -# User and saved configuration +.if ${_LICENSE_COMB} == "dual" +_LICENSE_NAME= Dual (any of): ${_LICENSE} +# Calculate least restrictive permissions (union) +_LICENSE_PERMS:= # +. for lic in ${_LICENSE} +. for comp in ${_LICENSE_LIST_PERMS} +. if ${_LICENSE_PERMS_${lic}:M${comp}} != "" && \ + ${_LICENSE_PERMS:M${comp}} == "" +_LICENSE_PERMS+= ${comp} +. endif +. endfor +. endfor +# Calculate least restrictive groups (union) +_LICENSE_GROUPS:= # . for lic in ${_LICENSE} -. for pair in ${_LICENSE_TYPE_PAIRS_${_LICENSE_TYPE}} -_LC_VAR:= ${pair:C/,.*//} -_LC_TYPE:= ${pair:C/.*,//} -. if ${${_LC_VAR}_REJECTED:M${lic}} != "" && !defined(_LICENSE_STATUS) -_LICENSE_STATUS= rejected -_LICENSE_STATUS_FROM:= ${_LC_TYPE} -. elif ${${_LC_VAR}_ACCEPTED:M${lic}} != "" && !defined(_LICENSE_STATUS) -_LICENSE_STATUS= accepted -_LICENSE_STATUS_FROM:= ${_LC_TYPE} +. for comp in ${_LICENSE_LIST_GROUPS} +. if ${_LICENSE_GROUPS_${lic}:M${comp}} != "" && \ + ${_LICENSE_GROUPS:M${comp}} == "" +_LICENSE_GROUPS+= ${comp} . endif . endfor +. endfor -# Automatic configuration -. if !defined(_LICENSE_STATUS) -# Check groups (only available for user configuration) -. for group in ${_LICENSE_LIST_GROUPS} -. if ${LICENSES_REJECTED:M\@${group}} != "" -_LICENSE_STATUS?= rejected -_LICENSE_STATUS_FROM?= user -. endif -. if ${LICENSES_ACCEPTED:M\@${group}} != "" -_LICENSE_STATUS?= accepted -_LICENSE_STATUS_FROM?= user -. endif -. endfor -# Auto-accept if LICENSE_PERMS has auto-accept, and !LICENSES_ASK -. if ${_LICENSE_PERMS:Mauto-accept} != "" -. if !defined(LICENSES_ASK) -_LICENSE_STATUS?= accepted -_LICENSE_STATUS_FROM?= default -. else -_LICENSE_STATUS?= ask -_LICENSE_STATUS_FROM?= user -. endif +.elif ${_LICENSE_COMB} == "multi" +_LICENSE_NAME= Multiple (all of): ${_LICENSE} +# Calculate most restrictive permissions (intersection) +_LICENSE_PERMS:= ${_LICENSE_LIST_PERMS} +. for lic in ${_LICENSE} +. for comp in ${_LICENSE_LIST_PERMS} +. if ${_LICENSE_PERMS_${lic}:M${comp}} == "" +_LICENSE_PERMS:= ${_LICENSE_PERMS:N${comp}} . endif -# If defined BATCH and need to ask, it fails -. if defined(BATCH) -_LICENSE_STATUS?= rejected -_LICENSE_STATUS_FROM?= user +. endfor +. endfor +# Calculate most restrictive groups (intersection) +_LICENSE_GROUPS:= ${_LICENSE_LIST_GROUPS} +. for lic in ${_LICENSE} +. for comp in ${_LICENSE_LIST_GROUPS} +. if ${_LICENSE_GROUPS_${lic}:M${comp}} == "" +_LICENSE_GROUPS:= ${_LICENSE_GROUPS:N${comp}} . endif -# Otherwise ask to the user -_LICENSE_STATUS?= ask -_LICENSE_STATUS_FROM?= default +. endfor +. endfor +.endif + +# Prepare information for asking license to the user + +.if ${_LICENSE_STATUS} == "ask" && ${_LICENSE_COMB} != "single" +_LICENSE_ASK_DATA!= mktemp -t portslicense +.endif + +# Calculate restrictions and set RESTRICTED_FILES when +# appropiate, together with cleaning targets. +# +# XXX For multiple licenses restricted distfiles are always removed from both +# CDROM and FTP, but the current framework supports separating them (would +# require better/new delete-package and delete-distfiles targets) + +.if ${_LICENSE_PERMS:Mpkg-mirror} == "" +_LICENSE_RESTRICTED+= delete-package +.elif ${_LICENSE_PERMS:Mpkg-sell} == "" +_LICENSE_CDROM+= delete-package +.endif + +.if ${_LICENSE_COMB} == "multi" +. for lic in ${_LICENSE} +. if ${_LICENSE_PERMS_${lic}:Mdist-mirror} == "" || ${_LICENSE_PERMS_${lic}:Mdist-sell} == "" +RESTRICTED_FILES+= ${_LICENSE_DISTFILES_${lic}} . endif . endfor +. if defined(RESTRICTED_FILES) +RESTRICTED_FILES+= ${_PATCHFILES} +_LICENSE_RESTRICTED+= delete-distfiles +_LICENSE_CDROM+= delete-distfiles +. endif +.else +. if ${_LICENSE_PERMS:Mdist-mirror} == "" +_LICENSE_RESTRICTED+= delete-distfiles +RESTRICTED_FILES= ${_PATCHFILES} ${_DISTFILES} +. elif ${_LICENSE_PERMS:Mdist-sell} == "" +_LICENSE_CDROM+= delete-distfiles +RESTRICTED_FILES= ${_PATCHFILES} ${_DISTFILES} +. endif +.endif -#.else -# XXX dual/multiple licenses -#.endif +.if defined(_LICENSE_RESTRICTED) +clean-restricted: ${_LICENSE_RESTRICTED} +clean-restricted-list: ${_LICENSE_RESTRICTED:C/$/-list/} +.else +clean-restricted: +clean-restricted-list: +.endif + +.if defined(_LICENSE_CDROM) +clean-cdrom: ${_LICENSE_CDROM} +clean-cdrom-list: ${_LICENSE_CDROM:C/$/-list/} +.else +clean-cdrom: +clean-cdrom-list: +.endif # Check variables are correctly defined and print status up to here @@ -366,160 +549,206 @@ @${ECHO_MSG} "===> License not correctly defined: ${_LICENSE_ERROR}" @exit 1 .endif -#.if defined(_LICENSE_SINGLE) . if ${_LICENSE_STATUS} == "rejected" - @${ECHO_MSG} "===> License ${_LICENSE} rejected by the user (by ${_LICENSE_STATUS_FROM})" + @${ECHO_MSG} "===> License rejected by the user" + @${ECHO_MSG} + @${ECHO_MSG} "If you want to install this port make sure the following license/s are not present in LICENSES_REJECTED, either in make arguments or /etc/make.conf: ${_LICENSE}. Also check LICENSES_GROUPS_REJECTED in case they contain a group this license/s belong to." | ${FMT} + @${ECHO_MSG} @exit 1 . elif ${_LICENSE_STATUS} == "accepted" - @${ECHO_MSG} "===> License ${_LICENSE} accepted by the user (by ${_LICENSE_STATUS_FROM})" + @${ECHO_MSG} "===> License accepted by the user" . elif ${_LICENSE_STATUS} == "ask" - @${ECHO_MSG} "===> License ${_LICENSE} needs agreement, will ask later (by ${_LICENSE_STATUS_FROM})" +. if defined(BATCH) + @${ECHO_MSG} "===> License needs confirmation, but BATCH is defined" + @exit 1 +. else + @${ECHO_MSG} "===> License needs confirmation, will ask later" +. endif . endif -#.else -# XXX dual/multiple licenses -#.endif + +# Display, ask and save preference if requested + +ask-license: ${_LICENSE_COOKIE} -.if defined(LICENSES_CONFIG) -_LICENSES_CONFIG= yes +${_LICENSE_COOKIE}: +# Make sure all required license files exist +.if ${_LICENSE_COMB} == "single" +. if !defined(LICENSE_FILE) && defined(_LICENSE_TEXT) + @test -f ${_LICENSE_FILE} || ${ECHO_CMD} "${_LICENSE_TEXT}" | ${FMT} > ${_LICENSE_FILE} +. endif + @test -f ${_LICENSE_FILE} || \ + (${ECHO_MSG} "===> Missing license file for ${_LICENSE} in ${_LICENSE_FILE}"; exit 1) .else -_LICENSES_CONFIG= no +. for lic in ${_LICENSE} +. if !defined(LICENSE_FILE_${lic}) && defined(_LICENSE_TEXT_${lic}) + @test -f ${_LICENSE_FILE_${lic}} || ${ECHO_CMD} "${_LICENSE_TEXT_${lic}}" | ${FMT} > ${_LICENSE_FILE_${lic}} +. endif + @test -f ${_LICENSE_FILE_${lic}} || \ + (${ECHO_MSG} "===> Missing license file for ${lic} in ${_LICENSE_FILE_${lic}}"; exit 1) +. endfor .endif -# For config when user accepts -_LICENSES_ACCEPTED_YES= ${_LICENSES_ACCEPTED} ${_LICENSE} -.for lic in ${_LICENSE} -_LICENSES_REJECTED_YES= ${_LICENSES_REJECTED:N${lic}} -.endfor -# For config when user rejects -.for lic in ${_LICENSE} -_LICENSES_ACCEPTED_NO= ${_LICENSES_ACCEPTED:N${lic}} -.endfor -_LICENSES_REJECTED_NO= ${_LICENSES_REJECTED} ${_LICENSE} +.if ${_LICENSE_STATUS} == "ask" +. if !defined(NO_LICENSES_DIALOGS) +# Dialog interface +. if ${_LICENSE_COMB} == "single" + @while true; do \ + tmpfile=$$(mktemp -t portlicenses); \ + ${DIALOG} --menu "License for ${PKGNAME} (${_LICENSE})" 21 70 15 accept "Accept license" reject "Reject license" view "View license" 2>"$${tmpfile}"; \ + result=`${CAT} $${tmpfile}`; \ + case $${result} in \ + accept) break ;; \ + reject) exit 1;; \ + view) ${DIALOG} --textbox "${_LICENSE_FILE}" 21 70 ;; \ + esac; \ + done -# Display, ask and save preference if requested +. elif ${_LICENSE_COMB} == "dual" + @${RM} -f ${_LICENSE_ASK_DATA} +. for lic in ${_LICENSE_TO_ASK} >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908150116.n7F1GB7v075555>