UNPKG

2.53 kBJavaScriptView Raw
1const { exec } = require('child_process')
2const { sep, join } = require('path')
3const { stat } = require('fs/promises')
4const { UTRError } = require('./error')
5const { getOutput } = require('./output')
6
7function npm (job, ...args) {
8 return new Promise((resolve, reject) => {
9 const childProcess = exec(`npm ${args.join(' ')}`, (err, stdout, stderr) => {
10 if (err) {
11 reject(UTRError.NPM_FAILED(stderr))
12 } else {
13 resolve(stdout.trim())
14 }
15 })
16 if (args[0] === 'install') {
17 getOutput(job).monitor(childProcess)
18 }
19 })
20}
21
22async function folderExists (path) {
23 try {
24 const result = await stat(path)
25 return result.isDirectory()
26 } catch (e) {
27 return false
28 }
29}
30
31let localRoot
32let globalRoot
33
34function resolveDependencyPath (name) {
35 require(name)
36 const pattern = `${sep}node_modules${sep}${name}${sep}`
37 const path = Object.keys(require.cache).filter(path => path.includes(pattern))[0]
38 if (path) {
39 const pos = path.indexOf(pattern)
40 return path.substring(0, pos + pattern.length - 1)
41 }
42}
43
44module.exports = {
45 resolveDependencyPath,
46
47 async resolvePackage (job, name) {
48 let modulePath
49 let justInstalled = false
50 try {
51 modulePath = resolveDependencyPath(name)
52 } catch (e) {
53 }
54 if (!modulePath) {
55 if (!localRoot) {
56 [localRoot, globalRoot] = await Promise.all([
57 npm(job, 'root'),
58 npm(job, 'root', '--global')
59 ])
60 }
61 const localPath = join(localRoot, name)
62 if (await folderExists(localPath)) {
63 modulePath = localPath
64 } else {
65 const globalPath = join(globalRoot, name)
66 if (!await folderExists(globalPath)) {
67 if (!job.npmInstall) {
68 throw UTRError.NPM_DEPENDENCY_NOT_FOUND(name)
69 }
70 const previousStatus = job.status
71 job.status = `Installing ${name}...`
72 await npm(job, 'install', name, '-g')
73 justInstalled = true
74 job.status = previousStatus
75 }
76 modulePath = globalPath
77 }
78 }
79 const output = getOutput(job)
80 const installedPackage = require(join(modulePath, 'package.json'))
81 const { version: installedVersion } = installedPackage
82 output.resolvedPackage(name, modulePath, installedVersion)
83 if (!justInstalled) {
84 const latestVersion = await npm(job, 'view', name, 'version')
85 if (latestVersion !== installedVersion) {
86 output.packageNotLatest(name, latestVersion)
87 }
88 }
89 return modulePath
90 }
91}