PERFORCE change 146748 for review
Alejandro Pulver
alepulver at FreeBSD.org
Wed Aug 6 03:32:13 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=146748
Change 146748 by alepulver at alepulver_deimos on 2008/08/06 03:31:31
- Implement basic LICENSE_COMPAT/LICENSE_INCOMPAT support.
- Add LICENSE_TEXT in case LICENSE_FILE is not available locally.
- Add aliases for LICENSE_PERMS: pkg, dist, sell and redist.
- Use '_' prefix for most internal variables.
- Check for invalid and ambiguous entries in LICENSE_PERMS.
- Add variable LICENSES_CONFIG (if defined acts as "make config").
- Avoid whitespace in configuration files, and store more information.
- Allow missing LICENSE_FILE if license is present in database.
Affected files ...
.. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/README#3 edit
.. //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.mk#3 edit
Differences ...
==== //depot/projects/soc2008/alepulver-portslicense/ports/Mk/README#3 (text+ko) ====
@@ -74,39 +74,31 @@
Interface:
* incorporate pattern matching in licenses/groups/distfiles/lic files
+ -> only if variables are solely used in commands
* extend LICENSE=... for dual/multiple
use (), [], {} or <> (use shell/commands as make can't parse this notation)
LICENSE= dual(BSD,GPLv2,multi(ART,etc))
dual/multiple licenses (need parsing code), start with only one of them
-* implement LICENSE_COMPAT for packaging/linking (check *_DEPENDS
- appropiately), but should be allowed by default first (maybe should be
- INCOMPAT instead)?
-* Consider licenses that need manual agreement/manual fetching
- provide framework help for manual distfile placing, etc
- maybe also add pkg-fetch-message or some variables to avoid manual IGNORE/printf?
-* how do you know if a license has changed? Save checksum? Maybe license
- revison number suffixed by a _n? Or not needed (this is only for changes of
- the same license type: e.g. BSD-based to BSD-based, but with no-pkg-sell).
- only for license "variant" and "unknown", save checksum in port cfg and compare
-* provide useful aliases like "no-sell" for a general no-pkg-sell no-dist-sell,
- and groups for the same purpose
+ -> For now use =LIC1|LIC2 LIC2|LIC3 ('|' is OR and ' ' is AND)
General:
* additional targets (show-license, show-license-report,
show-known-licenses, etc)
+ and ports framework configuration
* add common licenses (check a web page or try FOSSology)
-* avoid whitespace in saved files (reports and cfg)
-* add LICENSE_TEXT for when there is no LICENSE_FILE, and show instead (not
- with a license but maybe for a URL to read it)
+
+NOW:
+- * make list of error messages (by component/type) and the like, so targets are more dynamic
+- * unify echo messages, use ECHO_MSG, add a debug variable maybe
+- * prepare for multiple licenses support:
+ -> use _LICENSE in for loops, with AND criteria
-Configuration:
+Maybe:
+* separate groups into another variable (either internally and/or externally->better)
* provide target to assist cleaning LICENSES_ACCEPTED and LICENSES_REJECTED,
- and ports framework configuration
-* provide root credential switching like make-config
-* allow approving a previously rejected and saved license with a target like
- license-config (or by defining a variable)
-* separate groups into another variable (either internally and/or externally->better)
-* make list of error messages (by component/type) and the like, so targets are more dynamic
+* Consider licenses that need manual agreement/manual fetching
+ provide framework help for manual distfile placing, etc
+ maybe also add pkg-fetch-message or some variables to avoid manual IGNORE/printf?
Reports:
==== //depot/projects/soc2008/alepulver-portslicense/ports/Mk/bsd.licenses.mk#3 (text+ko) ====
@@ -33,31 +33,35 @@
# Variables provided to users
#
-# LICENSES_ACCEPTED - Accepted licenses and groups
-# LICENSES_REJECTED - Rejected licenses and groups
+# 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
+# present in configuration nor LICENSES_ACCEPTED.
#
# The components of LICENSES_{ACCEPTED,REJECTED} can be one of:
# - A license code (like "GPLv2").
# - A license group prefixed by '@' (like "@OSI").
#
-# Note that the framework configuration format is the same, but stored in
-# ${LICENSE_CFG} or ${LICENSE_CFG_PORT}. The user variables take precedence
-# (anyways the other configuration is also made by the user).
+# 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
-# LICENSE_NAME - Full license name (for the reports)
+# 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 - Path to license (or "none")
-# LICENSE_DISTFILE - Name of licensed files (defaults to ${DISTFILES})
+# 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}).
#
# The following cases are supported (see _LICENSE_TYPE):
#
@@ -69,7 +73,7 @@
# 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.
+# its base license or just let it fall in Case 3 (as now).
#
# Case 3: license only known by the port (aka "unknown").
# All license variables must be defined by the port.
@@ -77,7 +81,7 @@
# 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).
+# 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:
@@ -86,28 +90,26 @@
# LICENSE_NOTES= GPLv2:"No sell" BSD:"Allows everything"
#
# Available components for LICENSE_PERMS:
-# dist-redist - 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-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)
+# dist-redist - 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-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.
#
-# Available components for LICENSE_COMPAT:
-# link Linking
-# package - Packaging together
.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
+# - 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.
# XXX Start of editable section
@@ -124,18 +126,21 @@
# _LICENSE_NAME_xxx - Full name/description of license/group
# _LICENSE_PERMS_xxx - Permissions
# _LICENSE_COMPAT_xxx - Compatibility
+# _LICENSE_INCOMPAT_xxx - Incompatibility
# List of licenses
_LICENSE_NAME_GPLv2= GNU General Public License version 2
_LICENSE_PERMS_GPLv2= dist-redist dist-sell pkg-redist pkg-sell auto-accept
_LICENSE_COMPAT_GPLv2= #
+_LICENSE_INCOMPAT_GPLv2=#
# List of groups
_LICENSE_NAME_FSF= Free Software Foundation approved
_LICENSE_PERMS_FSF= #
_LICENSE_COMPAT_FSF= #
+_LICENSE_INCOMPAT_FSF= #
# Grouping
#
@@ -168,25 +173,33 @@
# _LICENSE_LIST_GROUP_VARS - License variables inherited from groups
# _LICENSE_LIST_SAVE_VARS - License variables present in the report
-_LICENSE_LIST_PERMS= dist-redist distsell pkg-redist pkg-sell auto-accept none
-_LICENSE_LIST_PORT_VARS= PERMS GROUPS NAME # COMPAT
-_LICENSE_LIST_GROUP_VARS= PERMS # COMPAT
-_LICENSE_LIST_SAVE_VARS= LICENSE ${_LICENSE_LIST_PORT_VARS:S/^/LICENSE_/} LICENSE_NOTES LICENSE_DISTFILE
+_LICENSE_LIST_PERMS= dist-redist dist-sell pkg-redist pkg-sell auto-accept none
+_LICENSE_LIST_PORT_VARS= PERMS GROUPS NAME
+_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_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_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_DISTFILE?= ${DISTFILES}
-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_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
# Check if single or dual/multiple license
#
@@ -230,7 +243,7 @@
_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"
+. elif ${_LICENSE_TYPE} == "variant" && defined(LICENSE_${var})
_LICENSE_${var}= ${LICENSE_${var}}
. endif
. endfor
@@ -242,35 +255,61 @@
_LICENSE_${var}= ${LICENSE_${var}}
. endif
. endfor
+. endif
+# XXX here it does not affect _LICENSE_TYPE
+_LICENSE_COMPAT?= #
+_LICENSE_INCOMPAT?= #
# Check everything needed is defined.
-. for var in ${_LICENSE_LIST_PORT_VARS}
-. if !defined(_LICENSE_${var})
-. if ${_LICENSE_TYPE} == "variant"
+. 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"
+. elif ${_LICENSE_TYPE} == "unknown"
_LICENSE_ERROR?= for a new/unknown license, defining LICENSE_${var} is mandatory (otherwise use a known LICENSE)
-. endif
. endif
-. endfor
-. endif
+. 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}}
. endfor
. endfor
-# Remove ambiguous and duplicate components
-__LICENSE_PERMS:= ${_LICENSE_PERMS}
-_LICENSE_PERMS:= #
-. for comp in ${_LICENSE_LIST_PERMS}
-. if ${__LICENSE_PERMS:M${comp}} != "" && ${__LICENSE_PERMS:Mno-${comp}} == "" && \
- ${_LICENSE_PERMS:M${comp}} == ""
-_LICENSE_PERMS+= ${comp}
+# 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
-# Check LICENSE_FILE (XXX Should be mandatory in all cases?)
+_LICENSE_PERMS:= ${__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)
-_LICENSE_ERROR?= LICENSE_FILE must be defined for unknown licenses
+. if !defined(LICENSE_TEXT)
+. if ${_LICENSE_TYPE} != "known"
+LICENSE_TEXT= License ${lic} is in internal database, please check ...
+. else
+_LICENSE_ERROR?= LICENSE_FILE or LICENSE_TEXT must be defined for unknown licenses
+. endif
+. else
+LICENSE_FILE= ${WRKDIR}/License-freebsd-port
+_LICENSE_FILE_SIM= yes
+. endif
. endif
. endfor
.else
@@ -279,7 +318,7 @@
# Check if the user agrees with the license
#
-# LICENSE_CFG - Path to cfg file (either global or per port)
+# _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)
@@ -290,15 +329,15 @@
# If _LICENSE_TYPE is "known", configuration is global, otherwise per port.
.if ${_LICENSE_TYPE} == "known"
-LICENSE_CFG= ${LICENSE_CFG_GLOB}
+_LICENSE_CFG= ${_LICENSE_CFG_GLOB}
_LICENSE_CFG_TYPE= global
.else
-LICENSE_CFG= ${LICENSE_CFG_PORT}
+_LICENSE_CFG= ${_LICENSE_CFG_PORT}
_LICENSE_CFG_TYPE= port
.endif
-.if exists(${LICENSE_CFG})
-. include "${LICENSE_CFG}"
+.if exists(${_LICENSE_CFG})
+. include "${_LICENSE_CFG}"
.endif
# Make sure these are defined
@@ -386,58 +425,100 @@
. elif ${_LICENSE_STATUS} == "ask"
@${ECHO_MSG} "===> License ${LICENSE} needs agreement, will ask later (by ${_LICENSE_STATUS_FROM})"
. endif
+. if defined(_LICENSE_FILE_SIM)
+# XXX escape shell chars
+ @${ECHO_CMD} ${LICENSE_TEXT} > ${LICENSE_FILE}
+. endif
.else
# XXX dual/multiple licenses
.endif
+.if defined(LICENSES_CONFIG)
+_LICENSES_CONFIG= yes
+.else
+_LICENSES_CONFIG= no
+.endif
+
# Display, ask and save preference if requested
ask-license:
-# XXX verify checksum if accepted by port cfg file
-.if ${_LICENSE_STATUS} == "ask"
@if [ ! -f ${LICENSE_FILE} ]; then \
${ECHO_CMD} "License not found in \"${LICENSE_FILE}\", aborting."; \
exit 1; \
fi
- @until [ "$$status" = done ]; do \
+ @if [ ${_LICENSE_STATUS} = "accepted" ]; then \
+ status=done; \
+ fi; \
+ if [ ${_LICENSE_STATUS} = "accepted" -a ${_LICENSE_TYPE} != "known" ]; then \
+ if [ ${_LICENSE_${LICENSE}_CHK} != `${SHA256} -q ${LICENSE_FILE}` ]; then \
+ ${ECHO_MSG} "===> License has changed, reconfiguring..."; \
+ status=ask; \
+ fi; \
+ fi; \
+ if [ ${_LICENSE_STATUS} != "ask" -a ${_LICENSES_CONFIG} = "yes" ]; then \
+ if [ ${_LICENSE_STATUS_FROM} = "user" ]; then \
+ ${ECHO_MSG} "===> Can't reconfigure, as user is manually defining the status"; \
+ exit 1; \
+ else \
+ status=ask; \
+ fi \
+ fi; \
+ until [ "$$status" = done ]; do \
${ECHO_CMD} "Press 'Y' to accept, 'S' to accept and save, 'N' to reject or 'V' to view." | ${FMT}; \
read ans; \
case $$ans in \
- [Yy]) ${ECHO_CMD} "License was accepted."; \
- status=done;; \
- [Nn]) ${ECHO_CMD} "License was rejected."; \
- exit 1;; \
- [Ss]) ${ECHO_CMD} "License was accepted and saved."; \
- ${MKDIR} ${LICENSE_CFG:H}; \
- ${ECHO_CMD} _LICENSES_ACCEPTED=${LICENSE} > ${LICENSE_CFG}; \
- status=done;; \
- [Vv]) more ${LICENSE_FILE}; \
+ [Yy]) ${ECHO_CMD} "License was accepted."; \
+ status=done;; \
+ [Nn]) ${ECHO_CMD} "License was rejected."; \
+ exit 1;; \
+ [Ss]) if [ ${UID} != 0 ]; then \
+ ${ECHO_CMD} "You don't have permissions to save the license"; \
+ else \
+ ${MKDIR} ${_LICENSE_CFG:H}; \
+ (${ECHO_CMD} _LICENSES_ACCEPTED=${LICENSE}; \
+ if [ ${_LICENSE_TYPE} != "known" ]; then \
+ ${ECHO_CMD} _LICENSE_${LICENSE}_CHK=`${SHA256} -q ${LICENSE_FILE}`; \
+ fi) > ${LICENSE_FILE}; \
+ ${ECHO_CMD} "License was accepted and saved."; \
+ status=done; \
+ fi;; \
+ [Vv]) more ${LICENSE_FILE}; \
esac; \
done
-.elif defined(LICENSES_CONFIG)
-. if ${_LICENSE_STATUS_FROM} == "user"
-# XXX fail here
-. else
-# XXX replace cfg
-. endif
+
+# License compatibility check (XXX is it useful? empty vaules of COMPAT do not
+# mean "nothing")
+
+.if !empty(_LICENSE_COMPAT) || !empty(_LICENSE_INCOMPAT)
+. for port in ${RUN_DEPENDS}
+_LICENSE_RESULT!= cd ${port} && ${MAKE} -V LICENSE
+. for lic in ${_LICENSE_RESULT}
+. if (!empty(_LICENSE_COMPAT) && ${LICENSE_COMPAT:M${lic}} == "") || \
+ (!empty(_LICENSE_INCOMPAT) && ${LICENSE_INCOMPAT:M${lic}} != "")
+IGNORE= depends on ${port:T} that uses license "${lic}" which is incompatible with "${LICENSE}" used by this port
+. endif
+. endfor
+. endfor
.endif
# Package list entries, and installation
-PLIST_FILES+= ${LICENSE_DIR_REL}/${LICENSE_REPORT:T}
-PLIST_DIRS+= ${LICENSE_DIR_REL}
+PLIST_FILES+= ${_LICENSE_DIR_REL}/${_LICENSE_REPORT:T}
+PLIST_DIRS+= ${_LICENSE_DIR_REL}
.if defined(LICENSE_FILE)
-PLIST_FILES+= ${LICENSE_DIR_REL}/${LICENSE_FILE:T}
+PLIST_FILES+= ${_LICENSE_DIR_REL}/${LICENSE_FILE:T}
.endif
install-license:
- @${MKDIR} ${LICENSE_DIR}
- @test -f ${LICENSE_FILE} && ${INSTALL_DATA} ${LICENSE_FILE} ${LICENSE_DIR}
- @${TRUE} > ${LICENSE_REPORT}
+ @${MKDIR} ${_LICENSE_DIR}
+.if defined(LICENSE_FILE)
+ @test -f ${LICENSE_FILE} && ${INSTALL_DATA} ${LICENSE_FILE} ${_LICENSE_DIR}
+.endif
+ @${TRUE} > ${_LICENSE_REPORT}
. for var in ${_LICENSE_LIST_SAVE_VARS}
. if !empty(${var})
- @${ECHO_CMD} '${var}=${${var}}' >> ${LICENSE_REPORT}
+ @${ECHO_CMD} ${var}=${${var}:C/^[[:blank:]]*//} >> ${_LICENSE_REPORT}
. endif
. endfor
More information about the p4-projects
mailing list