Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #11: Install emulator package in createEmulator #12

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ andromatic
- [getAndroidDevToolPath](README.md#getandroiddevtoolpath)
- [installAndroidDevTool](README.md#installandroiddevtool)
- [installPackages](README.md#installpackages)
- [isInstalled](README.md#isinstalled)
- [listPackages](README.md#listpackages)
- [runAndroidDevTool](README.md#runandroiddevtool)
- [updatePackages](README.md#updatepackages)
Expand Down Expand Up @@ -377,7 +378,7 @@ The path to the installed tool's executable.

#### Defined in

[index.ts:340](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L340)
[index.ts:357](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L357)

___

Expand Down Expand Up @@ -406,7 +407,7 @@ The path to the installed tool's executable.

#### Defined in

[index.ts:293](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L293)
[index.ts:310](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L310)

___

Expand All @@ -431,15 +432,47 @@ The path to `$ANDROID_HOME` where the packages are installed.

#### Defined in

[index.ts:266](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L266)
[index.ts:283](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L283)

___

### isInstalled

▸ **isInstalled**(`packageName`, `version?`): `Promise`<`boolean`\>

Checks whether a package has been installed by `sdkmanager`.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `packageName` | `string` | Name of the package to check. Should match the `sdkmanager` package path. |
| `version?` | `string` | If needed, additional check if the specified version ist installed. |

#### Returns

`Promise`<`boolean`\>

A boolean which is true if the package is currently installed.

#### Defined in

[index.ts:270](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L270)

___

### listPackages

▸ **listPackages**(): `Promise`<[`AvailablePackage`](README.md#availablepackage)[]\>
▸ **listPackages**(`options?`): `Promise`<[`AvailablePackage`](README.md#availablepackage)[]\>

Fetch a list of available packages that can be installed by `sdkmanager`.
Fetch a list of available or installed packages that can be or have been installed by `sdkmanager`.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `options?` | `Object` | If `ìnstalled` is true, fetch a list of all installed packages (instead of ones available for install). |
| `options.installed` | `boolean` | - |

#### Returns

Expand All @@ -449,7 +482,7 @@ An array of packages, each with their package path, version and description.

#### Defined in

[index.ts:237](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L237)
[index.ts:239](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L239)

___

Expand Down Expand Up @@ -479,7 +512,7 @@ The result from execa, see: https://github.com/sindresorhus/execa#childprocess.

#### Defined in

[index.ts:409](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L409)
[index.ts:426](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L426)

___

Expand All @@ -495,4 +528,4 @@ Update all installed packages to the latest version using `sdkmanager`.

#### Defined in

[index.ts:275](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L275)
[index.ts:292](https://github.com/tweaselORG/andromatic/blob/main/src/index.ts#L292)
3 changes: 3 additions & 0 deletions src/emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export const createEmulator = async (name: string, options: EmulatorOptions) =>
for (const dir of ['platforms', 'platform-tools'])
if (!(await fs.pathExists(join(androidHome, dir)))) await fs.ensureDir(join(androidHome, dir));

// The `emulator` package is required by avdmanager, so we need to check for it
if (!(await fs.pathExists(join(androidHome, 'emulator')))) await installPackages('emulator');

await runAndroidDevTool('avdmanager', [
'create',
'avd',
Expand Down
27 changes: 22 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,16 @@ export type AvailablePackage = {
description: string;
};
/**
* Fetch a list of available packages that can be installed by `sdkmanager`.
* Fetch a list of available or installed packages that can be or have been installed by `sdkmanager`.
*
* @param options If `ìnstalled` is true, fetch a list of all installed packages (instead of ones available for
* install). Defaults to `false`.
* @returns An array of packages, each with their package path, version and description.
*/
export const listPackages = async (): Promise<AvailablePackage[]> => {
export const listPackages = async (options?: { installed: boolean }): Promise<AvailablePackage[]> => {
const { sdkmanager, env } = await ensureSdkmanager();

const { stdout } = await execa(sdkmanager, ['--list'], { env });
const { stdout } = await execa(sdkmanager, [options?.installed ? '--list_installed' : '--list'], { env });

const lines = stdout.split('\n');
/*
Expand All @@ -246,15 +248,30 @@ export const listPackages = async (): Promise<AvailablePackage[]> => {
------- | ------- | -------
add-ons;addon-google_apis-google-15 | 3 | Google APIs
*/
const availableHeaderIndex = lines.findIndex((line) => line.startsWith('Available Packages:'));
const headerIndex = lines.findIndex((line) =>
line.startsWith(options?.installed ? 'Installed packages:' : 'Available Packages:')
);

return lines
.slice(availableHeaderIndex + 3)
.slice(headerIndex + 3)
.map((line) => line.split('|').map((v) => v.trim()))
.map(([path, version, description]) => ({ path, version, description }))
.filter((p): p is AvailablePackage => !!p.path && !!p.version && !!p.description);
};

/**
* Checks whether a package has been installed by `sdkmanager`.
*
* @param packageName Name of the package to check. Should match the `sdkmanager` package path.
* @param version If needed, additional check if the specified version ist installed.
*
* @returns A boolean which is true if the package is currently installed.
*/
export const isInstalled = async (packageName: string, version?: string) =>
(await listPackages({ installed: true })).some(
(p) => p.path.startsWith(packageName) && (version ? p.version === version : true)
);

/**
* Install one or more packages using `sdkmanager`. The specified packages are installed or updated to the latest
* version (if already installed) in an automatically created `$ANDROID_HOME` managed by andromatic.
Expand Down