chore: use jobs for artifact generation (#8864)

This commit is contained in:
jrandolf 2022-08-31 14:42:53 +02:00 committed by GitHub
parent 292216652b
commit eb6cea4f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 439 additions and 114 deletions

View File

@ -68,10 +68,15 @@ jobs:
run: npm run docs
- name: Check if autogenerated docs differ
run: |
if [[ $(git diff) ]]; then
echo "Please update the documentation by running 'npm run docs'"
diff_file=$(mktemp doc_diff_XXXXXX)
git diff --color > $diff_file
if [[ -s $diff_file ]]; then
echo "Please update the documentation by running 'npm run docs'. The following was the diff"
cat $diff_file
rm $diff_file
exit 1
fi
rm $diff_file
- name: Check if docs need to be deployed
id: needs_deploying
run: |
@ -165,7 +170,7 @@ jobs:
if: ${{ matrix.spec.name == 'Linux' }}
run: sudo apt-get install xvfb
- name: Build
run: npm run build
run: npm run build:ci
- name: Test types
run: npm run test:types
# On Linux we run all Chrome tests without retries and Firefox tests with retries.
@ -215,7 +220,7 @@ jobs:
ls .local-chromium
- name: Build
run: |
npm run build
npm run build:ci
docker/pack.sh
- name: Build docker image
working-directory: ./docker

216
package-lock.json generated
View File

@ -30,6 +30,7 @@
"@microsoft/api-extractor-model": "7.23.0",
"@types/debug": "4.1.7",
"@types/diff": "5.0.2",
"@types/glob": "7.2.0",
"@types/mime": "3.0.1",
"@types/mocha": "9.1.1",
"@types/node": "18.7.1",
@ -61,6 +62,7 @@
"eslint-plugin-unused-imports": "2.0.0",
"esprima": "4.0.1",
"expect": "25.2.7",
"glob": "8.0.3",
"gts": "4.0.0",
"husky": "8.0.1",
"jpeg-js": "0.4.4",
@ -4088,19 +4090,19 @@
}
},
"node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": "*"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@ -4118,6 +4120,27 @@
"node": ">= 6"
}
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/global-dirs": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
@ -5474,6 +5497,48 @@
"node": ">=0.3.1"
}
},
"node_modules/mocha/node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/glob/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/mocha/node_modules/glob/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/mocha/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -6614,6 +6679,25 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
@ -7087,6 +7171,26 @@
"node": ">=8"
}
},
"node_modules/test-exclude/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/text-diff": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/text-diff/-/text-diff-1.0.1.tgz",
@ -10655,16 +10759,36 @@
}
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
"integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"glob-parent": {
@ -11670,6 +11794,41 @@
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
"dev": true
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"dependencies": {
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
}
}
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -12501,6 +12660,21 @@
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"requires": {
"glob": "^7.1.3"
},
"dependencies": {
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
}
}
},
"run-async": {
@ -12859,6 +13033,22 @@
"@istanbuljs/schema": "^0.1.2",
"glob": "^7.1.4",
"minimatch": "^3.0.4"
},
"dependencies": {
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
}
}
},
"text-diff": {

View File

@ -42,24 +42,24 @@
"lint:eslint": "([ \"$CI\" = true ] && eslint --ext js --ext ts --quiet -f codeframe . || eslint --ext js --ext ts .)",
"install": "node install.js",
"generate:sources": "tsx utils/generate_sources.ts",
"generate:types": "node utils/export_all.js && api-extractor run --local --verbose && eslint --ext ts --no-ignore --no-eslintrc -c .eslintrc.types.cjs --fix lib/types.d.ts",
"generate:markdown": "tsx utils/generate_docs.ts && prettier --ignore-path none --write docs",
"generate:esm-package-json": "echo '{\"type\": \"module\"}' > lib/esm/package.json",
"generate:artifacts": "tsx utils/generate_artifacts.ts",
"generate:markdown": "tsx utils/generate_docs.ts",
"format": "run-s format:*",
"format:prettier": "prettier --write .",
"format:eslint": "eslint --ext js --ext ts --fix .",
"docs": "run-s build generate:markdown",
"debug": "npm run build && mocha --inspect-brk",
"debug": "npm run build:test && mocha --inspect-brk",
"commitlint": "commitlint --from=HEAD~1",
"clean": "rimraf lib && rimraf test/build",
"check": "run-p check:*",
"check:protocol-revision": "tsx scripts/ensure-correct-devtools-protocol-package",
"check:pinned-deps": "tsx scripts/ensure-pinned-deps",
"build": "run-s generate:sources build:tsc generate:types generate:esm-package-json",
"build:tsc": "tsc --version && run-p build:tsc:*",
"build:tsc:esm": "tsc -b src/tsconfig.esm.json",
"build:tsc:cjs": "tsc -b src/tsconfig.cjs.json",
"build:tsc:test": "tsc -b test"
"build": "npm run build:lib",
"build:test": "run-s generate:sources build:tsc:test",
"build:ci": "run-s build:test generate:artifacts",
"build:lib": "run-s generate:sources build:tsc:lib generate:artifacts",
"build:tsc:test": "tsc -b test",
"build:tsc:lib": "tsc -b tsconfig.lib.json"
},
"files": [
"lib",
@ -90,6 +90,7 @@
"@microsoft/api-extractor-model": "7.23.0",
"@types/debug": "4.1.7",
"@types/diff": "5.0.2",
"@types/glob": "7.2.0",
"@types/mime": "3.0.1",
"@types/mocha": "9.1.1",
"@types/node": "18.7.1",
@ -121,6 +122,7 @@
"eslint-plugin-unused-imports": "2.0.0",
"esprima": "4.0.1",
"expect": "25.2.7",
"glob": "8.0.3",
"gts": "4.0.0",
"husky": "8.0.1",
"jpeg-js": "0.4.4",

View File

@ -8,5 +8,6 @@
"references": [
{"path": "../vendor/tsconfig.cjs.json"},
{"path": "../compat/cjs/tsconfig.json"}
]
],
"exclude": ["injected/injected.ts"]
}

