Welcome to mirror list, hosted at ThFree Co, Russian Federation.

windows-shims.js « bin « test - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8d73e39f2c4d1949fa8951a412377dad05efadeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const t = require('tap')

if (process.platform !== 'win32') {
  t.plan(0, 'test only relevant on windows')
  process.exit(0)
}

const has = path => {
  try {
    // If WSL is installed, it *has* a bash.exe, but it fails if
    // there is no distro installed, so we need to detect that.
    const result = spawnSync(path, ['-l', '-c', 'exit 0'])
    if (result.status === 0)
      return true
    else {
      // print whatever error we got
      throw result.error || Object.assign(new Error(String(result.stderr)), {
        code: result.status,
      })
    }
  } catch (er) {
    t.comment(`not installed: ${path}`, er)
    return false
  }
}

const { version } = require('../../package.json')
const spawn = require('@npmcli/promise-spawn')
const { spawnSync } = require('child_process')
const { resolve } = require('path')
const { ProgramFiles, SystemRoot } = process.env
const { readFileSync, chmodSync } = require('fs')
const gitBash = resolve(ProgramFiles, 'Git', 'bin', 'bash.exe')
const gitUsrBinBash = resolve(ProgramFiles, 'Git', 'usr', 'bin', 'bash.exe')
const wslBash = resolve(SystemRoot, 'System32', 'bash.exe')
const cygwinBash = resolve(SystemRoot, '/', 'cygwin64', 'bin', 'bash.exe')

const bashes = Object.entries({
  'wsl bash': wslBash,
  'git bash': gitBash,
  'git internal bash': gitUsrBinBash,
  'cygwin bash': cygwinBash,
})

const npmShim = resolve(__dirname, '../../bin/npm')
const npxShim = resolve(__dirname, '../../bin/npx')

const path = t.testdir({
  'node.exe': readFileSync(process.execPath),
  npm: readFileSync(npmShim),
  npx: readFileSync(npxShim),
  // simulate the state where one version of npm is installed
  // with node, but we should load the globally installed one
  'global-prefix': {
    node_modules: {
      npm: t.fixture('symlink', resolve(__dirname, '../..')),
    },
  },
  // put in a shim that ONLY prints the intended global prefix,
  // and should not be used for anything else.
  node_modules: {
    npm: {
      bin: {
        'npx-cli.js': `
          throw new Error('this should not be called')
        `,
        'npm-cli.js': `
          const assert = require('assert')
          const args = process.argv.slice(2)
          assert.equal(args[0], 'prefix')
          assert.equal(args[1], '-g')
          const { resolve } = require('path')
          console.log(resolve(__dirname, '../../../global-prefix'))
        `,
      },
    },
  },
})
chmodSync(resolve(path, 'npm'), 0o755)
chmodSync(resolve(path, 'npx'), 0o755)

for (const [name, bash] of bashes) {
  if (!has(bash)) {
    t.skip(`${name} not installed`, { bin: bash, diagnostic: true })
    continue
  }

  if (bash === cygwinBash && process.env.NYC_CONFIG) {
    t.skip('Cygwin does not play nicely with NYC, run without coverage')
    continue
  }

  t.test(name, async t => {
    t.plan(2)
    t.test('npm', async t => {
      // only cygwin *requires* the -l, but the others are ok with it
      // don't hit the registry for the update check
      const args = ['-l', 'npm', 'help']

      const result = await spawn(bash, args, {
        env: { PATH: path, npm_config_update_notifier: 'false' },
        cwd: path,
        stdioString: true,
      })
      t.match(result, {
        cmd: bash,
        args: ['-l', 'npm', 'help'],
        code: 0,
        signal: null,
        stderr: String,
        // should have loaded this instance of npm we symlinked in
        stdout: `npm@${version} ${resolve(__dirname, '../..')}`,
      })
    })

    t.test('npx', async t => {
      const args = ['-l', 'npx', '--version']

      const result = await spawn(bash, args, {
        env: { PATH: path, npm_config_update_notifier: 'false' },
        cwd: path,
        stdioString: true,
      })
      t.match(result, {
        cmd: bash,
        args: ['-l', 'npx', '--version'],
        code: 0,
        signal: null,
        stderr: String,
        // should have loaded this instance of npm we symlinked in
        stdout: version,
      })
    })
  })
}