logo

overlay

My own overlay for experimentations, use with caution, no support is provided git clone https://anongit.hacktivis.me/git/overlay.git/

nodejs.eclass (4139B)


  1. # Copyright 2022-2023 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
  2. # Distributed under the terms of the GNU General Public License v2
  3. # @ECLASS: nodejs.eclass
  4. # @MAINTAINER:
  5. # Haelwenn (lanodan) Monnier <contact@hacktivis.me>
  6. # @AUTHOR:
  7. # Haelwenn (lanodan) Monnier <contact@hacktivis.me>
  8. # @SUPPORTED_EAPIS: 7 8
  9. # @BLURB: Build NodeJS projects
  10. # @DESCRIPTION:
  11. # An eclass providing functions to build NodeJS projects
  12. # https://docs.npmjs.com/cli/v6/configuring-npm/package-json/
  13. case "${EAPI:-0}" in
  14. 7|8)
  15. ;;
  16. *)
  17. die "Unsupported EAPI=${EAPI} for ${ECLASS}"
  18. ;;
  19. esac
  20. EXPORT_FUNCTIONS src_compile src_test src_install
  21. BDEPEND="
  22. net-libs/nodejs
  23. app-misc/jq
  24. sys-apps/cmd-glob
  25. "
  26. RDEPEND="dev-nodejs/node_path"
  27. NODEJS_SITELIB="/usr/share/nodejs/"
  28. NPM_FLAGS=(
  29. --audit false
  30. --offline
  31. --verbose
  32. )
  33. enpm() {
  34. debug-print-function ${FUNCNAME} "$@"
  35. set -- npm "${NPM_FLAGS[@]}" "$@"
  36. echo "$@" >&2
  37. "$@" || die
  38. }
  39. nodejs_src_test() {
  40. if jq -e '.scripts | has("test")' <package.json >/dev/null
  41. then
  42. # --ignore-scripts: do not run pretest and posttest
  43. enpm run test --ignore-scripts
  44. else
  45. die 'No "test" command defined in package.json'
  46. fi
  47. }
  48. nodejs_src_compile() {
  49. # https://docs.npmjs.com/cli/v10/configuring-npm/package-json/#default-values
  50. if jq -e '.scripts | has("install")' <package.json >/dev/null
  51. then
  52. if jq -e '.scripts | has("preinstall")' <package.json >/dev/null
  53. then
  54. enpm run preinstall
  55. fi
  56. npm "${NPM_FLAGS[@]}" run install || die
  57. if jq -e '.scripts | has("postinstall")' <package.json >/dev/null
  58. then
  59. enpm run postinstall
  60. fi
  61. else
  62. if test -e binding.gyp; then
  63. if has_version -b dev-nodejs/node-gyp; then
  64. node-gyp rebuild || die
  65. else
  66. # TODO: Check BDEPEND as QA
  67. die "binding.gyp found but dev-nodejs/node-gyp is not available as BDEPEND"
  68. fi
  69. fi
  70. fi
  71. if jq -e '.scripts | has("prepare")' <package.json >/dev/null
  72. then
  73. enpm run prepare
  74. fi
  75. }
  76. # Install files in nodejs hierarchy with preserving path of source files
  77. nodejs_install_path() {
  78. for file in "$@"; do
  79. target_dir="${ED}/${NODEJS_MODULE_DIR}/$(dirname "${file}")/"
  80. mkdir -p "${target_dir}" || die "Failed to create directory for ${file}"
  81. cp -r "${file}" "${target_dir}" || die "Failed to copy ${file}"
  82. done
  83. }
  84. nodejs_src_install() {
  85. einstalldocs
  86. # https://docs.npmjs.com/cli/v6/configuring-npm/package-json/#files
  87. if jq -e '.type == "module"' <package.json >/dev/null
  88. then
  89. # Assume that everything on NPM is using semver
  90. NODEJS_MODULE_DIR="${NODEJS_SITELIB}${PN}@$(ver_cut 1)"
  91. [[ "${SLOT}" != "$(ver_cut 1)" ]] && eqawarn "Got SLOT value ${SLOT} while ES Module would expect $(ver_cut 1)"
  92. else
  93. NODEJS_MODULE_DIR="${NODEJS_SITELIB}${PN}"
  94. fi
  95. insinto "${NODEJS_MODULE_DIR}"
  96. doins package.json
  97. if jq -e 'has("files")' <package.json >/dev/null
  98. then
  99. jq -r .files[] <package.json \
  100. | xargs -d '\n' glob -m \
  101. | while read file; do
  102. nodejs_install_path "${file}"
  103. done
  104. else
  105. doins -r .
  106. fi
  107. if jq -e 'has("main")' <package.json >/dev/null
  108. then
  109. main="$(jq -r -e '.main' <package.json)"
  110. if test -e "${main}"; then
  111. nodejs_install_path "${main}"
  112. else
  113. nodejs_install_path "${main}.js"
  114. fi
  115. else
  116. test -e index.js && nodejs_install_path index.js
  117. fi
  118. bin_type="$(jq -r '.bin | type' <package.json)"
  119. case "${bin_type}" in
  120. null)
  121. ;;
  122. object)
  123. jq -r '.bin | to_entries | .[] | .key + " " + .value' <package.json \
  124. | while read bin file; do
  125. nodejs_install_path "${file}"
  126. fperms 755 "${NODEJS_MODULE_DIR}/${file#./}"
  127. dosym "${NODEJS_MODULE_DIR}/${file#./}" "/usr/bin/${bin}"
  128. done
  129. ;;
  130. string)
  131. file="$(jq -r '.bin' <package.json)"
  132. bin="$(basename "${file}")"
  133. nodejs_install_path "${file}"
  134. fperms 755 "${NODEJS_MODULE_DIR}/${file#./}"
  135. dosym "${NODEJS_MODULE_DIR}/${file#./}" "/usr/bin/${bin}"
  136. ;;
  137. *)
  138. die "Unhandled package.json#bin type: ${bin_type}"
  139. ;;
  140. esac
  141. man_type="$(jq -r '.man | type' <package.json)"
  142. case "${man_type}" in
  143. null)
  144. ;;
  145. string)
  146. doman "$(jq -r '.man' <package.json)"
  147. ;;
  148. array)
  149. jq -r '.man[]' <package.json \
  150. | while read file; do
  151. doman "$file"
  152. done
  153. ;;
  154. esac
  155. }