Skip to content
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
45 changes: 31 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,37 @@ npm install -D react-native-owl

The config file - which unless specified in the cli should live in `./owl.config.json` - is used to descript how Owl should run your app and your tests. Below you can find all the options the can be specified.

| Name | Required | Description |
| ---------------------- | -------- | ------------------------------------------------------------------------------------------- |
| **general** | | |
| `debug` | false | Prevents the CLI/library from printing any logs/output |
| **ios config** | | |
| `ios.workspace` | true | Path to the `.xcworkspace` file of your react-native project |
| `ios.scheme` | true | The name of the scheme you would like to use for building the app |
| `ios.buildCommand` | false | Overrides the `xcodebuild` command making the above options obselete. Used only if required |
| `ios.quiet` | false | Passes the quiet flag to `xcode builds` |
| **android config** | | |
| `android.buildCommand` | false | Overrides the `assembleDebug` gradle command. Should build the apk |
| `android.quiet` | false | Passes the quiet flag to `gradlew` |

|
### Options

| Name | Required | Description |
| ---------------------- | -------- | -------------------------------------------------------------------- |
| **general** | | |
| `debug` | false | Prevents the CLI/library from printing any logs/output |
| **ios config** | | |
| `ios.workspace` | true | Path to the `.xcworkspace` file of your react-native project |
| `ios.scheme` | true | The name of the scheme you would like to use for building the app |
| `ios.buildCommand` | false | Overrides the `xcodebuild` command making the above options obselete |
| `ios.binaryPath` | false | The path to the binary, if you are using a custom build command |
| `ios.quiet` | false | Passes the quiet flag to `xcode builds` |
| **android config** | | |
| `android.buildCommand` | false | Overrides the `assembleDebug` gradle command. Should build the apk |
| `android.binaryPath` | false | The path to the binary, if you are using a custom build command |
| `android.quiet` | false | Passes the quiet flag to `gradlew` |

### Example

```json
{
"ios": {
"workspace": "ios/OwlDemoApp.xcworkspace",
"scheme": "OwlDemoApp",
"device": "iPhone 12 Pro"
},
"android": {
"packageName": "com.owldemoapp"
}
}
```

## CLI

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"testEnvironment": "node"
},
"dependencies": {
"ajv": "^7.0.1",
"ajv": "^7.0.3",
"execa": "^5.0.0",
"yargs": "^16.2.0"
},
Expand Down
28 changes: 15 additions & 13 deletions src/cli/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ import * as configHelpers from './config';

