Mk/bsd.port.{subdir}.mk: create describe-json

Summary:
Create "describe-json" target to get a JSON-compliant representation of the
ports tree.

It can be invoked from a single port directory, a category directory or from the
ports tree top directory.

It supports FLAVORS. E.g. It is possible to execute the following:

cd math/qalculate-qt && make describe-json-qt6

Performance-wise it is equivalent to a simple "make describe" although it
offers a more complete vision of the port in an easily parseable format.

Times for describe:
     1345.39 real       933.06 user       403.01 sys
     1317.00 real       929.22 user       406.43 sys
     1316.83 real       930.82 user       404.70 sys
     1316.75 real       928.05 user       407.39 sys
     1316.58 real       930.69 user       404.59 sys
Times for describe-json:
     1320.38 real       924.80 user       414.48 sys
     1320.66 real       926.14 user       413.41 sys
     1320.41 real       924.08 user       415.30 sys
     1320.37 real       922.96 user       416.35 sys
     1320.25 real       924.25 user       414.95 sys

Some examples assuming the output is saved in the `describe.json` file.

Show all ports in the "accessibility" category:

jq '.accessibility' describe.json

Show ports in the "accessibility" category with a USES=iconv dependency:

jq '.accessibility.[] | select(.uses | index("iconv")) | .pkgorigin' describe.json

Show ports in the tree that Uses=kmod:

jq '.[].[] | select(.uses | index("kmod")) | .pkgorigin' describe.json

Show ports having a LIB_DEPENDS on devel/binutils:

jq '.[].[] | select(.lib_depends | map(test("devel/binutils")) | any) | .pkgorigin' describe.json

Show ports in the "database" category which have no maintainer and are marked as
deprecated:

jq '.databases.[] | select(.maintainer=="ports@FreeBSD.org" and .deprecated!=" ") | .pkgorigin, .deprecated' describe.json

Approved by:		portmgr (bapt@)
Differential Revision:	https://reviews.freebsd.org/D42131
This commit is contained in:
Fernando Apesteguía 2023-09-27 17:32:12 +02:00
parent dcfd94ae42
commit 3d9f300e01
2 changed files with 93 additions and 0 deletions

View file

