diff options
| author | Hiroki Tagato <tagattie@FreeBSD.org> | 2026-06-27 08:32:20 +0000 |
|---|---|---|
| committer | Hiroki Tagato <tagattie@FreeBSD.org> | 2026-06-27 08:37:34 +0000 |
| commit | ed6a84c1c9793271c9cf948458808b47b2622d21 (patch) | |
| tree | 4a1e3a43eaec6daa1f799211f691be035355962d | |
| parent | 948f38cf392834bb8ce766ea952fe1a45b2dfd8b (diff) | |
Mk/Uses/electron.mk: Split fetch- and extract-related codes out to npm.mk
Prefetch and extract functions are not necessarily limited to electron
ports. Those functions can be utilized by any ports which needs an
offline node modules installation.
Previously, non-electron ports wanting to use prefetch and/or extract
functions needs to use USES=electron:env, which is now removed in
favor of USES=npm:<package manager name>.
The following description:
USES= electron:env
USE_ELECTRON= npm:npm-name prefetch extract
is simplified to:
USES= npm:npm-name
| -rw-r--r-- | Mk/Scripts/npm-create-mtree.sh (renamed from Mk/Scripts/electron-create-mtree.sh) | 4 | ||||
| -rw-r--r-- | Mk/Scripts/npm-normalize-permissions.awk (renamed from Mk/Scripts/electron-normalize-permissions.awk) | 0 | ||||
| -rw-r--r-- | Mk/Uses/electron.mk | 636 | ||||
| -rw-r--r-- | Mk/Uses/npm.mk | 516 |
4 files changed, 576 insertions, 580 deletions
diff --git a/Mk/Scripts/electron-create-mtree.sh b/Mk/Scripts/npm-create-mtree.sh index 6e213f0d5b23..44e33462b9c9 100644 --- a/Mk/Scripts/electron-create-mtree.sh +++ b/Mk/Scripts/npm-create-mtree.sh @@ -7,7 +7,7 @@ PATH=/bin:/usr/bin:/usr/sbin set -e set -o pipefail -[ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_ELECTRON_CREATE_MTREE}" ] && set -x +[ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_NPM_CREATE_MTREE}" ] && set -x PREFETCH_TIMESTAMP=61171200 # 1971-12-10 00:00:00 GMT @@ -25,7 +25,7 @@ if [ $# -ne 1 ]; then fi mtree -cbnSp "$1" | mtree -C | \ -awk -f "${SCRIPTSDIR}/electron-normalize-permissions.awk" | \ +awk -f "${SCRIPTSDIR}/npm-normalize-permissions.awk" | \ sed -e "s/time=[0-9.]*/time=${PREFETCH_TIMESTAMP}.000000000/" \ -e 's/\([gu]id\)=[0-9]*/\1=0/g' \ -e 's/flags=.*/flags=none/' \ diff --git a/Mk/Scripts/electron-normalize-permissions.awk b/Mk/Scripts/npm-normalize-permissions.awk index 876f6c4fb684..876f6c4fb684 100644 --- a/Mk/Scripts/electron-normalize-permissions.awk +++ b/Mk/Scripts/npm-normalize-permissions.awk diff --git a/Mk/Uses/electron.mk b/Mk/Uses/electron.mk index a764ff2adf8d..4815222a04a4 100644 --- a/Mk/Uses/electron.mk +++ b/Mk/Uses/electron.mk @@ -1,47 +1,22 @@ # Provides support for Electron-based ports # # Feature: electron -# Usage: USES=electron:<version>[,ARGS] -# Valid ARGS: <version>, build, run, test, env +# Usage: USES=electron:<version>[,arg,...] +# Valid ARGS: <version>, build, run, test # -# <version>: A specific major version of Electron the port is based on. -# The port must specify exactly a single major version. +# <version>: A major version of Electron the port is based on. The port must +# specify exactly a single major version. # build: Electron is needed at build time. Adds it to BUILD_DEPENDS. # run: Electron is needed at run time. Adds it to RUN_DEPENDS. # test: Electron is needed at test time. Adds it to TEST_DEPENDS. -# env: Electron is not needed at any of build, run, or test time. -# However, the port needs USE_ELECTRON features. # -# NOTE 1: {build, run, test} and env are mutually exclusive. If the port -# specifies both of them, env takes precedence. -# -# NOTE 2: If the port specifies none of build, run or test, we assume the port +# NOTE: If the port specifies none of build, run, or test, we assume the port # requires all those dependencies. # # Variables, which may be set by the port: # -# USE_ELECTRON: A list of additional features and functionalities to -# enable. Supported features are: -# -# npm: A node package manager the port uses. -# Supported package managers are: -# -# npm: The port uses NPM as package manager. -# yarn1: The port uses Yarn (v1) as package manager. -# yarn2: The port uses Yarn (v2 or v3) as package manager. -# yarn4: The port uses Yarn (v4+) as package manager. -# pnpm: The port uses PNPM as package manager. -# -# NOTE: The port must specify exactly a single package manager. -# Multiple package managers cannot be specified. -# -# Other valid arguments are: -# -# fetch, extract, build, run, and test, -# -# each of which corresponds to respective dependency. If the port -# does not specify any of those dependencies, we assume only -# build time dependency is required. +# USE_ELECTRON: A list of additional features and functionalities to enable. +# Supported features are: # # appbuilder: An app-builder version the port uses. Supported # arguments are: @@ -54,26 +29,6 @@ # NOTE: If the port specifies none of those arguments, we assume # release has been specified. # -# prefetch: Downloads node modules the port uses according to the -# pre-stored package.json (and package-lock.json, -# yarn.lock, or pnpm-lock.yaml depending on the node -# package manager used) in PKGJSONSDIR. Downloaded node -# modules are archived into a single tarball as one of -# the DISTFILES. -# -# NOTE 1: If the source directory of the port has other relevant -# files than package.json and lockfile, the relevant files must -# also be copied into PKGJSONSDIR. (Examples of relevant files -# includes .npmrc, .yarnrc, and pnpm-workspace.yaml.) -# -# NOTE 2: If the source directory of the port contains multiple -# package.json's and/or lockfiles, all files needed for generating -# node modules archive must be copied into PKGJSONSDIR with -# directory hierarchy preserved. -# -# extract: Installs the prefetched node modules into the port's -# working source directory. -# # rebuild: Rebuilds native node modules against nodejs or electron. # Supported arguments are: # @@ -99,49 +54,39 @@ # NOTE: The port must specify exactly a single argument. Multiple # package builders cannot be specified. # -# NPM_VER: A version of node package manager the port uses. If yarn -# 2 or later, or pnpm is used for the package manager, the -# framework requires the variable to be set so that it can -# bootstrap the correct version of package manager. -# -# It is usually specified as the key "packageManager" in -# package.json and the framework tries to automatically -# detect the version. Auto-detection can be overridden by -# manually specifying the value in Makefile. -# # UPSTREAM_ELECTRON_VER: # UPSTREAM_CHROMEDRIVER_VER: # UPSTREAM_MKSNAPSHOT_VER: -# Electron, chromedriver, and mksnapshot versions the port -# depends on. Those versions are usually specified in -# either package-lock.json, yarn.lock, or pnpm-lock.yaml -# file in the port's source directory. +# Electron, chromedriver, and mksnapshot versions the port depends +# on. Those versions are usually specified in either +# package-lock.json, yarn.lock, or pnpm-lock.yaml file in the +# port's source directory. # -# The build process tries to automatically detect those -# versions so the port does not usually have to specify -# the values. Auto-detection can be overridden by manually -# specifying the values in Makefile. +# The build process tries to automatically detect those versions +# so the port does not usually have to specify the values. +# Auto-detection can be overridden by manually specifying the +# values in Makefile. # -# The build process will generate a zip archive and a -# checksum file of electron/chromedriver/mksnapshot to -# prevent the build phase from trying to download binary -# distribution files from GitHub. +# The build process will generate a zip archive and a checksum +# file of electron/chromedriver/mksnapshot to prevent the build +# phase from trying to download binary distribution files from +# GitHub. # -# ELECTRON_MAKE_FLAGS: Additional command-line flags to pass to the specified -# package builder when build feature is used. The default -# flags are defined in this file. +# ELECTRON_MAKE_FLAGS: +# Additional command-line flags to pass to the specified package +# builder when build feature is used. The default flags are +# defined in this file. # # MAINTAINER: tagattie@FreeBSD.org .if !defined(_INCLUDE_USES_ELECTRON_MK) _INCLUDE_USES_ELECTRON_MK= yes -# Electron uses Node.js (actually a node package manager) for build -.include "${USESDIR}/nodejs.mk" +# Electron depends on Node.js package manager +.include "${USESDIR}/npm.mk" _VALID_ELECTRON_VERSIONS= 37 38 39 40 41 42 -_VALID_ELECTRON_FEATURES= npm appbuilder prefetch extract rebuild build -_VALID_ELECTRON_FEATURES_NPM= npm yarn1 yarn2 yarn4 pnpm +_VALID_ELECTRON_FEATURES= appbuilder rebuild build _VALID_ELECTRON_FEATURES_APPBUILDER=release devel _VALID_ELECTRON_FEATURES_REBUILD=nodejs electron _VALID_ELECTRON_FEATURES_BUILD= builder forge packager @@ -149,8 +94,6 @@ _VALID_ELECTRON_FEATURES_BUILD= builder forge packager _ELECTRON_CMD_BASE= electron _ELECTRON_PORT_BASE= devel/electron _ELECTRON_DOWNLOAD_URL_BASE= https://github.com/electron/electron/releases/download -_NODEJS_PKGNAME= node${NODEJS_VERSION} -_NODEJS_PORT= www/node${NODEJS_VERSION} # Process USES=electron[:ARGS] # Detect build, run, test, or env dependency @@ -167,28 +110,22 @@ _ELECTRON_ARGS:= ${_ELECTRON_ARGS:Nrun} _ELECTRON_TEST_DEP= yes _ELECTRON_ARGS:= ${_ELECTRON_ARGS:Ntest} . endif -. if ${_ELECTRON_ARGS:Menv} -_ELECTRON_NO_DEP= yes -_ELECTRON_ARGS:= ${_ELECTRON_ARGS:Nenv} -. endif # If no dependencies are specified, assume build, run, and test are required . if !defined(_ELECTRON_BUILD_DEP) && !defined(_ELECTRON_RUN_DEP) && \ - !defined(_ELECTRON_TEST_DEP) && !defined(_ELECTRON_NO_DEP) + !defined(_ELECTRON_TEST_DEP) _ELECTRON_BUILD_DEP= yes _ELECTRON_RUN_DEP= yes _ELECTRON_TEST_DEP= yes . endif -# Now _ELECTRON_ARGS should contain a single major version unless env is set -. if !defined(_ELECTRON_NO_DEP) -. if ${_VALID_ELECTRON_VERSIONS:M${_ELECTRON_ARGS}} +# Now _ELECTRON_ARGS should contain a major version of electron +. if ${_VALID_ELECTRON_VERSIONS:M${_ELECTRON_ARGS}} _ELECTRON_VERSION= ${_ELECTRON_ARGS} _ELECTRON_PORTDIR= ${_ELECTRON_PORT_BASE}${_ELECTRON_VERSION} . include "${PORTSDIR}/${_ELECTRON_PORTDIR}/Makefile.version" -. elif empty(_ELECTRON_ARGS) +. elif empty(_ELECTRON_ARGS) IGNORE= does not specify a major version of electron with USES=electron -. else +. else IGNORE= specifies unknown USES=electron arguments: ${_ELECTRON_ARGS} -. endif . endif # Detect features used with USE_ELECTRON @@ -204,60 +141,9 @@ IGNORE= uses unknown USE_ELECTRON features: ${_INVALID_ELECTRON_FEATURES} . for var in ${USE_ELECTRON} _ELECTRON_FEATURE_${var:C/\:.*//:tu}= ${var} . endfor -. if !defined(_ELECTRON_FEATURE_NPM) -IGNORE= does not specify a single node package manager with USE_ELECTRON=npm -. endif - -# Process USE_ELECTRON=npm[:ARGS] -# Detect fetch, extract, build, run, or test dependency -_NODEJS_NPM?= -. if defined(_ELECTRON_FEATURE_NPM) -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:S/,/ /g} -. if ${_ELECTRON_FEATURE_NPM:Mfetch} -_ELECTRON_FEATURE_NPM_FETCH= yes -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:Nfetch} -. endif -. if ${_ELECTRON_FEATURE_NPM:Mextract} -_ELECTRON_FEATURE_NPM_EXTRACT= yes -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:Nextract} -. endif -. if ${_ELECTRON_FEATURE_NPM:Mbuild} -_ELECTRON_FEATURE_NPM_BUILD= yes -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:Nbuild} -. endif -. if ${_ELECTRON_FEATURE_NPM:Mrun} -_ELECTRON_FEATURE_NPM_RUN= yes -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:Nrun} -. endif -. if ${_ELECTRON_FEATURE_NPM:Mtest} -_ELECTRON_FEATURE_NPM_TEST= yes -_ELECTRON_FEATURE_NPM:= ${_ELECTRON_FEATURE_NPM:Ntest} -. endif -# If no dependencies are specified, we assume only build dep is required -. if !defined(_ELECTRON_FEATURE_NPM_FETCH) && !defined(_ELECTRON_FEATURE_NPM_EXTRACT) && \ - !defined(_ELECTRON_FEATURE_NPM_BUILD) && !defined(_ELECTRON_FEATURE_NPM_RUN) && \ - !defined(_ELECTRON_FEATURE_NPM_TEST) -_ELECTRON_FEATURE_NPM_BUILD= yes -. endif -# Now _ELECTRON_FEATURE_NPM should contain a single package manager -. if ${_VALID_ELECTRON_FEATURES_NPM:M${_ELECTRON_FEATURE_NPM:C/^[^\:]*(\:|\$)//}} -_NODEJS_NPM= ${_ELECTRON_FEATURE_NPM:C/^[^\:]*(\:|\$)//} -. if ${_NODEJS_NPM} == npm -_NPM_PKGNAME= ${_NODEJS_NPM}${NODEJS_SUFFIX} -_NPM_PORTDIR= www/${_NODEJS_NPM}${NODEJS_SUFFIX} -. elif ${_NODEJS_NPM} == yarn1 -_NPM_PKGNAME= yarn${NODEJS_SUFFIX} -_NPM_PORTDIR= www/yarn${NODEJS_SUFFIX} -. endif -. elif empty(_ELECTRON_FEATURES_NPM) -IGNORE= does not specify a single node package manager with USE_ELECTRON=npm -. else -IGNORE= specifies unknown USE_ELECTRON=npm arguments: ${_ELECTRON_FEATURE_NPM} -. endif -. endif # Process USE_ELECTRON=appbuilder[:ARGS] -# Detect stable or devel argument of appbuilder feature +# Detect release or devel argument of appbuilder feature . if defined(_ELECTRON_FEATURE_APPBUILDER) _ELECTRON_FEATURE_APPBUILDER:= ${_ELECTRON_FEATURE_APPBUILDER:C/^[^\:]*(\:|\$)//} . if ${_ELECTRON_FEATURE_APPBUILDER:Mrelease} @@ -312,420 +198,19 @@ IGNORE= specifies unknown USE_ELECTRON=build arguments: ${_ELECTRON_FEATURE_BUIL # Setup dependencies . for stage in BUILD RUN TEST -. if defined(_ELECTRON_${stage}_DEP) && ${_ELECTRON_${stage}_DEP} == yes +. if defined(_ELECTRON_${stage}_DEP) ${stage}_DEPENDS+= ${_ELECTRON_CMD_BASE}${ELECTRON_VER_MAJOR}:${_ELECTRON_PORTDIR} . endif . endfor -. for stage in FETCH EXTRACT BUILD RUN TEST -. if defined(_ELECTRON_FEATURE_NPM_${stage}) && ${_ELECTRON_FEATURE_NPM_${stage}} == yes -. if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == yarn1 -${stage}_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} -. elif ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm -${stage}_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} -. endif -. endif -. endfor . if defined(_ELECTRON_FEATURE_APPBUILDER_RELEASE) && ${_ELECTRON_FEATURE_APPBUILDER_RELEASE} == yes BUILD_DEPENDS+= app-builder:devel/app-builder . elif defined(_ELECTRON_FEATURE_APPBUILDER_DEVEL) && ${_ELECTRON_FEATURE_APPBUILDER_DEVEL} == yes BUILD_DEPENDS+= app-builder:devel/app-builder-devel . endif -# Define variables related to node package manager -NPM_FETCH_FLAGS?= -NPM_EXTRACT_FLAGS?= -NPM_EXEC_FLAGS?= -NPM_REBUILD_FLAGS?= - -NPM_PKGFILE?= package.json -. if ${_NODEJS_NPM} == npm -NPM_LOCKFILE?= package-lock.json -NPM_MODULE_CACHE?= node_modules -NPM_CMDNAME?= npm -NPM_CACHE_SETUP_CMD?= ${DO_NADA} -NPM_FETCH_CMD?= ${NPM_CMDNAME} ci -NPM_FETCH_FLAGS+= --ignore-scripts --no-progress --no-audit --no-fund --no-update-notifier --loglevel=error -NPM_EXEC_CMD?= ${NPM_CMDNAME} exec -NPM_EXEC_FLAGS+= --no-update-notifier -NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild -NPM_REBUILD_FLAGS+= --no-update-notifier -. elif ${_NODEJS_NPM:Myarn*} -NPM_LOCKFILE?= yarn.lock -NPM_MODULE_CACHE?= yarn-offline-cache -NPM_CMDNAME?= yarn -NPM_FETCH_CMD?= ${NPM_CMDNAME} install -NPM_EXTRACT_CMD?= ${NPM_CMDNAME} install -NPM_EXEC_CMD?= ${NPM_CMDNAME} exec -. if ${_NODEJS_NPM} == yarn1 -NPM_CACHE_SETUP_CMD?= ${ECHO_CMD} 'yarn-offline-mirror "./${NPM_MODULE_CACHE}"' >> .yarnrc -NPM_FETCH_FLAGS+= --frozen-lockfile --ignore-scripts --silent -NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --offline -. elif ${_NODEJS_NPM} == yarn2 -NPM_CACHE_SETUP_CMD?= ${NPM_CMDNAME} config set cacheFolder "./${NPM_MODULE_CACHE}" -NPM_FETCH_FLAGS+= --immutable --mode=skip-build --silent -NPM_EXTRACT_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableNetwork false; \ - ${NPM_CMDNAME} config set enableInlineBuilds true" -NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --immutable-cache -NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild -. elif ${_NODEJS_NPM} == yarn4 -NPM_CACHE_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableGlobalCache false; \ - ${NPM_CMDNAME} config set cacheFolder \"./${NPM_MODULE_CACHE}\"" -NPM_FETCH_FLAGS+= --immutable --mode=skip-build --silent -NPM_EXTRACT_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableNetwork false; \ - ${NPM_CMDNAME} config set enableInlineBuilds true" -NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --immutable-cache -NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild -. endif -. elif ${_NODEJS_NPM} == pnpm -NPM_LOCKFILE?= pnpm-lock.yaml -NPM_MODULE_CACHE?= pnpm-store -NPM_CMDNAME?= pnpm -NPM_CACHE_SETUP_CMD?= ${DO_NADA} -NPM_FETCH_CMD?= ${NPM_CMDNAME} fetch -NPM_FETCH_FLAGS+= --frozen-lockfile --ignore-scripts --loglevel=error \ - --store-dir ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE} -NPM_EXTRACT_CMD?= ${NPM_CMDNAME} install -NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --offline -NPM_EXEC_CMD?= ${NPM_CMDNAME} exec -NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild -. endif - -# Define user-accessible variables -JQ_CMD?= ${LOCALBASE}/bin/jq -YQ_CMD?= ${LOCALBASE}/bin/yq -APP_BUILDER_CMD?= ${LOCALBASE}/bin/app-builder - ELECTRON_ARCH= ${ARCH:S/aarch64/arm64/:S/amd64/x64/:S/i386/ia32/} - -PKGJSONSDIR?= ${FILESDIR}/packagejsons -NPM_VER?= -NPM_EXTRACT_WRKSRC?= ${WRKSRC} -NPM_REBUILD_WRKSRC_NODEJS?= ${WRKSRC} -NPM_REBUILD_WRKSRC_ELECTRON?= ${WRKSRC} - -# Check existence of package.json -_EXISTS_NPM_PKGFILE?= -. if exists(${PKGJSONSDIR}/${NPM_PKGFILE}) -_EXISTS_NPM_PKGFILE= 1 -. endif - -# If yarn 2+ or pnpm is used, we need to know the version of node package -# manager. It is usually specified as the key "packageManager", so try to -# automatically detect the version. -. if ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm -. if ${_EXISTS_NPM_PKGFILE} == 1 && empty(NPM_VER) -NPM_VER!= ${CAT} ${PKGJSONSDIR}/${NPM_PKGFILE} | \ - ${TR} -d '\n\r\t' | ${SED} -e 's/ //g; s/"//g' | \ - ${SED} -E -e ' \ - /devEngines:\{packageManager:\{/ { \ - s/.*devEngines:\{packageManager:\{([^}]+)\}\}.*/\1/; \ - h; \ - s/.*name:([^,}]+).*/\1/p; \ - g; \ - s/.*version:([^+,}]+).*/@\1/p; \ - d; \ - }; \ - /packageManager:/ { \ - s/.*packageManager:([^+,}]+).*/\1/p; d; \ - }' | \ - ${CUT} -f 2 -d '@' -. endif -. if empty(NPM_VER) -IGNORE= does not specity version of ${NPM_CMDNAME} used for prefetching node modules -. endif - -_USES_fetch+= 490:electron-fetch-node-package-manager - -DISTFILES+= ${NPM_CMDNAME}-${NPM_VER}.tgz:prefetch -FETCH_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} - -electron-fetch-node-package-manager: - @${ECHO_MSG} "===> Fetching and setting up ${NPM_CMDNAME} version ${NPM_VER}" - @${MKDIR} ${DISTDIR}/${DIST_SUBDIR} ${WRKDIR}/.bin - @${SETENV} ${MAKE_ENV} corepack enable --install-directory ${WRKDIR}/.bin - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz ]; then \ - cd ${WRKDIR} && \ - ${SETENV} ${MAKE_ENV} corepack pack ${NPM_CMDNAME}@${NPM_VER} && \ - ${TAR} -xzf corepack.tgz && \ - ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ - ${SH} ${SCRIPTSDIR}/electron-create-mtree.sh ${NPM_CMDNAME} > \ - ${NPM_CMDNAME}.mtree && \ - ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ - ${TAR} -cz --options 'gzip:!timestamp' \ - -f ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz @${NPM_CMDNAME}.mtree; \ - fi - @${SETENV} ${MAKE_ENV} corepack install -g ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz -. endif - -# When prefetch feature is used, downloads node modules the port uses according -# to the pre-stored package.json. -. if defined(_ELECTRON_FEATURE_PREFETCH) -. if empty(_EXISTS_NPM_PKGFILE) -IGNORE= does not store ${NPM_PKGFILE} in ${PKGJSONSDIR} for prefetching node modules -. endif - -_USES_fetch+= 491:electron-fetch-node-modules \ - 492:electron-archive-node-modules - -_DISTFILE_prefetch= ${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${DISTVERSION}-node-modules${EXTRACT_SUFX} -DISTFILES+= ${_DISTFILE_prefetch}:prefetch - -. if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == yarn1 -FETCH_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} -. elif ${_NODEJS_NPM} == pnpm -FETCH_DEPENDS+= ${JQ_CMD}:textproc/jq -. if ${NPM_VER:R:R} >= 11 -FETCH_DEPENDS+= sqlite3:databases/sqlite3 -. endif -. endif - -electron-fetch-node-modules: - @${MKDIR} ${DISTDIR}/${DIST_SUBDIR} - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ]; then \ - ${ECHO_MSG} "===> Setting up node modules cache directory"; \ - ${MKDIR} ${WRKDIR}/node-modules-cache; \ - ${TAR} -cf - -C ${PKGJSONSDIR} . | ${TAR} -xf - -C ${WRKDIR}/node-modules-cache; \ - cd ${WRKDIR}/node-modules-cache && ${SETENV} ${MAKE_ENV} ${NPM_CACHE_SETUP_CMD}; \ - ${ECHO_MSG} "===> Prefetching node modules"; \ - for dir in `${FIND} ${WRKDIR}/node-modules-cache -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ - cd $${dir} && \ - ${SETENV} ${MAKE_ENV} ${NPM_FETCH_CMD} ${NPM_FETCH_FLAGS}; \ - ${RM} $${dir}/${NPM_MODULE_CACHE}/.gitignore; \ - done; \ - fi - -electron-archive-node-modules: -. if ${_NODEJS_NPM} == npm - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ - ${ECHO_MSG} "===> Archiving prefetched node modules"; \ - for dir in `${FIND} -s ${WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \ - ${GREP} -ve '${NPM_MODULE_CACHE}/.*/${NPM_MODULE_CACHE}'`; do \ - ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ - ${SH} ${SCRIPTSDIR}/electron-create-mtree.sh $${dir} >> \ - ${WRKDIR}/node-modules-cache.mtree; \ - done; \ - ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ - ${TAR} -cz --options 'gzip:!timestamp' \ - -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} \ - -C ${WRKDIR} @node-modules-cache.mtree; \ - if [ ${TMPDIR} != ${WRKDIR} ]; then \ - ${RM} -r ${WRKDIR}; \ - fi; \ - fi -. elif ${_NODEJS_NPM:Myarn*} || ${_NODEJS_NPM} == pnpm -. if ${_NODEJS_NPM} == pnpm -. if ${NPM_VER:R:R} >= 11 - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ - ${ECHO_MSG} "===> Normalizing timestamps and permissions of prefetched node modules"; \ - tmpdir=${WRKDIR}/pnpm_tmp; \ - input_db=${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/v11/index.db; \ - output_db=$${tmpdir}/index.db; \ - output_db_dump=${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/v11/index_dump.sql; \ - ${MKDIR} $${tmpdir}; \ - cd $${tmpdir} && ${SETENV} ${MAKE_ENV} ${NPM_CMDNAME} add --ignore-scripts --silent msgpackr; \ - sqlite3 $${input_db} \ - "SELECT writefile('$${tmpdir}/' || row_number() OVER (ORDER BY key ASC) || '.msgpack', data) FROM package_index;" > /dev/null; \ - sqlite3 $${input_db} \ - "SELECT key FROM package_index ORDER BY key ASC;" > $${tmpdir}/keys_list.txt; \ - counter=1; \ - while IFS= read -r key; do \ - ${PRINTF} "%s" "$${key}" > $${tmpdir}/$${counter}.key; \ - counter=$$((counter + 1)); \ - done < $${tmpdir}/keys_list.txt; \ - for file in $${tmpdir}/*.msgpack; do \ - base=$${file%.msgpack}; \ - node -e " \ - const fs = require('fs'); \ - const { Unpackr } = require('msgpackr'); \ - const unpackr = new Unpackr({}); \ - const buf = fs.readFileSync(0); \ - const data = unpackr.unpack(buf); \ - console.log(JSON.stringify(data, (key, value) => { \ - if (value instanceof Map) { \ - return { __type: 'Map', data: Array.from(value.entries()) }; \ - } \ - return value; \ - })); \ - " < $${file} > $${base}.msgpack.json; \ - ${JQ_CMD} -S ' \ - walk( \ - if type == "object" then \ - if has("checkedAt") then .checkedAt = 0 else . end | \ - if has("mode") then \ - if (.mode / 16 | floor) % 2 == 1 then .mode = .mode - 16 else . end \ - else \ - . \ - end \ - else \ - . \ - end \ - ) \ - ' $${base}.msgpack.json > $${base}.normalized.json; \ - node -e " \ - const fs = require('fs'); \ - const { Packr } = require('msgpackr'); \ - const packr = new Packr({ structuredClone: true }); \ - const rawJson = JSON.parse(fs.readFileSync(0, 'utf-8')); \ - const restoreMaps = (obj) => { \ - if (obj && typeof obj === 'object') { \ - if (obj.__type === 'Map') { \ - return new Map(obj.data.map(([k, v]) => [k, restoreMaps(v)])); \ - } \ - for (let k in obj) { \ - obj[k] = restoreMaps(obj[k]); \ - } \ - } \ - return obj; \ - }; \ - const restoredData = restoreMaps(rawJson); \ - process.stdout.write(packr.pack(restoredData)); \ - " < $${base}.normalized.json > $${base}.normalized.msgpack; \ - done; \ - sqlite3 $${output_db} \ - "CREATE TABLE package_index (key TEXT PRIMARY KEY, data BLOB) WITHOUT ROWID;" > /dev/null 2>&1; \ - sqlite3 $${output_db} \ - "PRAGMA page_size = 4096; PRAGMA journal_mode = DELETE; PRAGMA auto_vacuum = NONE; PRAGMA secure_delete = ON;" > /dev/null 2>&1; \ - total_files=$$((counter - 1)); \ - i=1; \ - while [ $${i} -le $${total_files} ]; do \ - real_key=`${CAT} $${tmpdir}/$${i}.key`; \ - { \ - ${PRINTF} "INSERT INTO package_index (key, data) VALUES ('%s', x'" "$${real_key}"; \ - hexdump -v -e '/1 "%02x"' $${tmpdir}/$${i}.normalized.msgpack; \ - ${PRINTF} "');\n"; \ - } | sqlite3 $${output_db}; \ - i=$$((i + 1)); \ - done; \ - sqlite3 $${output_db} "REINDEX; VACUUM;"; \ - sqlite3 $${output_db} ".dump" > $${output_db_dump}; \ - ${RM} $${input_db}; \ - fi -. else - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ - ${ECHO_MSG} "===> Normalizing timestamps and permissions of prefetched node modules"; \ - ${FIND} ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE} \ - -type f -name '*.json' -exec ${SH} -c ' \ - for f do \ - ${JQ_CMD} -c "walk(if type == \"object\" and has(\"checkedAt\") then .checkedAt = 0 else . end)" $${f} > $${f}.tmp && mv $${f}.tmp $${f}; \ - done \ - ' ${SH} {} ';'; \ - for dir in projects tmp; do \ - ${RM} -r ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/*/$${dir}; \ - done; \ - fi -. endif -. endif - @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ - ${ECHO_MSG} "===> Archiving prefetched node modules"; \ - cd ${WRKDIR}/node-modules-cache && \ - ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ - ${SH} ${SCRIPTSDIR}/electron-create-mtree.sh ${NPM_MODULE_CACHE} > \ - node-modules-cache.mtree && \ - ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ - ${TAR} -cz --options 'gzip:!timestamp' \ - -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} @node-modules-cache.mtree; \ - if [ ${TMPDIR} != ${WRKDIR} ]; then \ - ${RM} -r ${WRKDIR}; \ - fi; \ - fi -. endif -. endif # _FEATURE_ELECTRON_PREFETCH - -# When extract feature is used, installs the prefetched node modules into the -# port's working source directory. -. if defined(_ELECTRON_FEATURE_EXTRACT) -_USES_extract+= 600:electron-extract-node-package-manager \ - 601:electron-copy-package-file \ - 602:electron-install-node-modules - -. if ${_NODEJS_NPM} == yarn1 -EXTRACT_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} -. elif ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm -EXTRACT_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} -. endif -. if ${_NODEJS_NPM} == pnpm && ${NPM_VER:R:R} >= 11 -EXTRACT_DEPENDS+= sqlite3:databases/sqlite3 -. if ${NPM_VER:R} >= 11.3 -NPM_EXTRACT_FLAGS+= --trust-lockfile -. endif -. endif - -electron-extract-node-package-manager: -. if ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm - @${ECHO_MSG} "===> Setting up ${NPM_CMDNAME} version ${NPM_VER}" - @${MKDIR} ${WRKDIR}/.bin - @${SETENV} ${MAKE_ENV} corepack enable --install-directory ${WRKDIR}/.bin - @${SETENV} ${MAKE_ENV} corepack install -g ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz -. else - @${DO_NADA} -. endif - -electron-copy-package-file: -. if ${_EXISTS_NPM_PKGFILE} == 1 - @${ECHO_MSG} "===> Copying ${NPM_PKGFILE} and ${NPM_LOCKFILE} to ${NPM_EXTRACT_WRKSRC}" - @for f in `${FIND} ${PKGJSONSDIR} -type f \( -name ${NPM_PKGFILE} -o -name ${NPM_LOCKFILE} \) -print | ${SED} -e 's|${PKGJSONSDIR}/||'`; do \ - ${MKDIR} -p `${DIRNAME} ${NPM_EXTRACT_WRKSRC}/$${f}`; \ - if [ -f ${NPM_EXTRACT_WRKSRC}/$${f} ]; then \ - ${MV} -f ${NPM_EXTRACT_WRKSRC}/$${f} ${NPM_EXTRACT_WRKSRC}/$${f}.bak; \ - fi; \ - ${CP} ${PKGJSONSDIR}/$${f} ${NPM_EXTRACT_WRKSRC}/$${f}; \ - done -. endif - -electron-install-node-modules: -. if ${_NODEJS_NPM} == npm - @${ECHO_MSG} "===> Moving prefetched node modules to ${NPM_EXTRACT_WRKSRC}" - @if [ -d ${EXTRACT_WRKDIR}/node-modules-cache ]; then \ - for dir in `${FIND} -s ${EXTRACT_WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \ - ${GREP} -ve '${NPM_MODULE_CACHE}/.*/${NPM_MODULE_CACHE}'`; do \ - ${MV} $${dir} `${ECHO_CMD} $${dir} | sed -e 's|${EXTRACT_WRKDIR}/node-modules-cache|${NPM_EXTRACT_WRKSRC}|'`; \ - done; \ - fi -. elif ${_NODEJS_NPM:Myarn*} - @${ECHO_MSG} "===> Installing node modules from prefetched cache" - @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ - ${MV} ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ${NPM_EXTRACT_WRKSRC}; \ - fi - @cd ${NPM_EXTRACT_WRKSRC} && ${SETENV} ${MAKE_ENV} ${NPM_CACHE_SETUP_CMD} -. if defined(NPM_EXTRACT_SETUP_CMD) && !empty(NPM_EXTRACT_SETUP_CMD) - @${ECHO_MSG} "===> Setting up ${NPM_CMDNAME} command options" - @cd ${NPM_EXTRACT_WRKSRC} && ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_SETUP_CMD} -. endif - @if [ -d ${PKGJSONSDIR} ]; then \ - cd ${PKGJSONSDIR} && \ - for dir in `${FIND} . -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ - cd ${NPM_EXTRACT_WRKSRC}/$${dir} && \ - ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ - done; \ - else \ - cd ${NPM_EXTRACT_WRKSRC} && \ - ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ - fi -. elif ${_NODEJS_NPM} == pnpm - @${ECHO_MSG} "===> Installing node modules from prefetched cache" -. if ${NPM_VER:R:R} >= 11 - @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ - normalized_db_dump=${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE}/v11/index_dump.sql; \ - index_db=${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE}/v11/index.db; \ - sqlite3 $${index_db} < $${normalized_db_dump}; \ - fi -. endif - @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ - ${MKDIR} ${WRKDIR}/node-modules-cache; \ - ${MV} ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ${WRKDIR}/node-modules-cache; \ - fi - @if [ -d ${PKGJSONSDIR} ]; then \ - cd ${PKGJSONSDIR} && \ - for dir in `${FIND} . -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ - cd ${NPM_EXTRACT_WRKSRC}/$${dir} && \ - ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ - done; \ - else \ - cd ${NPM_EXTRACT_WRKSRC} && \ - ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ - fi -. endif -. endif # _ELECTRON_FEATURE_EXTRACT +ELECTRON_REBUILD_WRKSRC_NODEJS?= ${WRKSRC} +ELECTRON_REBUILD_WRKSRC_ELECTRON?= ${WRKSRC} # Always generate distribution zip files from installed electron package # directory. This is necessary to prevent the build phase from downloading @@ -733,38 +218,38 @@ electron-install-node-modules: _USES_build+= 290:electron-generate-electron-zip BUILD_DEPENDS+= zip:archivers/zip -. if ${_NODEJS_NPM} == npm -BUILD_DEPENDS+= ${JQ_CMD}:textproc/jq -. elif ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm -BUILD_DEPENDS+= ${YQ_CMD}:textproc/yq +. if ${NPM_NAME} == npm +BUILD_DEPENDS+= jq:textproc/jq +. elif ${NPM_NAME} == yarn2 || ${NPM_NAME} == yarn4 || ${NPM_NAME} == pnpm +BUILD_DEPENDS+= yq:textproc/yq . endif . if !defined(UPSTREAM_ELECTRON_VER) -. if ${_EXISTS_NPM_PKGFILE} == 1 -. if ${_NODEJS_NPM} == npm && exists(${JQ_CMD}) -UPSTREAM_ELECTRON_VER!= ${JQ_CMD} -r \ +. if ${_NPM_EXISTS_PKGFILE} == yes +. if ${NPM_NAME} == npm && exists(${LOCALBASE}/bin/jq) +UPSTREAM_ELECTRON_VER!= jq -r \ '.packages | \ to_entries | \ map(if(.key | test("electron$$")) then .value.version else empty end) | \ .[]' ${PKGJSONSDIR}/${NPM_LOCKFILE} | \ ${SORT} -n | \ ${TAIL} -n 1 -. elif ${_NODEJS_NPM} == yarn1 +. elif ${NPM_NAME} == yarn1 UPSTREAM_ELECTRON_VER!= ${GREP} -e 'resolved.*/electron/' ${PKGJSONSDIR}/${NPM_LOCKFILE} | \ ${AWK} -F- '{print $$NF}' | \ ${SED} -E 's/\.[a-z]+.*$$//' | \ ${SORT} -n | \ ${TAIL} -n 1 -. elif (${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4) && exists(${YQ_CMD}) -UPSTREAM_ELECTRON_VER!= ${YQ_CMD} -r \ +. elif (${NPM_NAME} == yarn2 || ${NPM_NAME} == yarn4) && exists(${LOCALBASE}/bin/yq) +UPSTREAM_ELECTRON_VER!= yq -r \ '. | \ to_entries | \ map(if(.key | test("^electron@")) then .value.version else empty end) | \ .[]' ${PKGJSONSDIR}/${NPM_LOCKFILE} | \ ${SORT} -n | \ ${TAIL} -n 1 -. elif ${_NODEJS_NPM} == pnpm && exists(${YQ_CMD}) -UPSTREAM_ELECTRON_VER!= ${YQ_CMD} -r \ +. elif ${NPM_NAME} == pnpm && exists(${LOCALBASE}/bin/yq) +UPSTREAM_ELECTRON_VER!= yq -r \ '.packages | \ to_entries | \ map(if(.key | test("^electron@")) then .key else empty end) | \ @@ -780,7 +265,7 @@ ELECTRON_DOWNLOAD_URL_HASH!= ${SHA256} -q -s ${ELECTRON_DOWNLOAD_URL} ELECTRON_DOWNLOAD_CACHE_DIR= .cache/electron/${ELECTRON_DOWNLOAD_URL_HASH} . if !defined(UPSTREAM_CHROMEDRIVER_VER) -. if ${_EXISTS_NPM_PKGFILE} == 1 +. if ${_NPM_EXISTS_PKGFILE} == yes UPSTREAM_CHROMEDRIVER_VER!= ${GREP} -e 'resolved.*/electron-chromedriver/' ${PKGJSONSDIR}/${NPM_LOCKFILE} | \ ${HEAD} -n 1 | ${AWK} -F- '{print $$NF}' | ${SED} -E 's/\.[a-z]+.*$$//' . endif @@ -790,7 +275,7 @@ CHROMEDRIVER_DOWNLOAD_URL_HASH!=${SHA256} -q -s ${CHROMEDRIVER_DOWNLOAD_URL} CHROMEDRIVER_DOWNLOAD_CACHE_DIR=.cache/electron/${CHROMEDRIVER_DOWNLOAD_URL_HASH} . if !defined(UPSTREAM_MKSNAPSHOT_VER) -. if ${_EXISTS_NPM_PKGFILE} == 1 +. if ${_NPM_EXISTS_PKGFILE} == yes UPSTREAM_MKSNAPSHOT_VER!= ${GREP} -e 'resolved.*/electron-mksnapshot/' ${PKGJSONSDIR}/${NPM_LOCKFILE} | \ ${HEAD} -n 1 | ${AWK} -F- '{print $$NF}' | ${SED} -E 's/\.[a-z]+.*$$//' . endif @@ -851,14 +336,9 @@ electron-generate-electron-zip: _USES_build+= 291:electron-rebuild-native-node-modules-for-node \ 490:electron-rebuild-native-node-modules-for-electron -. if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == yarn1 -BUILD_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} -. elif ${_NODEJS_NPM} == yarn2 || ${_NODEJS_NPM} == yarn4 || ${_NODEJS_NPM} == pnpm -BUILD_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} -. endif -. if ${_NODEJS_NPM} == yarn1 +. if ${NPM_NAME} == yarn1 # jq is needed for detecting native node modules needing build -BUILD_DEPENDS+= ${JQ_CMD}:textproc/jq +BUILD_DEPENDS+= jq:textproc/jq # npm is needed for executing "npm rebuild" command BUILD_DEPENDS+= npm${NODEJS_SUFFIX}>0:www/npm${NODEJS_SUFFIX} . endif @@ -867,11 +347,11 @@ electron-rebuild-native-node-modules-for-node: . if defined(_ELECTRON_FEATURE_REBUILD_NODEJS) && \ ${_ELECTRON_FEATURE_REBUILD_NODEJS} == yes @${ECHO_MSG} "===> Rebuilding native node modules for nodejs" -. if ${_NODEJS_NPM} == yarn1 - @cd ${NPM_REBUILD_WRKSRC_NODEJS} && \ +. if ${NPM_NAME} == yarn1 + @cd ${ELECTRON_REBUILD_WRKSRC_NODEJS} && \ ${SETENV} ${MAKE_ENV} ${NODEJS_REBUILD_ENV} npm rebuild . else - @cd ${NPM_REBUILD_WRKSRC_NODEJS} && \ + @cd ${ELECTRON_REBUILD_WRKSRC_NODEJS} && \ ${SETENV} ${MAKE_ENV} ${NODEJS_REBUILD_ENV} ${NPM_CMDNAME} rebuild . endif . else @@ -881,8 +361,8 @@ electron-rebuild-native-node-modules-for-node: electron-rebuild-native-node-modules-for-electron: . if defined(_ELECTRON_FEATURE_REBUILD_ELECTRON) && \ ${_ELECTRON_FEATURE_REBUILD_ELECTRON} == yes -. if ${_NODEJS_NPM} == pnpm - @for dir in `${APP_BUILDER_CMD} node-dep-tree --dir ${NPM_REBUILD_WRKSRC_ELECTRON} | ${JQ_CMD} -r '.[] | { dir: .dir, name: .deps[].name } | .dir + "/" + .name'`; do \ +. if ${NPM_NAME} == pnpm + @for dir in `app-builder node-dep-tree --dir ${ELECTRON_REBUILD_WRKSRC_ELECTRON} | jq -r '.[] | { dir: .dir, name: .deps[].name } | .dir + "/" + .name'`; do \ for subdir in `${FIND} $${dir} -type f -name binding.gyp -exec ${DIRNAME} {} ';' 2> /dev/null`; do \ cd $${subdir} && \ ${ECHO_MSG} "===> Rebuilding native node modules for electron in $${subdir}" && \ @@ -890,7 +370,7 @@ electron-rebuild-native-node-modules-for-electron: done \ done . else - @for dir in `${APP_BUILDER_CMD} node-dep-tree --dir ${NPM_REBUILD_WRKSRC_ELECTRON} | ${JQ_CMD} -r '.[] | { dir: .dir, name: .deps[].name } | .dir + "/" + .name'`; do \ + @for dir in `app-builder node-dep-tree --dir ${ELECTRON_REBUILD_WRKSRC_ELECTRON} | jq -r '.[] | { dir: .dir, name: .deps[].name } | .dir + "/" + .name'`; do \ for subdir in `${FIND} $${dir} -type f -name binding.gyp -exec ${DIRNAME} {} ';' 2> /dev/null`; do \ cd $${subdir} && \ ${ECHO_MSG} "===> Rebuilding native node modules for electron in $${subdir}" && \ @@ -938,7 +418,7 @@ ELECTRON_MAKE_CMD?= ${NPM_EXEC_CMD} ${NPM_EXEC_FLAGS} electron-forge package ELECTRON_MAKE_FLAGS+= --platform=linux DO_MAKE_BUILD= ${SETENV} ${MAKE_ENV} ${ELECTRON_MAKE_CMD} ${ELECTRON_MAKE_FLAGS} . endif -. if ${_NODEJS_NPM} == npm || ${_NODEJS_NPM} == yarn1 +. if ${NPM_NAME} == npm || ${NPM_NAME} == yarn1 ELECTRON_MAKE_CMD+= -- . endif ALL_TARGET= # empty diff --git a/Mk/Uses/npm.mk b/Mk/Uses/npm.mk new file mode 100644 index 000000000000..769d7c9e07d7 --- /dev/null +++ b/Mk/Uses/npm.mk @@ -0,0 +1,516 @@ +# Provides support for ports using Node.js package manager +# +# Feature: npm +# Usage: USES=npm:npm-name[,arg,...] +# Valid ARGS: <npm-name>, fetch, extract, build, run, test +# +# <npm-name>: The name of Node.js package manager (NPM) the port depends on. +# Supported package managers are: +# +# npm: The port uses NPM as package manager. +# yarn1: The port uses Yarn (v1) as package manager. +# yarn2: The port uses Yarn (v2 or v3) as package manager. +# yarn4: The port uses Yarn (v4+) as package manager. +# pnpm: The port uses PNPM as package manager. +# +# NOTE: The port must specify exactly a single package manager. +# Multiple package managers cannot be specified. +# +# fetch: NPM is needed at fetch time. Adds it to FETCH_DEPENDS. +# extract: NPM is needed at extract time. Adds it to EXTRACT_DEPENDS. +# build: NPM is needed at build time. Adds it to BUILD_DEPENDS. +# run: NPM is needed at run time. Adds it to RUN_DEPENDS. +# test: NPM is needed at test time. Adds it to TEST_DEPENDS. +# +# NOTE: If the port specifies none of fetch, extract, build, run or test, we +# assume the port requires build and test dependencies. +# +# Variables, which may be set by the port: +# +# NPM_VER: A version of node package manager the port uses. If yarn >2, or +# pnpm is used for the package manager, the framework requires the +# variable to be set so that it can bootstrap the correct version +# of package manager. +# +# It is usually specified in package.json and the framework tries +# to automatically detect the version. Auto-detection can be +# overridden by manually specifying the value in Makefile. +# +# Targets, which may be used by the port (ON by default, setting the variables +# to "no" disable the targets): +# +# NPM_PREFETCH: Downloads node modules the port uses according to the pre-stored +# package.json (and package-lock.json, yarn.lock, or +# pnpm-lock.yaml depending on the node package manager used) in +# PKGJSONSDIR. Downloaded node modules are archived into a single +# tarball as one of the DISTFILES. +# +# NOTE 1: If the source directory of the port has other relevant files +# than package.json and lockfile, the relevant files must also be copied +# into PKGJSONSDIR. (Examples of relevant files includes .npmrc, .yarnrc, +# and pnpm-workspace.yaml.) +# +# NOTE 2: If the source directory of the port contains multiple +# package.json's and/or lockfiles, all files needed for generating node +# modules archive must be copied into PKGJSONSDIR with directory hierarchy +# preserved. +# +# NPM_EXTRACT: Installs the prefetched node modules into the port's working +# source directory. +# +# MAINTAINER: tagattie@FreeBSD.org + +.if !defined(_INCLUDE_USES_NPM_MK) +_INCLUDE_USES_NPM_MK= yes + +# Node.js package manager depends on Node.js +.include "${USESDIR}/nodejs.mk" +_NODEJS_PKGNAME=node${NODEJS_VERSION} +_NODEJS_PORT= www/node${NODEJS_VERSION} + +_VALID_NPM_NAMES=npm yarn1 yarn2 yarn4 pnpm + +# Process USES=npm:ARG +# Detect fetch, extract, build, run, or test dependency +_NPM_ARGS= ${npm_ARGS:S/,/ /g} +. if ${_NPM_ARGS:Mfetch} +_NPM_FETCH_DEP= yes +_NPM_ARGS:= ${_NPM_ARGS:Nfetch} +. endif +. if ${_NPM_ARGS:Mextract} +_NPM_EXTRACT_DEP=yes +_NPM_ARGS:= ${_NPM_ARGS:Nextract} +. endif +. if ${_NPM_ARGS:Mbuild} +_NPM_BUILD_DEP= yes +_NPM_ARGS:= ${_NPM_ARGS:Nbuild} +. endif +. if ${_NPM_ARGS:Mrun} +_NPM_RUN_DEP= yes +_NPM_ARGS:= ${_NPM_ARGS:Nrun} +. endif +. if ${_NPM_ARGS:Mtest} +_NPM_TEST_DEP= yes +_NPM_ARGS:= ${_NPM_ARGS:Ntest} +. endif +# If no dependencies are specified, assume build and test are required +. if !defined(_NPM_FETCH_DEP) && !defied(_NPM_EXTRACT_DEP) && \ + !defined(_NPM_BUILD_DEP) && !defined(_NPM_RUN_DEP) && \ + !defined(_NPM_TEST_DEP) +_NPM_BUILD_DEP= yes +_NPM_TEST_DEP= yes +. endif +# Now _NPM_ARGS should contain a name of node package manager +. if ${_VALID_NPM_NAMES:M${_NPM_ARGS}} +_NPM_NAME= ${_NPM_ARGS} +. elif empty(_NPM_ARGS) +IGNORE= does not specify a name of node package manager +. else +IGNORE= specifies unknown USES=npm arguments: ${_NPM_ARGS} +. endif +. if ${_NPM_NAME} == npm +_NPM_PKGNAME= ${_NPM_NAME}${NODEJS_SUFFIX} +_NPM_PORTDIR= www/${_NPM_NAME}${NODEJS_SUFFIX} +. elif ${_NPM_NAME} == yarn1 +_NPM_PKGNAME= yarn${NODEJS_SUFFIX} +_NPM_PORTDIR= www/yarn${NODEJS_SUFFIX} +. endif + +# Setup dependencies +. for stage in FETCH EXTRACT BUILD RUN TEST +. if defined(_NPM_${stage}_DEP) +. if ${_NPM_NAME} == npm || ${_NPM_NAME} == yarn1 +${stage}_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} +. else +${stage}_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} +. endif +. endif +. endfor + +# Try to detect the version of package manager from the pre-stored package.json +# if it is not specified by a port. (If yarn >2 or pnpm is used, the framework +# needs to know the version for correctly boostrap the package manager.) +PKGJSONSDIR?= ${FILESDIR}/packagejsons +NPM_PKGFILE?= package.json +NPM_VER?= + +_NPM_EXISTS_PKGFILE?= no +. if exists(${PKGJSONSDIR}/${NPM_PKGFILE}) +_NPM_EXISTS_PKGFILE= yes +. endif +. if (${_NPM_NAME} == yarn2 || ${_NPM_NAME} == yarn4 || ${_NPM_NAME} == pnpm) && \ + ${_NPM_EXISTS_PKGFILE} == yes && empty(NPM_VER) +NPM_VER!= ${CAT} ${PKGJSONSDIR}/${NPM_PKGFILE} | \ + ${TR} -d '\n\r\t' | ${SED} -e 's/ //g; s/"//g' | \ + ${SED} -E -e ' \ + /devEngines:\{packageManager:\{/ { \ + s/.*devEngines:\{packageManager:\{([^}]+)\}\}.*/\1/; \ + h; \ + s/.*name:([^,}]+).*/\1/p; \ + g; \ + s/.*version:([^+,}]+).*/@\1/p; \ + d; \ + }; \ + /packageManager:/ { \ + s/.*packageManager:([^+,}]+).*/\1/p; d; \ + }' | \ + ${CUT} -f 2 -d '@' +. if empty(NPM_VER) +IGNORE= does not specity version of ${NPM_CMDNAME} used for prefetching node modules +. endif +. endif + +# Define variables related to node package manager +NPM_NAME= ${_NPM_NAME} +NPM_FETCH_FLAGS?= +NPM_EXTRACT_FLAGS?= +NPM_EXTRACT_WRKSRC?= ${WRKSRC} +. if ${_NPM_NAME} == npm +NPM_LOCKFILE?= package-lock.json +NPM_MODULE_CACHE?= node_modules +NPM_CMDNAME?= npm +NPM_CACHE_SETUP_CMD?= ${DO_NADA} +NPM_FETCH_CMD?= ${NPM_CMDNAME} ci +NPM_FETCH_FLAGS+= --ignore-scripts --no-progress --no-audit --no-fund \ + --no-update-notifier --loglevel=error +NPM_EXEC_CMD?= ${NPM_CMDNAME} exec +NPM_EXEC_FLAGS+= --no-update-notifier +NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild +NPM_REBUILD_FLAGS+= --no-update-notifier +. elif ${_NPM_NAME:Myarn*} +NPM_LOCKFILE?= yarn.lock +NPM_MODULE_CACHE?= yarn-offline-cache +NPM_CMDNAME?= yarn +NPM_FETCH_CMD?= ${NPM_CMDNAME} install +NPM_EXTRACT_CMD?= ${NPM_CMDNAME} install +NPM_EXEC_CMD?= ${NPM_CMDNAME} exec +. if ${_NPM_NAME} == yarn1 +NPM_CACHE_SETUP_CMD?= ${ECHO_CMD} 'yarn-offline-mirror "./${NPM_MODULE_CACHE}"' >> .yarnrc +NPM_FETCH_FLAGS+= --frozen-lockfile --ignore-scripts --silent +NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --offline +. elif ${_NPM_NAME} == yarn2 +NPM_CACHE_SETUP_CMD?= ${NPM_CMDNAME} config set cacheFolder "./${NPM_MODULE_CACHE}" +NPM_FETCH_FLAGS+= --immutable --mode=skip-build --silent +NPM_EXTRACT_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableNetwork false; \ + ${NPM_CMDNAME} config set enableInlineBuilds true" +NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --immutable-cache +NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild +. elif ${_NPM_NAME} == yarn4 +NPM_CACHE_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableGlobalCache false; \ + ${NPM_CMDNAME} config set cacheFolder \"./${NPM_MODULE_CACHE}\"" +NPM_FETCH_FLAGS+= --immutable --mode=skip-build --silent +NPM_EXTRACT_SETUP_CMD?= ${SH} -c "${NPM_CMDNAME} config set enableNetwork false; \ + ${NPM_CMDNAME} config set enableInlineBuilds true" +NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --immutable-cache +NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild +. endif +. elif ${_NPM_NAME} == pnpm +NPM_LOCKFILE?= pnpm-lock.yaml +NPM_MODULE_CACHE?= pnpm-store +NPM_CMDNAME?= pnpm +NPM_CACHE_SETUP_CMD?= ${DO_NADA} +NPM_FETCH_CMD?= ${NPM_CMDNAME} fetch +NPM_FETCH_FLAGS+= --frozen-lockfile --ignore-scripts --loglevel=error \ + --store-dir ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE} +NPM_EXTRACT_CMD?= ${NPM_CMDNAME} install +NPM_EXTRACT_FLAGS+= ${NPM_FETCH_FLAGS} --offline +NPM_EXEC_CMD?= ${NPM_CMDNAME} exec +NPM_REBUILD_CMD?= ${NPM_CMDNAME} rebuild +. endif + +# Use utility targets? +NPM_PREFETCH?= ${_NPM_EXISTS_PKGFILE} +NPM_EXTRACT?= ${NPM_PREFETCH} + +# Bootstrap node package manager for yarn >2 or pnpm +. if ${_NPM_NAME} == yarn2 || ${_NPM_NAME} == yarn4 || ${_NPM_NAME} == pnpm +_USES_fetch+= 490:npm-fetch-node-package-manager + +DISTFILES+= ${NPM_CMDNAME}-${NPM_VER}.tgz:prefetch +FETCH_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} + +npm-fetch-node-package-manager: + @${ECHO_MSG} "===> Fetching and setting up ${NPM_CMDNAME} version ${NPM_VER}" + @${MKDIR} ${DISTDIR}/${DIST_SUBDIR} ${WRKDIR}/.bin + @${SETENV} ${MAKE_ENV} corepack enable --install-directory ${WRKDIR}/.bin + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz ]; then \ + cd ${WRKDIR} && \ + ${SETENV} ${MAKE_ENV} corepack pack ${NPM_CMDNAME}@${NPM_VER} && \ + ${TAR} -xzf corepack.tgz && \ + ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ + ${SH} ${SCRIPTSDIR}/npm-create-mtree.sh ${NPM_CMDNAME} > \ + ${NPM_CMDNAME}.mtree && \ + ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ + ${TAR} -cz --options 'gzip:!timestamp' \ + -f ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz @${NPM_CMDNAME}.mtree; \ + fi + @${SETENV} ${MAKE_ENV} corepack install -g ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz +. endif + +. if ${NPM_PREFETCH:tl} == yes +. if ${_NPM_EXISTS_PKGFILE} == no +IGNORE= does not store ${NPM_PKGFILE} in ${PKGJSONSDIR} for prefetching node modules +. endif + +_USES_fetch+= 491:npm-fetch-node-modules \ + 492:npm-archive-node-modules + +_DISTFILE_prefetch= ${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${DISTVERSION}-node-modules${EXTRACT_SUFX} +DISTFILES+= ${_DISTFILE_prefetch}:prefetch + +. if ${_NPM_NAME} == npm || ${_NPM_NAME} == yarn1 +FETCH_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} +. elif ${_NPM_NAME} == pnpm +FETCH_DEPENDS+= jq:textproc/jq +. if ${NPM_VER:R:R} >= 11 +FETCH_DEPENDS+= sqlite3:databases/sqlite3 +. endif +. endif + +npm-fetch-node-modules: + @${MKDIR} ${DISTDIR}/${DIST_SUBDIR} + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ]; then \ + ${ECHO_MSG} "===> Setting up node modules cache directory"; \ + ${MKDIR} ${WRKDIR}/node-modules-cache; \ + ${TAR} -cf - -C ${PKGJSONSDIR} . | ${TAR} -xf - -C ${WRKDIR}/node-modules-cache; \ + cd ${WRKDIR}/node-modules-cache && ${SETENV} ${MAKE_ENV} ${NPM_CACHE_SETUP_CMD}; \ + ${ECHO_MSG} "===> Prefetching node modules"; \ + for dir in `${FIND} ${WRKDIR}/node-modules-cache -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ + cd $${dir} && \ + ${SETENV} ${MAKE_ENV} ${NPM_FETCH_CMD} ${NPM_FETCH_FLAGS}; \ + ${RM} $${dir}/${NPM_MODULE_CACHE}/.gitignore; \ + done; \ + fi + +npm-archive-node-modules: +. if ${_NPM_NAME} == npm + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ + ${ECHO_MSG} "===> Archiving prefetched node modules"; \ + for dir in `${FIND} -s ${WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \ + ${GREP} -ve '${NPM_MODULE_CACHE}/.*/${NPM_MODULE_CACHE}'`; do \ + ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ + ${SH} ${SCRIPTSDIR}/npm-create-mtree.sh $${dir} >> \ + ${WRKDIR}/node-modules-cache.mtree; \ + done; \ + ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ + ${TAR} -cz --options 'gzip:!timestamp' \ + -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} \ + -C ${WRKDIR} @node-modules-cache.mtree; \ + if [ ${TMPDIR} != ${WRKDIR} ]; then \ + ${RM} -r ${WRKDIR}; \ + fi; \ + fi +. elif ${_NPM_NAME:Myarn*} || ${_NPM_NAME} == pnpm +. if ${_NPM_NAME} == pnpm +. if ${NPM_VER:R:R} >= 11 + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ + ${ECHO_MSG} "===> Normalizing timestamps and permissions of prefetched node modules"; \ + tmpdir=${WRKDIR}/pnpm_tmp; \ + input_db=${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/v11/index.db; \ + output_db=$${tmpdir}/index.db; \ + output_db_dump=${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/v11/index_dump.sql; \ + ${MKDIR} $${tmpdir}; \ + cd $${tmpdir} && ${SETENV} ${MAKE_ENV} ${NPM_CMDNAME} add --ignore-scripts --silent msgpackr; \ + sqlite3 $${input_db} \ + "SELECT writefile('$${tmpdir}/' || row_number() OVER (ORDER BY key ASC) || '.msgpack', data) FROM package_index;" > /dev/null; \ + sqlite3 $${input_db} \ + "SELECT key FROM package_index ORDER BY key ASC;" > $${tmpdir}/keys_list.txt; \ + counter=1; \ + while IFS= read -r key; do \ + ${PRINTF} "%s" "$${key}" > $${tmpdir}/$${counter}.key; \ + counter=$$((counter + 1)); \ + done < $${tmpdir}/keys_list.txt; \ + for file in $${tmpdir}/*.msgpack; do \ + base=$${file%.msgpack}; \ + node -e " \ + const fs = require('fs'); \ + const { Unpackr } = require('msgpackr'); \ + const unpackr = new Unpackr({}); \ + const buf = fs.readFileSync(0); \ + const data = unpackr.unpack(buf); \ + console.log(JSON.stringify(data, (key, value) => { \ + if (value instanceof Map) { \ + return { __type: 'Map', data: Array.from(value.entries()) }; \ + } \ + return value; \ + })); \ + " < $${file} > $${base}.msgpack.json; \ + jq -S ' \ + walk( \ + if type == "object" then \ + if has("checkedAt") then .checkedAt = 0 else . end | \ + if has("mode") then \ + if (.mode / 16 | floor) % 2 == 1 then .mode = .mode - 16 else . end \ + else \ + . \ + end \ + else \ + . \ + end \ + ) \ + ' $${base}.msgpack.json > $${base}.normalized.json; \ + node -e " \ + const fs = require('fs'); \ + const { Packr } = require('msgpackr'); \ + const packr = new Packr({ structuredClone: true }); \ + const rawJson = JSON.parse(fs.readFileSync(0, 'utf-8')); \ + const restoreMaps = (obj) => { \ + if (obj && typeof obj === 'object') { \ + if (obj.__type === 'Map') { \ + return new Map(obj.data.map(([k, v]) => [k, restoreMaps(v)])); \ + } \ + for (let k in obj) { \ + obj[k] = restoreMaps(obj[k]); \ + } \ + } \ + return obj; \ + }; \ + const restoredData = restoreMaps(rawJson); \ + process.stdout.write(packr.pack(restoredData)); \ + " < $${base}.normalized.json > $${base}.normalized.msgpack; \ + done; \ + sqlite3 $${output_db} \ + "CREATE TABLE package_index (key TEXT PRIMARY KEY, data BLOB) WITHOUT ROWID;" > /dev/null 2>&1; \ + sqlite3 $${output_db} \ + "PRAGMA page_size = 4096; PRAGMA journal_mode = DELETE; PRAGMA auto_vacuum = NONE; PRAGMA secure_delete = ON;" > /dev/null 2>&1; \ + total_files=$$((counter - 1)); \ + i=1; \ + while [ $${i} -le $${total_files} ]; do \ + real_key=`${CAT} $${tmpdir}/$${i}.key`; \ + { \ + ${PRINTF} "INSERT INTO package_index (key, data) VALUES ('%s', x'" "$${real_key}"; \ + hexdump -v -e '/1 "%02x"' $${tmpdir}/$${i}.normalized.msgpack; \ + ${PRINTF} "');\n"; \ + } | sqlite3 $${output_db}; \ + i=$$((i + 1)); \ + done; \ + sqlite3 $${output_db} "REINDEX; VACUUM;"; \ + sqlite3 $${output_db} ".dump" > $${output_db_dump}; \ + ${RM} $${input_db}; \ + fi +. else + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ + ${ECHO_MSG} "===> Normalizing timestamps and permissions of prefetched node modules"; \ + ${FIND} ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE} \ + -type f -name '*.json' -exec ${SH} -c ' \ + for f do \ + jq -c "walk(if type == \"object\" and has(\"checkedAt\") then .checkedAt = 0 else . end)" $${f} > $${f}.tmp && mv $${f}.tmp $${f}; \ + done \ + ' ${SH} {} ';'; \ + for dir in projects tmp; do \ + ${RM} -r ${WRKDIR}/node-modules-cache/${NPM_MODULE_CACHE}/*/$${dir}; \ + done; \ + fi +. endif +. endif + @if [ ! -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} ] && [ -d ${WRKDIR}/node-modules-cache ]; then \ + ${ECHO_MSG} "===> Archiving prefetched node modules"; \ + cd ${WRKDIR}/node-modules-cache && \ + ${SETENV} SCRIPTSDIR=${SCRIPTSDIR} WRKDIR=${WRKDIR} \ + ${SH} ${SCRIPTSDIR}/npm-create-mtree.sh ${NPM_MODULE_CACHE} > \ + node-modules-cache.mtree && \ + ${SETENV} LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ + ${TAR} -cz --options 'gzip:!timestamp' \ + -f ${DISTDIR}/${DIST_SUBDIR}/${_DISTFILE_prefetch} @node-modules-cache.mtree; \ + if [ ${TMPDIR} != ${WRKDIR} ]; then \ + ${RM} -r ${WRKDIR}; \ + fi; \ + fi +. endif +. endif + +. if ${NPM_EXTRACT:tl} == yes +_USES_extract+= 600:npm-extract-node-package-manager \ + 601:npm-copy-package-file \ + 602:npm-install-node-modules + +. if ${_NPM_NAME} == yarn1 +EXTRACT_DEPENDS+= ${_NPM_PKGNAME}>0:${_NPM_PORTDIR} +. elif ${_NPM_NAME} == yarn2 || ${_NPM_NAME} == yarn4 || ${_NPM_NAME} == pnpm +EXTRACT_DEPENDS+= ${_NODEJS_PKGNAME}>0:${_NODEJS_PORT} +. if ${_NPM_NAME} == pnpm && ${NPM_VER:R:R} >= 11 +EXTRACT_DEPENDS+= sqlite3:databases/sqlite3 +. if ${NPM_VER:R} >= 11.3 +NPM_EXTRACT_FLAGS+= --trust-lockfile +. endif +. endif +. endif + +npm-extract-node-package-manager: +. if ${_NPM_NAME} == yarn2 || ${_NPM_NAME} == yarn4 || ${_NPM_NAME} == pnpm + @${ECHO_MSG} "===> Setting up ${NPM_CMDNAME} version ${NPM_VER}" + @${MKDIR} ${WRKDIR}/.bin + @${SETENV} ${MAKE_ENV} corepack enable --install-directory ${WRKDIR}/.bin + @${SETENV} ${MAKE_ENV} corepack install -g ${DISTDIR}/${DIST_SUBDIR}/${NPM_CMDNAME}-${NPM_VER}.tgz +. else + @${DO_NADA} +. endif + +npm-copy-package-file: +. if ${_NPM_EXISTS_PKGFILE} == yes + @${ECHO_MSG} "===> Copying ${NPM_PKGFILE} and ${NPM_LOCKFILE} to ${NPM_EXTRACT_WRKSRC}" + @for f in `${FIND} ${PKGJSONSDIR} -type f \( -name ${NPM_PKGFILE} -o -name ${NPM_LOCKFILE} \) -print | ${SED} -e 's|${PKGJSONSDIR}/||'`; do \ + ${MKDIR} -p `${DIRNAME} ${NPM_EXTRACT_WRKSRC}/$${f}`; \ + if [ -f ${NPM_EXTRACT_WRKSRC}/$${f} ]; then \ + ${MV} -f ${NPM_EXTRACT_WRKSRC}/$${f} ${NPM_EXTRACT_WRKSRC}/$${f}.bak; \ + fi; \ + ${CP} ${PKGJSONSDIR}/$${f} ${NPM_EXTRACT_WRKSRC}/$${f}; \ + done +. endif + +npm-install-node-modules: +. if ${_NPM_NAME} == npm + @${ECHO_MSG} "===> Moving prefetched node modules to ${NPM_EXTRACT_WRKSRC}" + @if [ -d ${EXTRACT_WRKDIR}/node-modules-cache ]; then \ + for dir in `${FIND} -s ${EXTRACT_WRKDIR}/node-modules-cache -type d -name ${NPM_MODULE_CACHE} -print | \ + ${GREP} -ve '${NPM_MODULE_CACHE}/.*/${NPM_MODULE_CACHE}'`; do \ + ${MV} $${dir} `${ECHO_CMD} $${dir} | sed -e 's|${EXTRACT_WRKDIR}/node-modules-cache|${NPM_EXTRACT_WRKSRC}|'`; \ + done; \ + fi +. elif ${_NPM_NAME:Myarn*} + @${ECHO_MSG} "===> Installing node modules from prefetched cache" + @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ + ${MV} ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ${NPM_EXTRACT_WRKSRC}; \ + fi + @cd ${NPM_EXTRACT_WRKSRC} && ${SETENV} ${MAKE_ENV} ${NPM_CACHE_SETUP_CMD} +. if defined(NPM_EXTRACT_SETUP_CMD) && !empty(NPM_EXTRACT_SETUP_CMD) + @${ECHO_MSG} "===> Setting up ${NPM_CMDNAME} command options" + @cd ${NPM_EXTRACT_WRKSRC} && ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_SETUP_CMD} +. endif + @if [ -d ${PKGJSONSDIR} ]; then \ + cd ${PKGJSONSDIR} && \ + for dir in `${FIND} . -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ + cd ${NPM_EXTRACT_WRKSRC}/$${dir} && \ + ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ + done; \ + else \ + cd ${NPM_EXTRACT_WRKSRC} && \ + ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ + fi +. elif ${_NPM_NAME} == pnpm + @${ECHO_MSG} "===> Installing node modules from prefetched cache" +. if ${NPM_VER:R:R} >= 11 + @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ + normalized_db_dump=${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE}/v11/index_dump.sql; \ + index_db=${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE}/v11/index.db; \ + sqlite3 $${index_db} < $${normalized_db_dump}; \ + fi +. endif + @if [ -d ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ]; then \ + ${MKDIR} ${WRKDIR}/node-modules-cache; \ + ${MV} ${EXTRACT_WRKDIR}/${NPM_MODULE_CACHE} ${WRKDIR}/node-modules-cache; \ + fi + @if [ -d ${PKGJSONSDIR} ]; then \ + cd ${PKGJSONSDIR} && \ + for dir in `${FIND} . -type f -name ${NPM_LOCKFILE} -exec ${DIRNAME} {} ';'`; do \ + cd ${NPM_EXTRACT_WRKSRC}/$${dir} && \ + ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ + done; \ + else \ + cd ${NPM_EXTRACT_WRKSRC} && \ + ${SETENV} ${MAKE_ENV} ${NPM_EXTRACT_CMD} ${NPM_EXTRACT_FLAGS}; \ + fi +. endif +. endif + +.endif # _INCLUDE_USES_NPM_MK |