describe('build.ts', () => {
const logger = createLogger();
const execMock = jest.spyOn(execa, 'command').mockImplementation();

describe('buildIOS', () => {
const execMock = jest.spyOn(execa, 'command').mockImplementation();

beforeEach(() => {
execMock.mockReset();
});
beforeEach(() => {
execMock.mockReset();
});

describe('buildIOS', () => {
it('builds an iOS project with workspace/scheme', async () => {
const config: Config = {
ios: {
workspace: 'ios/RNDemo.xcworkspace',
scheme: 'RNDemo',
device: 'iPhone Simulator',
},
};

Expand All @@ -41,6 +41,7 @@ describe('build.ts', () => {
workspace: 'ios/RNDemo.xcworkspace',
scheme: 'RNDemo',
quiet: true,
device: 'iPhone Simulator',
},
};

Expand All @@ -59,6 +60,7 @@ describe('build.ts', () => {
const config: Config = {
ios: {
buildCommand: "echo 'Hello World'",
device: 'iPhone Simulator',
},
};

Expand All @@ -72,15 +74,11 @@ describe('build.ts', () => {
});

describe('buildAndroid', () => {
const execMock = jest.spyOn(execa, 'command').mockImplementation();

beforeEach(() => {
execMock.mockReset();
});

it('builds an Android project with the default build command', async () => {
const config: Config = {
android: {},
android: {
packageName: 'com.rndemo',
},
};

await buildAndroid(config, logger);
Expand All @@ -95,6 +93,7 @@ describe('build.ts', () => {
it('builds an Android project with the default build command - with the quiet arg', async () => {
const config: Config = {
android: {
packageName: 'com.rndemo',
quiet: true,
},
};
Expand All @@ -111,6 +110,7 @@ describe('build.ts', () => {
it('builds an Android project with a custom build command', async () => {
const config: Config = {
android: {
packageName: 'com.rndemo',
buildCommand: "echo 'Hello World'",
},
};
Expand All @@ -133,8 +133,10 @@ describe('build.ts', () => {
const config: Config = {
ios: {
buildCommand: "echo 'Hello World'",
device: 'iPhone Simulator',
},
android: {
packageName: 'com.rndemo',
buildCommand: "echo 'Hello World'",
},
};
Expand Down
8 changes: 5 additions & 3 deletions src/cli/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ export const buildHandler = async (args: BuildRunOptions) => {
const logger = createLogger(config.debug);
const buildProject = args.platform === 'ios' ? buildIOS : buildAndroid;

await buildProject(config, logger);

logger.info(
`OWL will build for the ${args.platform} platform. Config file: ${args.config}`
`[OWL] Will build the app on ${args.platform} platform. Config file: ${args.config}`
);

await buildProject(config, logger);

logger.info(`[OWL] Successfully built for the ${args.platform} platform.`);
};
67 changes: 62 additions & 5 deletions src/cli/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { promises as fs } from 'fs';

import { Config } from './types';
import { getConfig, readConfigFile, validateSchema } from './config';

describe('config.ts', () => {
describe('validateSchema', () => {
it('validates a config', async () => {
const config = {
const config: Config = {
ios: {
buildCommand: 'echo "Hello iOS"',
binaryPath: '',
device: 'iPhone Simulator',
},
android: {
packageName: 'com.rndemo',
buildCommand: 'echo "Hello Android"',
},
};
Expand All @@ -20,15 +24,29 @@ describe('config.ts', () => {
});

it('accepts an ios config that has workspace/scheme but not a buildCommand', async () => {
const config = { ios: { workspace: 'Test', scheme: 'Test' } };
const config = {
ios: {
workspace: 'ios/RNDemo.xcworkspace',
scheme: 'Test',

device: 'iPhone Simulator',
},
};

const validate = async () => await validateSchema(config);

await expect(validate()).resolves.toEqual(config);
});

it('accepts an ios config that has buildCommand but not workspace/scheme', async () => {
const config = { ios: { workspace: 'Test', scheme: 'Test' } };
const config = {
ios: {
workspace: 'ios/RNDemo.xcworkspace',
scheme: 'Test',

device: 'iPhone Simulator',
},
};

const validate = async () => await validateSchema(config);

Expand All @@ -44,7 +62,43 @@ describe('config.ts', () => {
"should have required property 'workspace'"
);
await expect(validate()).rejects.toContain(
"should have required property 'workspace'"
"should have required property 'buildCommand'"
);
await expect(validate()).rejects.toContain(
'should match some schema in anyOf'
);
});

it('rejects an ios config that has a workspace but not a scheme', async () => {
const config = {
ios: {
workspace: 'ios/RNDemo.xcworkspace',
device: 'iPhone Simulator',
},
};

const validate = async () => await validateSchema(config);

await expect(validate()).rejects.toContain(
"should have required property 'scheme'"
);
await expect(validate()).rejects.toContain(
'should match some schema in anyOf'
);
});

it('rejects an ios config that has a build command but not a binary path', async () => {
const config = {
ios: {
buildCommand: 'echo "Hello iOS"',
device: 'iPhone Simulator',
},
};

const validate = async () => await validateSchema(config);

await expect(validate()).rejects.toContain(
"should have required property 'binaryPath'"
);
await expect(validate()).rejects.toContain(
'should match some schema in anyOf'
Expand Down Expand Up @@ -93,8 +147,11 @@ describe('config.ts', () => {
ios: {
workspace: 'ios/RNDemo.xcworkspace',
scheme: 'RNDemo',
device: 'iPhone Simulator',
},
android: {
packageName: 'com.rndemo',
},
android: {},
};

const filePath = './owl.config.json';
Expand Down
11 changes: 8 additions & 3 deletions src/cli/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,28 @@ export const validateSchema = (config: {}): Promise<Config> => {
workspace: { type: 'string', nullable: true },
scheme: { type: 'string', nullable: true },
buildCommand: { type: 'string', nullable: true },
binaryPath: { type: 'string', nullable: true },
device: { type: 'string' },
quiet: { type: 'boolean', nullable: true },
},
required: [],
required: ['device'],
anyOf: [
{ required: ['workspace', 'scheme'] },
{ required: ['buildCommand'] },
{ required: ['buildCommand', 'binaryPath'] },
],
nullable: true,
additionalProperties: false,
},
android: {
type: 'object',
properties: {
packageName: { type: 'string' },
buildCommand: { type: 'string', nullable: true },
binaryPath: { type: 'string', nullable: true },
quiet: { type: 'boolean', nullable: true },
},
required: [],
required: ['packageName'],
anyOf: [{ required: [] }, { required: ['buildCommand', 'binaryPath'] }],
nullable: true,
additionalProperties: false,
},
Expand Down
Loading