forked from storybookjs/storybook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhoist-internals.js
executable file
·114 lines (109 loc) · 3.54 KB
/
hoist-internals.js
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
const path = require('path');
const fs = require('fs-extra');
const fse = require('fs-extra');
const shell = require('shelljs');
const glob = require('glob');
const symlink = require('symlink-dir');
const log = require('npmlog');
const targetPath = path.join(__dirname, '..', 'node_modules', '@storybook');
const prefix = 'hoist-internals';
const cwd = path.join(__dirname, '..');
log.heading = 'lerna+';
log.addLevel('success', 3001, { fg: 'green', bold: true });
log.info(prefix, 'Hoisting internal packages');
const getLernaPackages = () =>
fse.readJson(path.join(__dirname, '..', 'lerna.json')).then(json => json.packages);
const passingLog = fn => i => {
fn(i);
return i;
};
const getPackageOfFolder = sourcePath => fse.readJsonSync(path.join(sourcePath, 'package.json'));
const task = getLernaPackages()
.then(
passingLog(packages => {
log.verbose(prefix, 'working dir paths: %j', cwd);
log.verbose(prefix, 'source paths: %j', packages);
log.verbose(prefix, 'target paths: %j', targetPath);
})
)
.then(packages => `@(${packages.map(s => s.replace('/*', '')).join('|')})/*/`)
.then(
passingLog(pattern => {
log.silly(prefix, 'pattern to look for packages: %j', pattern);
})
)
.then(
pattern =>
new Promise((resolve, reject) => {
glob(pattern, { cwd }, (error, results) => (error ? reject(error) : resolve(results)));
})
)
.then(results =>
Promise.all(
results
.map(sourcePath => path.resolve(fs.realpathSync(sourcePath)))
.reduce((acc, item) => {
if (!acc.includes(item)) {
acc.push(item);
}
return acc;
}, [])
.map(
passingLog(item => {
log.silly(prefix, 'found package path', item);
})
)
.map(sourcePath => ({
sourcePath,
packageJson: getPackageOfFolder(sourcePath),
}))
.filter(({ packageJson }) => !packageJson.private)
.map(({ sourcePath, packageJson }) =>
Promise.resolve(packageJson.name.replace('@storybook/', ''))
.then(packageName => {
log.silly(prefix, 'found package name', packageName);
return path.join(targetPath, packageName);
})
.then(localTargetPath =>
fse
.remove(localTargetPath)
.then(() => symlink(sourcePath, localTargetPath))
.then(
passingLog(() => {
log.silly(prefix, 'symlinked ', [sourcePath, localTargetPath]);
})
)
.then(() => localTargetPath)
.catch(error => {
log.error(prefix, 'symlink', error, [sourcePath, localTargetPath]);
throw new Error('failed symlink');
})
)
)
)
)
.then(locations =>
Promise.all(
locations
.map(location => path.join(location, 'node_modules', '@storybook'))
.map(
passingLog(removePath => {
log.verbose(prefix, 'removing ', removePath);
})
)
.map(removePath => shell.rm('-rf', removePath))
.map(
(item, index) =>
item.code === 0 ? Promise.resolve(locations[index]) : Promise.reject(item)
)
)
);
task
.then(packages => {
log.verbose(prefix, packages.map(dir => dir.replace(cwd, '')).join(',\n'));
log.success(prefix, `Hoisted ${packages.length} packages`);
})
.catch(error => {
log.error(prefix, 'failed', error);
shell.exit(1);
});