Skip to content
1 change: 0 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"recommendations": [
"dbaeumer.vscode-eslint",
"redhat.vscode-yaml",
"flowtype.flow-for-vscode",
"esbenp.prettier-vscode"
]
}
4 changes: 1 addition & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
"**/node_modules": true,
"**/build": true
},
"editor.formatOnSave": true,
"flow.useNPMPackagedFlow": true,
"javascript.validate.enable": false,
"eslint.autoFixOnSave": true,
"eslint.validate": [
"javascript",
"javascriptreact",
Expand Down
14 changes: 0 additions & 14 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,26 +267,12 @@ Builds your app and starts it on a connected Android emulator or device.

#### Options

#### `--root [string]`

Override the root directory for the Android build (which contains the android directory)'.

#### `--variant [string]`

> default: 'debug'

Specify your app's build variant.

#### `--appFolder [string]`

> default: 'app'

Specify a different application folder name for the Android source. If not, we assume is "app".

#### `--appId [string]`

Specify an `applicationId` to launch after build.

#### `--appIdSuffix [string]`

Specify an `applicationIdSuffix` to launch after build.
Expand Down
8 changes: 6 additions & 2 deletions docs/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ interface IOSDependencyParams {
interface AndroidDependencyParams {
packageName?: string;
sourceDir?: string;
appName?: string;
manifestPath?: string;

packageImportPath?: string;
packageInstance?: string;
}
Expand Down Expand Up @@ -106,7 +106,11 @@ See [`script_phase` options](https://www.rubydoc.info/gems/cocoapods-core/Pod/Po

#### platforms.android.sourceDir

A relative path to a folder with source files. E.g. `custom-android`, or `custom-android/app`. By default, CLI searches for `android` and `android/app` as source dirs.
A relative path to a folder with Android project (Gradle root project), e.g. `./path/to/custom-android`. By default, CLI searches for `./android` as source dir.

#### platforms.android.appName

A name of the app in the Android `sourceDir`, equivalent to Gradle project name. By default it's `app`.

#### platforms.android.packageName

Expand Down
1 change: 1 addition & 0 deletions docs/projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ The following settings are available on iOS and Android:
```ts
interface AndroidProjectParams {
sourceDir?: string;
appName?: string;
manifestPath?: string;
packageName?: string;
}
Expand Down
20 changes: 6 additions & 14 deletions packages/cli-types/src/android.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
export interface AndroidProjectConfig {
sourceDir: string;
appName: string;
packageName: string;
manifestPath: string;
}

export interface AndroidProjectParams {
sourceDir?: string;
manifestPath?: string;
packageName?: string;
}
export type AndroidProjectParams = Partial<AndroidProjectConfig>;

export interface AndroidDependencyConfig {
sourceDir: string;
appName: string;
packageName: string;

manifestPath: string;
packageImportPath: string;
packageInstance: string;
}

export interface AndroidDependencyParams {
packageName?: string;
sourceDir?: string;
manifestPath?: string;

packageImportPath?: string;
packageInstance?: string;
}
export type AndroidDependencyParams = Partial<AndroidDependencyConfig>;
2 changes: 2 additions & 0 deletions packages/cli/src/tools/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const dependencyConfig = t
// AndroidDependencyParams
.object({
sourceDir: t.string(),
appName: t.string(),
manifestPath: t.string(),
packageImportPath: t.string(),
packageInstance: t.string(),
Expand Down Expand Up @@ -130,6 +131,7 @@ export const projectConfig = t
// AndroidProjectParams
.object({
sourceDir: t.string(),
appName: t.string(),
manifestPath: t.string(),
packageName: t.string(),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,83 +7,104 @@
*/

import runOnAllDevices from '../runOnAllDevices';
import execa from 'execa';

jest.mock('child_process', () => ({
execFileSync: jest.fn(),
spawnSync: jest.fn(),
}));

jest.mock('execa');
jest.mock('../getAdbPath');
jest.mock('../tryLaunchEmulator');
const {execFileSync} = require('child_process');

describe('--appFolder', () => {
describe('runOnAllDevices', () => {
const args = {
tasks: undefined,
variant: 'debug',
appIdSuffix: '',
mainActivity: 'MainActivity',
deviceId: undefined,
packager: true,
port: 8081,
terminal: 'iTerm2',
jetifier: true,
};
const androidProject = {
manifestPath: '/android/app/src/main/AndroidManifest.xml',
appName: 'app',
packageName: 'com.test',
sourceDir: '/android',
};
beforeEach(() => {
jest.clearAllMocks();
});

it('uses task "install[Variant]" as default task', async () => {
// @ts-ignore
await runOnAllDevices({
variant: 'debug',
});
expect(execFileSync.mock.calls[0][1]).toContain('installDebug');
await runOnAllDevices(
{...args, variant: 'debug'},
'./gradlew',
'adb',
androidProject,
);
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain(
'app:installDebug',
);
});

it('uses appFolder and default variant', async () => {
// @ts-ignore
await runOnAllDevices({
appFolder: 'someApp',
variant: 'debug',
it('uses appName and default variant', async () => {
await runOnAllDevices({...args, variant: 'debug'}, './gradlew', 'adb', {
...androidProject,
appName: 'someApp',
});

expect(execFileSync.mock.calls[0][1]).toContain('someApp:installDebug');
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain(
'someApp:installDebug',
);
});

it('uses appFolder and custom variant', async () => {
// @ts-ignore
await runOnAllDevices({
appFolder: 'anotherApp',
variant: 'staging',
it('uses appName and custom variant', async () => {
await runOnAllDevices({...args, variant: 'staging'}, './gradlew', 'adb', {
...androidProject,
appName: 'anotherApp',
});

expect(execFileSync.mock.calls[0][1]).toContain(
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain(
'anotherApp:installStaging',
);
});

it('uses only task argument', async () => {
// @ts-ignore
await runOnAllDevices({
tasks: ['someTask'],
variant: 'debug',
});
await runOnAllDevices(
{...args, tasks: ['someTask']},
'./gradlew',
'adb',
androidProject,
);

expect(execFileSync.mock.calls[0][1]).toContain('someTask');
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain(
'app:someTask',
);
});

it('uses appFolder and custom task argument', async () => {
// @ts-ignore
await runOnAllDevices({
appFolder: 'anotherApp',
tasks: ['someTask'],
variant: 'debug',
it('uses appName and custom task argument', async () => {
await runOnAllDevices({...args, tasks: ['someTask']}, './gradlew', 'adb', {
...androidProject,
appName: 'anotherApp',
});

expect(execFileSync.mock.calls[0][1]).toContain('anotherApp:someTask');
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toContain(
'anotherApp:someTask',
);
});

it('uses multiple tasks', async () => {
// @ts-ignore
await runOnAllDevices({
appFolder: 'app',
tasks: ['clean', 'someTask'],
});
await runOnAllDevices(
{...args, tasks: ['clean', 'someTask']},
'./gradlew',
'adb',
androidProject,
);

expect(execFileSync.mock.calls[0][1]).toContain(
expect(((execa as unknown) as jest.Mock).mock.calls[0][1]).toEqual([
'app:clean',
// @ts-ignore
'app:someTask',
);
'-PreactNativeDevServerPort=8081',
]);
});
});
Loading