Skip to content

Commit

Permalink
fix: improve manifest path detection
Browse files Browse the repository at this point in the history
  • Loading branch information
Loïc Mangeonjean committed Apr 22, 2023
1 parent 81ff43a commit 58a0acb
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 12 deletions.
2 changes: 1 addition & 1 deletion rollup/rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ export default (args: Record<string, string>): rollup.RollupOptions[] => {
const manifest = JSON.parse((await fsPromise.readFile(manifestPath)).toString('utf8'))
const nlsExists = fs.existsSync(manifestNlsPath)
try {
const filePaths = extractPathsFromExtensionManifest(manifest.contributes)
const filePaths = extractPathsFromExtensionManifest(manifest)
return `
import manifest from '${manifestPath}'
${nlsExists ? `import nls from '${manifestNlsPath}'` : ''}
Expand Down
108 changes: 99 additions & 9 deletions src/extension-tools.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,104 @@
import type { ILocalizedString } from 'vs/platform/action/common/action'
import type { IExtensionManifest } from 'vs/platform/extensions/common/extensions'
import type { ITMSyntaxExtensionPoint } from 'vs/workbench/services/textMate/common/TMGrammars'
import { IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'
import { IDebuggerContribution } from 'vs/workbench/contrib/debug/common/debug'
import { IRawLanguageExtensionPoint } from 'vs/workbench/services/language/common/languageService'
import { IThemeExtensionPoint } from 'vs/workbench/services/themes/common/workbenchThemeService'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function extractPathsFromExtensionManifest (manifest: any): string[] {
const paths: string[] = []
for (const [key, value] of Object.entries(manifest)) {
if (typeof value === 'string' && (key === 'path' || value.startsWith('./'))) {
paths.push(value)
}
if (value != null && typeof value === 'object') {
paths.push(...extractPathsFromExtensionManifest(value))
type IUserFriendlyIcon = string | { light: string, dark: string }
interface IUserFriendlyCommand {
command: string
title: string | ILocalizedString
shortTitle?: string | ILocalizedString
enablement?: string
category?: string | ILocalizedString
icon?: IUserFriendlyIcon
}

interface IJSONValidationExtensionPoint {
fileMatch: string | string[]
url: string
}

interface ContributedKeyBinding {
command: string
args?: unknown
key: string
when?: string
mac?: string
linux?: string
win?: string
}

interface ISnippetsExtensionPoint {
language: string
path: string
}

interface RealContribute {
commands?: IUserFriendlyCommand | IUserFriendlyCommand[]
configuration?: IConfigurationNode
debuggers?: IDebuggerContribution[]
grammars?: ITMSyntaxExtensionPoint[]
jsonValidation?: IJSONValidationExtensionPoint[]
keybindings?: ContributedKeyBinding | ContributedKeyBinding[]
languages?: IRawLanguageExtensionPoint[]
snippets?: ISnippetsExtensionPoint[]
themes?: IThemeExtensionPoint[]
iconThemes?: IThemeExtensionPoint[]
productIconThemes?: IThemeExtensionPoint[]
}

function extractCommandPaths (command: IUserFriendlyCommand | IUserFriendlyCommand[]): string[] {
if (Array.isArray(command)) {
return command.flatMap(extractCommandPaths)
}
if (command.icon != null) {
if (typeof command.icon === 'object') {
return [command.icon.light, command.icon.dark]
} else {
return [command.icon]
}
}
return []
}

function extractGrammarPaths (grammar: ITMSyntaxExtensionPoint): string[] {
return [grammar.path]
}

function extractLanguagePaths (language: Partial<IRawLanguageExtensionPoint>): string[] {
const paths: string[] = []
if (language.icon != null) {
paths.push(language.icon.dark, language.icon.light)
}
if (language.configuration != null) {
paths.push(language.configuration)
}
return paths
}

function extractSnippetsPaths (snippet: ISnippetsExtensionPoint): string[] {
return [snippet.path]
}

function extractThemePaths (theme: IThemeExtensionPoint): string[] {
return [theme.path]
}

function extractPathsFromExtensionManifestContribute (contribute: RealContribute): string[] {
const paths: string[] = []
if (contribute.commands != null) paths.push(...extractCommandPaths(contribute.commands))
if (contribute.grammars != null) paths.push(...contribute.grammars.flatMap(extractGrammarPaths))
if (contribute.languages != null) paths.push(...contribute.languages.flatMap(extractLanguagePaths))
if (contribute.snippets != null) paths.push(...contribute.snippets.flatMap(extractSnippetsPaths))
if (contribute.themes != null) paths.push(...contribute.themes.flatMap(extractThemePaths))
if (contribute.iconThemes != null) paths.push(...contribute.iconThemes.flatMap(extractThemePaths))
if (contribute.productIconThemes != null) paths.push(...contribute.productIconThemes.flatMap(extractThemePaths))
return Array.from(new Set(paths))
}

export function extractPathsFromExtensionManifest (manifest: IExtensionManifest): string[] {
return manifest.contributes != null ? extractPathsFromExtensionManifestContribute(manifest.contributes as RealContribute) : []
}
4 changes: 2 additions & 2 deletions src/rollup-vsix-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createFilter, FilterPattern, dataToEsm } from '@rollup/pluginutils'
import { Plugin } from 'rollup'
import yauzl from 'yauzl'
import { parse } from 'vscode/vs/base/common/json.js'
import { Readable } from 'stream'
import * as path from 'path'
import { extractPathsFromExtensionManifest } from './extension-tools'
import { parse } from '../vscode/vs/base/common/json.js'

interface Options {
include?: FilterPattern
Expand Down Expand Up @@ -94,7 +94,7 @@ export default function plugin (options: Options = defaultOptions): Plugin {
return path.relative('/', path.resolve('/', file))
}

const usedFiles = extractPathsFromExtensionManifest(manifest.contributes).filter(file => getVsixPath(file) in files)
const usedFiles = extractPathsFromExtensionManifest(manifest).filter(file => getVsixPath(file) in files)

const allFiles = ['package.json', 'package.nls.json', ...usedFiles]
const nlsExists = files['package.nls.json'] != null
Expand Down

0 comments on commit 58a0acb

Please sign in to comment.