View File

@ -1,13 +1,5 @@
// AUTOGENERATED - Use `utils/export_all.js` to regenerate.
// AUTOGENERATED - Use `npm run generate:sources` to regenerate.
export * from './compat.d.js';
export * from './constants.js';
export * from './environment.js';
export * from './initializePuppeteer.js';
export * from './puppeteer.js';
export * from './revisions.js';
// Exports from `common`
export * from './common/Accessibility.js';
export * from './common/AriaQueryHandler.js';
export * from './common/Browser.js';
@ -26,6 +18,7 @@ export * from './common/EmulationManager.js';
export * from './common/Errors.js';
export * from './common/EventEmitter.js';
export * from './common/ExecutionContext.js';
export * from './common/fetch.js';
export * from './common/FileChooser.js';
export * from './common/FirefoxTargetManager.js';
export * from './common/Frame.js';
@ -39,8 +32,8 @@ export * from './common/LifecycleWatcher.js';
export * from './common/NetworkConditions.js';
export * from './common/NetworkEventManager.js';
export * from './common/NetworkManager.js';
export * from './common/PDFOptions.js';
export * from './common/Page.js';
export * from './common/PDFOptions.js';
export * from './common/Product.js';
export * from './common/Puppeteer.js';
export * from './common/PuppeteerViewport.js';
@ -51,25 +44,30 @@ export * from './common/TargetManager.js';
export * from './common/TaskQueue.js';
export * from './common/TimeoutSettings.js';
export * from './common/Tracing.js';
export * from './common/USKeyboardLayout.js';
export * from './common/WebWorker.js';
export * from './common/fetch.js';
export * from './common/types.js';
export * from './common/USKeyboardLayout.js';
export * from './common/util.js';
// Exports from `node`
export * from './common/WebWorker.js';
export * from './compat.d.js';
export * from './constants.js';
export * from './environment.js';
export * from './generated/injected.js';
export * from './generated/version.js';
export * from './initializePuppeteer.js';
export * from './node/BrowserFetcher.js';
export * from './node/BrowserRunner.js';
export * from './node/ChromeLauncher.js';
export * from './node/FirefoxLauncher.js';
export * from './node/install.js';
export * from './node/LaunchOptions.js';
export * from './node/NodeWebSocketTransport.js';
export * from './node/PipeTransport.js';
export * from './node/ProductLauncher.js';
export * from './node/Puppeteer.js';
export * from './node/install.js';
export * from './node/util.js';
// Exports from `generated`
export * from './generated/injected.js';
export * from './generated/version.js';
export * from './puppeteer.js';
export * from './revisions.js';
export * from './util/assert.js';
export * from './util/DeferredPromise.js';
export * from './util/ErrorLike.js';
export * from './util/getPackageDirectory.js';

