From dc68cc89fe9c7ac0c690a5bc01175756c431e781 Mon Sep 17 00:00:00 2001 From: Joe Rohde Date: Fri, 31 Dec 2021 03:56:30 -0800 Subject: [PATCH] feat: sanity check to validate entrypoints (#669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: sanity check to validate entrypoints - For 'main' and 'browser' keys in package.json verify the files will be copied into the vsix. * Update src/package.ts * Update src/test/package.test.ts * Update src/test/package.test.ts * Update src/test/package.test.ts * Update src/package.ts * Update src/test/package.test.ts Co-authored-by: João Moreno Co-authored-by: João Moreno --- src/package.ts | 27 +++++++++++++++++++++++++++ src/test/package.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/package.ts b/src/package.ts index 58d7ce13..2d96ff73 100644 --- a/src/package.ts +++ b/src/package.ts @@ -916,6 +916,32 @@ class LicenseProcessor extends BaseProcessor { } } +class LaunchEntryPointProcessor extends BaseProcessor { + private entryPoints: Set = new Set(); + + constructor(manifest: Manifest) { + super(manifest); + if (manifest.main) { + this.entryPoints.add(util.normalize(path.join('extension', manifest.main))); + } + if (manifest.browser) { + this.entryPoints.add(util.normalize(path.join('extension', manifest.browser))); + } + } + + onFile(file: IFile): Promise { + this.entryPoints.delete(util.normalize(file.path)); + return Promise.resolve(file); + } + + async onEnd(): Promise { + if (this.entryPoints.size > 0) { + const files: string = [...this.entryPoints].join(',\n '); + throw new Error(`Extension entrypoint(s) missing. Make sure these files exist and aren't ignored by '.vscodeignore':\n ${files}`); + } + } +} + class IconProcessor extends BaseProcessor { private icon: string | undefined; private didFindIcon = false; @@ -1498,6 +1524,7 @@ export function createDefaultProcessors(manifest: Manifest, options: IPackageOpt new TagsProcessor(manifest), new ReadmeProcessor(manifest, options), new ChangelogProcessor(manifest, options), + new LaunchEntryPointProcessor(manifest), new LicenseProcessor(manifest), new IconProcessor(manifest), new NLSProcessor(manifest), diff --git a/src/test/package.test.ts b/src/test/package.test.ts index bf38cf92..c780af1b 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -1794,6 +1794,28 @@ describe('toContentTypes', () => { }); }); +describe('LaunchEntryPointProcessor', () => { + it('should detect when declared entrypoint is not in package', async () => { + const manifest = createManifest({ + main: 'main.js', + }); + const files = [{ path: 'extension/browser.js', contents: Buffer.from('') }]; + let didErr = false; + try { + await _toVsixManifest(manifest, files); + } catch (err: any) { + const message = err.message; + didErr = message.includes('entrypoint(s) missing') && message.includes('main.js'); + } + assert.ok(didErr); + }); + + it('should accept manifest if no entrypoints defined', async () => { + const manifest = createManifest({}); + const files = [{ path: 'extension/something.js', contents: Buffer.from('') }]; + await _toVsixManifest(manifest, files); + }); +}); describe('ManifestProcessor', () => { it('should ensure that package.json is writable', async () => { const root = fixture('uuid');