View | Details | Raw Unified | Return to bug 204577 | Differences between
and this patch

Collapse All | Expand All

(-)Mk/Uses/nodejs.mk (+554 lines)
Line 0 Link Here
1
# $FreeBSD$
2
#
3
# Provide support for NodeJS based projects
4
#
5
# Feature:	nodejs
6
# Usage:	USES=nodejs
7
#
8
# MAINTAINER: portmgr@FreeBSD.org
9
10
# NODE_SUB_PROJECTS   - additional projects to extract into individual
11
#                       directories. Distfile for the group with the name
12
#                       of the sub-project is extracted into the sub-folder
13
#                       with the same name. Build is also performed for
14
#                       sub-projects.
15
# NODE_SUB_MODULES    - additional projects to insert as submodules into the
16
#                       specific directories identified. Build is not
17
#                       prformed for them.
18
# NODE_RM_DIRS        - directories to delete
19
# NODE_USES           - additional features enabled in nodejs module:
20
#               grunt   - run grunt tasks as a part of the build
21
#      merge-pkg-deps   - merge packageDependencies into dependencies in package.json
22
# NODE_MODULES_ADD    - add node module dependencies, in the format: {<dir>/}<module>:<version>
23
# NODE_MODULES_DEL    - delete node module dependencies, in the format: {<dir>/}<module>
24
# NODE_FILES_TO_CLEAN - wildcards for files and directoroes that do not need to be installed
25
26
# Port workflow:
27
# * It starts in the DEBUG mode. In DEBUG mode port can be built and run but
28
#   can't be committed. Developer can make changes to the port in the DEBUG mode.
29
# * 'make makerelease' - brings the port to RELEASE mode, when it can be committed
30
# * 'make makedebug'   - brings the port back to DEBUG mode in order to make changes
31
# * 'make printmode'   - prints the current mode of the port
32
# 
33
34
# NOTE: archivers/gtar is used to make the distfile because FreeBSD tar(1) has a bug
35
#       that prevents it from producing the deterministic output in certain situations
36
#       (https://github.com/libarchive/libarchive/pull/623)
37
# NOTE: some sections of package.json are deleted (ex. scripts/test) as a workaround
38
#       for the npm bug that causes package.json volatility
39
#       (https://github.com/npm/npm/issues/10406)
40
41
.if !defined(_INCLUDE_USES_NODE_MK)
42
_INCLUDE_USES_NODE_MK=	yes
43
44
FETCH_DEPENDS+=		npm:${PORTSDIR}/www/npm \
45
			jq:${PORTSDIR}/textproc/jq \
46
			gtar:${PORTSDIR}/archivers/gtar
47
BUILD_DEPENDS+=		npm:${PORTSDIR}/www/npm \
48
			gmake:${PORTSDIR}/devel/gmake
