Skip to content

Commit

Permalink
feat(bundle-source): Add tag command-line flag
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Jul 19, 2024
1 parent b7c37d4 commit 2417123
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 6 deletions.
2 changes: 2 additions & 0 deletions packages/bundle-source/NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Adds a `-f,--format` command flag to specify other module formats.
- Adds a new `endoScript` module format.
- Adds a no-cache, bundle-to-stdout mode.
- Adds a `-t,--tag` command flag to specify export/import conditions like
`"browser"`.

# v3.2.1 (2024-03-20)

Expand Down
35 changes: 32 additions & 3 deletions packages/bundle-source/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const { Fail, quote: q } = assert;
* @property {number} bundleSize
* @property {boolean} noTransforms
* @property {ModuleFormat} format
* @property {string[]} tags
* @property {{ relative: string, absolute: string }} moduleSource
* @property {Array<{ relativePath: string, mtime: string, size: number }>} contents
*/
Expand Down Expand Up @@ -51,12 +52,19 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
* @param {Logger} [log]
* @param {object} [options]
* @param {boolean} [options.noTransforms]
* @param {string[]} [options.tags]
* @param {ModuleFormat} [options.format]
*/
const add = async (rootPath, targetName, log = defaultLog, options = {}) => {
const srcRd = cwd.neighbor(rootPath);

const { noTransforms = false, format = 'endoZipBase64' } = options;
const {
noTransforms = false,
format = 'endoZipBase64',
tags = [],
} = options;

tags.sort();

const statsByPath = new Map();

Expand Down Expand Up @@ -115,6 +123,7 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
),
noTransforms,
format,
tags,
};

