build-strap 3.0.0-dev.40 → 4.0.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -34
  3. package/ant.d.ts +19 -0
  4. package/ant.js +12 -37
  5. package/cert.d.ts +12 -0
  6. package/cert.js +89 -151
  7. package/clean.d.ts +4 -0
  8. package/clean.js +7 -16
  9. package/copy.d.ts +7 -0
  10. package/copy.js +49 -76
  11. package/cp.d.ts +17 -0
  12. package/cp.js +85 -170
  13. package/docker.container.d.ts +73 -0
  14. package/docker.container.js +219 -362
  15. package/docker.d.ts +68 -0
  16. package/docker.js +167 -347
  17. package/docker.network.d.ts +42 -0
  18. package/docker.network.js +69 -144
  19. package/docker.volume.d.ts +26 -0
  20. package/docker.volume.js +52 -126
  21. package/dockerCleanup.d.ts +38 -0
  22. package/dockerCleanup.js +66 -141
  23. package/dockerCompose.d.ts +154 -0
  24. package/dockerCompose.js +400 -727
  25. package/fs.d.ts +5 -0
  26. package/fs.js +38 -95
  27. package/git.d.ts +9 -0
  28. package/git.js +19 -30
  29. package/index.d.ts +20 -0
  30. package/index.js +20 -27
  31. package/maps.d.ts +33 -0
  32. package/maps.js +16 -87
  33. package/npm.d.ts +35 -0
  34. package/npm.js +97 -138
  35. package/package.json +23 -19
  36. package/pkg.d.ts +39 -0
  37. package/pkg.js +26 -74
  38. package/publish.d.ts +27 -0
  39. package/publish.js +52 -140
  40. package/run.d.ts +13 -0
  41. package/run.js +39 -85
  42. package/tgz.d.ts +13 -0
  43. package/tgz.js +61 -96
  44. package/version.d.ts +34 -0
  45. package/version.js +86 -127
  46. package/yarn.d.ts +26 -0
  47. package/yarn.js +70 -119
  48. package/ant.js.flow +0 -42
  49. package/artifactory.js +0 -617
  50. package/artifactory.js.flow +0 -616
  51. package/cert.conf +0 -20
  52. package/cert.js.flow +0 -152
  53. package/clean.js.flow +0 -19
  54. package/copy.js.flow +0 -79
  55. package/cp.js.flow +0 -172
  56. package/docker.container.js.flow +0 -389
  57. package/docker.js.flow +0 -367
  58. package/docker.network.js.flow +0 -159
  59. package/docker.volume.js.flow +0 -136
  60. package/dockerCleanup.js.flow +0 -151
  61. package/dockerCompose.js.flow +0 -765
  62. package/flow.js +0 -21
  63. package/flow.js.flow +0 -20
  64. package/fs.js.flow +0 -96
  65. package/git.js.flow +0 -34
  66. package/hg.js +0 -35
  67. package/hg.js.flow +0 -34
  68. package/index.js.flow +0 -26
  69. package/inline-resources.js +0 -158
  70. package/inline-resources.js.flow +0 -157
  71. package/maps.js.flow +0 -111
  72. package/npm.js.flow +0 -144
  73. package/pkg.js.flow +0 -80
  74. package/publish.js.flow +0 -144
  75. package/run.js.flow +0 -89
  76. package/src/ant.js +0 -42
  77. package/src/artifactory.js +0 -616
  78. package/src/cert.conf +0 -20
  79. package/src/cert.js +0 -152
  80. package/src/clean.js +0 -19
  81. package/src/copy.js +0 -79
  82. package/src/cp.js +0 -172
  83. package/src/docker.container.js +0 -389
  84. package/src/docker.js +0 -367
  85. package/src/docker.network.js +0 -159
  86. package/src/docker.volume.js +0 -136
  87. package/src/dockerCleanup.js +0 -151
  88. package/src/dockerCompose.js +0 -765
  89. package/src/flow.js +0 -20
  90. package/src/fs.js +0 -96
  91. package/src/git.js +0 -34
  92. package/src/hg.js +0 -34
  93. package/src/index.js +0 -26
  94. package/src/inline-resources.js +0 -157
  95. package/src/maps.js +0 -111
  96. package/src/npm.js +0 -144
  97. package/src/pkg.js +0 -80
  98. package/src/publish.js +0 -144
  99. package/src/run.js +0 -89
  100. package/src/test.js +0 -55
  101. package/src/tgz.js +0 -101
  102. package/src/version.js +0 -141
  103. package/src/yarn.js +0 -123
  104. package/test.js +0 -56
  105. package/test.js.flow +0 -55
  106. package/tgz.js.flow +0 -101
  107. package/version.js.flow +0 -141
  108. package/yarn.js.flow +0 -123
