diff --git a/build/lib/bootstrapExtensions.js b/build/lib/bootstrapExtensions.js new file mode 100644 index 00000000000..b1acb27c465 --- /dev/null +++ b/build/lib/bootstrapExtensions.js @@ -0,0 +1,138 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getBootstrapExtensionStream = getBootstrapExtensionStream; +exports.getBootstrapExtensions = getBootstrapExtensions; +const fs = require("fs"); +const path = require("path"); +const os = require("os"); +const rimraf = require("rimraf"); +const es = require("event-stream"); +const rename = require("gulp-rename"); +const vfs = require("vinyl-fs"); +const ext = require("./extensions"); +const fancyLog = require("fancy-log"); +const ansiColors = require("ansi-colors"); +const root = path.dirname(path.dirname(__dirname)); +const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8')); +const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BOOTSTRAP_EXTENSIONS_SILENCE_PLEASE']; +const bootstrapExtensions = productjson.bootstrapExtensions || []; +const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'bootstrap-control.json'); +function log(...messages) { + if (ENABLE_LOGGING) { + fancyLog(...messages); + } +} +function getExtensionPath(extension) { + return path.join(root, '.build', 'bootstrapExtensions', extension.name); +} +function isUpToDate(extension) { + const packagePath = path.join(getExtensionPath(extension), 'package.json'); + if (!fs.existsSync(packagePath)) { + return false; + } + const packageContents = fs.readFileSync(packagePath, { encoding: 'utf8' }); + try { + const diskVersion = JSON.parse(packageContents).version; + return (diskVersion === extension.version); + } + catch (err) { + return false; + } +} +function getExtensionDownloadStream(extension) { + const url = extension.metadata.multiPlatformServiceUrl || productjson.extensionsGallery?.serviceUrl; + return (url ? ext.fromMarketplace(url, extension, true) : ext.fromGithub(extension)) + .pipe(rename(p => { p.basename = `${extension.name}-${extension.version}.vsix`; })); +} +function getBootstrapExtensionStream(extension) { + // if the extension exists on disk, use those files instead of downloading anew + if (isUpToDate(extension)) { + log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); + return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); + } + return getExtensionDownloadStream(extension); +} +function syncMarketplaceExtension(extension) { + const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; + const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); + if (isUpToDate(extension)) { + log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); + return es.readArray([]); + } + rimraf.sync(getExtensionPath(extension)); + return getExtensionDownloadStream(extension) + .pipe(vfs.dest('.build/bootstrapExtensions')) + .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); +} +function syncExtension(extension, controlState) { + if (extension.platforms) { + const platforms = new Set(extension.platforms); + if (!platforms.has(process.platform)) { + log(ansiColors.gray('[skip]'), `${extension.name}@${extension.version}: Platform '${process.platform}' not supported: [${extension.platforms}]`, ansiColors.green('✔︎')); + return es.readArray([]); + } + } + switch (controlState) { + case 'disabled': + log(ansiColors.blue('[disabled]'), ansiColors.gray(extension.name)); + return es.readArray([]); + case 'marketplace': + // --- Start Positron --- + return syncMarketplaceExtension(extension); + // --- End Positron --- + default: + if (!fs.existsSync(controlState)) { + // --- Start Positron --- + log(ansiColors.red(`Error: Bootstrap extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); + // --- End Positron --- + return es.readArray([]); + } + else if (!fs.existsSync(path.join(controlState, 'package.json'))) { + // --- Start Positron --- + log(ansiColors.red(`Error: Bootstrap extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); + // --- End Positron --- + return es.readArray([]); + } + log(ansiColors.blue('[local]'), `${extension.name}: ${ansiColors.cyan(controlState)}`, ansiColors.green('✔︎')); + return es.readArray([]); + } +} +function readControlFile() { + try { + return JSON.parse(fs.readFileSync(controlFilePath, 'utf8')); + } + catch (err) { + return {}; + } +} +function writeControlFile(control, filePath) { + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, JSON.stringify(control, null, 2)); +} +function getBootstrapExtensions() { + const control = readControlFile(); + const streams = []; + for (const extension of [...bootstrapExtensions]) { + const controlState = control[extension.name] || 'marketplace'; + control[extension.name] = controlState; + streams.push(syncExtension(extension, controlState)); + } + writeControlFile(control, controlFilePath); + return new Promise((resolve, reject) => { + es.merge(streams) + .on('error', reject) + .on('end', resolve); + }); +} +if (require.main === module) { + getBootstrapExtensions().then(() => process.exit(0)).catch(err => { + console.error(err); + process.exit(1); + }); +} +//# sourceMappingURL=bootstrapExtensions.js.map \ No newline at end of file diff --git a/build/lib/bootstrapExtensions.ts b/build/lib/bootstrapExtensions.ts new file mode 100644 index 00000000000..b6fb1e111b5 --- /dev/null +++ b/build/lib/bootstrapExtensions.ts @@ -0,0 +1,161 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import * as rimraf from 'rimraf'; +import * as es from 'event-stream'; +import * as rename from 'gulp-rename'; +import * as vfs from 'vinyl-fs'; +import * as ext from './extensions'; +import * as fancyLog from 'fancy-log'; +import * as ansiColors from 'ansi-colors'; +import { Stream } from 'stream'; +import { IExtensionDefinition } from './builtInExtensions'; + +const root = path.dirname(path.dirname(__dirname)); +const productjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../product.json'), 'utf8')); +const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BOOTSTRAP_EXTENSIONS_SILENCE_PLEASE']; + +const bootstrapExtensions = productjson.bootstrapExtensions || []; +const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'bootstrap-control.json'); + +function log(...messages: string[]): void { + if (ENABLE_LOGGING) { + fancyLog(...messages); + } +} + +function getExtensionPath(extension: IExtensionDefinition): string { + return path.join(root, '.build', 'bootstrapExtensions', extension.name); +} + +function isUpToDate(extension: IExtensionDefinition): boolean { + const packagePath = path.join(getExtensionPath(extension), 'package.json'); + + if (!fs.existsSync(packagePath)) { + return false; + } + + const packageContents = fs.readFileSync(packagePath, { encoding: 'utf8' }); + + try { + const diskVersion = JSON.parse(packageContents).version; + return (diskVersion === extension.version); + } catch (err) { + return false; + } +} + +function getExtensionDownloadStream(extension: IExtensionDefinition) { + const url = extension.metadata.multiPlatformServiceUrl || productjson.extensionsGallery?.serviceUrl; + return (url ? ext.fromMarketplace(url, extension, true) : ext.fromGithub(extension)) + .pipe(rename(p => { p.basename = `${extension.name}-${extension.version}.vsix`; })); +} + +export function getBootstrapExtensionStream(extension: IExtensionDefinition) { + // if the extension exists on disk, use those files instead of downloading anew + if (isUpToDate(extension)) { + log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); + return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); + } + + return getExtensionDownloadStream(extension); +} + +function syncMarketplaceExtension(extension: IExtensionDefinition): Stream { + const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; + const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); + if (isUpToDate(extension)) { + log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); + return es.readArray([]); + } + + rimraf.sync(getExtensionPath(extension)); + + return getExtensionDownloadStream(extension) + .pipe(vfs.dest('.build/bootstrapExtensions')) + .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); +} + +function syncExtension(extension: IExtensionDefinition, controlState: 'disabled' | 'marketplace'): Stream { + if (extension.platforms) { + const platforms = new Set(extension.platforms); + + if (!platforms.has(process.platform)) { + log(ansiColors.gray('[skip]'), `${extension.name}@${extension.version}: Platform '${process.platform}' not supported: [${extension.platforms}]`, ansiColors.green('✔︎')); + return es.readArray([]); + } + } + + switch (controlState) { + case 'disabled': + log(ansiColors.blue('[disabled]'), ansiColors.gray(extension.name)); + return es.readArray([]); + + case 'marketplace': + return syncMarketplaceExtension(extension); + + default: + if (!fs.existsSync(controlState)) { + log(ansiColors.red(`Error: Bootstrap extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); + return es.readArray([]); + + } else if (!fs.existsSync(path.join(controlState, 'package.json'))) { + log(ansiColors.red(`Error: Bootstrap extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); + return es.readArray([]); + } + + log(ansiColors.blue('[local]'), `${extension.name}: ${ansiColors.cyan(controlState)}`, ansiColors.green('✔︎')); + return es.readArray([]); + } +} + +interface IControlFile { + [name: string]: 'disabled' | 'marketplace'; +} + +function readControlFile(): IControlFile { + try { + return JSON.parse(fs.readFileSync(controlFilePath, 'utf8')); + } catch (err) { + return {}; + } +} + +function writeControlFile(control: IControlFile, filePath: string): void { + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, JSON.stringify(control, null, 2)); +} + +export function getBootstrapExtensions(): Promise { + + const control = readControlFile(); + const streams: Stream[] = []; + + for (const extension of [...bootstrapExtensions]) { + const controlState = control[extension.name] || 'marketplace'; + control[extension.name] = controlState; + + streams.push(syncExtension(extension, controlState)); + } + + writeControlFile(control, controlFilePath); + + return new Promise((resolve, reject) => { + es.merge(streams) + .on('error', reject) + .on('end', resolve); + }); +} + +if (require.main === module) { + getBootstrapExtensions().then(() => process.exit(0)).catch(err => { + console.error(err); + process.exit(1); + }); +} diff --git a/build/lib/builtInExtensions.js b/build/lib/builtInExtensions.js index 1a72f87c603..0b95972afda 100644 --- a/build/lib/builtInExtensions.js +++ b/build/lib/builtInExtensions.js @@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getExtensionStream = getExtensionStream; exports.getBuiltInExtensions = getBuiltInExtensions; -exports.getBootstrapExtensions = getBootstrapExtensions; const fs = require("fs"); const path = require("path"); const os = require("os"); @@ -23,24 +22,16 @@ const builtInExtensions = productjson.builtInExtensions || []; const webBuiltInExtensions = productjson.webBuiltInExtensions || []; const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json'); const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE']; -// --- Start Positron --- -const bootstrapExtensions = productjson.bootstrapExtensions || []; -const bootstrapControlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'bootstrap-control.json'); -// --- End Positron --- function log(...messages) { if (ENABLE_LOGGING) { fancyLog(...messages); } } -// --- Start Positron --- -function getExtensionPath(extension, bootstrap = false) { - return path.join(root, '.build', bootstrap ? 'bootstrapExtensions' : 'builtInExtensions', extension.name); - // --- End Positron --- +function getExtensionPath(extension) { + return path.join(root, '.build', 'builtInExtensions', extension.name); } -// --- Start Positron --- -function isUpToDate(extension, bootstrap = false) { - const packagePath = path.join(getExtensionPath(extension, bootstrap), 'package.json'); - // --- End Positron --- +function isUpToDate(extension) { + const packagePath = path.join(getExtensionPath(extension), 'package.json'); if (!fs.existsSync(packagePath)) { return false; } @@ -53,9 +44,7 @@ function isUpToDate(extension, bootstrap = false) { return false; } } -// --- Start Positron --- -function getExtensionDownloadStream(extension, bootstrap = false) { - // --- End Positron --- +function getExtensionDownloadStream(extension) { // --- Start PWB: Bundle PWB extension --- // the PWB extension is a special case because it's not availble from the marketplace or github if (extension.name === 'rstudio.rstudio-workbench') { @@ -65,50 +54,32 @@ function getExtensionDownloadStream(extension, bootstrap = false) { // --- End PWB: Bundle PWB extension --- // --- Start Positron --- const url = extension.metadata.multiPlatformServiceUrl || productjson.extensionsGallery?.serviceUrl; - return (url ? ext.fromMarketplace(url, extension, bootstrap) : ext.fromGithub(extension)) - .pipe(rename(p => { - if (bootstrap) { - p.basename = `${extension.name}-${extension.version}.vsix`; - } - else { - p.dirname = `${extension.name}/${p.dirname}`; - } - })); - // --- End Positron --- + return (url ? ext.fromMarketplace(url, extension) : ext.fromGithub(extension)) + // --- End Positron --- + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } -// --- Start Positron --- -function getExtensionStream(extension, bootstrap = false) { +function getExtensionStream(extension) { // if the extension exists on disk, use those files instead of downloading anew - if (isUpToDate(extension, bootstrap)) { - // --- End Positron --- + if (isUpToDate(extension)) { log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } - // --- Start Positron --- - return getExtensionDownloadStream(extension, bootstrap); - // --- End Positron --- + return getExtensionDownloadStream(extension); } -// --- Start Positron --- -function syncMarketplaceExtension(extension, bootstrap = false) { +function syncMarketplaceExtension(extension) { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); - if (isUpToDate(extension, bootstrap)) { - // --- End Positron --- + if (isUpToDate(extension)) { log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); return es.readArray([]); } rimraf.sync(getExtensionPath(extension)); - // --- Start Positron --- - return getExtensionDownloadStream(extension, bootstrap) - .pipe(vfs.dest(bootstrap ? '.build/bootstrapExtensions' : '.build/builtInExtensions')) - // --- End Positron --- + return getExtensionDownloadStream(extension) + .pipe(vfs.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); } -// --- Start Positron --- -function syncExtension(extension, controlState, bootstrap = false) { - const description = bootstrap ? 'Bootstrap' : 'Built-in'; - // --- End Positron --- +function syncExtension(extension, controlState) { if (extension.platforms) { const platforms = new Set(extension.platforms); if (!platforms.has(process.platform)) { @@ -121,43 +92,31 @@ function syncExtension(extension, controlState, bootstrap = false) { log(ansiColors.blue('[disabled]'), ansiColors.gray(extension.name)); return es.readArray([]); case 'marketplace': - // --- Start Positron --- - return syncMarketplaceExtension(extension, bootstrap); - // --- End Positron --- + return syncMarketplaceExtension(extension); default: if (!fs.existsSync(controlState)) { - // --- Start Positron --- - log(ansiColors.red(`Error: ${description} extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); - // --- End Positron --- + log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); return es.readArray([]); } else if (!fs.existsSync(path.join(controlState, 'package.json'))) { - // --- Start Positron --- - log(ansiColors.red(`Error: ${description} extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); - // --- End Positron --- + log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); return es.readArray([]); } log(ansiColors.blue('[local]'), `${extension.name}: ${ansiColors.cyan(controlState)}`, ansiColors.green('✔︎')); return es.readArray([]); } } -// --- Start Positron --- -function readControlFile(filePath = controlFilePath) { - // --- End Positron --- +function readControlFile() { try { - // --- Start Positron --- - return JSON.parse(fs.readFileSync(filePath, 'utf8')); - // --- End Positron --- + return JSON.parse(fs.readFileSync(controlFilePath, 'utf8')); } catch (err) { return {}; } } -// --- Start Positron --- -function writeControlFile(control, filePath = controlFilePath) { - fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, JSON.stringify(control, null, 2)); - // --- End Positron --- +function writeControlFile(control) { + fs.mkdirSync(path.dirname(controlFilePath), { recursive: true }); + fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } function getBuiltInExtensions() { log('Synchronizing built-in extensions...'); @@ -185,29 +144,10 @@ function getBuiltInExtensions() { .on('end', resolve); }); } -// --- Start Positron --- -function getBootstrapExtensions() { - const control = readControlFile(bootstrapControlFilePath); - const streams = []; - for (const extension of [...bootstrapExtensions]) { - const controlState = control[extension.name] || 'marketplace'; - control[extension.name] = controlState; - streams.push(syncExtension(extension, controlState, true)); - } - writeControlFile(control, bootstrapControlFilePath); - return new Promise((resolve, reject) => { - es.merge(streams) - .on('error', reject) - .on('end', resolve); - }); -} if (require.main === module) { - Promise.all([getBuiltInExtensions(), getBootstrapExtensions()]) - .then(() => process.exit(0)) - .catch(err => { + getBuiltInExtensions().then(() => process.exit(0)).catch(err => { console.error(err); process.exit(1); }); } -// --- End Positron --- //# sourceMappingURL=builtInExtensions.js.map \ No newline at end of file diff --git a/build/lib/builtInExtensions.ts b/build/lib/builtInExtensions.ts index e7705461db9..1a376cbe9a7 100644 --- a/build/lib/builtInExtensions.ts +++ b/build/lib/builtInExtensions.ts @@ -46,27 +46,18 @@ const webBuiltInExtensions = productjson.webBuiltInExten const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json'); const ENABLE_LOGGING = !process.env['VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE']; -// --- Start Positron --- -const bootstrapExtensions = productjson.bootstrapExtensions || []; -const bootstrapControlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'bootstrap-control.json'); -// --- End Positron --- - function log(...messages: string[]): void { if (ENABLE_LOGGING) { fancyLog(...messages); } } -// --- Start Positron --- -function getExtensionPath(extension: IExtensionDefinition, bootstrap: boolean = false): string { - return path.join(root, '.build', bootstrap ? 'bootstrapExtensions' : 'builtInExtensions', extension.name); - // --- End Positron --- +function getExtensionPath(extension: IExtensionDefinition): string { + return path.join(root, '.build', 'builtInExtensions', extension.name); } -// --- Start Positron --- -function isUpToDate(extension: IExtensionDefinition, bootstrap: boolean = false): boolean { - const packagePath = path.join(getExtensionPath(extension, bootstrap), 'package.json'); - // --- End Positron --- +function isUpToDate(extension: IExtensionDefinition): boolean { + const packagePath = path.join(getExtensionPath(extension), 'package.json'); if (!fs.existsSync(packagePath)) { return false; @@ -82,9 +73,7 @@ function isUpToDate(extension: IExtensionDefinition, bootstrap: boolean = false) } } -// --- Start Positron --- -function getExtensionDownloadStream(extension: IExtensionDefinition, bootstrap: boolean = false) { - // --- End Positron --- +function getExtensionDownloadStream(extension: IExtensionDefinition) { // --- Start PWB: Bundle PWB extension --- // the PWB extension is a special case because it's not availble from the marketplace or github if (extension.name === 'rstudio.rstudio-workbench') { @@ -94,55 +83,38 @@ function getExtensionDownloadStream(extension: IExtensionDefinition, bootstrap: // --- End PWB: Bundle PWB extension --- // --- Start Positron --- const url = extension.metadata.multiPlatformServiceUrl || productjson.extensionsGallery?.serviceUrl; - return (url ? ext.fromMarketplace(url, extension, bootstrap) : ext.fromGithub(extension)) - .pipe(rename(p => { - if (bootstrap) { - p.basename = `${extension.name}-${extension.version}.vsix`; - } else { - p.dirname = `${extension.name}/${p.dirname}`; - } - })); - // --- End Positron --- + return (url ? ext.fromMarketplace(url, extension) : ext.fromGithub(extension)) + // --- End Positron --- + .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } -// --- Start Positron --- -export function getExtensionStream(extension: IExtensionDefinition, bootstrap: boolean = false) { +export function getExtensionStream(extension: IExtensionDefinition) { // if the extension exists on disk, use those files instead of downloading anew - if (isUpToDate(extension, bootstrap)) { - // --- End Positron --- + if (isUpToDate(extension)) { log('[extensions]', `${extension.name}@${extension.version} up to date`, ansiColors.green('✔︎')); return vfs.src(['**'], { cwd: getExtensionPath(extension), dot: true }) .pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`)); } - // --- Start Positron --- - return getExtensionDownloadStream(extension, bootstrap); - // --- End Positron --- + return getExtensionDownloadStream(extension); } -// --- Start Positron --- -function syncMarketplaceExtension(extension: IExtensionDefinition, bootstrap: boolean = false): Stream { +function syncMarketplaceExtension(extension: IExtensionDefinition): Stream { const galleryServiceUrl = productjson.extensionsGallery?.serviceUrl; const source = ansiColors.blue(galleryServiceUrl ? '[marketplace]' : '[github]'); - if (isUpToDate(extension, bootstrap)) { - // --- End Positron --- + if (isUpToDate(extension)) { log(source, `${extension.name}@${extension.version}`, ansiColors.green('✔︎')); return es.readArray([]); } rimraf.sync(getExtensionPath(extension)); - // --- Start Positron --- - return getExtensionDownloadStream(extension, bootstrap) - .pipe(vfs.dest(bootstrap ? '.build/bootstrapExtensions' : '.build/builtInExtensions')) - // --- End Positron --- + return getExtensionDownloadStream(extension) + .pipe(vfs.dest('.build/builtInExtensions')) .on('end', () => log(source, extension.name, ansiColors.green('✔︎'))); } -// --- Start Positron --- -function syncExtension(extension: IExtensionDefinition, controlState: 'disabled' | 'marketplace', bootstrap: boolean = false): Stream { - const description: string = bootstrap ? 'Bootstrap' : 'Built-in'; - // --- End Positron --- +function syncExtension(extension: IExtensionDefinition, controlState: 'disabled' | 'marketplace'): Stream { if (extension.platforms) { const platforms = new Set(extension.platforms); @@ -158,21 +130,15 @@ function syncExtension(extension: IExtensionDefinition, controlState: 'disabled' return es.readArray([]); case 'marketplace': - // --- Start Positron --- - return syncMarketplaceExtension(extension, bootstrap); - // --- End Positron --- + return syncMarketplaceExtension(extension); default: if (!fs.existsSync(controlState)) { - // --- Start Positron --- - log(ansiColors.red(`Error: ${description} extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); - // --- End Positron --- + log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`)); return es.readArray([]); } else if (!fs.existsSync(path.join(controlState, 'package.json'))) { - // --- Start Positron --- - log(ansiColors.red(`Error: ${description} extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); - // --- End Positron --- + log(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`)); return es.readArray([]); } @@ -185,23 +151,17 @@ interface IControlFile { [name: string]: 'disabled' | 'marketplace'; } -// --- Start Positron --- -function readControlFile(filePath: string = controlFilePath): IControlFile { - // --- End Positron --- +function readControlFile(): IControlFile { try { - // --- Start Positron --- - return JSON.parse(fs.readFileSync(filePath, 'utf8')); - // --- End Positron --- + return JSON.parse(fs.readFileSync(controlFilePath, 'utf8')); } catch (err) { return {}; } } -// --- Start Positron --- -function writeControlFile(control: IControlFile, filePath: string = controlFilePath): void { - fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, JSON.stringify(control, null, 2)); - // --- End Positron --- +function writeControlFile(control: IControlFile): void { + fs.mkdirSync(path.dirname(controlFilePath), { recursive: true }); + fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } export function getBuiltInExtensions(): Promise { @@ -237,36 +197,9 @@ export function getBuiltInExtensions(): Promise { }); } -// --- Start Positron --- - -export function getBootstrapExtensions(): Promise { - - const control = readControlFile(bootstrapControlFilePath); - const streams: Stream[] = []; - - for (const extension of [...bootstrapExtensions]) { - const controlState = control[extension.name] || 'marketplace'; - control[extension.name] = controlState; - - streams.push(syncExtension(extension, controlState, true)); - } - - writeControlFile(control, bootstrapControlFilePath); - - return new Promise((resolve, reject) => { - es.merge(streams) - .on('error', reject) - .on('end', resolve); - }); -} - if (require.main === module) { - Promise.all([getBuiltInExtensions(), getBootstrapExtensions()]) - .then(() => process.exit(0)) - .catch(err => { - console.error(err); - process.exit(1); - }); + getBuiltInExtensions().then(() => process.exit(0)).catch(err => { + console.error(err); + process.exit(1); + }); } - -// --- End Positron --- diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 531d9e6e52f..8f114bb9967 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -35,6 +35,7 @@ const buffer = require('gulp-buffer'); const jsoncParser = require("jsonc-parser"); const dependencies_1 = require("./dependencies"); const builtInExtensions_1 = require("./builtInExtensions"); +const bootstrapExtensions_1 = require("./bootstrapExtensions"); const getVersion_1 = require("./getVersion"); const fetch_1 = require("./fetch"); // --- Start Positron --- @@ -503,7 +504,7 @@ function packageMarketplaceExtensionsStream(forWeb) { function packageBootstrapExtensionsStream() { return es.merge(...bootstrapExtensions .map(extension => { - const src = (0, builtInExtensions_1.getExtensionStream)(extension, true).pipe(rename(p => { + const src = (0, bootstrapExtensions_1.getBootstrapExtensionStream)(extension).pipe(rename(p => { p.dirname = `extensions/bootstrap`; })); return src; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 8183cf34f0a..443186f8631 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -23,6 +23,7 @@ import * as jsoncParser from 'jsonc-parser'; import webpack = require('webpack'); import { getProductionDependencies } from './dependencies'; import { IExtensionDefinition, getExtensionStream } from './builtInExtensions'; +import { getBootstrapExtensionStream } from './bootstrapExtensions'; import { getVersion } from './getVersion'; import { fetchUrls, fetchGithub } from './fetch'; @@ -580,7 +581,7 @@ export function packageBootstrapExtensionsStream(): Stream { return es.merge( ...bootstrapExtensions .map(extension => { - const src = getExtensionStream(extension, true).pipe(rename(p => { + const src = getBootstrapExtensionStream(extension).pipe(rename(p => { p.dirname = `extensions/bootstrap`; })); return src; diff --git a/src/vs/platform/extensionManagement/node/positronBootstrapExtensionsInitializer.ts b/src/vs/platform/extensionManagement/node/positronBootstrapExtensionsInitializer.ts index a69ceaaed25..5e206d6c1f2 100644 --- a/src/vs/platform/extensionManagement/node/positronBootstrapExtensionsInitializer.ts +++ b/src/vs/platform/extensionManagement/node/positronBootstrapExtensionsInitializer.ts @@ -28,8 +28,11 @@ export class PositronBootstrapExtensionsInitializer extends Disposable { this.storageFilePath = join(this.getVSIXPath().fsPath, '.version'); const currentVersion = this.productService.positronVersion; + + this.logService.info('currentVersion:', currentVersion); const lastKnownVersion = existsSync(this.storageFilePath) ? readFileSync(this.storageFilePath, 'utf8').trim() : ''; + this.logService.info('lastKnownVersion:', lastKnownVersion); if (lastKnownVersion !== currentVersion) { this.logService.info('First launch after first install, upgrade, or downgrade. Installing bootstrapped extensions'); this.installVSIXOnStartup() @@ -43,6 +46,8 @@ export class PositronBootstrapExtensionsInitializer extends Disposable { .catch(error => { this.logService.error('Error installing bootstrapped extensions', getErrorMessage(error)); }); + } else { + this.logService.info('Subsequent launch, skipping bootstrapped extensions'); } }