util.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. import { spawnSync } from '../../helpers/spawn'
  5. import { sync as crossSpawnSync } from 'cross-spawn'
  6. import { appDir, resolve as appResolve } from '../../helpers/app-paths'
  7. import { existsSync } from 'fs'
  8. import semver from 'semver'
  9. async function useYarn(): Promise<boolean> {
  10. const hasYarnLockfile = existsSync(appResolve.app('yarn.lock'))
  11. if (hasYarnLockfile) {
  12. return true
  13. } else {
  14. return await new Promise((resolve) => {
  15. const child = crossSpawnSync('npm', ['--version'])
  16. resolve(!!(child.status ?? child.error))
  17. })
  18. }
  19. }
  20. function getCrateLatestVersion(crateName: string): string | null {
  21. const child = crossSpawnSync('cargo', ['search', crateName, '--limit', '1'])
  22. const output = String(child.output[1])
  23. // eslint-disable-next-line security/detect-non-literal-regexp
  24. const matches = new RegExp(crateName + ' = "(\\S+)"', 'g').exec(output)
  25. if (matches?.[1]) {
  26. return matches[1]
  27. } else {
  28. return null
  29. }
  30. }
  31. async function getNpmLatestVersion(packageName: string): Promise<string> {
  32. if (await useYarn()) {
  33. const child = crossSpawnSync(
  34. 'yarn',
  35. ['info', packageName, 'versions', '--json'],
  36. {
  37. cwd: appDir
  38. }
  39. )
  40. const output = String(child.output[1])
  41. const packageJson = JSON.parse(output) as { data: string[] }
  42. return packageJson.data[packageJson.data.length - 1]
  43. } else {
  44. const child = crossSpawnSync('npm', ['show', packageName, 'version'], {
  45. cwd: appDir
  46. })
  47. return String(child.output[1]).replace('\n', '')
  48. }
  49. }
  50. async function getNpmPackageVersion(
  51. packageName: string
  52. ): Promise<string | null> {
  53. const child = (await useYarn())
  54. ? crossSpawnSync(
  55. 'yarn',
  56. ['list', '--pattern', packageName, '--depth', '0'],
  57. {
  58. cwd: appDir
  59. }
  60. )
  61. : crossSpawnSync('npm', ['list', packageName, 'version', '--depth', '0'], {
  62. cwd: appDir
  63. })
  64. const output = String(child.output[1])
  65. // eslint-disable-next-line security/detect-non-literal-regexp
  66. const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output)
  67. if (matches?.[1]) {
  68. return matches[1]
  69. } else {
  70. return null
  71. }
  72. }
  73. async function installNpmPackage(packageName: string): Promise<void> {
  74. if (await useYarn()) {
  75. spawnSync('yarn', ['add', packageName], appDir)
  76. } else {
  77. spawnSync('npm', ['install', packageName], appDir)
  78. }
  79. }
  80. async function installNpmDevPackage(packageName: string): Promise<void> {
  81. if (await useYarn()) {
  82. spawnSync('yarn', ['add', packageName, '--dev'], appDir)
  83. } else {
  84. spawnSync('npm', ['install', packageName, '--save-dev'], appDir)
  85. }
  86. }
  87. function updateNpmPackage(packageName: string): void {
  88. const usesYarn = existsSync(appResolve.app('yarn.lock'))
  89. if (usesYarn) {
  90. spawnSync('yarn', ['upgrade', packageName, '--latest'], appDir)
  91. } else {
  92. spawnSync('npm', ['install', `${packageName}@latest`], appDir)
  93. }
  94. }
  95. function padVersion(version: string): string {
  96. let count = (version.match(/\./g) ?? []).length
  97. while (count < 2) {
  98. count++
  99. version += '.0'
  100. }
  101. return version
  102. }
  103. function semverLt(first: string, second: string): boolean {
  104. return semver.lt(padVersion(first), padVersion(second))
  105. }
  106. export {
  107. useYarn,
  108. getCrateLatestVersion,
  109. getNpmLatestVersion,
  110. getNpmPackageVersion,
  111. installNpmPackage,
  112. installNpmDevPackage,
  113. updateNpmPackage,
  114. padVersion,
  115. semverLt
  116. }