Skip to content

Commit 99ebd7f

Browse files
committed
feat: pnpm compatible, manually invoke mdep install
1 parent a0aa2d5 commit 99ebd7f

File tree

14 files changed

+6590
-7356
lines changed

14 files changed

+6590
-7356
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pnpm-lock.yaml merge=text
2+
shrinkwrap.yaml merge=binary
3+
npm-shrinkwrap.json merge=binary
4+
yarn.lock merge=binary

.husky/commit-msg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
22
. "$(dirname "$0")/_/husky.sh"
33

4-
npx --no-install commitlint --edit $1
4+
"$(dirname "$0")/../node_modules/.bin/commitlint" --edit $1

.mdeprc.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
/* eslint-disable no-template-curly-in-string */
22
const execa = require('execa');
33

4-
const yarnCache = execa.commandSync('yarn cache dir').stdout;
5-
64
module.exports = {
75
nycCoverage: false,
86
test_framework: 'jest --coverage --coverageDirectory <coverageDirectory> --runTestsByPath --maxWorkers=50% --verbose --colors',
@@ -27,12 +25,10 @@ module.exports = {
2725
CHROME_PATH: '/usr/bin/chromium-browser',
2826
DEBUG: "${DEBUG:-''}",
2927
},
30-
volumes: [
31-
`${yarnCache}:/tmp/yarn-cache/v6:ro`,
32-
],
3328
},
3429
},
3530
arbitrary_exec: [
36-
'apk add git',
31+
'apk add git curl',
32+
'npm i --global pnpm@6'
3733
],
3834
};

.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
access = public
2+
hoist = false

__tests__/install.spec.js

Lines changed: 170 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
const { directory } = require('tempy');
44
const { resolve } = require('path');
5-
const { promisify } = require('util');
65
const set = require('lodash.set');
7-
const stripEOF = require('strip-final-newline');
86
const fs = require('fs/promises');
97
const debug = require('debug')('test');
10-
const execFile = promisify(require('child_process').execFile);
8+
const execa = require('execa');
119