49
RUN_DEPENDS+=		node:${PORTSDIR}/www/node
50
51
_NODE_DIR?=		${PORTNAME}-${PORTVERSION}
52
53
# commands
54
NPM_CMD=		${LOCALBASE}/bin/npm
55
NODE_CMD=		${LOCALBASE}/bin/node
56
JQ_CMD=			${LOCALBASE}/bin/jq
57
GTAR_CMD=		${LOCALBASE}/bin/gtar
58
59
#DISTRO_TAR_CMD=	${TAR}
60
DISTRO_TAR_CMD=		${GTAR_CMD}
61
62
# variables
63
_NODE_TMP_BASE_FETCH=	${DISTDIR}/${_NODE_DIR}.tmpdirs
64
_NODE_TMP_BASE_BUILD=	${WRKDIR}/.tmpdirs
65
_NODE_USERHOME_FETCH=	${_NODE_TMP_BASE_FETCH}/.userhome
66
_NODE_TMP_FETCH=	${_NODE_TMP_BASE_FETCH}/.tmp
67
_NODE_USERHOME_BUILD=	${_NODE_TMP_BASE_BUILD}/.userhome
68
_NODE_TMP_BUILD=	${_NODE_TMP_BASE_BUILD}/.tmp
69
_NODE_FAKE_GIT=	${_NODE_TMP_FETCH}/fake-git
70
_NODE_FAKE_GMAKE=	${_NODE_TMP_BUILD}/gmake
71
_NODE_NPMRC_FETCH=	${_NODE_USERHOME_FETCH}/.npmrc
72
_MAKE_TMP_DIRS_FETCH=	${MKDIR} ${_NODE_USERHOME_FETCH} ${_NODE_TMP_FETCH}
73
_MAKE_TMP_DIRS_BUILD=	${MKDIR} ${_NODE_USERHOME_BUILD} ${_NODE_TMP_BUILD}
74
_CLEAN_TMP_DIRS_FETCH=	${RM} -r ${_NODE_TMP_BASE_FETCH}
75
_CLEAN_TMP_DIRS_BUILD=	${RM} -r ${_NODE_TMP_BASE_BUILD}
76
_INIT_TMP_DIRS_FETCH=	${_CLEAN_TMP_DIRS_FETCH} && ${_MAKE_TMP_DIRS_FETCH}
77
_INIT_TMP_DIRS_BUILD=	${_CLEAN_TMP_DIRS_BUILD} && ${_MAKE_TMP_DIRS_BUILD}
78
CFLAGS+=		-I${LOCALBASE}/include/node
79
CXXFLAGS+=		-I${LOCALBASE}/include/node
80
NPM_ENV+=		C=${CC} CXX=${CXX}
81
NPM_ENV_FETCH=		${NPM_ENV} HOME=${_NODE_USERHOME_FETCH} TMP=${_NODE_TMP_FETCH} PATH=${_NODE_TMP_FETCH}:${PATH}
82
NPM_ENV_BUILD=		${NPM_ENV} HOME=${_NODE_USERHOME_BUILD} TMP=${_NODE_TMP_BUILD} PATH=${_NODE_TMP_BUILD}:${PATH}
83
NPM_LOG_LEVEL?=		warn
84
NPM_FETCH_ARGS=		--loglevel ${NPM_LOG_LEVEL} --ignore-scripts
85
NPM_BUILD_ARGS=		--loglevel ${NPM_LOG_LEVEL} --nodedir=${LOCALBASE}
86
NPM_PRUNE_ARGS=		--loglevel ${NPM_LOG_LEVEL} --production=true
87
NPM_SHRINKWRAP_ARGS=	--dev
88
REINPLACE_ARGS=		-i ""
89
_NODE_PACKAGE_JSON=	package.json
90
_NODE_PACKAGE_EXISTS=	[ -f ${_NODE_PACKAGE_JSON} ]
91
SHRINKWRAP_NAME=	npm-shrinkwrap.json
92
SHRINKWRAP_FILE=	${FILESDIR}/${SHRINKWRAP_NAME}
93
NODE_INSTALL_BASE:=	${LOCALBASE}/share/node-projects
94
NODE_INSTALL_DIR:=	${NODE_INSTALL_BASE}/${PORTNAME}
95
NODE_ORIG_DISTFILES:=	${DISTFILES}
96
NODE_DISTFILE:=		${PORTNAME}-${PORTVERSION}-nodejs.tar.gz
97
CKSUMFILES+=		${NODE_DISTFILE}
98
_NODE_MASTER_SITE_BACKUP_URLS= ${MASTER_SITE_BACKUP}${NODE_DISTFILE}
99
NPM_BUILD_DIR?=		.
100
NODE_FILES_TO_CLEAN+=	.git* CVS .svn .
101
NODE_FILES_TO_CLEAN+=	.lock-wscript .wafpickle-N *.swp .DS_Store ._* npm-debug.log
102
NODE_FILES_TO_CLEAN+=	*.bak *.log *.bat file .travis.yml man *.info
103
NODE_FILES_TO_CLEAN+=	CHANGELOG CHANGELOG.md README README.* AUTHORS AUTHORS.* HISTORY HISTORY.*
104
NODE_FILES_TO_CLEAN+=	Makefile
105
_NODE_DO_FAIL=	return 1
106
107
WRKSRC=			${WRKDIR}/${_NODE_DIR}
108
109
.if ! exists(${SHRINKWRAP_FILE})
110
NO_CHECKSUM=    yes
111
  ODE_DEBUG_MODE=yes
112
node-remind-debug-mode:
113
	@${ECHO_CMD} "(!!!)"
114
	@${ECHO_CMD} "(!!!) Port ${PORTNAME} is in the DEBUG mode, run 'make makerelease' to finalize it"
115
	@${ECHO_CMD} "(!!!)"
116
node-assert-debug-mode: node-check-shrinkwrap-files
117
node-assert-release-mode: node-check-shrinkwrap-files
118
	@${ECHO} "(!!!)"
119
	@${ECHO} "(!!!) already in the DEBUG mode"
120
	@${ECHO} "(!!!)"
121
	@${FALSE}
122
node-print-mode: node-check-shrinkwrap-files
123
	@${ECHO} "Port ${PORTNAME} is in the DEBUG mode"
124
node-check-shrinkwrap-files:
125
	@for sp in ${NODE_SUB_PROJECTS}; do \
126
	  if [ -f ${FILESDIR}/$${sp}/${SHRINKWRAP_NAME} ]; then \
127
	    ${ECHO} "(!!!) ERROR: shrinkwrap file for sub-project $${sp} exists in DEBUG mode!"; \