package/src/publish.js DELETED
@@ -1,144 +0,0 @@
1
- // @flow
2
- import path from 'path';
3
- import fs from 'fs-extra';
4
- import { run, buildLog } from './run';
5
- import { getVersion, type Version } from './version';
6
- import { getPkgName } from './pkg';
7
- import {
8
- artifactoryNpm,
9
- artifactoryStandard,
10
- type ArtifactoryConfig,
11
- type ArtifactoryCreds,
12
- } from './artifactory';
13
- import { npmPublish } from './npm';
14
- import type { NpmConfig, NpmCreds } from './npm';
15
- import { tgzDir, type ArtifactInfo } from './tgz';
16
-
17
- export type CreateArtifactOptions = {
18
- distDir: string, // What to bundle up and publish
19
- outDir: string, // Where the bundled tgz file should go
20
- fileName?: string, // (optional) Specify the tgz file name
21
- };
22
-
23
- export type Artifact = {
24
- name: string,
25
- version: Version,
26
- info: ArtifactInfo,
27
- fileName: string,
28
- filePath: string,
29
- }
30
-
31
- // create tgz from distDir in outDir
32
- export async function createArtifact({
33
- distDir,
34
- outDir,
35
- fileName,
36
- }: CreateArtifactOptions): Promise<Artifact> {
37
- const version = await getVersion();
38
- const name = getPkgName();
39
-
40
- buildLog(`gzipping ${name} v${version.info}...`);
41
-
42
- const tgzFileName = fileName || `${name}-${version.info}.tgz`;
43
- const tgzFilePath = path.join(outDir, tgzFileName);
44
- const info = await tgzDir(distDir, tgzFilePath, {
45
- prefix: 'package',
46
- });
47
-
48
- buildLog(`md5: ${info.md5}`);
49
- buildLog(`sha1: ${info.sha1}`);
50
- buildLog(`sha512: ${info.sha512}`);
51
- buildLog(`size: ${info.size} bytes`);
52
-
53
- return {
54
- name,
55
- version,
56
- info,
57
- fileName: tgzFileName,
58
- filePath: tgzFilePath,
59
- };
60
- }
61
-
62
- export type PublishConfiguration = {
63
- ...CreateArtifactOptions,
64
- doPublish: boolean, // Actually publish?
65
- prePublishFn?: () => any, // (optional) Callback to invoke before publishing
66
- artifactoryConfig?: ArtifactoryConfig, // (optional) Artifactory config info (normally in package.json)
67
- artifactoryCreds?: ArtifactoryCreds, // (optional) Artifactory credentials (normally from ENV var)
68
- npmPath?: string, // (optional) Path to npm executable
69
- npmTag?: string, // (optional) tag to apply to npm package
70
- npmSkipExisting?: boolean, // (optional) if true, don't error when artifact already exists (skip publish)
71
- npmConfig?: NpmConfig, // (optional) Npm config info (normally in package.json)
72
- npmCreds?: NpmCreds, // (optional) Npm credentials (normally from ENV var)
73
- npmAuthToken?: string, // (optional) Npm auth token (normally from ENV var)
74
- };
75
-
76
- // tgz the distDir, and copy it to the outDir
77
- // if toArtifactory is true, also publishes to artifactory
78
- export async function publish({
79
- distDir,
80
- outDir,
81
- doPublish,
82
- prePublishFn,
83
- fileName,
84
- artifactoryConfig,
85
- artifactoryCreds,
86
- npmPath,
87
- npmTag,
88
- npmSkipExisting = false,
89
- npmConfig,
90
- npmCreds,
91
- npmAuthToken,
92
- }: PublishConfiguration) {
93
- if (typeof prePublishFn === 'function') {
94
- await run(async () => {
95
- await prePublishFn();
96
- });
97
- }
98
-
99
- const {
100
- info,
101
- filePath: tgzFilePath,
102
- fileName: tgzFileName,
103
- } = await createArtifact({ distDir, outDir, fileName });
104
-
105
- if (!doPublish) {
106
- buildLog(
107
- 'Skipping publish for dev build. Use `--publish` arg to publish for real.',
108
- );
109
- return;
110
- }
111
-
112
- // Publish to all repos configured in package.json
113
- await fs.copyFile(
114
- path.join(distDir, 'package.json'),
115
- path.join(outDir, 'package.json'),
116
- );
117
- const artifact = fs.createReadStream(tgzFilePath);
118
- await Promise.all([
119
- npmPublish({
120
- publishPath: tgzFilePath,
121
- npmConfig,
122
- npmCreds,
123
- npmAuthToken,
124
- tag: npmTag,
125
- skipExisting: npmSkipExisting,
126
- npmPath,
127
- }),
128
- artifactoryStandard(
129
- artifact,
130
- info,
131
- tgzFileName,
132
- artifactoryConfig,
133
- artifactoryCreds,
134
- ),
135
- artifactoryNpm(
136
- distDir,
137
- artifactoryConfig,
138
- artifactoryCreds,
139
- npmPath,
140
- npmTag,
141
- npmSkipExisting,
142
- ),
143
- ]);
144
- }
package/src/run.js DELETED
@@ -1,89 +0,0 @@
1
- // @flow
2
- export function format(time?: Date = new Date()): string {
3
- return time.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1');
4
- }
5
-
6
- const silenceLogs = process.argv.includes('--silence-buildLog');
7
-
8
- export function buildLog(msg: string, time?: Date) {
9
- if (silenceLogs) {
10
- return;
11
- }
12
- console.info(`[${format(time || new Date())}] ${msg}`);
13
- }
14
-
15
- export type RunnableModule<T> =
16
- | (() => Promise<T>)
17
- | { default: () => Promise<T> };
18
-
19
- export async function run<T>(
20
- fn: RunnableModule<T>,
21
- ...options: any[]
22
- ): Promise<T> {
23
- if (fn == null) {
24
- throw new Error(`Invalid argument passed to run(${fn})`);
25
- }
26
- const task = typeof fn === 'function' ? fn : fn.default;
27
- if (typeof task !== 'function') {
28
- throw new Error(
29
- 'First argument to run must be a function or module with default function.',
30
- );
31
- }
32
- const start = new Date();
33
- buildLog(`Starting '${task.name}'...`, start);
34
- const result = await task(...options);
35
- const end = new Date();
36
- const time = end.getTime() - start.getTime();
37
- buildLog(`Finished '${task.name}' after ${time} ms`, end);
38
- return result;
39
- }
40
-
41
- export type RunCliOptions<T> = {
42
- resolveFn?: (path: string) => RunnableModule<T>,
43
- defaultAction?: string | RunnableModule<T>,
44
- argv?: string[],
45
- passthroughArgv?: boolean,
46
- };
47
-
48
- export async function runCli<T>({
49
- resolveFn = (path: string) =>
50
- // $FlowFixMe
51
- require(`./${path}`).default, // eslint-disable-line
52
- defaultAction = 'publish',
53
- argv = process.argv,
54
- passthroughArgv = false,
55
- }: RunCliOptions<T> = {}): Promise<T> {
56
- const module =
57
- argv.length > 2
58
- ? resolveFn(argv[2])
59
- : typeof defaultAction === 'string'
60
- ? resolveFn(defaultAction)
61
- : defaultAction;
62
- const args = Array.isArray(passthroughArgv)
63
- ? passthroughArgv.includes(argv[2] || defaultAction)
64
- ? argv.slice(3)
65
- : []
66
- : passthroughArgv
67
- ? argv.slice(3)
68
- : [];
69
- return run(module, ...args).catch((err) => {
70
- console.error((err && err.stack) || err);
71
- process.exit(1);
72
- throw err;
73
- });
74
- }
75
-
76
- export function handleEntryPoint<T>(
77
- mainModule: typeof module,
78
- mainModuleFilename: string,
79
- cliOptions?: RunCliOptions<T>,
80
- ) {
81
- if (require.main === mainModule) {
82
- delete require.cache[mainModuleFilename]; // eslint-disable-line no-underscore-dangle
83
- runCli(cliOptions);
84
- }
85
- }
86
-
87
- handleEntryPoint(module, __filename);
88
-
89
- export default run;
package/src/test.js DELETED
@@ -1,55 +0,0 @@
1
- // @flow
2
- import { run, buildLog } from './run';
3
- import { onKillSignal } from './cp';
4
-
5
- export async function karmaTest(
6
- karma: Object,
7
- karmaConfig: any,
8
- preTestFn?: () => any,
9
- watch: boolean = process.argv.includes('--watch'),
10
- ) {
11
- // Lazy require karma
12
- const { Server, runner, stopper, config } = karma;
13
-
14
- const testConfig = config.parseConfig(karmaConfig, {
15
- autoWatch: false,
16
- singleRun: !watch,
17
- });
18
- const server = new Server(testConfig, (exitCode) => {
19
- buildLog(`Karma has exited with code ${exitCode}`);
20
- });
21
- onKillSignal(() => stopper.stop(testConfig));
22
-
23
- let started = false;
24
- async function doTest() {
25
- if (!started) {
26
- await Promise.all([
27
- new Promise((resolve) => {
28
- server.on('browsers_ready', resolve);
29
- }),
30
- server.start(),
31
- ]);
32
- started = true;
33
- }
34
- if (watch) {
35
- // await server.refreshFiles();
36
- await new Promise((resolve, reject) => {
37
- runner.run(testConfig, (exitCode) => {
38
- buildLog(`Karma run completed with exit code ${exitCode}`);
39
- if (exitCode === 0 || watch) {
40
- resolve(exitCode);
41
- } else {
42
- reject(exitCode);
43
- }
44
- });
45
- });
46
- }
47
- }
48
-
49
- if (typeof preTestFn === 'function') {
50
- // preTestFn is expected to callback and run doTest
51
- await run(preTestFn, doTest);
52
- } else {
53
- await doTest();
54
- }
55
- }
package/src/tgz.js DELETED
@@ -1,101 +0,0 @@
1
- // @flow
2
- import path from 'path';
3
- import tar from 'tar';
4
- import fs from 'fs';
5
- import crypto from 'crypto';
6
- import StreamCounter from 'stream-counter';
7
- import { makeDir } from './fs';
8
- import { buildLog } from './run';
9
-
10
- export type ArtifactInfo = {
11
- md5: string,
12
- sha1: string,
13
- sha512: string,
14
- size: number,
15
- contentType?: string,
16
- };
17
-
18
- const generateHash = async (
19
- stream: stream$Readable,
20
- type: 'md5' | 'sha1' | 'sha512',
21
- ): Promise<string> =>
22
- new Promise((resolve, reject) => {
23
- stream
24
- .pipe(crypto.createHash(type).setEncoding('hex'))
25
- .on('finish', function () {
26
- resolve(this.read());
27
- })
28
- .on('end', function () {
29
- resolve(this.read());
30
- })
31
- .on('error', (err) => reject(err));
32
- });
33
-
34
- const countBytes = async (stream: stream$Readable): Promise<number> =>
35
- new Promise((resolve, reject) => {
36
- const counter = new StreamCounter();
37
- stream
38
- .pipe(counter)
39
- .on('finish', () => resolve(counter.bytes))
40
- .on('end', () => resolve(counter.bytes))
41
- .on('error', (err) => reject(err));
42
- });
43
-
44
- const writeStreamToFile = async (stream: stream$Readable, filePath: string) =>
45
- new Promise((resolve, reject) => {
46
- stream
47
- .pipe(fs.createWriteStream(filePath))
48
- .on('finish', () => {
49
- buildLog(`Successfully wrote file: ${filePath}`);
50
- resolve();
51
- })
52
- .on('error', (err) => reject(err));
53
- });
54
-
55
- // Take the given file (path or stream) and compute the info that artifactory needs.
56
- // md5 + sha1 hash, and size in bytes
57
- export async function getArtifactInfo(
58
- artifact: string | stream$Readable,
59
- ): Promise<ArtifactInfo> {
60
- // make it into a stream
61
- const stream: stream$Readable =
62
- typeof artifact === 'string' ? fs.createReadStream(artifact) : artifact;
63
-
64
- const [md5, sha1, sha512, size] = await Promise.all([
65
- generateHash(stream, 'md5'),
66
- generateHash(stream, 'sha1'),
67
- generateHash(stream, 'sha512'),
68
- countBytes(stream),
69
- ]);
70
- return { md5, sha1, sha512, size };
71
- }
72
-
73
- // Creates a gzipped tarball of a directory, returns sha1 + md5 hash and size of resulting file
74
- export async function tgzDir(
75
- srcDir: string,
76
- outPath: string,
77
- options?: ?{ [string]: any },
78
- ): Promise<ArtifactInfo> {
79
- await makeDir(path.dirname(outPath));
80
- const tgzStream = tar.c(
81
- // $FlowFixMe
82
- {
83
- gzip: true,
84
- cwd: srcDir,
85
- portable: true,
86
- // $FlowFixMe
87
- ...options,
88
- },
89
- ['.'],
90
- );
91
-
92
- // write the file to disk (outPath)
93
- const [info] = await Promise.all([
94
- getArtifactInfo(tgzStream),
95
- writeStreamToFile(tgzStream, `${outPath}`),
96
- ]);
97
- return {
98
- ...info,
99
- contentType: 'application/gzip',
100
- };
101
- }
package/src/version.js DELETED
@@ -1,141 +0,0 @@
1
- // @flow
2
- import fs from 'fs';
3
- import { gitInfo } from './git';
4
- import { hgInfo } from './hg';
5
- import { getCfg, getPkg } from './pkg';
6
- import { buildLog } from './run';
7
-
8
- export function getBuild(): string {
9
- let arg = process.argv.find((el) => /^--buildNum=\d+$/.test(el));
10
- arg = arg && arg.substr(11);
11
- return arg || process.env.BUILD_NUMBER || '0';
12
- }
13
-
14
- export function getReleaseBranch(): string {
15
- const { releaseBranch } = getCfg();
16
- return releaseBranch || 'master';
17
- }
18
-
19
- type RepoType = 'git' | 'hg' | 'unknown';
20
- export function getRepoType(): RepoType {
21
- const { repoType } = getCfg();
22
-
23
- return (
24
- repoType ||
25
- (fs.existsSync('./.hg')
26
- ? 'hg'
27
- : fs.existsSync('./.git')
28
- ? 'git'
29
- : 'unknown')
30
- );
31
- }
32
-
33
- type RepoInfo = {
34
- branch: string,
35
- revision: string,
36
- };
37
-
38
- export async function getRepoInfo(): Promise<RepoInfo> {
39
- const repoType = getRepoType();
40
- const { branch, revision } =
41
- repoType === 'git'
42
- ? await gitInfo()
43
- : repoType === 'hg'
44
- ? await hgInfo()
45
- : {};
46
- if (!branch || !revision) {
47
- throw new Error('Failed to parse branch and revision from source repo.');
48
- }
49
- return { branch, revision };
50
- }
51
-
52
- export function getDevBranch(): string {
53
- const { devBranch } = getCfg();
54
- return devBranch || getRepoType() === 'hg' ? 'default' : 'dev';
55
- }
56
-
57
- export async function getIsRelease(
58
- passedBranch?: ?string = null,
59
- releaseOverride?: ?boolean = null,
60
- ): Promise<boolean> {
61
- const branch = passedBranch || (await getRepoInfo()).branch;
62
- return releaseOverride != null
63
- ? releaseOverride
64
- : process.argv.includes('--force-release-version')
65
- ? true
66
- : branch === getReleaseBranch();
67
- }
68
-
69
- let cacheVersion = true;
70
- export function useVersionCache(useCache: boolean = true): void {
71
- cacheVersion = useCache;
72
- }
73
-
74
- export type Version = {|
75
- branch: string,
76
- build: string,
77
- info: string,
78
- isRelease: boolean,
79
- major: string,
80
- minor: string,
81
- name: string,
82
- npm: string,
83
- patch: string,
84
- revision: string,
85
- short: string,
86
- |};
87
-
88
- let version = null;
89
- export async function getVersion(
90
- logIt: boolean = true,
91
- release: ?boolean = null,
92
- ): Promise<Version> {
93
- if (!cacheVersion || version == null) {
94
- const { version: pkgVers, name } = getPkg();
95
- const { branch, revision } = await getRepoInfo();
96
- const [, major, minor, patch] =
97
- pkgVers.match(/^(\d+)\.(\d+)\.(\d+)$/) || [];
98
- if (!major || !minor || !patch) {
99
- throw new Error('Invalid version format in package.json');
100
- }
101
- const build = getBuild();
102
- const isRelease = await getIsRelease(branch, release);
103
- const short = `${major}.${minor}.${patch}`;
104
- const npm = `${short}${isRelease ? '' : `-${branch}.${build}`}`;
105
- const info = `${short}${
106
- isRelease ? `+${build}.` : `-${branch}.${build}+`
107
- }${revision}`;
108
- version = {
109
- name,
110
- branch,
111
- revision,
112
- major,
113
- minor,
114
- patch,
115
- build,
116
- short,
117
- isRelease,
118
- npm,
119
- info,
120
- };
121
- if (logIt) buildLog(`Building version ${info}`);
122
- }
123
- return version;
124
- }
125
-
126
- export async function getBanner(): Promise<string> {
127
- const { copyright = '' } = getCfg();
128
- const { info, name } = await getVersion();
129
- const today = new Date();
130
- return `${name} v${info} | (c) ${today.getFullYear()} ${copyright} | built on ${today.toISOString()}`;
131
- }
132
-
133
- export async function getVersionCode(): Promise<string> {
134
- return `// This file is auto-generated
135
- export const version = ${JSON.stringify(await getVersion(), null, 2)}`;
136
- }
137
-
138
- export async function getUniqueBuildTag(): Promise<string> {
139
- const { branch, revision, build } = await getVersion();
140
- return `${branch}-${revision}-${build}`;
141
- }
package/src/yarn.js DELETED
@@ -1,123 +0,0 @@
1
- // @flow
2
- import md5File from 'md5-file';
3
- import fs from 'fs-extra';
4
- import path from 'path';
5
- import { spawnAdv } from './cp';
6
- import type { SpawnOptions, SpawnResult } from './cp';
7
- import { buildLog } from './run';
8
- import { readDir } from './fs';
9
- import { getPkg } from './pkg';
10
-
11
- export type YarnOptions = {|
12
- args?: string[],
13
- spawnOptions?: ?SpawnOptions,
14
- |};
15
-
16
- export async function yarnAdv(opts?: YarnOptions): Promise<SpawnResult> {
17
- const { args = [], spawnOptions } = opts || {};
18
- const localYarn = path.join(
19
- path.dirname(process.execPath),
20
- '/node_modules/yarn/bin/yarn.js',
21
- );
22
-
23
- const spawnOpts = {
24
- stdio: 'inherit',
25
- shell: true,
26
- env: process.env,
27
- ...spawnOptions,
28
- };
29
-
30
- return (await fs.exists(localYarn))
31
- ? // prefer to use local copy of yarn
32
- spawnAdv(process.execPath, [localYarn, ...args], spawnOpts)
33
- : // fall back to globally installed yarn
34
- spawnAdv('yarn', args, spawnOpts);
35
- }
36
-
37
- export async function yarn(opts?: YarnOptions): Promise<string> {
38
- const { args = [], spawnOptions } = opts || {};
39
- return yarnAdv({
40
- args,
41
- spawnOptions: { rejectOnErrorCode: true, ...spawnOptions },
42
- }).then((r) => r.output);
43
- }
44
-
45
- export const yarnFiles = ['./package.json', './yarn.lock'];
46
-
47
- export type YarnInstallOptions = {|
48
- nodeModulesPath?: string,
49
- hashFilePath?: string,
50
- force?: boolean,
51
- |};
52
-
53
- // Smart yarn invocation, only if package changed
54
- export async function yarnInstall(opts?: YarnInstallOptions) {
55
- const {
56
- nodeModulesPath = './node_modules',
57
- hashFilePath = './download/buildHash_yarn.md5',
58
- force = false,
59
- } = opts || {};
60
- await fs.ensureDir(nodeModulesPath);
61
- const currentHash = (
62
- await Promise.all(yarnFiles.map(async (f) => md5File(f)))
63
- ).join('|');
64
- await fs.ensureFile(hashFilePath);
65
- const prevHash = await fs.readFile(hashFilePath, 'utf8');
66
- if (currentHash !== prevHash) {
67
- buildLog(
68
- 'node package definition changed since last build, invoking yarn.',
69
- );
70
- } else if (!(await readDir(`${nodeModulesPath}/**/*.js`)).length) {
71
- buildLog('node packages missing, invoking yarn.');
72
- } else if (force) {
73
- buildLog('node packages unchanged, but yarn forced on command line...');
74
- } else {
75
- buildLog('node packages unchanged since last build, skipping yarn.');
76
- return;
77
- }
78
- await yarn();
79
- await fs.writeFile(hashFilePath, currentHash);
80
- }
81
-
82
- export type YarnUpgradeOptions = {|
83
- /**
84
- * Use `yarn outdated` to find packages that should be upgraded
85
- * May include breaking changes (major version changes)
86
- */
87
- outdated?: boolean,
88
- /**
89
- * `false` by default
90
- * we assume any package with an explicit version shouldn't be touched
91
- */
92
- all?: boolean,
93
- |};
94
-
95
- export async function yarnUpgrade(opts?: YarnUpgradeOptions) {
96
- const { outdated = false, all = false } = opts || {};
97
- if (outdated) {
98
- const { code, stdout } = await yarnAdv({
99
- args: ['outdated'],
100
- spawnOptions: { stdio: 'pipe', captureOutput: true },
101
- });
102
- if (code === 0) {
103
- buildLog('No outdated packages.');
104
- } else {
105
- const { dependencies = {}, devDependencies = {} } = getPkg();
106
- const packages = stdout
107
- .split('\n')
108
- .slice(5, -1)
109
- .map((l) => l.split(/\s+/)[0])
110
- .filter(
111
- (p) =>
112
- all || !/^\d/.test(dependencies[p] || devDependencies[p] || ''),
113
- );
114
- if (packages.length) {
115
- await yarn({ args: ['add', ...packages] });
116
- buildLog(`Upgraded: ${packages.join(', ')}`);
117
- } else {
118
- buildLog('No eligible outdated packages');
119
- }
120
- }
121
- }
122
- await yarn({ args: ['upgrade'] });
123
- }