12-
describe('test installing the package', () => {
13-
const kFilename = 'deploy.tgz';
10+
describe('(yarn) test installing the package', () => {
11+
const kFilename = 'deploy-yarn.tgz';
1412
const cwd = process.cwd();
1513
const tarball = resolve(cwd, kFilename);
1614
const clean = async () => {
@@ -23,11 +21,10 @@ describe('test installing the package', () => {
2321

2422
beforeAll(async () => {
2523
await clean();
26-
await execFile('yarn', ['config', 'set', 'preferred-cache-folder', '/tmp/yarn-cache']);
27-
await execFile('yarn', ['config', 'set', 'cache-folder', '/tmp/yarn-cache-internal']);
28-
await execFile('yarn', ['config', 'set', 'prefer-offline', 'true']);
29-
const { stdout } = await execFile('yarn', ['pack', '--filename', kFilename]);
30-
console.info(stdout);
24+
await execa('yarn', ['config', 'set', 'preferred-cache-folder', '/tmp/yarn-cache']);
25+
await execa('yarn', ['config', 'set', 'cache-folder', '/tmp/yarn-cache-internal']);
26+
await execa('yarn', ['config', 'set', 'prefer-offline', 'true']);
27+
await execa('yarn', ['pack', '--filename', kFilename]);
3128
});
3229

3330
describe('local install', () => {
@@ -36,21 +33,160 @@ describe('test installing the package', () => {
3633
beforeAll(async () => {
3734
debug('changing to %s', tmpDir);
3835
process.chdir(tmpDir);
39-
await execFile('yarn', ['init', '-yp']);
40-
await execFile('git', ['init']);
36+
await execa('yarn', ['init', '-yp']);
37+
await execa('git', ['init']);
4138
});
4239

4340
test('is able to install package locally', async () => {
44-
await execFile('yarn', ['add', tarball, '--no-lockfile']);
41+
await execa('yarn', ['add', tarball, '--no-lockfile']);
42+
await execa('yarn', ['mdep', 'install']);
4543
}, 240000);
4644

4745
test('returns node version', async () => {
48-
const { stdout } = await execFile('node_modules/.bin/mdep', ['get-config', 'node', '--node', '99.0.0']);
49-
expect(stripEOF(stdout)).toBe('99.0.0');
46+
const { stdout } = await execa('node_modules/.bin/mdep', ['get-config', 'node', '--node', '99.0.0']);
47+
expect(stdout).toBe('99.0.0');
5048
});
5149

5250
test('package.json enhanced', async () => {
53-
const pkg = require(`${tmpDir}/package.json`); // eslint-disable-line import/no-dynamic-require
51+
const pkg = JSON.parse(await fs.readFile(`${tmpDir}/package.json`));
52+
expect(pkg.scripts['semantic-release']).toBeDefined();
53+
expect(pkg.husky).toBeUndefined();
54+
});
55+
56+
test('.husky create', async () => {
57+
expect((await fs.stat('.husky')).isDirectory()).toBe(true);
58+
expect((await fs.stat('.husky/_/husky.sh')).isFile()).toBe(true);
59+
expect((await fs.stat('.husky/commit-msg')).isFile()).toBe(true);
60+
expect((await fs.stat('.husky/prepare-commit-msg')).isFile()).toBe(true);
61+
});
62+
63+
test('releaserc & commitlint copied over', async () => {
64+
expect((await fs.stat('.releaserc.json')).isFile()).toBe(true);
65+
expect((await fs.stat('.commitlintrc.js')).isFile()).toBe(true);
66+
});
67+
68+
test('on reinstall doesnt overwrite existing .releaserc.js(on)', async () => {
69+
expect.assertions(1);
70+
71+
await fs.writeFile('.releaserc.json', 'overwrite');
72+
const { stderr } = await execa('yarn', ['add', tarball, '--no-lockfile']);
73+
debug(stderr);
74+
await expect(fs.readFile('.releaserc.json', 'utf8')).resolves.toBe('overwrite');
75+
}, 240000);
76+
77+
test('on reinstall doesnt overwrite existing .commitlintrc.js', async () => {
78+
expect.assertions(1);
79+
80+
await fs.writeFile('.commitlintrc.js', 'overwrite');
81+
await execa('yarn', ['add', tarball, '--no-lockfile']);
82+
await expect(fs.readFile('.commitlintrc.js', 'utf8')).resolves.toBe('overwrite');
83+
}, 240000);
84+
});
85+
86+
describe('local install (husky migration)', () => {
87+
const tmpDir = directory();
88+
89+
beforeAll(async () => {
90+
debug('changing to %s', tmpDir);
91+
process.chdir(tmpDir);
92+
await execa('yarn', ['init', '-yp']);
93+
await execa('git', ['init']);
94+
95+
const pkgName = `${tmpDir}/package.json`;
96+
const pkg = JSON.parse(await fs.readFile(pkgName));
97+
set(pkg, 'husky.hooks.commit-msg', 'commitlint -e $HUSKY_GIT_PARAMS');
98+
await fs.writeFile(pkgName, JSON.stringify(pkg, null, 2));
99+
});
100+
101+
test('is able to install package locally', async () => {
102+
await execa('yarn', ['add', tarball, '--no-lockfile']);
103+
await execa('yarn', ['mdep', 'install']);
104+
}, 240000);
105+
106+
test('package.json enhanced, no husky', async () => {
107+
const pkg = JSON.parse(await fs.readFile(`${tmpDir}/package.json`));
108+
expect(pkg.husky).toBeUndefined();
109+
});
110+
111+
test('.husky files present', async () => {
112+
expect((await fs.stat('.husky')).isDirectory()).toBe(true);
113+
expect((await fs.stat('.husky/_/husky.sh')).isFile()).toBe(true);
114+
expect((await fs.stat('.husky/commit-msg')).isFile()).toBe(true);
115+
expect((await fs.stat('.husky/prepare-commit-msg')).isFile()).toBe(true);
116+
117+
const files = await fs.readdir('.husky');
118+
expect(files.length).toBe(3);
119+
});
120+
121+
test('.husky files content sane', async () => {
122+
const contents = await fs.readFile('.husky/commit-msg', { encoding: 'utf8' });
123+
expect(contents).toContain('npx --no-install commitlint -e $1');
124+
});
125+
});
126+
127+
describe('installs globally', () => {
128+
test('is able to install package globally', async () => {
129+
await execa('yarn', ['global', 'add', tarball, '--no-lockfile']);
130+
}, 240000);
131+
132+
test('returns current node version in module', async () => {
133+
process.chdir(cwd);
134+
const { stdout } = await execa('mdep', ['get-config', '--path', 'node']);
135+
expect(stdout).toBe('16');
136+
});
137+
});
138+
139+
afterAll(clean);
140+
});
141+
142+
describe('(pnpm) test installing the package', () => {
143+
const kFilename = 'makeomatic-deploy-0.0.0-development.tgz';
144+
const cwd = process.cwd();
145+
const tarball = resolve(cwd, kFilename);
146+
const clean = async () => {
147+
try {
148+
await fs.rm(tarball);
149+
} catch (e) {
150+
process.stderr.write(`nothing to cleanup ~ ${tarball}\n`);
151+
}
152+
};
153+
154+
beforeAll(async () => {
155+
await clean();
156+
await execa('pnpm', ['pack']);
157+
});
158+
159+
describe('local install', () => {
160+
const tmpDir = directory();
161+
162+
beforeAll(async () => {
163+
debug('changing to %s', tmpDir);
164+
process.chdir(tmpDir);
165+
await execa('pnpm', ['init', '-yp']);
166+
await execa('git', ['init']);
167+
});
168+
169+
test('is able to install package locally', async () => {
170+
const proc = execa('pnpm', ['add', tarball], {
171+
buffer: false,
172+
cwd: tmpDir,
173+
all: true,
174+
env: {
175+
DEBUG: 'makeomatic:deploy',
176+
},
177+
});
178+
proc.all.pipe(process.stdout);
179+
await proc;
180+
await execa('pnpm', ['mdep', 'install']);
181+
}, 240000);
182+
183+
test('returns node version', async () => {
184+
const { stdout } = await execa('node_modules/.bin/mdep', ['get-config', 'node', '--node', '99.0.0']);
185+
expect(stdout).toBe('99.0.0');
186+
});
187+
188+
test('package.json enhanced', async () => {
189+
const pkg = JSON.parse(await fs.readFile(`${tmpDir}/package.json`));
54190
expect(pkg.scripts['semantic-release']).toBeDefined();
55191
expect(pkg.husky).toBeUndefined();
56192
});
@@ -71,7 +207,7 @@ describe('test installing the package', () => {
71207
expect.assertions(1);
72208

73209
await fs.writeFile('.releaserc.json', 'overwrite');
74-
const { stderr } = await execFile('yarn', ['add', tarball, '--no-lockfile']);
210+
const { stderr } = await execa('pnpm', ['add', tarball]);
75211
debug(stderr);
76212
await expect(fs.readFile('.releaserc.json', 'utf8')).resolves.toBe('overwrite');
77213
}, 240000);
@@ -80,7 +216,7 @@ describe('test installing the package', () => {
80216
expect.assertions(1);
81217

82218
await fs.writeFile('.commitlintrc.js', 'overwrite');
83-
await execFile('yarn', ['add', tarball, '--no-lockfile']);
219+
await execa('pnpm', ['add', tarball]);
84220
await expect(fs.readFile('.commitlintrc.js', 'utf8')).resolves.toBe('overwrite');
85221
}, 240000);
86222
});
@@ -91,8 +227,8 @@ describe('test installing the package', () => {
91227
beforeAll(async () => {
92228
debug('changing to %s', tmpDir);
93229
process.chdir(tmpDir);
94-
await execFile('yarn', ['init', '-yp']);
95-
await execFile('git', ['init']);
230+
await execa('pnpm', ['init', '-yp']);
231+
await execa('git', ['init']);
96232

97233
const pkgName = `${tmpDir}/package.json`;
98234
const pkg = JSON.parse(await fs.readFile(pkgName));
@@ -101,7 +237,17 @@ describe('test installing the package', () => {
101237
});
102238

103239
test('is able to install package locally', async () => {
104-
await execFile('yarn', ['add', tarball, '--no-lockfile']);
240+
const proc = execa('pnpm', ['add', tarball], {
241+
buffer: false,
242+
cwd: tmpDir,
243+
all: true,
244+
env: {
245+
DEBUG: 'makeomatic:deploy',
246+
},
247+
});
248+
proc.all.pipe(process.stdout);
249+
await proc;
250+
await execa('pnpm', ['mdep', 'install']);
105251
}, 240000);
106252

107253
test('package.json enhanced, no husky', async () => {
@@ -127,13 +273,13 @@ describe('test installing the package', () => {
127273

128274
describe('installs globally', () => {
129275
test('is able to install package globally', async () => {
130-
await execFile('yarn', ['global', 'add', tarball, '--no-lockfile']);
276+
await execa('pnpm', ['-g', 'add', tarball]);
131277
}, 240000);
132278

133279
test('returns current node version in module', async () => {
134280
process.chdir(cwd);
135-
const { stdout } = await execFile('mdep', ['get-config', '--path', 'node']);
136-
expect(stripEOF(stdout)).toBe('16');
281+
const { stdout } = await execa('mdep', ['get-config', '--path', 'node']);
282+
expect(stdout).toBe('16');
137283
});
138284
});
139285

bin/cmds/get-config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { get } = require('lodash');
1+
const get = require('lodash.get');
22

33
exports.command = 'get-config [path]';
44
exports.desc = 'return mdeprc properties';

bin/cmds/install.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const execa = require('execa');
2+
const { resolve } = require('path');
3+
4+
exports.command = 'install';
5+
exports.desc = 'install husky, performs auto migration';
6+
exports.handler = async () => {
7+
const proc = execa('node', [resolve(__dirname, '../../scripts/setup-semantic-release.js')], { all: true, buffer: false });
8+
proc.all.pipe(process.stdout);
9+
await proc;
10+
};

bin/cmds/test_cmds/init.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
const path = require('path');
77
const fs = require('fs');
8-
const { get, set } = require('lodash');
8+
const get = require('lodash.get');
9+
const set = require('lodash.set');
910
const { cp, test } = require('shelljs');
1011

1112
exports.command = 'init';

bin/cmds/test_cmds/run.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ const glob = require('glob');
88
const execa = require('execa');
99
const { echo, exit } = require('shelljs');
1010
const { Client } = require('undici');
11-
// const { resolve } = require('path');
1211
const split = require('split2');
1312
const { pipeline: _pipeline, Writable } = require('stream');
1413
const { promisify } = require('util');
1514
const { deserializeError } = require('serialize-error');
15+
const assert = require('assert');
1616

1717
const pipeline = promisify(_pipeline);
1818
const debug = require('debug')('test');
@@ -84,14 +84,25 @@ exports.handler = async (argv) => {
8484
let dockerExec;
8585
if (argv.http) {
8686
const getSocketId = async (attempt = 0) => {
87-
try {
88-
const { stdout } = await execAsync('docker', ['logs', container]);
89-
return JSON.parse(stdout.split('\n').pop()).socketId;
90-
} catch (e) {
91-
if (attempt > 10) throw e;
92-
await new Promise((resolve) => setTimeout(resolve, 500));
93-
return getSocketId(attempt + 1);
87+
const { stdout } = await execAsync('docker', ['logs', container]);
88+
const lines = stdout.split('\n');
89+
90+
let line;
91+
// eslint-disable-next-line no-cond-assign
92+
while ((line = lines.pop()) !== undefined) {
93+
try {
94+
const { socketId } = JSON.parse(line);
95+
assert(socketId);
96+
return socketId;
97+
} catch (e) {
98+
// ignore line, check previous
99+
}
94100
}
101+
102+
if (attempt > 20) throw new Error('cant get socket id after 20s');
103+
104+
await new Promise((resolve) => setTimeout(resolve, 1000));
105+
return getSocketId(attempt + 1);
95106
};
96107

97108
const socketId = await getSocketId();

0 commit comments

Comments
 (0)