process-release.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* eslint-disable n/no-deprecated-api */
  2. 'use strict'
  3. const semver = require('semver')
  4. const url = require('url')
  5. const path = require('path')
  6. const log = require('./log')
  7. // versions where -headers.tar.gz started shipping
  8. const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42'
  9. const bitsre = /\/win-(x86|x64|arm64)\//
  10. const bitsreV3 = /\/win-(x86|ia32|x64)\// // io.js v3.x.x shipped with "ia32" but should
  11. // have been "x86"
  12. // Captures all the logic required to determine download URLs, local directory and
  13. // file names. Inputs come from command-line switches (--target, --dist-url),
  14. // `process.version` and `process.release` where it exists.
  15. function processRelease (argv, gyp, defaultVersion, defaultRelease) {
  16. let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
  17. const versionSemver = semver.parse(version)
  18. let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl
  19. let isNamedForLegacyIojs
  20. let name
  21. let distBaseUrl
  22. let baseUrl
  23. let libUrl32
  24. let libUrl64
  25. let libUrlArm64
  26. let tarballUrl
  27. let canGetHeaders
  28. if (!versionSemver) {
  29. // not a valid semver string, nothing we can do
  30. return { version }
  31. }
  32. // flatten version into String
  33. version = versionSemver.version
  34. // defaultVersion should come from process.version so ought to be valid semver
  35. const isDefaultVersion = version === semver.parse(defaultVersion).version
  36. // can't use process.release if we're using --target=x.y.z
  37. if (!isDefaultVersion) {
  38. defaultRelease = null
  39. }
  40. if (defaultRelease) {
  41. // v3 onward, has process.release
  42. name = defaultRelease.name.replace(/io\.js/, 'iojs') // remove the '.' for directory naming purposes
  43. } else {
  44. // old node or alternative --target=
  45. // semver.satisfies() doesn't like prerelease tags so test major directly
  46. isNamedForLegacyIojs = versionSemver.major >= 1 && versionSemver.major < 4
  47. // isNamedForLegacyIojs is required to support Electron < 4 (in particular Electron 3)
  48. // as previously this logic was used to ensure "iojs" was used to download iojs releases
  49. // and "node" for node releases. Unfortunately the logic was broad enough that electron@3
  50. // published release assets as "iojs" so that the node-gyp logic worked. Once Electron@3 has
  51. // been EOL for a while (late 2019) we should remove this hack.
  52. name = isNamedForLegacyIojs ? 'iojs' : 'node'
  53. }
  54. // check for the nvm.sh standard mirror env variables
  55. if (!overrideDistUrl && process.env.NODEJS_ORG_MIRROR) {
  56. overrideDistUrl = process.env.NODEJS_ORG_MIRROR
  57. }
  58. if (overrideDistUrl) {
  59. log.verbose('download', 'using dist-url', overrideDistUrl)
  60. }
  61. if (overrideDistUrl) {
  62. distBaseUrl = overrideDistUrl.replace(/\/+$/, '')
  63. } else {
  64. distBaseUrl = 'https://nodejs.org/dist'
  65. }
  66. distBaseUrl += '/v' + version + '/'
  67. // new style, based on process.release so we have a lot of the data we need
  68. if (defaultRelease && defaultRelease.headersUrl && !overrideDistUrl) {
  69. baseUrl = url.resolve(defaultRelease.headersUrl, './')
  70. libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major)
  71. libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major)
  72. libUrlArm64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'arm64', versionSemver.major)
  73. tarballUrl = defaultRelease.headersUrl
  74. } else {
  75. // older versions without process.release are captured here and we have to make
  76. // a lot of assumptions, additionally if you --target=x.y.z then we can't use the
  77. // current process.release
  78. baseUrl = distBaseUrl
  79. libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major)
  80. libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major)
  81. libUrlArm64 = resolveLibUrl(name, baseUrl, 'arm64', versionSemver.major)
  82. // making the bold assumption that anything with a version number >3.0.0 will
  83. // have a *-headers.tar.gz file in its dist location, even some frankenstein
  84. // custom version
  85. canGetHeaders = semver.satisfies(versionSemver, headersTarballRange)
  86. tarballUrl = url.resolve(baseUrl, name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz')
  87. }
  88. return {
  89. version,
  90. semver: versionSemver,
  91. name,
  92. baseUrl,
  93. tarballUrl,
  94. shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'),
  95. versionDir: (name !== 'node' ? name + '-' : '') + version,
  96. ia32: {
  97. libUrl: libUrl32,
  98. libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path))
  99. },
  100. x64: {
  101. libUrl: libUrl64,
  102. libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path))
  103. },
  104. arm64: {
  105. libUrl: libUrlArm64,
  106. libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrlArm64).path))
  107. }
  108. }
  109. }
  110. function normalizePath (p) {
  111. return path.normalize(p).replace(/\\/g, '/')
  112. }
  113. function resolveLibUrl (name, defaultUrl, arch, versionMajor) {
  114. const base = url.resolve(defaultUrl, './')
  115. const hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl))
  116. if (!hasLibUrl) {
  117. // let's assume it's a baseUrl then
  118. if (versionMajor >= 1) {
  119. return url.resolve(base, 'win-' + arch + '/' + name + '.lib')
  120. }
  121. // prior to io.js@1.0.0 32-bit node.lib lives in /, 64-bit lives in /x64/
  122. return url.resolve(base, (arch === 'x86' ? '' : arch + '/') + name + '.lib')
  123. }
  124. // else we have a proper url to a .lib, just make sure it's the right arch
  125. return defaultUrl.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/')
  126. }
  127. module.exports = processRelease