Skip to content

Commit

Permalink
feat(cli): STUDIO_PATH environment variable (#3755)
Browse files Browse the repository at this point in the history
  • Loading branch information
imhoffd authored Nov 3, 2020
1 parent 74815fc commit 65cef53
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 83 deletions.
84 changes: 24 additions & 60 deletions cli/src/android/open.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,37 @@
import { pathExists } from '@ionic/utils-fs';
import Debug from 'debug';
import open from 'open';

import { runCommand } from '../common';
import c from '../colors';
import type { Config } from '../definitions';
import { OS } from '../definitions';
import { logger } from '../log';

export async function openAndroid(config: Config): Promise<void> {
logger.info(`Opening Android project at ${config.android.platformDir}.`);
const debug = Debug('capacitor:android:open');

export async function openAndroid(config: Config): Promise<void> {
const androidStudioPath = config.android.studioPath;
const dir = config.android.platformDirAbs;

switch (config.cli.os) {
case OS.Mac: {
await open(dir, { app: 'android studio', wait: false });
break;
}
case OS.Windows: {
let androidStudioPath = config.windows.androidStudioPath;
try {
if (!(await pathExists(androidStudioPath))) {
let commandResult = await runCommand('REG', [
'QUERY',
'HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio',
'/v',
'Path',
]);
commandResult = commandResult.replace(/(\r\n|\n|\r)/gm, '');
const ix = commandResult.indexOf('REG_SZ');
if (ix > 0) {
androidStudioPath =
commandResult.substring(ix + 6).trim() + '\\bin\\studio64.exe';
}
}
} catch (e) {
androidStudioPath = '';
}
if (androidStudioPath) {
open(dir, { app: androidStudioPath, wait: false });
} else {
logger.error(
'Android Studio not found.\n' +
'Make sure it\'s installed and configure "windowsAndroidStudioPath" in your capacitor.config.json to point to the location of studio64.exe, using JavaScript-escaped paths:\n' +
'Example:\n' +
'{\n' +
' "windowsAndroidStudioPath": "C:\\\\Program Files\\\\Android\\\\Android Studio\\\\bin\\\\studio64.exe"\n' +
'}',
);
}
break;
try {
if (!(await pathExists(androidStudioPath))) {
throw new Error(`Android Studio does not exist at: ${androidStudioPath}`);
}
case OS.Linux: {
const linuxError = () => {
logger.error(
'Unable to launch Android Studio.\n' +
'You must configure "linuxAndroidStudioPath" in your capacitor.config.json to point to the location of studio.sh, using JavaScript-escaped paths:\n' +
'Example:\n' +
'{\n' +
' "linuxAndroidStudioPath": "/usr/local/android-studio/bin/studio.sh"\n' +
'}',
);
};

try {
await open(dir, { app: config.linux.androidStudioPath, wait: true });
} catch (e) {
linuxError();
}
break;
}
await open(dir, { app: androidStudioPath, wait: false });
logger.info(
`Opening Android project at: ${c.strong(config.android.platformDir)}.`,
);
} catch (e) {
debug('Error opening Android Studio: %O', e);

logger.error(
'Unable to launch Android Studio. Is it installed?\n' +
`Attempted to open Android Studio at: ${c.strong(
androidStudioPath,
)}\n` +
`You can configure this with the ${c.input(
'STUDIO_PATH',
)} environment variable.`,
);
}
}
79 changes: 59 additions & 20 deletions cli/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { readJSON } from 'fs-extra';
import { pathExists, readJSON } from '@ionic/utils-fs';
import Debug from 'debug';
import { dirname, join, resolve } from 'path';

import { runCommand } from './common';
import type {
Config,
ExternalConfig,
Expand All @@ -12,6 +14,8 @@ import type {
} from './definitions';
import { OS } from './definitions';

const debug = Debug('capacitor:config');

export const EXTERNAL_CONFIG_FILE = 'capacitor.config.json';

export async function loadConfig(): Promise<Config> {
Expand All @@ -26,19 +30,9 @@ export async function loadConfig(): Promise<Config> {
const webDir = extConfig.webDir ?? 'www';
const cli = await loadCLIConfig(cliRootDir);

return {
windows: {
androidStudioPath:
extConfig.windowsAndroidStudioPath ??
'C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe',
},
linux: {
androidStudioPath:
extConfig.linuxAndroidStudioPath ??
'/usr/local/android-studio/bin/studio.sh',
},
android: await loadAndroidConfig(appRootDir, extConfig, cli.assetsDir),
ios: await loadIOSConfig(appRootDir, extConfig, cli.assetsDir),
const config = {
android: await loadAndroidConfig(appRootDir, extConfig, cli),
ios: await loadIOSConfig(appRootDir, extConfig, cli),
web: await loadWebConfig(appRootDir, webDir),
cli,
app: {
Expand All @@ -57,6 +51,10 @@ export async function loadConfig(): Promise<Config> {
bundledWebRuntime: extConfig.bundledWebRuntime ?? false,
},
};

debug('config: %O', config);

return config;
}

async function loadCLIConfig(rootDir: string): Promise<CLIConfig> {
Expand All @@ -74,7 +72,7 @@ async function loadCLIConfig(rootDir: string): Promise<CLIConfig> {
async function loadAndroidConfig(
rootDir: string,
extConfig: ExternalConfig,
assetDir: string,
cliConfig: CLIConfig,
): Promise<AndroidConfig> {
const name = 'android';
const platformDir = extConfig.android?.path ?? 'android';
Expand All @@ -85,10 +83,12 @@ async function loadAndroidConfig(

const templateName = 'android-template';
const pluginsFolderName = 'capacitor-cordova-android-plugins';
const studioPath = await determineAndroidStudioPath(cliConfig.os);

return {
name,
minVersion: '21',
studioPath,
platformDir,
platformDirAbs,
webDir,
Expand All @@ -100,16 +100,16 @@ async function loadAndroidConfig(
assets: {
templateName,
pluginsFolderName,
templateDir: resolve(assetDir, templateName),
pluginsDir: resolve(assetDir, pluginsFolderName),
templateDir: resolve(cliConfig.assetsDir, templateName),
pluginsDir: resolve(cliConfig.assetsDir, pluginsFolderName),
},
};
}

async function loadIOSConfig(
rootDir: string,
extConfig: ExternalConfig,
assetDir: string,
cliConfig: CLIConfig,
): Promise<IOSConfig> {
const name = 'ios';
const platformDir = extConfig.ios?.path ?? 'ios';
Expand All @@ -131,8 +131,8 @@ async function loadIOSConfig(
assets: {
templateName,
pluginsFolderName,
templateDir: resolve(assetDir, templateName),
pluginsDir: resolve(assetDir, pluginsFolderName),
templateDir: resolve(cliConfig.assetsDir, templateName),
pluginsDir: resolve(cliConfig.assetsDir, pluginsFolderName),
},
};
}
Expand Down Expand Up @@ -164,6 +164,45 @@ function determineOS(os: NodeJS.Platform): OS {
return OS.Unknown;
}

async function determineAndroidStudioPath(os: OS): Promise<string> {
if (process.env.STUDIO_PATH) {
return process.env.STUDIO_PATH;
}

switch (os) {
case OS.Mac:
return '/Applications/Android Studio.app';
case OS.Windows: {
let p = 'C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe';

try {
if (!(await pathExists(p))) {
let commandResult = await runCommand('REG', [
'QUERY',
'HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio',
'/v',
'Path',
]);
commandResult = commandResult.replace(/(\r\n|\n|\r)/gm, '');
const i = commandResult.indexOf('REG_SZ');
if (i > 0) {
p = commandResult.substring(i + 6).trim() + '\\bin\\studio64.exe';
}
}
} catch (e) {
debug(`Error checking registry for Android Studio path: %O`, e);
break;
}

return p;
}
case OS.Linux:
return '/usr/local/android-studio/bin/studio.sh';
}

return '';
}

async function loadExternalConfig(p: string): Promise<ExternalConfig> {
try {
return await readJSON(p);
Expand Down
3 changes: 1 addition & 2 deletions cli/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export interface AppConfig {
}

export interface AndroidConfig extends PlatformConfig {
readonly studioPath: string;
readonly minVersion: string;
readonly webDir: string;
readonly webDirAbs: string;
Expand All @@ -107,8 +108,6 @@ export interface IOSConfig extends PlatformConfig {
export type WebConfig = PlatformConfig;

export interface Config {
readonly windows: WindowsConfig;
readonly linux: LinuxConfig;
readonly android: AndroidConfig;
readonly ios: IOSConfig;
readonly web: WebConfig;
Expand Down
2 changes: 1 addition & 1 deletion cli/src/web/copy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { copy } from 'fs-extra';
import { copy } from '@ionic/utils-fs';
import { join } from 'path';

import c from '../colors';
Expand Down

0 comments on commit 65cef53

Please sign in to comment.