diff --git a/cli/src/bin/code/legacy_args.rs b/cli/src/bin/code/legacy_args.rs index 6a533426608..3f134443641 100644 --- a/cli/src/bin/code/legacy_args.rs +++ b/cli/src/bin/code/legacy_args.rs @@ -60,6 +60,7 @@ pub fn try_parse_legacy( // Now translate them to subcommands. // --list-extensions -> ext list + // --update-extensions -> update // --install-extension=id -> ext install // --uninstall-extension=id -> ext uninstall // --status -> status @@ -87,6 +88,14 @@ pub fn try_parse_legacy( })), ..Default::default() }) + } else if let Some(_exts) = args.remove("update-extensions") { + Some(CliCore { + subcommand: Some(Commands::Extension(ExtensionArgs { + subcommand: ExtensionSubcommand::Update, + desktop_code_options, + })), + ..Default::default() + }) } else if let Some(exts) = args.remove("uninstall-extension") { Some(CliCore { subcommand: Some(Commands::Extension(ExtensionArgs { diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index 7863635ae99..6b0017a3488 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -254,6 +254,8 @@ pub enum ExtensionSubcommand { Install(InstallExtensionArgs), /// Uninstall an extension. Uninstall(UninstallExtensionArgs), + /// Update the marketplace-installed extensions. + Update, } impl ExtensionSubcommand { @@ -284,6 +286,9 @@ impl ExtensionSubcommand { target.push(format!("--uninstall-extension={}", id)); } } + ExtensionSubcommand::Update => { + target.push("--update-extensions".to_string()); + } } } } diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 06e42681799..27d8bed1845 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -58,6 +58,7 @@ pub struct CodeServerArgs { // extension management pub install_extensions: Vec, pub uninstall_extensions: Vec, + pub update_extensions: bool, pub list_extensions: bool, pub show_versions: bool, pub category: Option, @@ -129,6 +130,9 @@ impl CodeServerArgs { for extension in &self.uninstall_extensions { args.push(format!("--uninstall-extension={}", extension)); } + if self.update_extensions { + args.push(String::from("--update-extensions")); + } if self.list_extensions { args.push(String::from("--list-extensions")); if self.show_versions { diff --git a/resources/completions/bash/code b/resources/completions/bash/code index 9f1b3d682d3..d141c297b96 100644 --- a/resources/completions/bash/code +++ b/resources/completions/bash/code @@ -49,7 +49,7 @@ _@@APPNAME@@() --list-extensions --show-versions --install-extension --uninstall-extension --enable-proposed-api --verbose --log -s --status -p --performance --prof-startup --disable-extensions - --disable-extension --inspect-extensions + --disable-extension --inspect-extensions --update-extensions --inspect-brk-extensions --disable-gpu' -- "$cur") ) [[ $COMPREPLY == *= ]] && compopt -o nospace return diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 97d163c13c3..46a0e019680 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -21,6 +21,7 @@ arguments=( '--show-versions[show versions of installed extensions, when using --list-extensions]' '--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"' '--uninstall-extension[uninstall an extension]:id or path:_files -g "*.vsix(-.)"' + '--update-extensions[update the marketplace-installed extensions]' '--enable-proposed-api[enables proposed API features for extensions]::extension id: ' '--verbose[print verbose output (implies --wait)]' '--log[log level to use]:level [info]:(critical error warn info debug trace off)' diff --git a/src/server-main.js b/src/server-main.js index 5167527baed..81e88e118f7 100644 --- a/src/server-main.js +++ b/src/server-main.js @@ -20,7 +20,7 @@ async function start() { // Do a quick parse to determine if a server or the cli needs to be started const parsedArgs = minimist(process.argv.slice(2), { - boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms'], + boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'], string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'compatibility'], alias: { help: 'h', version: 'v' } }); @@ -34,7 +34,7 @@ async function start() { }); const extensionLookupArgs = ['list-extensions', 'locate-extension']; - const extensionInstallArgs = ['install-extension', 'install-builtin-extension', 'uninstall-extension']; + const extensionInstallArgs = ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'update-extensions']; const shouldSpawnCli = parsedArgs.help || parsedArgs.version || extensionLookupArgs.some(a => !!parsedArgs[a]) || (extensionInstallArgs.some(a => !!parsedArgs[a]) && !parsedArgs['start-server']); diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 4770e9ef0bd..89265911347 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -33,6 +33,7 @@ function shouldSpawnCliProcess(argv: NativeParsedArgs): boolean { || !!argv['list-extensions'] || !!argv['install-extension'] || !!argv['uninstall-extension'] + || !!argv['update-extensions'] || !!argv['locate-extension'] || !!argv['telemetry']; } diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index b2861976c11..b91367f1fc2 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -280,6 +280,10 @@ class CliMain extends Disposable { return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).uninstallExtensions(this.asExtensionIdOrVSIX(this.argv['uninstall-extension']), !!this.argv['force'], profileLocation); } + else if (this.argv['update-extensions']) { + return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).updateExtensions(profileLocation); + } + // Locate Extension else if (this.argv['locate-extension']) { return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).locateExtension(this.argv['locate-extension']); diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index f205cc30439..8b9f9100b05 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -82,6 +82,7 @@ export interface NativeParsedArgs { 'pre-release'?: boolean; 'install-builtin-extension'?: string[]; // undefined or array of 1 or more 'uninstall-extension'?: string[]; // undefined or array of 1 or more + 'update-extensions'?: boolean; 'locate-extension'?: string[]; // undefined or array of 1 or more 'enable-proposed-api'?: string[]; // undefined or array of 1 or more 'open-url'?: boolean; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 79046c7fa20..8ffc1c4a775 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -100,6 +100,7 @@ export const OPTIONS: OptionDescriptions> = { 'install-extension': { type: 'string[]', cat: 'e', args: 'ext-id | path', description: localize('installExtension', "Installs or updates an extension. The argument is either an extension id or a path to a VSIX. The identifier of an extension is '${publisher}.${name}'. Use '--force' argument to update to latest version. To install a specific version provide '@${version}'. For example: 'vscode.csharp@1.2.3'.") }, 'pre-release': { type: 'boolean', cat: 'e', description: localize('install prerelease', "Installs the pre-release version of the extension, when using --install-extension") }, 'uninstall-extension': { type: 'string[]', cat: 'e', args: 'ext-id', description: localize('uninstallExtension', "Uninstalls an extension.") }, + 'update-extensions': { type: 'boolean', cat: 'e', description: localize('updateExtensions', "Update the marketplace-installed extensions.") }, 'enable-proposed-api': { type: 'string[]', allowEmptyValue: true, cat: 'e', args: 'ext-id', description: localize('experimentalApis', "Enables proposed API features for extensions. Can receive one or more extension IDs to enable individually.") }, 'version': { type: 'boolean', cat: 't', alias: 'v', description: localize('version', "Print version.") }, diff --git a/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts b/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts index 1515c45cca2..046ba0df740 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts @@ -172,6 +172,10 @@ export class ExtensionManagementCLI { } } + public async updateExtensions(profileLocation?: URI): Promise { + this.logger.info("Update extensions: TODO"); + } + private async installVSIX(vsix: URI, installOptions: InstallOptions, force: boolean, installedExtensions: ILocalExtension[]): Promise { const manifest = await this.extensionManagementService.getManifest(vsix); diff --git a/src/vs/server/node/remoteExtensionHostAgentCli.ts b/src/vs/server/node/remoteExtensionHostAgentCli.ts index 5f6c64c3a1d..6960a2d4424 100644 --- a/src/vs/server/node/remoteExtensionHostAgentCli.ts +++ b/src/vs/server/node/remoteExtensionHostAgentCli.ts @@ -159,6 +159,11 @@ class CliMain extends Disposable { return extensionManagementCLI.uninstallExtensions(this.asExtensionIdOrVSIX(this.args['uninstall-extension']), !!this.args['force']); } + // Update the marketplace-installed extensions + else if (this.args['update-extensions']) { + return extensionManagementCLI.updateExtensions(); + } + // Locate Extension else if (this.args['locate-extension']) { return extensionManagementCLI.locateExtension(this.args['locate-extension']); diff --git a/src/vs/server/node/server.cli.ts b/src/vs/server/node/server.cli.ts index 10e1acbb917..22e77753062 100644 --- a/src/vs/server/node/server.cli.ts +++ b/src/vs/server/node/server.cli.ts @@ -67,6 +67,7 @@ const isSupportedForPipe = (optionId: keyof RemoteParsedArgs) => { case 'status': case 'install-extension': case 'uninstall-extension': + case 'update-extensions': case 'list-extensions': case 'force': case 'show-versions': @@ -217,7 +218,7 @@ export async function main(desc: ProductDescription, args: string[]): Promise cmdLine.push('--install-extension', id)); parsedArgs['uninstall-extension']?.forEach(id => cmdLine.push('--uninstall-extension', id)); @@ -227,6 +228,9 @@ export async function main(desc: ProductDescription, args: string[]): Promise console.log(err)); @@ -293,7 +297,7 @@ export async function main(desc: ProductDescription, args: string[]): Promise> = { 'builtin-extensions-dir': OPTIONS['builtin-extensions-dir'], 'install-extension': OPTIONS['install-extension'], 'install-builtin-extension': OPTIONS['install-builtin-extension'], + 'update-extensions': OPTIONS['update-extensions'], 'uninstall-extension': OPTIONS['uninstall-extension'], 'list-extensions': OPTIONS['list-extensions'], 'locate-extension': OPTIONS['locate-extension'], @@ -177,6 +178,7 @@ export interface ServerParsedArgs { 'builtin-extensions-dir'?: string; 'install-extension'?: string[]; 'install-builtin-extension'?: string[]; + 'update-extensions'?: boolean; 'uninstall-extension'?: string[]; 'list-extensions'?: boolean; 'locate-extension'?: string[];