diff --git a/package-lock.json b/package-lock.json index ab8d257..6880283 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-manager", - "version": "2.1.2", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-manager", - "version": "2.1.2", + "version": "2.2.0", "dependencies": { "axios": "^0.21.4", "child-process-promise": "^2.2.1", diff --git a/package.json b/package.json index 8944280..1ecb432 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "publisher": "mrsauravsahu", "icon": "resources/icon.png", "description": "Manage VSCode custom profiles with isolated settings and extensions", - "version": "2.1.2", + "version": "2.2.0", "repository": { "url": "https://github.com/mrsauravsahu/vscode-manager", "type": "git" diff --git a/src/commands/clone-profile.ts b/src/commands/clone-profile.ts index 0cca72e..d82b46c 100644 --- a/src/commands/clone-profile.ts +++ b/src/commands/clone-profile.ts @@ -9,7 +9,7 @@ import {Command} from '../types' export const cloneProfileCommand: Command = { name: commands.cloneProfile, - handler: ({provider, services: [_, __, commandGeneratorService]}) => async (customProfile: CustomProfile) => vscode.window.withProgress({ + handler: ({provider, services: {commandGeneratorService, commandMetaService}}) => async (customProfile: CustomProfile) => vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Clone', cancellable: false, @@ -30,8 +30,10 @@ export const cloneProfileCommand: Command = { await fs.promises.copyFile(path.join(originalProfilePath, 'data', 'User', 'settings.json'), path.join(clonedProfilePath, 'data', 'User', 'settings.json')) + const codeBin = await commandMetaService.getProgramBasedOnMetaAsync('code') + // Get extensions - const {command: getExtensionsCommand, shell} = commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(originalProfilePath, 'data')}' --extensions-dir '${path.join(originalProfilePath, 'extensions')}' --list-extensions`) + const {command: getExtensionsCommand, shell} = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(originalProfilePath, 'data')}' --extensions-dir '${path.join(originalProfilePath, 'extensions')}' --list-extensions`) progress.report({increment: 10, message: 'Retrieving extensions from old profile...'}) const getExtensionsCommandOutput = await child_process.exec(getExtensionsCommand, {shell}) @@ -50,7 +52,7 @@ export const cloneProfileCommand: Command = { }) ?? [] const installExtensionPromises = selectedExtensions.map(async extension => { - const {command: extensionInstallCommand, shell} = commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(clonedProfilePath, 'data')}' --extensions-dir '${path.join(clonedProfilePath, 'extensions')}' --install-extension ${extension}`) + const {command: extensionInstallCommand, shell} = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(clonedProfilePath, 'data')}' --extensions-dir '${path.join(clonedProfilePath, 'extensions')}' --install-extension ${extension}`) progress.report({ increment: 50, diff --git a/src/commands/create-profile.ts b/src/commands/create-profile.ts index 13783e2..3ec93af 100644 --- a/src/commands/create-profile.ts +++ b/src/commands/create-profile.ts @@ -9,7 +9,7 @@ import type {Command} from '../types' export const createProfileCommand: Command = { name: commands.createProfile, - handler: ({provider, services: [customProfileService, _, commandGeneratorService], treeView}) => async () => { + handler: ({provider, services: {customProfileService, commandGeneratorService}, treeView}) => async () => { const newProfileName = uniqueNamesGenerator({ dictionaries: [adjectives, animals], separator: '-', diff --git a/src/commands/delete-profile.ts b/src/commands/delete-profile.ts index dcc1602..6a41167 100644 --- a/src/commands/delete-profile.ts +++ b/src/commands/delete-profile.ts @@ -8,7 +8,7 @@ import {CustomProfile} from '../models/custom-profile' export const deleteProfileCommand: Command = { name: commands.deleteProfile, - handler: ({services: [customProfileService, ..._], treeView, provider}) => async (customProfile: CustomProfile) => { + handler: ({services: {customProfileService}, treeView, provider}) => async (customProfile: CustomProfile) => { const {name} = customProfile if (name === profiles.default) { await vscode.window.showErrorMessage('Cannot delete the default profile') diff --git a/src/commands/launch-profile.ts b/src/commands/launch-profile.ts index c05f8a4..1378d5f 100644 --- a/src/commands/launch-profile.ts +++ b/src/commands/launch-profile.ts @@ -9,11 +9,12 @@ import {Command, CustomProfileDetails} from '../types' export const launchProfileCommand: Command = { name: commands.launchProfile, - handler: ({services: [customProfileService, _, commandGeneratorService]}) => (arg: CustomProfile | {fsPath: string}) => vscode.window.withProgress({ + handler: ({services: {customProfileService, commandGeneratorService, commandMetaService}}) => (arg: CustomProfile | {fsPath: string}) => vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Launching Custom Profile', cancellable: false, }, async progress => { + const codeBin = await commandMetaService.getProgramBasedOnMetaAsync('code') if (arg instanceof CustomProfile) { // Custom profile launch const {name} = arg @@ -21,7 +22,7 @@ export const launchProfileCommand: Command = { if (name === 'default') { await child_process.exec('code -n') } else { - const {command: launchCommand, shell} = commandGeneratorService.generateCommand('code', + const {command: launchCommand, shell} = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(rootStoragePath, name, 'data')}' --extensions-dir '${path.join(rootStoragePath, name, 'extensions')}' -n`) await child_process.exec(launchCommand, {shell}) } @@ -83,7 +84,7 @@ export const launchProfileCommand: Command = { progress.report({increment: 50, message: 'installing extensions...'}) const installExtensionPromises = extensions.map(async extension => { - const {command: extensionInstallCommand, shell} = commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' --install-extension ${extension}`) + const {command: extensionInstallCommand, shell} = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' --install-extension ${extension}`) return child_process.exec(extensionInstallCommand, {shell}) }) @@ -91,7 +92,7 @@ export const launchProfileCommand: Command = { await Promise.all(installExtensionPromises) const launchCommand - = commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' -n`) + = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' -n`) await child_process.exec(launchCommand.command, {shell: launchCommand.shell}) } else { @@ -99,7 +100,7 @@ export const launchProfileCommand: Command = { const profileDetailsJsonString = JSON.stringify(profileDetailsJson, undefined, 2) if (profileDetailsJsonString === alreadyPresentJsonString) { - const launchCommand = commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' -n`) + const launchCommand = commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(rootStoragePath, profileName, 'extensions')}' -n`) await child_process.exec(launchCommand.command, {shell: launchCommand.shell}) } else { await vscode.window.showInformationMessage('Please use a different name. Another profile with the same name already exists, but with different settings.') diff --git a/src/commands/refresh-profiles.ts b/src/commands/refresh-profiles.ts index 55ca9ac..8f7457c 100644 --- a/src/commands/refresh-profiles.ts +++ b/src/commands/refresh-profiles.ts @@ -3,7 +3,7 @@ import {Command} from '../types' export const refreshProfilesCommand: Command = { name: commands.refreshProfiles, - handler: ({treeView, provider, services: [customProfileService, ..._]}) => () => { + handler: ({treeView, provider, services: {customProfileService}}) => () => { provider.refresh() treeView.message = customProfileService.getAll().length === 0 ? strings.noProfiles : undefined diff --git a/src/commands/rename-profile.ts b/src/commands/rename-profile.ts index f3d40fe..74725e7 100644 --- a/src/commands/rename-profile.ts +++ b/src/commands/rename-profile.ts @@ -8,7 +8,7 @@ import {Command} from '../types' export const renameProfileCommand: Command = { name: commands.renameProfile, - handler: ({services: [_, __, commandGeneratorService]}) => async (customProfile: CustomProfile) => { + handler: ({services: {commandGeneratorService}}) => async (customProfile: CustomProfile) => { const {name} = customProfile const value = await vscode.window.showInputBox({ diff --git a/src/extension.ts b/src/extension.ts index b6787ba..9003d80 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,13 +10,15 @@ import {FeaturedProfileService} from './services/featured-profile.service' import {FeaturedProfilesProvider} from './providers/featured-profiles.provider' import {FeaturedProfileContentProvider} from './providers/featured-profile-content.provider' import {CommandGeneratorService} from './services/command-generator.service' +import {CommandMetaService} from './services/command-meta.service' // This method is called when your extension is activated // your extension is activated the very first time the command is executed export async function activate(context: vscode.ExtensionContext) { // TODO: Make rootPath cross platform + const commandMetaService = new CommandMetaService() const commandGeneratorService = new CommandGeneratorService() - const customProfileService = new CustomProfileService(commandGeneratorService) + const customProfileService = new CustomProfileService(commandGeneratorService, commandMetaService) const customProfilesProvider = new CustomProfilesProvider(context, customProfileService) vscode.window.registerTreeDataProvider('customProfiles', customProfilesProvider) @@ -45,8 +47,8 @@ export async function activate(context: vscode.ExtensionContext) { customProfilesProvider.refresh() /* FEATURED PROFILES SECTION */ - const featuredProfilesService = new FeaturedProfileService() - const featuredProfilesProvider = new FeaturedProfilesProvider(featuredProfilesService) + const featuredProfileService = new FeaturedProfileService() + const featuredProfilesProvider = new FeaturedProfilesProvider(featuredProfileService) vscode.window.createTreeView(constants.views.featuredProfiles, { treeDataProvider: featuredProfilesProvider, }) @@ -54,7 +56,7 @@ export async function activate(context: vscode.ExtensionContext) { await featuredProfilesProvider.refresh() context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(constants.uriSchemes.featuredProfile, - new FeaturedProfileContentProvider(featuredProfilesService), + new FeaturedProfileContentProvider(featuredProfileService), )) // Register commands @@ -64,7 +66,12 @@ export async function activate(context: vscode.ExtensionContext) { command.handler({ context, provider: customProfilesProvider, - services: [customProfileService, featuredProfilesService, commandGeneratorService], + services: { + customProfileService, + featuredProfileService, + commandGeneratorService, + commandMetaService, + }, treeView: customProfilesExplorer, }), ) diff --git a/src/services/command-meta.service.ts b/src/services/command-meta.service.ts new file mode 100644 index 0000000..a1c297e --- /dev/null +++ b/src/services/command-meta.service.ts @@ -0,0 +1,15 @@ +import * as vscode from 'vscode' + +export class CommandMetaService { + async getProgramBasedOnMetaAsync(programName: string): Promise { + if (programName === 'code') { + if (vscode.env.appName === 'Visual Studio Code - Insiders') { + return 'code-insiders' + } + + return 'code' + } + + return programName + } +} diff --git a/src/services/custom-profile.service.ts b/src/services/custom-profile.service.ts index d7daaba..0ceddf6 100644 --- a/src/services/custom-profile.service.ts +++ b/src/services/custom-profile.service.ts @@ -6,9 +6,11 @@ import * as json5 from 'json5' import * as constants from '../constants' import {CustomProfile} from '../models/custom-profile' import {CommandGeneratorService} from './command-generator.service' +import {CommandMetaService} from './command-meta.service' export class CustomProfileService { - public constructor(private readonly commandGeneratorService: CommandGeneratorService) {} + public constructor(private readonly commandGeneratorService: CommandGeneratorService, + private readonly commandMetaService: CommandMetaService) {} getAll(): CustomProfile[] { const {rootStoragePath} = constants @@ -60,8 +62,10 @@ export class CustomProfileService { await vscode.window.showInformationMessage('The profile contains invalid user settings.') } + const codeBin = await this.commandMetaService.getProgramBasedOnMetaAsync('code') + // Get extensions - const {command: getExtensionsCommand, shell} = this.commandGeneratorService.generateCommand('code', `--user-data-dir '${path.join(constants.rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(constants.rootStoragePath, profileName, 'extensions')}' --list-extensions`) + const {command: getExtensionsCommand, shell} = this.commandGeneratorService.generateCommand(codeBin, `--user-data-dir '${path.join(constants.rootStoragePath, profileName, 'data')}' --extensions-dir '${path.join(constants.rootStoragePath, profileName, 'extensions')}' --list-extensions`) const getExtensionsCommandOutput = await child_process.exec(getExtensionsCommand, {shell}) const extensions = getExtensionsCommandOutput .stdout diff --git a/src/types.ts b/src/types.ts index 8e3eae9..86500c3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,6 +3,7 @@ import * as vscode from 'vscode' import {CustomProfilesProvider} from './custom-profile-tree' import {CustomProfile} from './models/custom-profile' import {CommandGeneratorService} from './services/command-generator.service' +import {CommandMetaService} from './services/command-meta.service' import {CustomProfileService} from './services/custom-profile.service' import {FeaturedProfileService} from './services/featured-profile.service' @@ -16,7 +17,12 @@ export type HandlerArgs = { context: vscode.ExtensionContext; treeView: vscode.TreeView; provider: CustomProfilesProvider; - services: [CustomProfileService, FeaturedProfileService, CommandGeneratorService]; + services: { + customProfileService: CustomProfileService; + featuredProfileService: FeaturedProfileService; + commandGeneratorService: CommandGeneratorService; + commandMetaService: CommandMetaService; + }; } export type CommandHandler = ((args: HandlerArgs) => (...args: any[]) => any)