diff --git a/CHANGELOG.md b/CHANGELOG.md index a43acb5..fcc878f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log (vscode-deploy-reloaded) -## 0.1.1 (December 27th, 2017; initial release) +## 0.2.0 (December 27th, 2017; improvements and bugfixes) + +* bugfixes +* improved displaying [packages](https://github.com/mkloubert/vscode-deploy-reloaded/wiki#packages-) and [targets](https://github.com/mkloubert/vscode-deploy-reloaded/wiki#targets-) in the GUI + +## 0.1.2 (December 27th, 2017; initial release) For more information about the extension, that a look at the [project page](https://github.com/mkloubert/vscode-deploy-reloaded) or the [wiki](https://github.com/mkloubert/vscode-deploy-reloaded/wiki). diff --git a/package-lock.json b/package-lock.json index 800a052..4906897 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vscode-deploy-reloaded", - "version": "0.1.2", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8978777..aaaa098 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-deploy-reloaded", "displayName": "Deploy (Reloaded)", "description": "Deploys files of a workspace to a destination.", - "version": "0.1.2", + "version": "0.2.0", "publisher": "mkloubert", "engines": { "vscode": "^1.19.0" diff --git a/src/extension.ts b/src/extension.ts index 4b37589..e08b7d5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -72,6 +72,40 @@ function getActiveWorkspacesOrAll() { return listOfWorkspaces.map(ws => ws); } +function getAllWorkspacesSorted() { + return Enumerable.from( WORKSPACES ).orderBy(ws => { + return ws.isActive ? 0 : 1; + }).thenBy(ws => { + return deploy_helpers.normalizeString(ws.name); + }).thenBy(ws => { + return deploy_helpers.normalizeString(ws.rootPath); + }).toArray(); +} + +function getAllPackagesSorted() { + return Enumerable.from( getAllWorkspacesSorted() ).selectMany(ws => { + return Enumerable.from( ws.getPackages() ).orderBy(pkg => { + return deploy_helpers.normalizeString( + deploy_packages.getPackageName(pkg) + ); + }).thenBy(pkg => { + return pkg.__index; + }); + }).toArray(); +} + +function getAllTargetsSorted() { + return Enumerable.from( getAllWorkspacesSorted() ).selectMany(ws => { + return Enumerable.from( ws.getTargets() ).orderBy(t => { + return deploy_helpers.normalizeString( + deploy_targets.getTargetName(t) + ); + }).thenBy(t => { + return t.__index; + }); + }).toArray(); +} + async function invokeForActiveEditor(placeHolder: string, action: (file: string, target: deploy_targets.Target) => any) { const ACTIVE_EDITOR = vscode.window.activeTextEditor; @@ -134,50 +168,6 @@ async function invokeForActiveEditor(placeHolder: string, } } -async function invokeForActivePackage(placeHolder: string, - action: (pkg: deploy_packages.Package) => any) { - const PACKAGES = getActivePackages(); - - const QUICK_PICK_ITEMS: deploy_contracts.ActionQuickPick[] = PACKAGES.map((p, i) => { - return { - action: async () => { - if (action) { - await Promise.resolve( - action(p) - ); - } - }, - description: deploy_helpers.toStringSafe( p.description ).trim(), - detail: p.__workspace.folder.uri.fsPath, - label: deploy_packages.getPackageName(p), - }; - }); - - if (QUICK_PICK_ITEMS.length < 1) { - deploy_helpers.showWarningMessage( - i18.t('packages.noneFound') - ); - - return; - } - - let selectedItem: deploy_contracts.ActionQuickPick; - if (1 === QUICK_PICK_ITEMS.length) { - selectedItem = QUICK_PICK_ITEMS[0]; - } - else { - selectedItem = await vscode.window.showQuickPick(QUICK_PICK_ITEMS, { - placeHolder: placeHolder, - }); - } - - if (selectedItem) { - await Promise.resolve( - selectedItem.action() - ); - } -} - function normalizeActiveWorkspaces(aws: deploy_workspaces.Workspace | deploy_workspaces.Workspace[]) { aws = deploy_helpers.asArray(aws); @@ -299,6 +289,7 @@ async function reloadWorkspaceFolders(added: vscode.WorkspaceFolder[], removed?: for (let i = 0; i < WORKSPACES.length; ) { const WS = WORKSPACES[i]; let removeWorkspace = false; + let hasBeenRemoved = false; for (let rws of removed) { if (Path.resolve(rws.uri.fsPath) === Path.resolve(WS.folder.uri.fsPath)) { @@ -310,8 +301,13 @@ async function reloadWorkspaceFolders(added: vscode.WorkspaceFolder[], removed?: if (removeWorkspace) { if (deploy_helpers.tryDispose(WS)) { WORKSPACES.splice(i, 1); + hasBeenRemoved = true; } } + + if (!hasBeenRemoved) { + ++i; + } } } @@ -679,7 +675,7 @@ async function activateExtension(context: vscode.ExtensionContext) { outputChannel.appendLine(''); outputChannel.appendLine(`GitHub : https://github.com/mkloubert/vscode-deploy-reloaded`); outputChannel.appendLine(`Twitter: https://twitter.com/mjkloubert`); - outputChannel.appendLine(`Donate : [PayPal] https://paypal.me/MarcelKloubert`); + outputChannel.appendLine(`Donate : https://paypal.me/MarcelKloubert`); }); // commands @@ -755,13 +751,17 @@ async function activateExtension(context: vscode.ExtensionContext) { // deploy workspace vscode.commands.registerCommand('extension.deploy.reloaded.deployWorkspace', async () => { try { - await invokeForActivePackage( - i18.t('packages.selectPackage'), - async (pkg) => { - await pkg.__workspace - .deployPackage(pkg); + const PKG = await deploy_packages.showPackageQuickPick( + getAllPackagesSorted(), + { + placeHolder: i18.t('packages.selectPackage'), } ); + + if (PKG) { + await PKG.__workspace + .deployPackage(PKG); + } } catch (e) { deploy_log.CONSOLE @@ -835,13 +835,17 @@ async function activateExtension(context: vscode.ExtensionContext) { // pull workspace vscode.commands.registerCommand('extension.deploy.reloaded.pullWorkspace', async () => { try { - await invokeForActivePackage( - i18.t('packages.selectPackage'), - async (pkg) => { - await pkg.__workspace - .pullPackage(pkg); + const PKG = await deploy_packages.showPackageQuickPick( + getAllPackagesSorted(), + { + placeHolder: i18.t('packages.selectPackage'), } ); + + if (PKG) { + await PKG.__workspace + .pullPackage(PKG); + } } catch (e) { deploy_log.CONSOLE @@ -914,13 +918,17 @@ async function activateExtension(context: vscode.ExtensionContext) { // delete package vscode.commands.registerCommand('extension.deploy.reloaded.deletePackage', async () => { try { - await invokeForActivePackage( - i18.t('packages.selectPackage'), - async (pkg) => { - await pkg.__workspace - .deletePackage(pkg); + const PKG = await deploy_packages.showPackageQuickPick( + getAllPackagesSorted(), + { + placeHolder: i18.t('packages.selectPackage'), } ); + + if (PKG) { + await PKG.__workspace + .deletePackage(PKG); + } } catch (e) { deploy_log.CONSOLE @@ -956,25 +964,17 @@ async function activateExtension(context: vscode.ExtensionContext) { // list directory vscode.commands.registerCommand('extension.deploy.reloaded.listDirectory', async () => { try { - let workspacesWithTargets = activeWorkspaces; - if (workspacesWithTargets.length < 1) { - workspacesWithTargets = WORKSPACES; - } - - const TARGETS = Enumerable.from(workspacesWithTargets).selectMany(ws => { - return ws.getTargets(); - }).where(t => { - return t.__workspace.getListPlugins(t).length > 0; - }).toArray(); - - await deploy_targets.showTargetQuickPick( - TARGETS, - i18.t('listDirectory.selectSource'), - async (target) => { - await target.__workspace - .listDirectory(target); + const TARGET = await deploy_targets.showTargetQuickPick( + getAllTargetsSorted(), + { + placeHolder: i18.t('listDirectory.selectSource'), } ); + + if (TARGET) { + await TARGET.__workspace + .listDirectory(TARGET); + } } catch (e) { deploy_log.CONSOLE @@ -991,7 +991,7 @@ async function activateExtension(context: vscode.ExtensionContext) { try { await deploy_tools_quick_execution._1b87f2ee_b636_45b6_807c_0e2d25384b02_1409614337( currentContext, - WORKSPACES.map(ws => ws), + getAllWorkspacesSorted(), activeWorkspaces.map(aws => aws), ); } diff --git a/src/packages.ts b/src/packages.ts index 0215282..a745d2e 100644 --- a/src/packages.ts +++ b/src/packages.ts @@ -21,6 +21,7 @@ import * as deploy_log from './log'; import * as deploy_targets from './targets'; import * as deploy_workspaces from './workspaces'; import * as Enumerable from 'node-enumerable'; +import * as i18 from './i18'; import * as Moment from 'moment'; import * as Path from 'path'; import * as UUID from 'uuid'; @@ -345,3 +346,48 @@ export function getTargetsOfPackage(pkg: Package): deploy_targets.Target[] | fal return targets; } + +/** + * Shows a quick pick for a list of packages. + * + * @param {Package|Package[]} packages One or more packages. + * @param {vscode.QuickPickOptions} [opts] Custom options for the quick picks. + * + * @return {Promise} The promise that contains the selected package (if selected) + * or (false) if no package is available. + */ +export async function showPackageQuickPick(packages: Package | Package[], + opts?: vscode.QuickPickOptions): Promise { + const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = deploy_helpers.asArray(packages).map(pkg => { + const WORKSPACE = pkg.__workspace; + + return { + label: getPackageName(pkg), + description: deploy_helpers.toStringSafe(pkg.description), + detail: WORKSPACE.rootPath, + state: pkg, + }; + }); + + if (QUICK_PICKS.length < 1) { + deploy_helpers.showWarningMessage( + i18.t('packages.noneFound') + ); + + return false; + } + + let selectedItem: deploy_contracts.ActionQuickPick; + if (1 === QUICK_PICKS.length) { + selectedItem = QUICK_PICKS[0]; + } + else { + selectedItem = await vscode.window.showQuickPick( + QUICK_PICKS, opts + ); + } + + if (selectedItem) { + return selectedItem.state; + } +} diff --git a/src/targets.ts b/src/targets.ts index 1674e7a..4b792d9 100644 --- a/src/targets.ts +++ b/src/targets.ts @@ -653,63 +653,47 @@ export function normalizeTargetType(target: Target): string { } /** - * Shows a quick for targets. + * Shows a quick pick for a list of targets. * - * @param {TTarget|TTarget[]} targets One or more target. - * @param {string} placeHolder The placeholder. - * @param {Function} action The action to invoke. - * @param {TNoTargets} [ifNoTargets] The custom value to return if no target was found. + * @param {Target|Target[]} targets One or more targets. + * @param {vscode.QuickPickOptions} [opts] Custom options for the quick picks. * - * @return {TResult|TNoTargets|void} The result of the action (if available) or 'ifNoTargets' if no target has been found. + * @return {Promise} The promise that contains the selected target (if selected) + * or (false) if no target is available. */ -export async function showTargetQuickPick( - targets: TTarget | TTarget[], - placeHolder: string, - action: (target: TTarget) => TResult, - ifNoTargets: TNoTargets = false, -): Promise -{ - targets = deploy_helpers.asArray(targets) - .filter(t => deploy_helpers.isObject(t)); - - const QUICK_PICK_ITEMS: deploy_contracts.ActionQuickPick[] = targets.map(t => { +export async function showTargetQuickPick(targets: Target | Target[], + opts?: vscode.QuickPickOptions): Promise { + const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = deploy_helpers.asArray(targets).map(t => { + const WORKSPACE = t.__workspace; + return { - action: async () => { - if (action) { - await Promise.resolve( - action(t) - ) - } - }, - description: deploy_helpers.toStringSafe( t.description ).trim(), - detail: `${t.__workspace.name} (${t.__workspace.rootPath})`, label: getTargetName(t), + description: deploy_helpers.toStringSafe(t.description), + detail: WORKSPACE.rootPath, + state: t, }; }); - if (QUICK_PICK_ITEMS.length < 1) { + if (QUICK_PICKS.length < 1) { deploy_helpers.showWarningMessage( i18.t('targets.noneFound') ); - - return ifNoTargets; + + return false; } - let selectedItem: deploy_contracts.ActionQuickPick; - - if (1 === QUICK_PICK_ITEMS.length) { - selectedItem = QUICK_PICK_ITEMS[0]; + let selectedItem: deploy_contracts.ActionQuickPick; + if (1 === QUICK_PICKS.length) { + selectedItem = QUICK_PICKS[0]; } else { - selectedItem = await vscode.window.showQuickPick(QUICK_PICK_ITEMS, { - placeHolder: deploy_helpers.toStringSafe(placeHolder), - }); + selectedItem = await vscode.window.showQuickPick( + QUICK_PICKS, opts + ); } if (selectedItem) { - return await Promise.resolve( - selectedItem.action(), - ); + return selectedItem.state; } } diff --git a/src/tools.ts b/src/tools.ts index 9195276..15bfb90 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -636,96 +636,99 @@ exports.execute = function(args) { if (SELECTED_ITEM) { if (1 === SELECTED_ITEM.value) { - await deploy_targets.showTargetQuickPick( + const selectedTarget = await deploy_targets.showTargetQuickPick( WORKSPACE_TARGETS, - selectedWorkspace.t('tools.createDeployOperationScript.selectTarget'), - async (selectedTarget) => { - const CFG = selectedWorkspace.config; - - const TARGETS_FROM_CFG = deploy_helpers.asArray( - CFG.targets - ); + { + placeHolder: selectedWorkspace.t('tools.createDeployOperationScript.selectTarget') + } + ); - const CLONED_CFG = deploy_helpers.cloneObjectWithoutFunctions(CFG); - (CLONED_CFG).targets = deploy_helpers.cloneObject(TARGETS_FROM_CFG); + if (selectedTarget) { + const CFG = selectedWorkspace.config; - const SETTINGS_FILE = Path.resolve( - selectedWorkspace.configSource.resource.fsPath, - ); - const SETTINGS_SECTION = selectedWorkspace.configSource.section; + const TARGETS_FROM_CFG = deploy_helpers.asArray( + CFG.targets + ); - const CLONED_TARGETS_FROM_CFG = deploy_helpers.asArray( - CLONED_CFG.targets - ); + const CLONED_CFG = deploy_helpers.cloneObjectWithoutFunctions(CFG); + (CLONED_CFG).targets = deploy_helpers.cloneObject(TARGETS_FROM_CFG); - let targetScriptPath = scriptFile; - if (scriptFile.startsWith(selectedWorkspace.settingFolder)) { - targetScriptPath = './' + deploy_helpers.normalizePath( - scriptFile.substr(selectedWorkspace.settingFolder.length) - ); - } + const SETTINGS_FILE = Path.resolve( + selectedWorkspace.configSource.resource.fsPath, + ); + const SETTINGS_SECTION = selectedWorkspace.configSource.section; - let operationStorage: deploy_targets.TargetOperationValue[] | false = false; - let updater: () => void; - - const TARGET_ITEM_FROM_CLONED_CFG = CLONED_TARGETS_FROM_CFG[selectedTarget.__index]; - if (TARGET_ITEM_FROM_CLONED_CFG) { - switch (operationEvent) { - case deploy_targets.TargetOperationEvent.AfterDeployed: - operationStorage = deploy_helpers.asArray(TARGET_ITEM_FROM_CLONED_CFG.deployed); - updater = () => { - (TARGET_ITEM_FROM_CLONED_CFG).deployed = operationStorage; - }; - break; - - case deploy_targets.TargetOperationEvent.BeforeDeploy: - operationStorage = deploy_helpers.asArray(TARGET_ITEM_FROM_CLONED_CFG.beforeDeploy); - updater = () => { - (TARGET_ITEM_FROM_CLONED_CFG).beforeDeploy = operationStorage; - }; - break; - } - } + const CLONED_TARGETS_FROM_CFG = deploy_helpers.asArray( + CLONED_CFG.targets + ); - if (false === operationStorage) { - return; - } + let targetScriptPath = scriptFile; + if (scriptFile.startsWith(selectedWorkspace.settingFolder)) { + targetScriptPath = './' + deploy_helpers.normalizePath( + scriptFile.substr(selectedWorkspace.settingFolder.length) + ); + } - let newTargetOperationName = await vscode.window.showInputBox({ - placeHolder: selectedWorkspace.t('tools.createDeployOperationScript.askForNewOperationName'), - }); - newTargetOperationName = deploy_helpers.toStringSafe(newTargetOperationName).trim(); - if ('' === newTargetOperationName) { - newTargetOperationName = undefined; + let operationStorage: deploy_targets.TargetOperationValue[] | false = false; + let updater: () => void; + + const TARGET_ITEM_FROM_CLONED_CFG = CLONED_TARGETS_FROM_CFG[selectedTarget.__index]; + if (TARGET_ITEM_FROM_CLONED_CFG) { + switch (operationEvent) { + case deploy_targets.TargetOperationEvent.AfterDeployed: + operationStorage = deploy_helpers.asArray(TARGET_ITEM_FROM_CLONED_CFG.deployed); + updater = () => { + (TARGET_ITEM_FROM_CLONED_CFG).deployed = operationStorage; + }; + break; + + case deploy_targets.TargetOperationEvent.BeforeDeploy: + operationStorage = deploy_helpers.asArray(TARGET_ITEM_FROM_CLONED_CFG.beforeDeploy); + updater = () => { + (TARGET_ITEM_FROM_CLONED_CFG).beforeDeploy = operationStorage; + }; + break; } + } - operationStorage.push({ - name: newTargetOperationName, - script: targetScriptPath, - type: 'script' - }); - - updater(); + if (false === operationStorage) { + return; + } - let settings: any; - if (await deploy_helpers.exists(SETTINGS_FILE)) { - settings = JSON.parse( - (await deploy_helpers.readFile(SETTINGS_FILE)).toString('utf8') - ); - } + let newTargetOperationName = await vscode.window.showInputBox({ + placeHolder: selectedWorkspace.t('tools.createDeployOperationScript.askForNewOperationName'), + }); + newTargetOperationName = deploy_helpers.toStringSafe(newTargetOperationName).trim(); + if ('' === newTargetOperationName) { + newTargetOperationName = undefined; + } - if (deploy_helpers.isNullOrUndefined(settings)) { - settings = {}; - } + operationStorage.push({ + name: newTargetOperationName, + script: targetScriptPath, + type: 'script' + }); - settings[SETTINGS_SECTION] = CLONED_CFG; + updater(); - await deploy_helpers.writeFile( - SETTINGS_FILE, - new Buffer( JSON.stringify(settings, null, 4) ) + let settings: any; + if (await deploy_helpers.exists(SETTINGS_FILE)) { + settings = JSON.parse( + (await deploy_helpers.readFile(SETTINGS_FILE)).toString('utf8') ); } - ); + + if (deploy_helpers.isNullOrUndefined(settings)) { + settings = {}; + } + + settings[SETTINGS_SECTION] = CLONED_CFG; + + await deploy_helpers.writeFile( + SETTINGS_FILE, + new Buffer( JSON.stringify(settings, null, 4) ) + ); + } } } } diff --git a/src/workspaces.ts b/src/workspaces.ts index f179dc2..12a4b79 100644 --- a/src/workspaces.ts +++ b/src/workspaces.ts @@ -1214,6 +1214,14 @@ export class Workspace extends deploy_objects.DisposableBase implements deploy_c return true; } + /** + * Gets if the workspace is active or not. + */ + public get isActive() { + return getActiveWorkspaces().map(aws => aws.id) + .indexOf( this.id ) > -1; + } + /** * Gets if 'deploy on change' is currently freezed or not. */