await metaWr.atomicWriteText(JSON.stringify(meta, null, 2));
Expand Down Expand Up @@ -144,6 +153,7 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
* @param {object} [options]
* @param {boolean} [options.noTransforms]
* @param {ModuleFormat} [options.format]
* @param {string[]} [options.tags]
* @returns {Promise<BundleMeta>}
*/
const validate = async (
Expand All @@ -154,8 +164,12 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
options = {},
) => {
await null;
const { noTransforms: expectedNoTransforms, format: expectedFormat } =
options;
const {
noTransforms: expectedNoTransforms,
format: expectedFormat,
tags: expectedTags = [],
} = options;
expectedTags.sort();
if (!meta) {
const metaJson = await loadMetaText(targetName, log);
if (metaJson) {
Expand All @@ -180,10 +194,16 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
moduleSource: { absolute: moduleSource },
format = 'endoZipBase64',
noTransforms = false,
tags = [],
} = meta;
tags.sort();
assert.equal(bundleFileName, toBundleName(targetName));
assert.equal(format, expectedFormat);
assert.equal(noTransforms, expectedNoTransforms);
assert.equal(tags.length, expectedTags.length);
tags.forEach((tag, index) => {
assert.equal(tag, expectedTags[index]);
});
if (rootOpt) {
moduleSource === cwd.neighbor(rootOpt).absolute() ||
Fail`bundle ${targetName} was for ${moduleSource}, not ${rootOpt}`;
Expand Down Expand Up @@ -230,6 +250,7 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
* @param {object} [options]
* @param {boolean} [options.noTransforms]
* @param {ModuleFormat} [options.format]
* @param {string[]} [options.tags]
* @returns {Promise<BundleMeta>}
*/
const validateOrAdd = async (
Expand All @@ -248,13 +269,15 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
meta = await validate(targetName, rootPath, log, meta, {
format: options.format,
noTransforms: options.noTransforms,
tags: options.tags,
});
const {
bundleTime,
bundleSize,
contents,
noTransforms,
format = 'endoZipBase64',
tags = [],
} = meta;
log(
`${wr}`,
Expand All @@ -268,6 +291,8 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
noTransforms ? 'w/o transforms' : 'with transforms',
'with format',
format,
'and tags',
JSON.stringify(tags),
);
} catch (invalid) {
meta = undefined;
Expand All @@ -284,6 +309,7 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
contents,
noTransforms,
format = 'endoZipBase64',
tags = [],
} = meta;
log(
`${wr}`,
Expand All @@ -296,6 +322,8 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
noTransforms ? 'w/o transforms' : 'with transforms',
'with format',
format,
'and tags',
JSON.stringify(tags),
);
}

Expand All @@ -310,6 +338,7 @@ export const makeBundleCache = (wr, cwd, readPowers, opts) => {
* @param {object} [options]
* @param {boolean} [options.noTransforms]
* @param {ModuleFormat} [options.format]
* @param {string[]} [options.tags]
*/
const load = async (
rootPath,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions packages/bundle-source/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { jsOpts, jsonOpts, makeNodeBundleCache } from '../cache.js';
/** @import {ModuleFormat} from './types.js' */

const USAGE = `\
bundle-source [-Tf] <entry.js>
bundle-source [-Tf] --cache-js|--cache-json <cache/> (<entry.js> <bundle-name>)*
bundle-source [-Tft] <entry.js>
bundle-source [-Tft] --cache-js|--cache-json <cache/> (<entry.js> <bundle-name>)*
-f,--format endoZipBase64*|nestedEvaluate|getExport
-t,--tag <tag> (browser, node, &c)
-T,--no-transforms`;

const options = /** @type {const} */ ({
Expand All @@ -32,6 +33,11 @@ const options = /** @type {const} */ ({
short: 'f',
multiple: false,
},
tag: {
type: 'string',
short: 't',
multiple: true,
},
// deprecated
to: {
type: 'string',
Expand All @@ -52,6 +58,7 @@ export const main = async (args, { loadModule, pid, log }) => {
const {
values: {
format: moduleFormat = 'endoZipBase64',
tag: tags = [],
'no-transforms': noTransforms,
'cache-json': cacheJson,
'cache-js': cacheJs,
Expand Down Expand Up @@ -84,7 +91,11 @@ export const main = async (args, { loadModule, pid, log }) => {
throw new Error(USAGE);
}
const [entryPath] = positionals;
const bundle = await bundleSource(entryPath, { noTransforms, format });
const bundle = await bundleSource(entryPath, {
noTransforms,
format,
tags,
});
process.stdout.write(JSON.stringify(bundle));
process.stdout.write('\n');
return;
Expand Down Expand Up @@ -114,6 +125,7 @@ export const main = async (args, { loadModule, pid, log }) => {
await cache.validateOrAdd(bundleRoot, bundleName, undefined, {
noTransforms,
format,
tags,
});
}
};
2 changes: 2 additions & 0 deletions packages/bundle-source/src/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export async function bundleScript(
dev = false,
cacheSourceMaps = false,
noTransforms = false,
tags = [],
commonDependencies,
} = options;
const powers = { ...readPowers, ...grantedPowers };
Expand Down Expand Up @@ -69,6 +70,7 @@ export async function bundleScript(

const source = await makeBundle(powers, entry, {
dev,
tags,
commonDependencies,
parserForLanguage,
moduleTransforms,
Expand Down
2 changes: 2 additions & 0 deletions packages/bundle-source/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export {};
* @property {boolean} [noTransforms] - when true, generates a bundle with the
* original sources instead of SES-shim specific ESM and CJS. This may become
* default in a future major version.
* @property {string[]} [tags] - conditions for package.json conditional
* exports and imports.
*/

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/bundle-source/src/zip-base64.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const readPowers = makeReadPowers({ fs, url, crypto });
* @param {boolean} [options.dev]
* @param {boolean} [options.cacheSourceMaps]
* @param {boolean} [options.noTransforms]
* @param {string[]} [options.tags]
* @param {Record<string, string>} [options.commonDependencies]
* @param {object} [grantedPowers]
* @param {(bytes: string | Uint8Array) => string} [grantedPowers.computeSha512]
Expand All @@ -39,6 +40,7 @@ export async function bundleZipBase64(
dev = false,
cacheSourceMaps = false,
noTransforms = false,
tags = [],
commonDependencies,
} = options;
const powers = { ...readPowers, ...grantedPowers };
Expand Down Expand Up @@ -71,6 +73,7 @@ export async function bundleZipBase64(

const compartmentMap = await mapNodeModules(powers, entry, {
dev,
tags,
commonDependencies,
});

Expand Down
67 changes: 67 additions & 0 deletions packages/bundle-source/test/tags-command.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* global Buffer */
import test from '@endo/ses-ava/prepare-endo.js';

import { spawn } from 'child_process';
import url from 'url';

const textDecoder = new TextDecoder();

const cwd = url.fileURLToPath(new URL('..', import.meta.url));

const bundleSource = async (...args) => {
const bundleBytes = await new Promise((resolve, reject) => {
const errorChunks = [];
const outputChunks = [];
const child = spawn('node', ['bin/bundle-source', ...args], {
cwd,
stdio: ['inherit', 'pipe', 'pipe'],
});
child.on('close', code => {
if (code !== 0) {
reject(
new Error(
`Exit code: ${code}\nError output: ${new TextDecoder().decode(
Buffer.concat(errorChunks),
)}`,
),
);
} else {
resolve(Buffer.concat(outputChunks));
}
});
child.stdout.on('data', chunk => {
outputChunks.push(chunk);
});
child.stderr.on('data', chunk => {
errorChunks.push(chunk);
});
});
const bundleText = textDecoder.decode(bundleBytes);
return JSON.parse(bundleText);
};

test('bundle-source with --format and --tag', async t => {
const compartment = new Compartment();
{
const bundle = await bundleSource(
'--tag',
'b',
'--format',
'endoScript',
'demo/node_modules/conditional-reexports/entry.js',
);
const namespace = compartment.evaluate(bundle.source);
t.is(namespace.default, 'b');
}
{
const bundle = await bundleSource(
'--tag',
'a',
'--format',
'endoScript',
'demo/node_modules/conditional-reexports/entry.js',
);
const namespace = compartment.evaluate(bundle.source);
t.is(namespace.default, 'a');
}
});

0 comments on commit 2417123

Please sign in to comment.