fix(tauri.js) deps cmd usage when npm is not installed, closes #1037 (#1053)

This commit is contained in:
Lucas Fernandes Nogueira 2020-12-05 00:17:57 -03:00 committed by GitHub
parent fc368169d1
commit 8da495f78c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 42 deletions

View File

@ -0,0 +1,5 @@
---
"tauri.js": patch
---
Fixes `tauri deps` command usage when `npm` is not installed.

View File

@ -1,5 +0,0 @@
---
"tauri.js": patch
---
Fixes an issue with the dependency updater when NPM isn't installed.

View File

@ -11,6 +11,7 @@ import logger from '../../helpers/logger'
import { resolve } from '../../helpers/app-paths'
import inquirer from 'inquirer'
import { existsSync } from 'fs'
import { sync as crossSpawnSync } from 'cross-spawn'
const log = logger('dependency:npm-packages')
@ -21,19 +22,30 @@ async function manageDependencies(
const installedDeps = []
const updatedDeps = []
const npmChild = crossSpawnSync('npm', ['--version'])
const yarnChild = crossSpawnSync('yarn', ['--version'])
if (
(npmChild.status ?? npmChild.error) &&
(yarnChild.status ?? yarnChild.error)
) {
throw new Error(
'must have `npm` or `yarn` installed to manage dependenices'
)
}
if (existsSync(resolve.app('package.json'))) {
for (const dependency of dependencies) {
const currentVersion = await getNpmPackageVersion(dependency)
if (currentVersion === null) {
log(`Installing ${dependency}...`)
if (managementType === ManagementType.Install) {
installNpmPackage(dependency)
await installNpmPackage(dependency)
} else if (managementType === ManagementType.InstallDev) {
installNpmDevPackage(dependency)
await installNpmDevPackage(dependency)
}
installedDeps.push(dependency)
} else if (managementType === ManagementType.Update) {
const latestVersion = getNpmLatestVersion(dependency)
const latestVersion = await getNpmLatestVersion(dependency)
if (semverLt(currentVersion, latestVersion)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
const inquired = await inquirer.prompt([

View File

@ -8,6 +8,18 @@ import semver from 'semver'
const BASE_URL = 'https://docs.rs/crate/'
async function useYarn(): Promise<boolean> {
const hasYarnLockfile = existsSync(appResolve.app('yarn.lock'))
if (hasYarnLockfile) {
return true
} else {
return await new Promise((resolve) => {
const child = crossSpawnSync('npm', ['--version'])
resolve(!!(child.status ?? child.error))
})
}
}
async function getCrateLatestVersion(crateName: string): Promise<string> {
return await new Promise((resolve, reject) => {
const url = `${BASE_URL}${crateName}`
@ -22,51 +34,60 @@ async function getCrateLatestVersion(crateName: string): Promise<string> {
})
}
function getNpmLatestVersion(packageName: string): string {
const usesYarn = existsSync(appResolve.app('yarn.lock'))
const cmd = usesYarn ? 'yarn' : 'npm'
const args = usesYarn
? ['--silent', 'info', packageName, 'version']
: ['show', packageName, 'version']
const child = crossSpawnSync(cmd, args, {
cwd: appDir
})
return String(child.output[1]).replace('\n', '')
async function getNpmLatestVersion(packageName: string): Promise<string> {
if (await useYarn()) {
const child = crossSpawnSync(
'yarn',
['info', packageName, 'versions', '--json'],
{
cwd: appDir
}
)
const output = String(child.output[1])
const packageJson = JSON.parse(output) as { data: string[] }
return packageJson.data[packageJson.data.length - 1]
} else {
const child = crossSpawnSync('npm', ['show', packageName, 'version'], {
cwd: appDir
})
return String(child.output[1]).replace('\n', '')
}
}
async function getNpmPackageVersion(
packageName: string
): Promise<string | null> {
const usesYarn = existsSync(appResolve.app('yarn.lock'))
const cmd = usesYarn ? 'yarn' : 'npm'
const args = usesYarn
? ['--silent', 'list', packageName, 'version', '--depth', '0']
: ['list', packageName, 'version', '--depth', '0']
return await new Promise((resolve) => {
const child = crossSpawnSync(cmd, args, { cwd: appDir })
const output = String(child.output[1])
// eslint-disable-next-line security/detect-non-literal-regexp
const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output)
if (matches?.[1]) {
resolve(matches[1])
} else {
resolve(null)
}
})
const child = (await useYarn())
? crossSpawnSync(
'yarn',
['list', '--patern', packageName, '--depth', '0'],
{
cwd: appDir
}
)
: crossSpawnSync('npm', ['list', packageName, 'version', '--depth', '0'], {
cwd: appDir
})
const output = String(child.output[1])
// eslint-disable-next-line security/detect-non-literal-regexp
const matches = new RegExp(packageName + '@(\\S+)', 'g').exec(output)
if (matches?.[1]) {
return matches[1]
} else {
return null
}
}
function installNpmPackage(packageName: string): void {
const usesYarn = existsSync(appResolve.app('yarn.lock'))
if (usesYarn) {
async function installNpmPackage(packageName: string): Promise<void> {
if (await useYarn()) {
spawnSync('yarn', ['add', packageName], appDir)
} else {
spawnSync('npm', ['install', packageName], appDir)
}
}
function installNpmDevPackage(packageName: string): void {
const usesYarn = existsSync(appResolve.app('yarn.lock'))
if (usesYarn) {
async function installNpmDevPackage(packageName: string): Promise<void> {
if (await useYarn()) {
spawnSync('yarn', ['add', packageName, '--dev'], appDir)
} else {
spawnSync('npm', ['install', packageName, '--save-dev'], appDir)

View File

@ -265,7 +265,7 @@ module.exports = async () => {
printVersion({
key: ' tauri.js',
version: packageJson.version,
targetVersion: getNpmLatestVersion('tauri')
targetVersion: await getNpmLatestVersion('tauri')
})
printInfo({ key: 'Rust environment', section: true })

View File

@ -7732,7 +7732,7 @@ resolve@1.17.0, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.15
dependencies:
path-parse "^1.0.6"
resolve@^1.19.0:
resolve@^1.18.1, resolve@^1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==