diff --git a/package.json b/package.json index f645a9ab9..8b448ca29 100644 --- a/package.json +++ b/package.json @@ -234,12 +234,12 @@ "properties": { "titanium.android.keystoreAlias": { "type": "string", - "default": "", + "default": null, "description": "Keystore alias used for packaging Android applications" }, "titanium.android.keystorePath": { "type": "string", - "default": "", + "default": null, "description": "Path to keystore used for packaging Android applications" }, "titanium.build.liveview": { diff --git a/src/commands/packageApp.ts b/src/commands/packageApp.ts index ca0feb0fb..176973f6c 100644 --- a/src/commands/packageApp.ts +++ b/src/commands/packageApp.ts @@ -65,8 +65,9 @@ export async function packageApplication (node: DeviceNode | OSVerNode | Platfor if (platform === 'android' && !keystoreInfo) { const lastKeystore = ExtensionContainer.context.workspaceState.get(WorkspaceState.LastKeystorePath); + const savedKeystorePath = ExtensionContainer.config.android.keystorePath; // TODO: Private key password? - keystoreInfo = await enterAndroidKeystoreInfo(lastKeystore); + keystoreInfo = await enterAndroidKeystoreInfo(lastKeystore, savedKeystorePath); ExtensionContainer.context.workspaceState.update(WorkspaceState.LastKeystorePath, keystoreInfo.location); } else if (platform === 'ios' && !iOSCertificate) { const codesigning = await selectiOSCodeSigning(buildType, target, project.appId()); diff --git a/src/quickpicks/common.ts b/src/quickpicks/common.ts index 806e35be5..c111064b6 100644 --- a/src/quickpicks/common.ts +++ b/src/quickpicks/common.ts @@ -1,8 +1,11 @@ +import * as path from 'path'; import appc from '../appc'; import * as utils from '../utils'; -import { InputBoxOptions, OpenDialogOptions, QuickPickOptions, window } from 'vscode'; -import { UserCancellation } from '../commands/common'; +import { pathExists } from 'fs-extra'; +import { InputBoxOptions, OpenDialogOptions, QuickPickOptions, window, workspace } from 'vscode'; +import { InteractionError, UserCancellation } from '../commands/common'; +import { ExtensionContainer } from '../container'; export async function selectFromFileSystem (options: OpenDialogOptions) { if (!options.canSelectMany) { @@ -111,7 +114,7 @@ export function selectAndroidEmulator () { return quickPick(options, { placeHolder: 'Select emulator' }); } -export async function selectAndroidKeystore (lastUsed) { +export async function selectAndroidKeystore (lastUsed, savedKeystorePath) { const items = [{ label: 'Browse for keystore', id: 'browse' @@ -122,18 +125,33 @@ export async function selectAndroidKeystore (lastUsed) { id: 'last' }); } + if (savedKeystorePath) { + items.push({ + label: `Saved ${savedKeystorePath}`, + id: 'saved' + }); + } const keystoreAction = await quickPick(items, { placeHolder: 'Browse for keystore or use last keystore' }); if (keystoreAction.id === 'browse') { const uri = await window.showOpenDialog({ canSelectFolders: false, canSelectMany: false }); return uri[0].path; + } else if (keystoreAction.id === 'saved') { + if (!path.isAbsolute(savedKeystorePath)) { + savedKeystorePath = path.resolve(workspace.rootPath, savedKeystorePath); + } + return savedKeystorePath; } else { return lastUsed; } } -export async function enterAndroidKeystoreInfo (lastUsed) { - const location = await selectAndroidKeystore(lastUsed); - const alias = await inputBox({ placeHolder: 'Enter your keystore alias' }); +export async function enterAndroidKeystoreInfo (lastUsed, savedKeystorePath) { + const location = await selectAndroidKeystore(lastUsed, savedKeystorePath); + + if (!await pathExists(location)) { + throw new InteractionError(`The Keystore file ${location} does not exist`); + } + const alias = await inputBox({ placeHolder: 'Enter your keystore alias', value: ExtensionContainer.config.android.keystoreAlias }); const password = await enterPassword({ placeHolder: 'Enter your keystore password' }); return { alias, diff --git a/src/types/config.ts b/src/types/config.ts index aa9d32d78..ce13c5df7 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -2,8 +2,8 @@ import { LogLevel } from './common'; export interface Config { android: { - keystoreAlias: string, - keystorePath: string + keystoreAlias: string | null, + keystorePath: string | null }; build: { liveview: boolean