128
	    ${FALSE}; \
129
	  fi; \
130
	done
131
.else
132
node-remind-debug-mode:
133
node-assert-debug-mode: node-check-shrinkwrap-files
134
	@${ECHO} "(!!!)"
135
	@${ECHO} "(!!!) already in RELEASE mode"
136
	@${ECHO} "(!!!)"
137
	@${FALSE}
138
node-assert-release-mode: node-check-shrinkwrap-files
139
node-print-mode: node-check-shrinkwrap-files
140
	@${ECHO} "Port ${PORTNAME} is in the RELEASE mode"
141
node-check-shrinkwrap-files:
142
	@for sp in ${NODE_SUB_PROJECTS}; do \
143
	  if ! [ -f ${FILESDIR}/$${sp}/${SHRINKWRAP_NAME} ]; then \
144
	    ${ECHO} "(!!!) ERROR: shrinkwrap file for sub-project $${sp} is missing!"; \
145
	    ${_NODE_DO_FAIL}; \
146
	  fi; \
147
	done
148
.endif
149
150
.for f in ${NODE_USES}
151
_f:=	${f:C/\:.*//}
152
.if ${_f}=="grunt"
153
FETCH_DEPENDS+=		grunt:${PORTSDIR}/devel/grunt
154
GRUNT_CMD=		${LOCALBASE}/bin/grunt
155
GRUNT_ENV+=		HOME=${_NODE_USERHOME_BUILD} TMP=${_NODE_TMP_BUILD} PATH=${_NODE_TMP_BUILD}:${PATH}
156
GRUNT_BUILD_ARGS+=
157
NODE_GRUNT_TARGETS?=
158
_NODE_USES_GRUNT=	yes
159
.elif ${_f}=="merge-pkg-deps"
160
_NODE_USES_MERGE_PKG_DEPS=	yes
161
.endif
162
.endfor
163
164
.if defined(NODE_SRCDIR)
165
_NODE_DO_CD=node_modules/${NODE_SUBDIR}
166
.else
167
_NODE_DO_CD=.
168
.endif
169
_NODE_FETCH_WORKDIR=${DISTDIR}
170
171
node-delete-distfile:
172
	@${RM} -f ${_NODE_FETCH_WORKDIR}/${NODE_DISTFILE}
173
174
# exported development mode targets
175
printmode: node-print-mode
176
makerelease: node-assert-debug-mode node-delete-distfile clean fetch node-make-shrinkwrap
177
makedebug: node-assert-release-mode node-delete-shrinkwrap
178
179
node-make-shrinkwrap:
180
	@(${ECHO} "===>  Making npm-shrinkwrap set to fix component versions for ${PKGNAME}" && \
181
	${_INIT_TMP_DIRS_FETCH} && \
182
	cd ${_NODE_FETCH_WORKDIR} && \
183
	${RM} -rf ${_NODE_DIR} && \
184
	${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${NODE_DISTFILE} ${EXTRACT_AFTER_ARGS} && \
185
	cd ${_NODE_DIR}/${_NODE_DO_CD} && \
186
	(cd ${NPM_BUILD_DIR} && \
187
	  ${NPM_ENV_FETCH} ${NPM_CMD} shrinkwrap ${NPM_SHRINKWRAP_ARGS} && \
188
	  ${MKDIR} ${FILESDIR} && \
189
	  ${MV} ${SHRINKWRAP_NAME} ${SHRINKWRAP_FILE}) && \
190
	for sp in ${NODE_SUB_PROJECTS}; do \
191
	  (cd $${sp} && \
192
	    ${NPM_ENV_FETCH} ${NPM_CMD} shrinkwrap ${NPM_SHRINKWRAP_ARGS} && \
193
	    ${MKDIR} ${FILESDIR}/$${sp} && \
194
	    ${MV} ${SHRINKWRAP_NAME} ${FILESDIR}/$${sp}/) || ${_NODE_DO_FAIL}; \
195
	done && \
196
	cd ${_NODE_FETCH_WORKDIR} && \
197
	${RM} -r ${_NODE_DIR} && \
198
	${RM} ${NODE_DISTFILE} && \
199
	${_CLEAN_TMP_DIRS_FETCH}) && \
200
	${ECHO} "-" && \
201
	${ECHO} "- shrinkwrap file(s) have been generated, entering RELEASE mode" && \
202
	${ECHO} "-" && \
203
	${ECHO} "==>  Re-fetching with shrinkwrap in RELEASE mode" && \
204
	${MAKE} fetch && \
205
	${ECHO} "-" && \
206
	${ECHO} "- in RELEASE mode now, run 'make makesum'" && \
207
	${ECHO} "-"
208
209
node-delete-shrinkwrap: node-assert-release-mode
210
	@${RM} -f `${FIND} ${FILESDIR} -name ${SHRINKWRAP_NAME}`
211
	@${ECHO} "-"
212
	@${ECHO} "- shrinkwrap file(s) have been deleted, entering DEBUG mode"
213
	@${ECHO} "-"
214
215
node-fakegit: .EXEC .PHONY
216
	@${_INIT_TMP_DIRS_FETCH} && \
217
	(${ECHO} '#!/bin/sh'; \
218
	${ECHO} ''; \
219
	${ECHO} 'name="nodejs-fetch"'; \
220
	${ECHO} 'DISTDIR="${DISTDIR}"'; \
221
	${ECHO} 'NODE_ORIG_DISTFILES="${NODE_ORIG_DISTFILES:C@^([^:]+).*@\1@}"'; \
222
	${ECHO} 'NODE_VERBOSE="${NODE_VERBOSE}"'; \
223
	${ECHO} 'NODE_DEBUG="${NODE_DEBUG}"'; \
224
	${ECHO} ''; \
225
	${ECHO} 'msg() {'; \
226
	${ECHO} '  [ "$$NODE_VERBOSE" = yes ] && echo "$${name}: $$1" >&2'; \
227
	${ECHO} '  dbg_log "$${name}: $$1"'; \
228
	${ECHO} '}'; \
229
	${ECHO} 'err() {'; \
230
	${ECHO} '  echo "$${name}: ERROR: $$1" >&2'; \
231
	${ECHO} '  dbg_log "$${name}: ERROR: $$1"'; \
232
	${ECHO} '}'; \
233
	${ECHO} 'dbg_log() {'; \
234
	${ECHO} '  [ "$$NODE_DEBUG" = yes ] && (echo "$$1" >>/tmp/nodejs-$$$$.log)'; \
235
	${ECHO} '}'; \
236
	${ECHO} ''; \
237
	${ECHO} 'dbg_log "called with arguments: $$*"'; \
238
	${ECHO} ''; \
239
	${ECHO} 'cmd_clone_remote() {'; \
240
	${ECHO} '  local mirror="$$1"'; \
241
	${ECHO} '  local dir="$$2"'; \
242
	${ECHO} '  msg "Git clone requested: mirror=$$mirror -> dir=$${dir}"'; \
243
	${ECHO} '  local fname_regex=$$(echo $$mirror | sed -E "s/https:\/\/github\.com\/([^/]+)\/([^/]+)\.git$$/^\1-\2-[[:alnum:].]*_GH0.tar.gz$$/g")'; \
244
	${ECHO} '  local fname=$$(find_file "$${fname_regex}")'; \
245
	${ECHO} '  if [ -n "$${fname}" ]; then'; \
246
	${ECHO} '    msg "Found distfile=$$fname for $$mirror"'; \
247
	${ECHO} '    (cd $${dir} && tar xzf $${DISTDIR}/$${fname} --strip 1)'; \
248
	${ECHO} '    return $$?'; \
249
	${ECHO} '  else'; \
250
	${ECHO} '    err "Failed to find distfile for $$mirror"'; \
251
	${ECHO} '    return 1'; \
252
	${ECHO} '  fi'; \
253
	${ECHO} '}'; \
254
	${ECHO} 'cmd_clone_local() {'; \
255
	${ECHO} '  local src="$$1"'; \
256
	${ECHO} '  local dst="$$2"'; \
257
	${ECHO} '  msg "copy $$src -> $$dst"'; \
258
	${ECHO} '  (cd $${src} && tar czf - .) | (cd $${dst} && tar xzf -)'; \
259
	${ECHO} '}'; \
260
	${ECHO} ''; \
261
	${ECHO} 'cmd_checkout() {'; \
262
	${ECHO} '  msg "do nothing for checkout of $$1 in `pwd`"'; \
263
	${ECHO} '}'; \
264
	${ECHO} ''; \
265
	${ECHO} 'find_file() {'; \
266
	${ECHO} '  for f in $${NODE_ORIG_DISTFILES}; do'; \
267
	${ECHO} '    if expr "$${f}" : "$${fname_regex}" > /dev/null; then'; \
268
	${ECHO} '      echo "$$f"'; \
269
	${ECHO} '      return'; \
270
	${ECHO} '    fi'; \
271
	${ECHO} '  done'; \
272
	${ECHO} '}'; \
273
	${ECHO} ''; \
274
	${ECHO} 'case $$1 in'; \
275
	${ECHO} 'clone)'; \
276
	${ECHO} '  shift'; \
277
	${ECHO} '  while [ $$# -gt 0 ]; do'; \
278
	${ECHO} '    key="$$1"'; \
279
	${ECHO} '    case $$key in'; \
280
	${ECHO} '        --template=*)'; \
281
	${ECHO} '      ;;'; \
282
	${ECHO} '      --mirror)'; \
283
	${ECHO} '        MIRROR="$$2"'; \
284
	${ECHO} '        shift'; \
285
	${ECHO} '      ;;'; \
286
	${ECHO} '      -*)'; \
287
	${ECHO} '        err "Unknown argument: $$key" && exit 1'; \
288
	${ECHO} '      ;;'; \
289
	${ECHO} '      *)'; \
290
	${ECHO} '        if [ $$# -eq 1 -a -n "$$MIRROR" ]; then'; \
291
	${ECHO} '          cmd_clone_remote "$${MIRROR}" "$$key"'; \
292
	${ECHO} '          exit $$?'; \
293
	${ECHO} '        fi'; \
294
	${ECHO} '        if [ $$# -eq 2 -a -z "$$MIRROR" ]; then'; \
295
	${ECHO} '          cmd_clone_local "$$1" "$$2"'; \
296
	${ECHO} '          exit $$?'; \
297
	${ECHO} '        fi'; \
298
	${ECHO} '        err "Unknown argument #=$$#: $$key"'; \
299
	${ECHO} '        exit 1'; \
300
	${ECHO} '      ;;'; \
301
	${ECHO} '    esac'; \
302
	${ECHO} '    shift'; \
303
	${ECHO} '  done'; \
304
	${ECHO} '  ;;'; \
305
	${ECHO} 'rev-list)'; \
306
	${ECHO} '  shift'; \
307
	${ECHO} '  while [ $$# -gt 0 ]; do'; \
308
	${ECHO} '    key="$$1"'; \
309
	${ECHO} '    case $$key in'; \
310
	${ECHO} '      -n1)'; \
311
	${ECHO} '        shift'; \
312
	${ECHO} '        [ $$# -eq 1 ] || ! err "Unknown argument: $$key" || exit 1'; \
313
	${ECHO} '        msg "Returning same revision $$1"'; \
314
	${ECHO} '        echo $$1'; \
315
	${ECHO} '        exit 0'; \
316
	${ECHO} '      ;;'; \
317
	${ECHO} '      *)'; \
318
	${ECHO} '        err "Unknown argument: $$key" && exit 1'; \
319
	${ECHO} '      ;;'; \
320
	${ECHO} '    esac'; \
321
	${ECHO} '    shift'; \
322
	${ECHO} '  done'; \
323
	${ECHO} '  err "rev-list without arguments" && exit 1'; \
324
	${ECHO} '  ;;'; \
325
	${ECHO} 'checkout)'; \
326
	${ECHO} '  shift'; \
327
	${ECHO} '  if [ $$# -eq 1 ]; then'; \
328
	${ECHO} '    cmd_checkout "$$1"'; \
329
	${ECHO} '    exit 0'; \
330
	${ECHO} '  fi'; \
331
	${ECHO} '  ;;'; \
332
	${ECHO} 'config)'; \
333
	${ECHO} '  echo ""'; \
334
	${ECHO} '  ;;'; \
335
	${ECHO} '*)'; \
336
	${ECHO} '  err "Unknown command: $$1" && exit 1'; \
337
	${ECHO} '  ;;'; \
338
	${ECHO} 'esac'; \
339
	${ECHO} '') > ${_NODE_FAKE_GIT}
340
	@${CHMOD} +x ${_NODE_FAKE_GIT}
341
	@${ECHO} "git = ${_NODE_FAKE_GIT}" >> ${_NODE_NPMRC_FETCH}
342
343
fakemake: .EXEC .PHONY
344
	@${_INIT_TMP_DIRS_BUILD} && \
345
	(${ECHO} '#!/bin/sh'; \
346
	${ECHO} ''; \
347
	${ECHO} '${MAKE_ENV} PATH=$$PATH:${LOCALBASE}/bin ${LOCALBASE}/bin/gmake ${MAKE_ARGS} $$@'; \
348
	${ECHO} '') >> ${_NODE_FAKE_GMAKE}
349
	@${CHMOD} +x ${_NODE_FAKE_GMAKE}
350
351
.if !target(nodejs-patch-fetch)
352
nodejs-patch-fetch:
353
.endif
354
355
_USES_fetch+= 750:npm-fetch
356
npm-fetch: node-fakegit
357
	@${MKDIR} ${_NODE_FETCH_WORKDIR}
358
	@cd ${_NODE_FETCH_WORKDIR}; \
359
	force_fetch=false; \
360
	for afile in ${FORCE_FETCH}; do \
361
	  afile=$${afile##*/}; \
362
	  if [ "x$$afile" = "x${NODE_DISTFILE}" ]; then \
363
	    force_fetch=true; \
364
	  fi; \
365
	done; \
366
	if [ ! -f ${NODE_DISTFILE} -o "$$force_fetch" = "true" ]; then \
367
	  ${RM} -rf ${_NODE_PROJECT_FILE} ${_NODE_DIR} ${NODE_DISTFILE}; \
368
	  for url in ${_NODE_MASTER_SITE_BACKUP_URLS}; do \
369
	    if ${ECHO_MSG} "===>  Attempting to fetch ${PORTNAME} from the master backup site" && \
370
	       ${SETENV} ${FETCH_ENV} ${FETCH_CMD} ${FETCH_BEFORE_ARGS} $${url} ${FETCH_AFTER_ARGS}; then \
371
	       return 0; \
372
	    fi; \
373
	  done && \
374
	  if ${ECHO_MSG} "===>  Extracting node project source for ${PKGNAME}" && \
375
	     ${MKDIR} ${_NODE_DIR} && \
376
	     for main_distfile in ${NODE_ORIG_DISTFILES:N*\:*}; do \
377
	       ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} $${main_distfile} ${EXTRACT_AFTER_ARGS} \
378
	           -C ${_NODE_DIR} --strip 1 || ${_NODE_DO_FAIL}; \
379
	     done && \
380
	     for sp in ${NODE_SUB_PROJECTS}; do \
381
	       for df in `${ECHO} ${NODE_ORIG_DISTFILES} | tr ' ' '\n' | grep :$${sp}$$`; do \
382
	         ${MKDIR} ${_NODE_DIR}/$${sp} && \
383
	         ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${DISTDIR}/`${ECHO} $${df} | ${SED} -e 's/:[^:]*$$//g'` ${EXTRACT_AFTER_ARGS} \
384
	           -C ${_NODE_DIR}/$${sp} --strip 1 || ${_NODE_DO_FAIL}; \
385
	       done; \
386
	     done && \
387
	     (cd ${_NODE_DIR} && ${MAKE} -f ${MASTERDIR}/Makefile nodejs-patch-fetch) && \
388
	     for sm in ${NODE_SUB_MODULES}; do \
389
	       sm_path=$${sm%%:*}; \
390
	       sm_group=$${sm##*:}; \
391
	       for df in `${ECHO} ${NODE_ORIG_DISTFILES} | tr ' ' '\n' | grep :$${sm_group}$$`; do \
392
	         ${EXTRACT_CMD} ${EXTRACT_BEFORE_ARGS} ${DISTDIR}/`${ECHO} $${df} | ${SED} -e 's/:[^:]*$$//g'` ${EXTRACT_AFTER_ARGS} \
393
	           -C ${_NODE_DIR}/$${sm_path} --strip 1 || ${_NODE_DO_FAIL}; \
394
	       done; \
395
	     done && \
396
	     ${ECHO_MSG} "===>  Preparing the node project for ${PKGNAME}" && \
397
	     cd ${_NODE_DIR} && \
398
	     ([ -z "${NODE_SRCDIR}" ] || \
399
	        (${MKDIR} node_modules && \
400
	         ${MV} ${NODE_SRCDIR} node_modules/${NODE_SUBDIR} \
401
	        ) \
402
	     ) && cd ${_NODE_DO_CD} && \
403
	     for m in ${NODE_MODULES_ADD}; do \
404
	       if expr $$m : ".*@.*@.*" > /dev/null ; then \
405
	         mloc=$${m%@*@*}; \
406
	         mdir=$${m%@*}; \
407
	         mdir=$${mdir#*@}; \
408
	         mmod=$${m#*@*@}; \
409
	       elif expr $$m : ".*@.*" > /dev/null ; then \
410
	         mloc=dependencies; \
411
	         mdir=$${m%@*}; \
412
	         mmod=$${m#*@}; \
413
	       else \
414
	         mloc=dependencies; \
415
	         mdir=.; \
416
	         mmod=$$m; \
417
	       fi && \
418
	       mloc=$$(${ECHO} $$mloc | ${SED} -E 's/^(dev|peer|bundle)$$/\1Dependencies/') && \
419
	       (cd $$mdir && ${JQ_CMD} -s ".[0] * `echo $$mmod | sed -E 's/^([[:alnum:]_-]+):(.+)$$/{"'$$mloc'":{"\\1":"\\2"}}/'`" \
420
	         package.json > package-new.json && ${MV} package-new.json package.json) || ${_NODE_DO_FAIL}; \
421
	     done && \
422
	     for m in ${NODE_MODULES_DEL}; do \
423
	       if expr $$m : ".*@.*@.*" > /dev/null ; then \
424
	         mloc=$${m%@*@*}; \
425
	         mdir=$${m%@*}; \
426
	         mdir=$${mdir#*@}; \
427
	         mmod=$${m#*@*@}; \
428
	       elif expr $$m : ".*@.*" > /dev/null ; then \
429
	         mloc=dependencies; \
430
	         mdir=$${m%@*}; \
431
	         mmod=$${m#*@}; \
432
	       else \
433
	         mloc=dependencies; \
434
	         mdir=.; \
435
	         mmod=$$m; \
436
	       fi && \
437
	       mloc=$$(${ECHO} $$mloc | ${SED} -E 's/^(dev|peer|bundle)$$/\1Dependencies/') && \
438
	       (cd $$mdir && ${JQ_CMD} -s ".[0] | del(.[\"$$mloc\"][\"$$mmod\"])" \
439
	         package.json > package-new.json && ${MV} package-new.json package.json) || ${_NODE_DO_FAIL}; \
440
	     done && \
441
	     ([ -z ${_NODE_USES_MERGE_PKG_DEPS} ] || \
442
	       (${JQ_CMD} -s '(.[0] | del(.["packageDependencies"])) * (.[0]["packageDependencies"] | {"dependencies": .})' \
443
	         package.json > package-new.json && ${MV} package-new.json package.json)) && \
444
	     ([ ! -f "${SHRINKWRAP_FILE}" ] || ${CP} ${SHRINKWRAP_FILE} .) && \
445
	     for sp in ${NODE_SUB_PROJECTS}; do \
446
	       (cd $${sp} && \
447
	         ([ ! -f "${FILESDIR}/$${sp}/${SHRINKWRAP_NAME}" ] || ${CP} ${FILESDIR}/$${sp}/${SHRINKWRAP_NAME} npm-shrinkwrap.json)); \
448
	     done && \
449
	     ${ECHO_MSG} "===>  Downloading the nodejs dependencies for ${PKGNAME}" && \
450
	     (cd ${NPM_BUILD_DIR} && ${_NODE_PACKAGE_EXISTS} && ${NPM_ENV_FETCH} ${NPM_CMD} install ${NPM_FETCH_ARGS}) && \
451
	     for sp in ${NODE_SUB_PROJECTS}; do \
452
	       ${ECHO_MSG} "===>  Downloading the nodejs dependencies for ${PKGNAME}/$${sp}" && \
453
	       (cd $${sp} && ${NPM_ENV_FETCH} ${NPM_CMD} install ${NPM_FETCH_ARGS}) || ${_NODE_DO_FAIL}; \
454
	     done && \
455
	     for dir in ${NODE_RM_DIRS}; do \
456
	       ${RM} -rf ${NPM_BUILD_DIR}/$${dir}; \
457
	     done && \
458
	     cd ${_NODE_FETCH_WORKDIR} && \
459
	     ${_CLEAN_TMP_DIRS_FETCH} && \
460
	     ${ECHO_MSG} "===>  Applying the workaround for the package volatility bug for ${PKGNAME}" && \
461
	     ${FIND} ${_NODE_DIR} -name package.json -and -exec test -s {} \; -print0 | \
462
	       ${XARGS} -0 -n1 -I @@ -S 10000 \
463
	         ${SH} -c "${JQ_CMD} -s '.[0] | (del(.[\"scripts\"]) \
464
	                                        * ((select(.scripts.preinstall)  | {scripts:{preinstall:  .scripts.preinstall}})  // { }) \
465
	                                        * ((select(.scripts.install)     | {scripts:{install:     .scripts.install}})     // { }) \
466
	                                        * ((select(.scripts.postinstall) | {scripts:{postinstall: .scripts.postinstall}}) // { })) \
467
	                                      | del(.[\"scripts\"] | select(length==0)) \
468
	                                      | del(.[\"man\"])' \
469
	                                      @@ > @@.new && ${MV} @@.new @@" && \
470
	     ${ECHO_MSG} "===>  Packaging the final distfile for ${PKGNAME}" && \
471
	     ${FIND} -d ${_NODE_DIR} -and -exec ${TOUCH} -h -m -a -d 1970-01-01T00:00:00Z {} \; && \
472
	     ${FIND} ${_NODE_DIR} -print0 | \
473
	       LC_ALL=C sort -z | \
474
	       ${DISTRO_TAR_CMD} cf - \
475
	         --no-recursion --null -T - | \
476
	       gzip -9n > ${NODE_DISTFILE} && \
477
	     ${RM} -rf ${_NODE_DIR}; then \
478
	     return 0; \
479
	  fi; \
480
	  ${_CLEAN_TMP_DIRS_FETCH} && \
481
	  ${ECHO_MSG} "===>  Fetch failed for ${PKGNAME}"; \
482
	  ${FALSE}; \
483
	fi;
484
485
do-extract:
486
	@cd ${WRKDIR} && \
487
		tar xzf ${DISTDIR}/${NODE_DISTFILE}
488
489
_USES_patch+= 750:patch-gyp-cflags
490
patch-gyp-cflags:
491
	@${FIND} ${WRKSRC} -name "*.gyp" -and -exec ${REINPLACE_CMD} -e "s|cflags': \[|cflags': ['-I${LOCALBASE}/include/node',|g" {} \;
492
493
npm-build: node-remind-debug-mode fakemake
494
	@cd ${WRKSRC}/${_NODE_DO_CD} && \
495
	${ECHO} "===>  NPM build for ${PKGNAME}" && \
496
	(cd ${NPM_BUILD_DIR} && ${_NODE_PACKAGE_EXISTS} && ${NPM_ENV_BUILD} ${NPM_CMD} rebuild ${NPM_BUILD_ARGS}) && \
497
	for sp in ${NODE_SUB_PROJECTS}; do \
498
	  ${ECHO} "===>  NPM build for ${PKGNAME}/$${sp}" && \
499
	  (cd $${sp} && ${NPM_ENV_BUILD} ${NPM_CMD} rebuild ${NPM_BUILD_ARGS}); \
500
	done && \
501
	${_CLEAN_TMP_DIRS_BUILD}
502
503
.if defined(_NODE_USES_GRUNT)
504
grunt-build:
505
	@${ECHO} "===>  Grunt build for ${PKGNAME}"
506
	@cd ${WRKSRC}/${_NODE_DO_CD} && \
507
		${GRUNT_ENV} ${GRUNT_CMD} ${NODE_GRUNT_TARGETS} ${GRUNT_BUILD_ARGS}
508
opt-grunt-build: grunt-build
509
.else
510
opt-grunt-build:
511
.endif
512
513
.if !target(do-pre-build)
514
do-pre-build:
515
.endif
516
.if !target(do-post-build)
517
do-post-build:
518
.endif
519
520
# TODO npm-clean ?
521
npm-prune:
522
	@${ECHO} "===>  Pruning for ${PKGNAME}"
523
	@cd ${WRKSRC}/${_NODE_DO_CD} && \
524
	${_NODE_PACKAGE_EXISTS} && ${NPM_ENV_BUILD} ${NPM_CMD} prune ${NPM_PRUNE_ARGS} && \
525
	for sp in ${NODE_SUB_PROJECTS}; do \
526
	  (cd $${sp} && ${NPM_ENV_BUILD} ${NPM_CMD} prune ${NPM_PRUNE_ARGS}) || ${_NODE_DO_FAIL}; \
527
	done
528
529
node-clean-files:
530
	@${ECHO} "===>  Cleaning files for ${PKGNAME}"
531
	@cd ${WRKSRC}/${_NODE_DO_CD} && \
532
	for f in ${NODE_FILES_TO_CLEAN}; do \
533
	  ${FIND} -d . -name "$${f}" -and -exec ${RM} -rf {} \;; \
534
	done && \
535
	${FIND} -d . -type d -empty -exec rmdir {} \;
536
537
do-build: do-pre-build npm-build opt-grunt-build do-post-build npm-prune node-clean-files
538
539
_USES_build+= 751:delete-gyp-pyc
540
delete-gyp-pyc:
541
	@${ECHO} "===>  Deleting created .pyc files that npm should have installed"
542
	@${RM} -rf `${FIND} ${LOCALBASE}/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp -name "*.pyc"`
543
544
do-install:
545
	@${ECHO} "===>  Staging for ${PKGNAME}"
546
	@${MKDIR} ${STAGEDIR}${NODE_INSTALL_BASE}
547
	@${CP} -r ${WRKSRC} ${STAGEDIR}${NODE_INSTALL_DIR}
548
	@${RM} `${FIND} ${STAGEDIR}${NODE_INSTALL_DIR} -name "*.orig"`
549
	@${RM} `${FIND} ${STAGEDIR}${NODE_INSTALL_DIR} -name npm-shrinkwrap.json`
550
	@${RM} -rf `${FIND} ${STAGEDIR}${NODE_INSTALL_DIR} -name .deps`
551
	@${FIND} ${STAGEDIR}${NODE_INSTALL_DIR} -name "*.o" -and -exec ${STRIP_CMD} {} \;
552
	@${FIND} ${STAGEDIR}${NODE_INSTALL_DIR} -name "*.node" -and -exec ${STRIP_CMD} {} \;
553
554
.endif

Return to bug 204577