@ -619,6 +619,7 @@ FreeBSD_MAINTAINER= portmgr@FreeBSD.org
# - Create a package for a port and _all_ of its dependencies.
# describe - Try to generate a one-line description for each port for
# use in INDEX files and the like.
# describe-json - Generate a JSON-compliant representation of each port.
# check-plist - Checks for files missing from the plist, and files in the plist
# that are not installed by the port.
# check-sanity - Perform some basic checks of the port layout.
@ -4406,6 +4407,78 @@ describe-${f}:
. endif # empty(FLAVORS)
. endif
. if empty(FLAVORS) || defined(_DESCRIBE_WITH_FLAVOR)
. if defined(_DESCRIBE_WITH_FLAVOR)
_JSON_OBJ_NAME="\"${FLAVOR}-${.CURDIR:T}\":"
. endif
describe-json:
@(${ECHO_CMD} "${_JSON_OBJ_NAME} { ";\
${ECHO_CMD} \"uses\":[\"${USES:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"flavors\":[\"${FLAVORS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"options_default\":[\"${OPTIONS_DEFAULT:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"fetch_depends\":[\"${FETCH_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"extract_depends\":[\"${EXTRACT_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"patch_depends\":[\"${PATCH_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"build_depends\":[\"${BUILD_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"lib_depends\":[\"${LIB_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"run_depends\":[\"${RUN_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"test_depends\":[\"${TEST_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"pkg_depends\":[\"${PKG_DEPENDS:ts,:Q:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"complete_options_list\":[\"${COMPLETE_OPTIONS_LIST:ts,:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"categories\":[\"${CATEGORIES:ts,:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"license\":[\"${LICENSE:ts,:S/,/\",\"/g}\"], ;\
${ECHO_CMD} \"deprecated\":\""${DEPRECATED:S/"/\\\"/g:S/\\\\*/*/g:S/\\\'/'/g}" \", ;\
${ECHO_CMD} \"broken\":\"${BROKEN:Q:S/"/\\\"/g:S/\\\\*/*/g:S/\\\'/'/g}\", ;\
${ECHO_CMD} \"distversion\":\"${DISTVERSION}\", ;\
${ECHO_CMD} \"distversionprefix\":\"${DISTVERSIONPREFIX}\", ;\
${ECHO_CMD} \"distversionsuffix\":\"${DISTVERSIONSUFFIX}\", ;\
${ECHO_CMD} \"expiration_date\":\"${EXPIRATION_DATE}\", ;\
${ECHO_CMD} \"flavor\":\"${FLAVOR}\", ;\
${ECHO_CMD} \"gh_account\":\"${GH_ACCOUNT}\", ;\
${ECHO_CMD} \"gh_project\":\"${GH_PROJECT}\", ;\
${ECHO_CMD} \"gh_tagname\":\"${GH_TAGNAME}\", ;\
${ECHO_CMD} \"gl_account\":\"${GL_ACCOUNT}\", ;\
${ECHO_CMD} \"gl_commit\":\"${GL_COMMIT}\", ;\
${ECHO_CMD} \"gl_project\":\"${GL_PROJECT}\", ;\
${ECHO_CMD} \"gl_site\":\"${GL_SITE}\", ;\
${ECHO_CMD} \"maintainer\":\"${MAINTAINER}\", ;\
${ECHO_CMD} \"makefiles\":\"${MAKEFILES}\", ;\
${ECHO_CMD} \"pkgbase\":\"${PKGBASE}\", ;\
${ECHO_CMD} \"pkgname\":\"${PKGNAME}\", ;\
${ECHO_CMD} \"pkgnamesuffix\":\"${PKGNAMESUFFIX}\", ;\
${ECHO_CMD} \"pkgorigin\":\"${PKGORIGIN}\", ;\
${ECHO_CMD} \"pkg_depends\":\"${PKG_DEPENDS}\", ;\
${ECHO_CMD} \"portepoch\":\"${PORTEPOCH}\", ;\
${ECHO_CMD} \"portname\":\"${PORTNAME}\", ;\
${ECHO_CMD} \"portrevision\":\"${PORTREVISION}\", ;\
${ECHO_CMD} \"portversion\":\"${PORTVERSION}\", ;\
${ECHO_CMD} \"use_github\":\"${USE_GITHUB}\", ;\
${ECHO_CMD} \"use_gitlab\":\"${USE_GITLAB}\", ;\
${ECHO_CMD} \"www\":\"${WWW:Q}\" ;\
${ECHO_CMD} "}" >> ${INDEX_OUT})
. else # empty(FLAVORS)
describe-json: ${FLAVORS:S/^/describe-json-/}
_LAST_FLAVOR = ${FLAVORS:[-1]}
. for f in ${FLAVORS}
describe-json-${f}:
@if [ "${f}" == "${FLAVORS:[1]}" ]; then \
${ECHO_CMD} "{" ;\
fi;
@cd ${.CURDIR} && ${SETENV} FLAVOR=${f} ${MAKE} -B -D_DESCRIBE_WITH_FLAVOR describe-json
@if [ "${f}" != "${_LAST_FLAVOR}" ]; then \
${ECHO_MSG} "," ;\
else \
${ECHO_CMD} "}" ;\
fi; \
. endfor
. endif # empty(FLAVORS)
www-site:
@${ECHO_CMD} ${_WWW}

View file

@ -300,6 +300,26 @@ describe:
. endif
.endif
# Store last subdir name
_LAST_DIR = ${SUBDIR:[-1]}
describe-json:
@${ECHO_MSG} "{"
@for sub in ${SUBDIR}; do \
if ${TEST} -d ${.CURDIR}/$${sub}; then \
cd ${.CURDIR}/$${sub}; \
${ECHO_MSG} "\"$${sub}\": " ;\
${MAKE} -B describe-json || \
(${ECHO_CMD} "===> ${DIRPRFX}$${sub} failed" >&2; \
exit 1) ;\
if [ "$${sub}" != "${_LAST_DIR}" ]; then \
(${ECHO_MSG} ",") ; \
fi; \
else \
${ECHO_MSG} "===> ${DIRPRFX}$${sub} non-existent"; \
fi; \
done
@${ECHO_MSG} "}"
.if !target(readmes)
. if defined(PORTSTOP)
readmes: readme ${SUBDIR:S/^/_/:S/$/.readmes/}