Skip to content

Commit

Permalink
feat(android): create AVD home if not found
Browse files Browse the repository at this point in the history
resolves #64
  • Loading branch information
imhoffd committed Sep 10, 2020
1 parent 18371f2 commit 1cec3c2
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 33 deletions.
33 changes: 8 additions & 25 deletions src/android/utils/avd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as Debug from 'debug';
import * as pathlib from 'path';

import { ASSETS_PATH } from '../../constants';
import { AVDException, ERR_AVD_HOME_NOT_FOUND, ERR_INVALID_SKIN, ERR_INVALID_SYSTEM_IMAGE, ERR_MISSING_SYSTEM_IMAGE, ERR_SDK_UNSATISFIED_PACKAGES, ERR_UNSUITABLE_API_INSTALLATION, ERR_UNSUPPORTED_API_LEVEL, SDKException } from '../../errors';
import { AVDException, ERR_INVALID_SKIN, ERR_INVALID_SYSTEM_IMAGE, ERR_MISSING_SYSTEM_IMAGE, ERR_SDK_UNSATISFIED_PACKAGES, ERR_UNSUITABLE_API_INSTALLATION, ERR_UNSUPPORTED_API_LEVEL } from '../../errors';
import { readINI, writeINI } from '../../utils/ini';
import { sort } from '../../utils/object';

Expand Down Expand Up @@ -88,17 +88,11 @@ export const isAVDConfigINI = (o: any): o is AVDConfigINI => o
export async function getAVDINIs(sdk: SDK): Promise<[string, AVDINI][]> {
const debug = Debug(`${modulePrefix}:${getAVDINIs.name}`);

const { avdHome } = sdk;

if (!avdHome) {
throw new SDKException(`No valid Android AVD home found.`, ERR_AVD_HOME_NOT_FOUND);
}

const contents = await readdir(avdHome);
const contents = await readdir(sdk.avdHome);

const iniFilePaths = contents
.filter(f => pathlib.extname(f) === '.ini')
.map(f => pathlib.resolve(avdHome, f));
.map(f => pathlib.resolve(sdk.avdHome, f));

debug('Discovered AVD ini files: %O', iniFilePaths);

Expand Down Expand Up @@ -204,37 +198,26 @@ export async function getDefaultAVD(sdk: SDK, avds: readonly AVD[]): Promise<AVD
}

export async function createAVD(sdk: SDK, schematic: AVDSchematic): Promise<AVD> {
const { avdHome } = sdk;
const { id, ini, configini } = schematic;

if (!avdHome) {
throw new SDKException(`No valid Android AVD home found.`, ERR_AVD_HOME_NOT_FOUND);
}

await mkdirp(pathlib.join(avdHome, `${id}.avd`));
await mkdirp(pathlib.join(sdk.avdHome, `${id}.avd`));

await Promise.all([
writeINI(pathlib.join(avdHome, `${id}.ini`), ini),
writeINI(pathlib.join(avdHome, `${id}.avd`, 'config.ini'), configini),
writeINI(pathlib.join(sdk.avdHome, `${id}.ini`), ini),
writeINI(pathlib.join(sdk.avdHome, `${id}.avd`, 'config.ini'), configini),
]);

return getAVDFromConfigINI(pathlib.join(avdHome, `${id}.ini`), ini, configini);
return getAVDFromConfigINI(pathlib.join(sdk.avdHome, `${id}.ini`), ini, configini);
}

export async function createAVDSchematic(sdk: SDK, partialSchematic: PartialAVDSchematic): Promise<AVDSchematic> {
const { avdHome } = sdk;

if (!avdHome) {
throw new SDKException(`No valid Android AVD home found.`, ERR_AVD_HOME_NOT_FOUND);
}

const sysimage = findPackageBySchemaPath(sdk.packages || [], new RegExp(`^system-images;${partialSchematic.ini.target}`));

if (!sysimage) {
throw new AVDException(`Cannot create AVD schematic for ${partialSchematic.id}: missing system image.`, ERR_MISSING_SYSTEM_IMAGE);
}

const avdpath = pathlib.join(avdHome, `${partialSchematic.id}.avd`);
const avdpath = pathlib.join(sdk.avdHome, `${partialSchematic.id}.avd`);
const skinpath = getSkinPathByName(sdk, partialSchematic.configini['skin.name']);
const sysdir = pathlib.relative(sdk.root, sysimage.location);
const [ , , tagid ] = sysimage.path.split(';');
Expand Down
15 changes: 8 additions & 7 deletions src/android/utils/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readdirp } from '@ionic/utils-fs';
import { mkdirp, readdirp } from '@ionic/utils-fs';
import * as Debug from 'debug';
import * as os from 'os';
import * as pathlib from 'path';
Expand All @@ -20,7 +20,7 @@ export const SDK_DIRECTORIES: ReadonlyMap<NodeJS.Platform, string[] | undefined>
export interface SDK {
readonly root: string;
readonly emulatorHome: string;
readonly avdHome?: string;
readonly avdHome: string;
packages?: SDKPackage[];
}

Expand Down Expand Up @@ -190,7 +190,7 @@ export async function resolveEmulatorHome(): Promise<string> {
throw new SDKException(`No valid Android Emulator home found.`, ERR_EMULATOR_HOME_NOT_FOUND);
}

export async function resolveAVDHome(): Promise<string | undefined> {
export async function resolveAVDHome(): Promise<string> {
const debug = Debug(`${modulePrefix}:${resolveAVDHome.name}`);

debug('Looking for $ANDROID_AVD_HOME');
Expand All @@ -204,12 +204,13 @@ export async function resolveAVDHome(): Promise<string | undefined> {

const homeAvdHome = pathlib.join(homedir, '.android', 'avd');

if (await isDir(homeAvdHome)) {
debug('Using $HOME/.android/avd/ at %s', homeAvdHome);
return homeAvdHome;
if (!(await isDir(homeAvdHome))) {
debug('Creating directory: %s', homeAvdHome);
await mkdirp(homeAvdHome);
}

debug('No valid AVD home found.');
debug('Using $HOME/.android/avd/ at %s', homeAvdHome);
return homeAvdHome;
}

export function supplementProcessEnv(sdk: SDK): NodeJS.ProcessEnv {
Expand Down
1 change: 0 additions & 1 deletion src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export type AndroidRunExceptionCode = (
export class AndroidRunException extends AndroidException<AndroidRunExceptionCode> {}

export type SDKExceptionCode = (
typeof ERR_AVD_HOME_NOT_FOUND |
typeof ERR_EMULATOR_HOME_NOT_FOUND |
typeof ERR_INVALID_SDK_PACKAGE |
typeof ERR_SDK_NOT_FOUND |
Expand Down

0 comments on commit 1cec3c2

Please sign in to comment.