process-release.js 6.0KB

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