View File

@ -1,6 +1,9 @@
import {existsSync} from 'fs';
import {dirname, join, parse} from 'path';
/**
* @internal
*/
export const getPackageDirectory = (from: string): string => {
let found = existsSync(join(from, 'package.json'));
const root = parse(from).root;

16
tsconfig.lib.json Normal file
View File

@ -0,0 +1,16 @@
/**
* This configuration only exists for the API Extractor tool and for VSCode to use. It is NOT the tsconfig used for compilation.
* For CJS builds, `tsconfig.cjs.json` is used, and for ESM, it's `tsconfig.esm.json`.
* See the details in CONTRIBUTING.md that describes our TypeScript setup.
*/
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true
},
"references": [
{"path": "src/tsconfig.esm.json"},
{"path": "src/tsconfig.cjs.json"}
],
"exclude": ["**/*"]
}

View File

@ -1,30 +0,0 @@
const {readdirSync, writeFileSync} = require('fs');
const {join, basename} = require('path');
const EXCLUDE_FILES = ['puppeteer-core.ts'];
let typesTs = '// AUTOGENERATED - Use `utils/export_all.js` to regenerate.\n';
typesTs += `\n`;
for (const file of readdirSync(join(__dirname, `../src`)).filter(filename => {
return (
filename.endsWith('ts') &&
!filename.startsWith('types') &&
!EXCLUDE_FILES.includes(filename)
);
})) {
typesTs += `export * from './${basename(file, '.ts')}.js';\n`;
}
for (const folder of ['common', 'node', 'generated']) {
typesTs += `\n// Exports from \`${folder}\`\n`;
for (const file of readdirSync(join(__dirname, `../src/${folder}`)).filter(
filename => {
return filename.endsWith('ts') && !EXCLUDE_FILES.includes(filename);
}
)) {
typesTs += `export * from './${folder}/${basename(file, '.ts')}.js';\n`;
}
}
writeFileSync(join(__dirname, '../src/types.ts'), typesTs);

View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
import {writeFile} from 'fs/promises';
import {job} from './internal/job.js';
import {spawnAndLog} from './internal/util.js';
(async () => {
job('', async ({outputs}) => {
await writeFile(outputs[0]!, '{"type": "module"}');
})
.outputs(['lib/esm/package.json'])
.build();
job('', async ({outputs}) => {
spawnAndLog('api-extractor', 'run', '--local');
spawnAndLog(
'eslint',
'--ext=ts',
'--no-ignore',
'--no-eslintrc',
'-c=.eslintrc.types.cjs',
'--fix',
outputs[0]!
);
})
.inputs(['lib/esm/puppeteer/types.d.ts'])
.outputs(['lib/types.d.ts', 'puppeteer.api.json'])
.build();
})();

View File

