process-release.js 5.7 KB

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