├── .github
├── CODEOWNERS
└── workflows
│ ├── publish-npm.yml
│ ├── release.yml
│ ├── semantic.yml
│ └── test.yml
├── .gitignore
├── LICENSE
├── README.md
├── download-mksnapshot.js
├── mksnapshot.js
├── package-lock.json
├── package.json
├── script
├── publish.js
└── update-version.js
└── test
├── fixtures
├── invalid.js
└── snapshot.js
└── mksnapshot-test.js
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @electron/wg-releases
2 |
--------------------------------------------------------------------------------
/.github/workflows/publish-npm.yml:
--------------------------------------------------------------------------------
1 | name: Publish npm Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - v[0-9]+.[0-9]+.[0-9]+
7 |
8 | jobs:
9 | test:
10 | uses: ./.github/workflows/test.yml
11 | with:
12 | electron-version: ${{ github.ref_name }}
13 | release:
14 | runs-on: ubuntu-latest
15 | needs: test
16 | environment: npm
17 | permissions:
18 | contents: write # for creating new release
19 | id-token: write # for CFA
20 | steps:
21 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
22 | - name: "Use Node.js ${{ matrix.node-version }}"
23 | uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
24 | with:
25 | node-version: "20.16.0"
26 | - name: Update Version
27 | run: node script/update-version.js ${{ github.ref_name }}
28 | - name: Confirm Version Updated
29 | run: node -e "if (require('./package.json').version === '0.0.0-development') process.exit(1)"
30 | - name: Install Dependencies
31 | run: npm ci
32 | - name: Obtain OIDC token
33 | id: oidc
34 | run: |
35 | token=$(curl --fail -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
36 | "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=continuousauth.dev" | jq -r '.value')
37 | echo "::add-mask::${token}"
38 | echo "token=${token}" >> $GITHUB_OUTPUT
39 | - name: Obtain GitHub credentials
40 | id: github_creds
41 | run: |
42 | token=$(curl --fail "https://continuousauth.dev/api/request/${{ secrets.CFA_PROJECT_ID }}/github/credentials" \
43 | -X POST \
44 | -H "Content-Type: application/json" \
45 | -H "Authorization: bearer ${{ secrets.CFA_SECRET }}" \
46 | --data "{\"token\":\"${{ steps.oidc.outputs.token }}\"}" | jq -r '.GITHUB_TOKEN')
47 | echo "::add-mask::${token}"
48 | echo "token=${token}" >> $GITHUB_OUTPUT
49 | - name: Set NPM Credentials
50 | run: echo //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }} > ~/.npmrc
51 | - name: Check NPM Credentials
52 | run: npm whoami
53 | - name: CFA Publish
54 | env:
55 | CFA_PROJECT_ID: ${{ secrets.CFA_PROJECT_ID }}
56 | CFA_SECRET: ${{ secrets.CFA_SECRET }}
57 | GITHUB_OIDC_TOKEN: ${{ steps.oidc.outputs.token }}
58 | run: node script/publish.js
59 | - name: Create Release
60 | env:
61 | GITHUB_TOKEN: ${{ steps.github_creds.outputs.token }}
62 | run: gh release create ${{ github.ref_name }} -t ${{ github.ref_name }}
63 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release For New Electron Version
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | version:
7 | description: Electron version to use with "v" prefix (e.g. v30.0.0)
8 | required: true
9 |
10 | jobs:
11 | test:
12 | uses: ./.github/workflows/test.yml
13 | with:
14 | electron-version: ${{ github.event.inputs.version }}
15 | tag_new_version:
16 | runs-on: ubuntu-latest
17 | environment: deps-releaser
18 | needs: test
19 | steps:
20 | - name: Generate GitHub App token
21 | uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
22 | id: generate-token
23 | with:
24 | creds: ${{ secrets.DEPS_RELEASER_GH_APP_CREDS }}
25 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
26 | with:
27 | token: ${{ steps.generate-token.outputs.token }}
28 | # Tag here, the publish-npm.yml workflow will trigger on the new tag and do the CFA publish
29 | - name: Push New Tag
30 | run: |
31 | git tag ${{ github.event.inputs.version }}
32 | git push origin ${{ github.event.inputs.version }}
33 |
--------------------------------------------------------------------------------
/.github/workflows/semantic.yml:
--------------------------------------------------------------------------------
1 | name: "Check Semantic Commit"
2 |
3 | on:
4 | pull_request:
5 | types:
6 | - opened
7 | - edited
8 | - synchronize
9 |
10 | permissions:
11 | contents: read
12 |
13 | jobs:
14 | main:
15 | permissions:
16 | pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
17 | statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
18 | name: Validate PR Title
19 | runs-on: ubuntu-latest
20 | steps:
21 | - name: semantic-pull-request
22 | uses: amannn/action-semantic-pull-request@01d5fd8a8ebb9aafe902c40c53f0f4744f7381eb # tag: v5
23 | env:
24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25 | with:
26 | validateSingleCommit: false
27 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | electron-version:
7 | required: true
8 | type: string
9 | workflow_dispatch:
10 | schedule:
11 | - cron: '0 19 * * 1-5'
12 | push:
13 | branches:
14 | - main
15 | pull_request:
16 | branches:
17 | - main
18 |
19 | permissions:
20 | contents: read
21 |
22 | jobs:
23 | test:
24 | defaults:
25 | run:
26 | shell: bash
27 | strategy:
28 | matrix:
29 | node-version:
30 | - '20.16.0'
31 | - '18.20.4'
32 | - '16.20.2'
33 | - '14.21.3'
34 | os:
35 | - macos-latest
36 | - ubuntu-latest
37 | - windows-latest
38 | exclude:
39 | - os: macos-latest
40 | node-version: 14.21.3
41 | runs-on: "${{ matrix.os }}"
42 | steps:
43 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
44 | - name: "Use Node.js ${{ matrix.node-version }}"
45 | uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
46 | with:
47 | node-version: "${{ matrix.node-version }}"
48 | - name: Update Version
49 | if: ${{ inputs.electron-version != '' }}
50 | run: node script/update-version.js ${{ inputs.electron-version }}
51 | - name: Use Latest Electron Version
52 | if: ${{ inputs.electron-version == '' }}
53 | run: echo "ELECTRON_MKSNAPSHOT_STABLE_FALLBACK=1" >> $GITHUB_ENV
54 | - name: Install Dependencies
55 | run: npm ci
56 | - name: Run Tests
57 | run: |
58 | node --version
59 | npm --version
60 | npm test
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bin
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Contributors to the Electron project
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Electron mksnapshot
2 |
3 | [](https://github.com/electron/mksnapshot/actions/workflows/test.yml)
4 | [](https://www.npmjs.com/package/electron-mksnapshot)
5 |
6 | [](http://standardjs.com/)
7 | [](https://opensource.org/licenses/MIT)
8 |
9 | [](https://www.npmjs.com/package/electron-mksnapshot)
10 |
11 | Simple node module to download the `mksnapshot` binaries compatible with
12 | Electron for creating v8 snapshots.
13 |
14 | The major version of this library tracks the major version of the Electron
15 | versions released. So if you are using Electron `2.0.x` you would want to use
16 | an `electron-mksnapshot` dependency of `~2.0.0` in your `package.json` file.
17 |
18 | ## Using
19 |
20 | ```sh
21 | npm install --save-dev electron-mksnapshot
22 | mksnapshot.js file.js (--output_dir OUTPUT_DIR).
23 | ```
24 | Running mksnapshot.js will generate both a snapshot_blob.bin and v8_context_snapshot.bin files which
25 | are needed to use custom snapshots in Electron.
26 | If an output directory isn't specified, the current directory will be used.
27 | (Additional mksnapshot args except for --startup_blob are supported, run mksnapshot --help to see options)
28 |
29 | ## Custom Mirror
30 |
31 | You can set the `ELECTRON_MIRROR` or [`NPM_CONFIG_ELECTRON_MIRROR`](https://docs.npmjs.com/misc/config#environment-variables)
32 | environment variables to use a custom base URL for downloading mksnapshot zips.
33 |
34 | ```sh
35 | # Electron mirror for China
36 | ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/"
37 |
38 | # Local mirror
39 | # Example of requested URL: http://localhost:8080/1.2.0/mksnapshot-v1.2.0-darwin-x64.zip
40 | ELECTRON_MIRROR="http://localhost:8080/"
41 | ```
42 |
43 | ## Overriding the version downloaded
44 |
45 | The version downloaded can be overriden by setting the `ELECTRON_CUSTOM_VERSION` environment variable.
46 |
47 | ```sh
48 | # Install mksnapshot for Electron v8.3.0
49 | ELECTRON_CUSTOM_VERSION=8.3.0 npm install
50 | ```
51 |
52 | ## Generating snapshots for ARM hardware
53 |
54 | If you need to generate snapshots for Linux on 32 bit ARM, Linux on ARM64, or Windows on ARM64 you will need to install a cross arch mksnapshot on an Intel x64 machine. To do so, set the npm config `arch` to the proper arch and then run `npm install --save-dev electron-mksnapshot`. For example:
55 |
56 | ### Linux on ARM64
57 | From an Intel x64 Linux OS run:
58 | ```sh
59 | npm config set arch arm64
60 | npm install --save-dev electron-mksnapshot
61 | ```
62 |
63 | ### Linux on 32 bit ARM
64 | From an Intel x64 Linux OS run:
65 | ```sh
66 | npm config set arch armv7l
67 | npm install --save-dev electron-mksnapshot
68 | ```
69 |
70 | ### Windows on ARM (64-bit)
71 | From an Intel x64 Windows OS run:
72 | ```sh
73 | npm config set arch arm64
74 | npm install --save-dev electron-mksnapshot
75 | ```
76 |
77 | ### macOS on ARM64
78 | On macOS you can either run the cross arch mksnapshot directly on arm64 hardware or if you wish you can generate the snapshot on an Intel X64 macOS hardware via the following:
79 | ```sh
80 | npm config set arch arm64
81 | npm install --save-dev electron-mksnapshot
82 | npm run mksnapshot ABSOLUTE_PATH_TO_FILE/file.js -- --output_dir ABSOLUTE_PATH_TO_OUTPUT_DIR
83 | ```
84 |
--------------------------------------------------------------------------------
/download-mksnapshot.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const { downloadArtifact } = require('@electron/get')
4 | const extractZip = require('extract-zip')
5 | const versionToDownload = require('./package').version
6 | let archToDownload = process.env.npm_config_arch
7 |
8 | function download (version) {
9 | return downloadArtifact({
10 | version: version,
11 | artifactName: 'mksnapshot',
12 | platform: process.env.npm_config_platform,
13 | arch: archToDownload,
14 | rejectUnauthorized: process.env.npm_config_strict_ssl === 'true',
15 | quiet: ['info', 'verbose', 'silly', 'http'].indexOf(process.env.npm_config_loglevel) === -1
16 | })
17 | }
18 |
19 | async function attemptDownload (version) {
20 | // Fall back to latest stable if there is not a stamped version, for tests
21 | if (version === '0.0.0-development') {
22 | if (!process.env.ELECTRON_MKSNAPSHOT_STABLE_FALLBACK) {
23 | console.log('WARNING: mksnapshot in development needs the environment variable ELECTRON_MKSNAPSHOT_STABLE_FALLBACK set')
24 | process.exit(1)
25 | }
26 |
27 | const { ElectronVersions } = require('@electron/fiddle-core')
28 | const versions = await ElectronVersions.create(undefined, { ignoreCache: true })
29 | version = versions.latestStable.version
30 | }
31 |
32 | if (process.arch.indexOf('arm') === 0 && process.platform !== 'darwin') {
33 | console.log(`WARNING: mksnapshot does not run on ${process.arch}. Download
34 | https://github.com/electron/electron/releases/download/v${version}/mksnapshot-v${version}-${process.platform}-${process.arch}-x64.zip
35 | on a x64 ${process.platform} OS to generate ${archToDownload} snapshots.`)
36 | process.exit(1)
37 | }
38 |
39 | if (archToDownload && archToDownload.indexOf('arm') === 0 && process.platform !== 'darwin') {
40 | archToDownload += '-x64'
41 | }
42 |
43 | try {
44 | const targetFolder = path.join(__dirname, 'bin')
45 | const zipPath = await download(version)
46 | await extractZip(zipPath, { dir: targetFolder })
47 | const platform = process.env.npm_config_platform || process.platform
48 | if (platform !== 'win32') {
49 | const mksnapshotPath = path.join(__dirname, 'bin', 'mksnapshot')
50 | if (fs.existsSync(mksnapshotPath)) {
51 | fs.chmod(mksnapshotPath, '755', function (error) {
52 | if (error != null) throw error
53 | })
54 | }
55 | }
56 | } catch (err) {
57 | // attempt to fall back to semver minor
58 | const parts = version.split('.')
59 | const baseVersion = `${parts[0]}.${parts[1]}.0`
60 |
61 | // don't recurse infinitely
62 | if (baseVersion === version) {
63 | throw err
64 | } else {
65 | await attemptDownload(baseVersion)
66 | }
67 | }
68 | }
69 |
70 | attemptDownload(versionToDownload)
71 |
--------------------------------------------------------------------------------
/mksnapshot.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs-extra')
4 | const { spawnSync } = require('child_process')
5 | const path = require('path')
6 | const temp = require('temp').track()
7 | const workingDir = temp.mkdirSync('mksnapshot-workdir')
8 | const crossArchDirs = [
9 | 'clang_x86_v8_arm',
10 | 'clang_x64_v8_arm64',
11 | 'win_clang_x64'
12 | ]
13 |
14 | function getBinaryPath (binary, binaryPath) {
15 | if (process.platform === 'win32') {
16 | return path.join(binaryPath, `${binary}.exe`)
17 | } else {
18 | return path.join(binaryPath, binary)
19 | }
20 | }
21 |
22 | const args = process.argv.slice(2)
23 | if (args.length === 0 || args.includes('--help')) {
24 | console.log('Usage: mksnapshot file.js (--output_dir OUTPUT_DIR). ' +
25 | 'Additional mksnapshot args except for --startup_blob are supported:')
26 | args.push('--help')
27 | }
28 | const outDirIdx = args.indexOf('--output_dir')
29 | let outputDir = process.cwd()
30 | let mksnapshotArgs = args
31 | if (outDirIdx > -1) {
32 | mksnapshotArgs = args.slice(0, outDirIdx)
33 | if (args.length >= (outDirIdx + 2)) {
34 | outputDir = args[(outDirIdx + 1)]
35 | if (args.length > (outDirIdx + 2)) {
36 | mksnapshotArgs = mksnapshotArgs.concat(args.slice(outDirIdx + 2))
37 | }
38 | } else {
39 | console.log('Error! Output directory argument given but directory not specified.')
40 | process.exit(1)
41 | }
42 | }
43 | if (args.includes('--startup_blob')) {
44 | console.log('--startup_blob argument not supported. Use --output_dir to specify where to output snapshot_blob.bin')
45 | process.exit(1)
46 | }
47 |
48 | const mksnapshotDir = path.join(__dirname, 'bin')
49 |
50 | // Copy mksnapshot files to temporary working directory because
51 | // v8_context_snapshot_generator expects to run everything from the same
52 | // directory.
53 | fs.copySync(mksnapshotDir, workingDir)
54 |
55 | const argsFile = path.join(mksnapshotDir, 'mksnapshot_args')
56 | let mksnapshotBinaryDir = workingDir
57 | if (fs.existsSync(argsFile)) {
58 | // Use args from args file if it is provided as these match what is used to generate the original snapshot
59 | const mksnapshotArgsFile = fs.readFileSync(argsFile, 'utf8')
60 | const newlineRegEx = /(\r\n|\r|\n)/g
61 | const turboProfileRegEx = /--turbo-profiling/g
62 | const builtinsRegEx = /.*builtins-pgo.*/g
63 | const mksnapshotArgsFromFile = mksnapshotArgsFile.split(newlineRegEx).filter((arg) => {
64 | return (!arg.match(newlineRegEx) && !arg.match(turboProfileRegEx) && !arg.match(builtinsRegEx) && arg !== '')
65 | })
66 | const mksnapshotBinaryPath = path.parse(mksnapshotArgsFromFile[0])
67 | if (mksnapshotBinaryPath.dir) {
68 | mksnapshotBinaryDir = path.join(workingDir, mksnapshotBinaryPath.dir)
69 | }
70 | mksnapshotArgs = mksnapshotArgs.concat(mksnapshotArgsFromFile.slice(1))
71 | } else {
72 | mksnapshotArgs = mksnapshotArgs.concat(['--startup_blob', 'snapshot_blob.bin'])
73 | if (!mksnapshotArgs.includes('--turbo_instruction_scheduling')) {
74 | mksnapshotArgs.push('--turbo_instruction_scheduling')
75 | }
76 | if (!fs.existsSync(getBinaryPath('mksnapshot', mksnapshotBinaryDir))) {
77 | const matchingDir = crossArchDirs.find((crossArchDir) => {
78 | const candidatePath = path.join(mksnapshotBinaryDir, crossArchDir)
79 | if (fs.existsSync(getBinaryPath('mksnapshot', candidatePath))) {
80 | return true
81 | }
82 | })
83 | if (matchingDir) {
84 | mksnapshotBinaryDir = path.join(workingDir, matchingDir)
85 | } else {
86 | console.log('ERROR: Could not find mksnapshot')
87 | process.exit(1)
88 | }
89 | }
90 | }
91 |
92 | const options = {
93 | cwd: mksnapshotBinaryDir,
94 | env: process.env,
95 | stdio: 'inherit'
96 | }
97 |
98 | const mksnapshotCommand = getBinaryPath('mksnapshot', mksnapshotBinaryDir)
99 | const mksnapshotProcess = spawnSync(mksnapshotCommand, mksnapshotArgs, options)
100 | if (mksnapshotProcess.status !== 0) {
101 | let code = mksnapshotProcess.status
102 | if (code == null) {
103 | code = 1
104 | }
105 | console.log('Error running mksnapshot.')
106 | process.exit(code)
107 | }
108 | if (args.includes('--help')) {
109 | process.exit(0)
110 | }
111 |
112 | fs.copyFileSync(path.join(mksnapshotBinaryDir, 'snapshot_blob.bin'),
113 | path.join(outputDir, 'snapshot_blob.bin'))
114 |
115 | const v8ContextGenCommand = getBinaryPath('v8_context_snapshot_generator', mksnapshotBinaryDir)
116 | let v8ContextFile = 'v8_context_snapshot.bin'
117 | if (process.platform === 'darwin') {
118 | const targetArch = process.env.npm_config_arch || process.arch
119 | if (targetArch === 'arm64') {
120 | v8ContextFile = 'v8_context_snapshot.arm64.bin'
121 | } else {
122 | v8ContextFile = 'v8_context_snapshot.x86_64.bin'
123 | }
124 | }
125 | const v8ContextGenArgs = [
126 | `--output_file=${path.join(outputDir, v8ContextFile)}`
127 | ]
128 |
129 | const v8ContextGenOptions = {
130 | cwd: mksnapshotDir,
131 | env: process.env,
132 | stdio: 'inherit'
133 | }
134 | const v8ContextGenProcess = spawnSync(v8ContextGenCommand, v8ContextGenArgs, v8ContextGenOptions)
135 | if (v8ContextGenProcess.status !== 0) {
136 | console.log('Error running the v8 context snapshot generator.', v8ContextGenProcess)
137 | process.exit(v8ContextGenProcess.status)
138 | }
139 | process.exit(0)
140 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-mksnapshot",
3 | "version": "0.0.0-development",
4 | "description": "Electron version of the mksnapshot binary",
5 | "repository": "https://github.com/electron/mksnapshot",
6 | "bin": {
7 | "mksnapshot": "./mksnapshot.js"
8 | },
9 | "files": [
10 | "./download-mksnapshot.js",
11 | "./mksnapshot.js"
12 | ],
13 | "scripts": {
14 | "mksnapshot": "node ./mksnapshot.js",
15 | "install": "node ./download-mksnapshot.js",
16 | "test": "mocha && standard"
17 | },
18 | "license": "MIT",
19 | "dependencies": {
20 | "@electron/get": "^2.0.1",
21 | "extract-zip": "^2.0.0",
22 | "fs-extra": "^7.0.1",
23 | "temp": "^0.8.3"
24 | },
25 | "devDependencies": {
26 | "@continuous-auth/client": "^2.3.0",
27 | "@electron/fiddle-core": "^1.3.0",
28 | "mocha": "^10.1.0",
29 | "semver": "^7.3.8",
30 | "standard": "^14.3.1"
31 | },
32 | "standard": {
33 | "ignore": [
34 | "test/fixtures"
35 | ]
36 | },
37 | "engines": {
38 | "node": ">=10.5.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/script/publish.js:
--------------------------------------------------------------------------------
1 | // Publish the package in the CWD with an OTP code from CFA
2 | const { getOtp } = require('@continuous-auth/client')
3 | const { spawnSync } = require('child_process')
4 |
5 | async function publish () {
6 | const { status } = spawnSync('npm', ['publish', '--provenance', '--otp', await getOtp()])
7 | process.exit(status)
8 | }
9 |
10 | publish()
11 |
--------------------------------------------------------------------------------
/script/update-version.js:
--------------------------------------------------------------------------------
1 | const { promises: fs } = require('fs')
2 | const path = require('path')
3 |
4 | const versionFormat = /^(\d+\.)(\d+\.)(\d+)$/
5 |
6 | const normalizeVersion = (version = '') => {
7 | return version.startsWith('v') ? version.slice(1) : version
8 | }
9 |
10 | async function updateVersion () {
11 | const version = normalizeVersion(process.argv[2])
12 | if (!versionFormat.test(version)) {
13 | console.error(`Unsupported version ${version} - only major, minor, and patch releases are currently supported`)
14 | return
15 | }
16 |
17 | const PJ_PATH = path.join(__dirname, '..', 'package.json')
18 | const pj = require(PJ_PATH)
19 |
20 | const PJLOCK_PATH = path.join(__dirname, '..', 'package-lock.json')
21 | const pjLock = require(PJLOCK_PATH)
22 |
23 | try {
24 | pj.version = version
25 | await fs.writeFile(PJ_PATH, JSON.stringify(pj, null, 2))
26 | console.log(`Updated package.json version to ${version}`)
27 |
28 | pjLock.version = version
29 | await fs.writeFile(PJLOCK_PATH, JSON.stringify(pjLock, null, 2))
30 | console.log(`Updated package-lock.json version to ${version}`)
31 | } catch (e) {
32 | console.error('Failed to update mksnapshot version: ', e)
33 | process.exit(1)
34 | }
35 | }
36 |
37 | updateVersion()
38 |
--------------------------------------------------------------------------------
/test/fixtures/invalid.js:
--------------------------------------------------------------------------------
1 | 1}2{3
2 |
--------------------------------------------------------------------------------
/test/fixtures/snapshot.js:
--------------------------------------------------------------------------------
1 | var foo = function () {
2 | return 'bar'
3 | }
4 |
--------------------------------------------------------------------------------
/test/mksnapshot-test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert')
2 | var ChildProcess = require('child_process')
3 | var fs = require('fs')
4 | var path = require('path')
5 | var temp = require('temp').track()
6 |
7 | var describe = global.describe
8 | var it = global.it
9 |
10 | describe('mksnapshot binary', function () {
11 | this.timeout(30000)
12 |
13 | it('creates a snapshot for a valid file', function (done) {
14 | var tempDir = temp.mkdirSync('mksnapshot-')
15 | var outputFile = path.join(tempDir, 'snapshot_blob.bin')
16 | let v8ContextFileName = 'v8_context_snapshot.bin'
17 | if (process.platform === 'darwin') {
18 | const targetArch = process.env.npm_config_arch || process.arch
19 | if (targetArch === 'arm64') {
20 | v8ContextFileName = 'v8_context_snapshot.arm64.bin'
21 | } else {
22 | v8ContextFileName = 'v8_context_snapshot.x86_64.bin'
23 | }
24 | }
25 | var v8ContextFile = path.join(tempDir, v8ContextFileName)
26 | var args = [
27 | path.join(__dirname, '..', 'mksnapshot.js'),
28 | path.join(__dirname, 'fixtures', 'snapshot.js'),
29 | '--output_dir',
30 | tempDir
31 | ]
32 | var mksnapshot = ChildProcess.spawn(process.execPath, args)
33 |
34 | var output = ''
35 | mksnapshot.stdout.on('data', function (data) { output += data })
36 | mksnapshot.stderr.on('data', function (data) { output += data })
37 |
38 | mksnapshot.on('close', function (code) {
39 | if (code !== 0) {
40 | console.log('Error calling mksnapshot', output)
41 | }
42 | assert.strictEqual(typeof code, 'number', 'Exit code is a number')
43 | assert.strictEqual(code, 0, 'Exit code is not zero')
44 | assert.strictEqual(output.indexOf('Loading script for embedding'), 0, output, 'Output is correct')
45 | assert.strictEqual(fs.existsSync(outputFile), true, 'Output file exists.')
46 | assert.strictEqual(fs.existsSync(v8ContextFile), true, 'V8 context file exists.')
47 | done()
48 | })
49 |
50 | mksnapshot.on('error', function (code) {
51 | console.log('error Output is', output)
52 | done()
53 | })
54 | })
55 |
56 | it('fails for invalid JavaScript files', function (done) {
57 | var tempDir = temp.mkdirSync('mksnapshot-')
58 | var outputFile = path.join(tempDir, 'snapshot_blob.bin')
59 | var v8ContextFile = path.join(tempDir, 'v8_context_snapshot.bin')
60 | var args = [
61 | path.join(__dirname, '..', 'mksnapshot.js'),
62 | path.join(__dirname, 'fixtures', 'invalid.js'),
63 | '--output_dir',
64 | tempDir
65 | ]
66 | var mksnapshot = ChildProcess.spawn(process.execPath, args)
67 |
68 | var output = ''
69 | mksnapshot.stdout.on('data', function (data) { output += data })
70 | mksnapshot.stderr.on('data', function (data) { output += data })
71 |
72 | mksnapshot.on('close', function (code) {
73 | assert.strictEqual(typeof code, 'number', 'Exit code is a number')
74 | assert.notStrictEqual(code, 0, 'Exit code is not zero')
75 | assert.notStrictEqual(output.indexOf('Error running mksnapshot.'), -1, 'Output has error message')
76 | assert.strictEqual(fs.existsSync(outputFile), false, 'Output file does not exist.')
77 | assert.strictEqual(fs.existsSync(v8ContextFile), false, 'V8 context file does not exist.')
78 | done()
79 | })
80 |
81 | mksnapshot.on('error', function (code) {
82 | console.log('error Output is', output)
83 | done()
84 | })
85 | })
86 | })
87 |
--------------------------------------------------------------------------------