@ -14,11 +14,11 @@
* limitations under the License.
*/
import {readFile, writeFile} from 'fs/promises';
import rimraf from 'rimraf';
import {readFile, rm, writeFile} from 'fs/promises';
import semver from 'semver';
import {generateDocs} from './internal/custom_markdown_action.js';
import {job} from './internal/job.js';
import {spawnAndLog} from './internal/util.js';
function getOffsetAndLimit(
sectionName: string,
@ -46,7 +46,7 @@ function spliceIntoSection(
}
(async () => {
job('', async ({inputs, outputs}) => {
const job1 = job('', async ({inputs, outputs}) => {
const content = await readFile(inputs[0]!, 'utf-8');
const sectionContent = `
---
@ -60,8 +60,8 @@ sidebar_position: 1
.build();
// Chrome Versions
job('', async ({inputs, outputs}) => {
let content = await readFile(outputs[0]!, {encoding: 'utf8'});
const job2 = job('', async ({inputs, outputs}) => {
let content = await readFile(inputs[2]!, {encoding: 'utf8'});
const {versionsPerRelease} = await import(inputs[0]!);
const versionsArchived = JSON.parse(await readFile(inputs[1]!, 'utf8'));
@ -95,14 +95,21 @@ sidebar_position: 1
await writeFile(outputs[0]!, content);
})
.inputs(['versions.js', 'website/versionsArchived.json'])
.inputs([
'versions.js',
'website/versionsArchived.json',
'docs/chromium-support.md',
])
.outputs(['docs/chromium-support.md'])
.build();
await Promise.all([job1, job2]);
// Generate documentation
job('', async ({inputs, outputs}) => {
rimraf.sync(outputs[0]!);
await rm(outputs[0]!, {recursive: true, force: true});
generateDocs(inputs[0]!, outputs[0]!);
spawnAndLog('prettier', '--ignore-path', 'none', '--write', 'docs');
})
.inputs(['docs/puppeteer.api.json'])
.outputs(['docs/api'])

View File

@ -1,10 +1,13 @@
#!/usr/bin/env node
import {createHash} from 'crypto';
import esbuild from 'esbuild';
import {mkdir, mkdtemp, readFile, writeFile} from 'fs/promises';
import {mkdir, mkdtemp, readFile, rm, writeFile} from 'fs/promises';
import {sync as glob} from 'glob';
import path from 'path';
import rimraf from 'rimraf';
import {job} from './internal/job.js';
const INCLUDED_FOLDERS = ['common', 'node', 'generated', 'util'];
(async () => {
await job('', async ({outputs}) => {
await Promise.all(
@ -45,12 +48,35 @@ import {job} from './internal/job.js';
JSON.stringify(content)
);
await writeFile(outputs[0]!, scriptContent);
rimraf.sync(tmp);
await rm(tmp, {recursive: true, force: true});
})
.inputs(['src/templates/injected.ts.tmpl', 'src/injected/**.ts'])
.inputs(['src/templates/injected.ts.tmpl', 'src/injected/**/*.ts'])
.outputs(['src/generated/injected.ts'])
.build();
const sources = glob(
`src/{@(${INCLUDED_FOLDERS.join('|')})/*.ts,!(types|puppeteer-core).ts}`
);
await job('', async ({outputs}) => {
let types =
'// AUTOGENERATED - Use `npm run generate:sources` to regenerate.\n\n';
for (const input of sources.map(source => {
return `.${source.slice(3)}`;
})) {
types += `export * from '${input.replace('.ts', '.js')}';\n`;
}
await writeFile(outputs[0]!, types);
})
.value(
sources
.reduce((hmac, value) => {
return hmac.update(value);
}, createHash('sha256'))
.digest('hex')
)
.outputs(['src/types.ts'])
.build();
job('', async ({inputs, outputs}) => {
const version = JSON.parse(await readFile(inputs[0]!, 'utf8')).version;
await writeFile(

View File

@ -1,7 +1,13 @@
import {Stats} from 'fs';
import {stat} from 'fs/promises';
import {createHash} from 'crypto';
import {existsSync, Stats} from 'fs';
import {mkdir, readFile, stat, writeFile} from 'fs/promises';
import {glob} from 'glob';
import path from 'path';
import {tmpdir} from 'os';
import {dirname, join, resolve} from 'path';
import {chdir} from 'process';
const packageRoot = resolve(join(__dirname, '..', '..'));
chdir(packageRoot);
interface JobContext {
name: string;
@ -14,61 +20,120 @@ class JobBuilder {
#outputs: string[] = [];
#callback: (ctx: JobContext) => Promise<void>;
#name: string;
#value = '';
#force = false;
constructor(name: string, callback: (ctx: JobContext) => Promise<void>) {
this.#name = name;
this.#callback = callback;
}
get jobHash(): string {
return createHash('sha256').update(this.#name).digest('hex');
}
force() {
this.#force = true;
return this;
}
value(value: string) {
this.#value = value;
return this;
}
inputs(inputs: string[]): JobBuilder {
this.#inputs = inputs.flatMap(value => {
value = path.resolve(__dirname, '..', '..', value);
const paths = glob.sync(value);
return paths.length ? paths : [value];
if (glob.hasMagic(value)) {
return glob.sync(value).map(value => {
// Glob doesn't support `\` on Windows, so we join here.
return join(packageRoot, value);
});
}
return join(packageRoot, value);
});
return this;
}
outputs(outputs: string[]): JobBuilder {
if (!this.#name) {
this.#name = outputs[0]!;
this.#name = outputs.join(' and ');
}
this.#outputs = outputs.map(value => {
return path.resolve(__dirname, '..', '..', value);
return join(packageRoot, value);
});
return this;
}
async build(): Promise<void> {
console.log(`Running job ${this.#name}...`);
// For debugging.
if (this.#force) {
return this.#run();
}
// In case we deleted an output file on purpose.
if (!this.getOutputStats()) {
return this.#run();
}
// Run if the job has a value, but it changes.
if (this.#value) {
if (!(await this.isValueDifferent())) {
return;
}
return this.#run();
}
// Always run when there is no output.
if (!this.#outputs.length) {
return this.#run();
}
// Make-like comparator.
if (!(await this.areInputsNewer())) {
return;
}
return this.#run();
}
let shouldRun = true;
async isValueDifferent(): Promise<boolean> {
const file = join(tmpdir(), `puppeteer/${this.jobHash}.txt`);
await mkdir(dirname(file), {recursive: true});
if (!existsSync(file)) {
await writeFile(file, this.#value);
return true;
}
return this.#value !== (await readFile(file, 'utf8'));
}
#outputStats?: Stats[];
async getOutputStats(): Promise<Stats[] | undefined> {
if (this.#outputStats) {
return this.#outputStats;
}
try {
this.#outputStats = await Promise.all(
this.#outputs.map(output => {
return stat(output);
})
);
} catch {}
return this.#outputStats;
}
async areInputsNewer(): Promise<boolean> {
const inputStats = await Promise.all(
this.#inputs.map(input => {
return stat(input);
})
);
let outputStats: Stats[];
try {
outputStats = await Promise.all(
this.#outputs.map(output => {
return stat(output);
})
);
if (
outputStats.reduce(reduceMinTime, Infinity) >
const outputStats = await this.getOutputStats();
if (
outputStats &&
outputStats.reduce(reduceMinTime, Infinity) >
inputStats.reduce(reduceMaxTime, 0)
) {
shouldRun = false;
}
} catch {}
if (shouldRun) {
this.#run();
) {
return false;
}
return true;
}
#run(): Promise<void> {

14
utils/internal/util.ts Normal file
View File

@ -0,0 +1,14 @@
import {spawnSync} from 'child_process';
export const spawnAndLog = (...args: string[]): void => {
const {stdout, stderr} = spawnSync(args[0]!, args.slice(1), {
encoding: 'utf-8',
shell: true,
});
if (stdout) {
console.log(stdout);
}
if (stderr) {
console.error(stderr);
}
};