getVersions.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. const { semver } = require('@vue/cli-shared-utils')
  2. const PackageManager = require('./ProjectPackageManager')
  3. const { loadOptions, saveOptions } = require('../options')
  4. let sessionCached
  5. const pm = new PackageManager()
  6. module.exports = async function getVersions () {
  7. if (sessionCached) {
  8. return sessionCached
  9. }
  10. let latest
  11. const local = require(`../../package.json`).version
  12. if (process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG) {
  13. return (sessionCached = {
  14. current: local,
  15. latest: local,
  16. latestMinor: local
  17. })
  18. }
  19. // should also check for prerelease versions if the current one is a prerelease
  20. const includePrerelease = !!semver.prerelease(local)
  21. const { latestVersion = local, lastChecked = 0 } = loadOptions()
  22. const cached = latestVersion
  23. const daysPassed = (Date.now() - lastChecked) / (60 * 60 * 1000 * 24)
  24. let error
  25. if (daysPassed > 1) {
  26. // if we haven't check for a new version in a day, wait for the check
  27. // before proceeding
  28. try {
  29. latest = await getAndCacheLatestVersion(cached, includePrerelease)
  30. } catch (e) {
  31. latest = cached
  32. error = e
  33. }
  34. } else {
  35. // Otherwise, do a check in the background. If the result was updated,
  36. // it will be used for the next 24 hours.
  37. // don't throw to interrupt the user if the background check failed
  38. getAndCacheLatestVersion(cached, includePrerelease).catch(() => {})
  39. latest = cached
  40. }
  41. // if the installed version is updated but the cache doesn't update
  42. if (semver.gt(local, latest) && !semver.prerelease(local)) {
  43. latest = local
  44. }
  45. let latestMinor = `${semver.major(latest)}.${semver.minor(latest)}.0`
  46. if (
  47. // if the latest version contains breaking changes
  48. /major/.test(semver.diff(local, latest)) ||
  49. // or if using `next` branch of cli
  50. (semver.gte(local, latest) && semver.prerelease(local))
  51. ) {
  52. // fallback to the local cli version number
  53. latestMinor = local
  54. }
  55. return (sessionCached = {
  56. current: local,
  57. latest,
  58. latestMinor,
  59. error
  60. })
  61. }
  62. // fetch the latest version and save it on disk
  63. // so that it is available immediately next time
  64. async function getAndCacheLatestVersion (cached, includePrerelease) {
  65. let version = await pm.getRemoteVersion('vue-cli-version-marker', 'latest')
  66. if (includePrerelease) {
  67. const next = await pm.getRemoteVersion('vue-cli-version-marker', 'next')
  68. version = semver.gt(next, version) ? next : version
  69. }
  70. if (semver.valid(version) && version !== cached) {
  71. saveOptions({ latestVersion: version, lastChecked: Date.now() })
  72. return version
  73. }
  74. return cached
  75. }