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

Collapse All | Expand All

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

Return to bug 204577