Skip to content

Commit 6250426

Browse files
committed
feat: --skip-config option for skipping config.xml read/write
Also clean up some docs and config structure.
1 parent 58fb49e commit 6250426

File tree

6 files changed

+243
-74
lines changed

6 files changed

+243
-74
lines changed

README.md

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Resource Generator
22

3-
This tool will crop and resize JPEG and PNG source images to generate images for modern iOS and Android devices. It will also register the generated images in `config.xml` so that Cordova projects are updated accordingly.
3+
This tool will crop and resize JPEG and PNG source images to generate icons and splash screens for modern iOS, Android, and Windows. `cordova-res` was developed for use with Cordova, but Capacitor and other native runtimes are supported.
44

55
## Install
66

@@ -10,7 +10,7 @@ $ npm install -g cordova-res
1010

1111
## Usage
1212

13-
`cordova-res` must run at the root of a Cordova project, such as:
13+
`cordova-res` expects a Cordova project structure such as:
1414

1515
```
1616
resources/
@@ -19,8 +19,9 @@ resources/
1919
config.xml
2020
```
2121

22-
* `resources/icon.png` must be at least 1024×1024px
23-
* `resources/splash.png` must be at least 2732×2732px
22+
* `resources/icon.(png|jpg)` must be at least 1024×1024px
23+
* `resources/splash.(png|jpg)` must be at least 2732×2732px
24+
* `config.xml` is optional. If present, the generated images are registered accordingly
2425

2526
To generate resources with all the default options, just run:
2627

@@ -34,7 +35,7 @@ $ cordova-res
3435
$ cordova-res ios
3536
```
3637

37-
Otherwise, `cordova-res` looks for platforms in `config.xml` (e.g. `<platform name="ios">`) and generates resources only for them.
38+
Otherwise, if `config.xml` exists, `cordova-res` will look for platforms (e.g. `<platform name="ios">`) and generate resources only for the configured platforms.
3839

3940
#### Documentation
4041

@@ -55,7 +56,20 @@ A color may also be used for the icon background by specifying the `--icon-backg
5556

5657
Regular Android icons will still be generated as a fallback for Android devices that do not support adaptive icons.
5758

58-
:memo: **Note**: Cordova 9+ and `cordova-android` 8+ is required.
59+
:memo: **Note**: For Cordova apps, Cordova 9+ and `cordova-android` 8+ is required.
60+
61+
### Capacitor
62+
63+
To use `cordova-res` in Capacitor and other native runtimes, it is recommended to use `--skip-config` (skips reading & writing to Cordova's `config.xml` file) and `--copy` (copies generated resources into native projects).
64+
65+
For example, to generate icons and splash screens for iOS and Android in Capacitor, run:
66+
67+
```bash
68+
$ cordova-res ios --skip-config --copy
69+
$ cordova-res android --skip-config --copy
70+
```
71+
72+
You can use `--ios-project` and `--android-project` to specify the native project directories into which these resources are copied. By default, `cordova-res` copies Android resources into `android/` and iOS resources into `ios/` (the directories Capacitor uses).
5973

6074
### Tips
6175

src/__tests__/cli.ts

+107-6
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,122 @@ import { Options } from '..';
22
import { generateRunOptions, parseOptions } from '../cli';
33
import { Platform } from '../platform';
44

5+
function generatePlatformsConfig(resourcesDirectory: string) {
6+
return {
7+
android: {
8+
'adaptive-icon': {
9+
background: {
10+
sources: [
11+
`${resourcesDirectory}/android/icon-background.png`,
12+
`${resourcesDirectory}/android/icon-background.jpg`,
13+
`${resourcesDirectory}/android/icon-background.jpeg`,
14+
],
15+
},
16+
foreground: {
17+
sources: [
18+
`${resourcesDirectory}/android/icon-foreground.png`,
19+
`${resourcesDirectory}/android/icon-foreground.jpg`,
20+
`${resourcesDirectory}/android/icon-foreground.jpeg`,
21+
],
22+
},
23+
icon: {
24+
sources: [
25+
`${resourcesDirectory}/android/icon.png`,
26+
`${resourcesDirectory}/android/icon.jpg`,
27+
`${resourcesDirectory}/android/icon.jpeg`,
28+
`${resourcesDirectory}/icon.png`,
29+
`${resourcesDirectory}/icon.jpg`,
30+
`${resourcesDirectory}/icon.jpeg`,
31+
],
32+
},
33+
},
34+
icon: {
35+
sources: [
36+
`${resourcesDirectory}/android/icon.png`,
37+
`${resourcesDirectory}/android/icon.jpg`,
38+
`${resourcesDirectory}/android/icon.jpeg`,
39+
`${resourcesDirectory}/icon.png`,
40+
`${resourcesDirectory}/icon.jpg`,
41+
`${resourcesDirectory}/icon.jpeg`,
42+
],
43+
},
44+
splash: {
45+
sources: [
46+
`${resourcesDirectory}/android/splash.png`,
47+
`${resourcesDirectory}/android/splash.jpg`,
48+
`${resourcesDirectory}/android/splash.jpeg`,
49+
`${resourcesDirectory}/splash.png`,
50+
`${resourcesDirectory}/splash.jpg`,
51+
`${resourcesDirectory}/splash.jpeg`,
52+
],
53+
},
54+
},
55+
ios: {
56+
icon: {
57+
sources: [
58+
`${resourcesDirectory}/ios/icon.png`,
59+
`${resourcesDirectory}/ios/icon.jpg`,
60+
`${resourcesDirectory}/ios/icon.jpeg`,
61+
`${resourcesDirectory}/icon.png`,
62+
`${resourcesDirectory}/icon.jpg`,
63+
`${resourcesDirectory}/icon.jpeg`,
64+
],
65+
},
66+
splash: {
67+
sources: [
68+
`${resourcesDirectory}/ios/splash.png`,
69+
`${resourcesDirectory}/ios/splash.jpg`,
70+
`${resourcesDirectory}/ios/splash.jpeg`,
71+
`${resourcesDirectory}/splash.png`,
72+
`${resourcesDirectory}/splash.jpg`,
73+
`${resourcesDirectory}/splash.jpeg`,
74+
],
75+
},
76+
},
77+
windows: {
78+
icon: {
79+
sources: [
80+
`${resourcesDirectory}/windows/icon.png`,
81+
`${resourcesDirectory}/windows/icon.jpg`,
82+
`${resourcesDirectory}/windows/icon.jpeg`,
83+
`${resourcesDirectory}/icon.png`,
84+
`${resourcesDirectory}/icon.jpg`,
85+
`${resourcesDirectory}/icon.jpeg`,
86+
],
87+
},
88+
splash: {
89+
sources: [
90+
`${resourcesDirectory}/windows/splash.png`,
91+
`${resourcesDirectory}/windows/splash.jpg`,
92+
`${resourcesDirectory}/windows/splash.jpeg`,
93+
`${resourcesDirectory}/splash.png`,
94+
`${resourcesDirectory}/splash.jpg`,
95+
`${resourcesDirectory}/splash.jpeg`,
96+
],
97+
},
98+
},
99+
};
100+
}
101+
5102
describe('cordova-res', () => {
6103

7104
describe('cli', () => {
8105

9106
describe('parseOptions', () => {
10107

11108
const DEFAULT_OPTIONS: Options = {
109+
directory: process.cwd(),
12110
logstream: process.stdout,
13111
errstream: process.stderr,
14112
resourcesDirectory: 'resources',
15-
nativeProject: {
16-
enabled: false,
17-
androidProjectDirectory: '',
18-
iosProjectDirectory: '',
113+
platforms: generatePlatformsConfig('resources'),
114+
projectConfig: {
115+
android: { directory: 'android' },
116+
ios: { directory: 'ios' },
117+
windows: { directory: 'windows' },
19118
},
119+
skipConfig: false,
120+
copy: false,
20121
};
21122

22123
it('should parse default options with no arguments', () => {
@@ -27,7 +128,7 @@ describe('cordova-res', () => {
27128
it('should parse options for android', () => {
28129
const args = ['android'];
29130
const result = parseOptions(args);
30-
expect(result).toEqual({ ...DEFAULT_OPTIONS, platforms: { android: generateRunOptions(Platform.ANDROID, 'resources', args) } });
131+
expect(result).toEqual({ ...DEFAULT_OPTIONS, platforms: { android: generateRunOptions(Platform.ANDROID, 'resources', args), }, projectConfig: { android: { directory: 'android' } } });
31132
});
32133

33134
it('should parse default options when the first argument is not a platform', () => {
@@ -39,7 +140,7 @@ describe('cordova-res', () => {
39140
it('should accept --resources flag', () => {
40141
const args = ['--resources', 'res'];
41142
const result = parseOptions(args);
42-
expect(result).toEqual({ ...DEFAULT_OPTIONS, resourcesDirectory: 'res' });
143+
expect(result).toEqual({ ...DEFAULT_OPTIONS, platforms: generatePlatformsConfig('res'), resourcesDirectory: 'res' });
43144
});
44145

45146
it('should log to stderr with --json flag', () => {

src/cli.ts

+31-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import et from 'elementtree';
22

3-
import { Options, PlatformOptions } from '.';
3+
import type { NativeProjectConfigByPlatform, Options, PlatformOptions } from '.';
44
import { getPlatforms } from './config';
55
import { BadInputError } from './error';
6-
import { NativeProject } from './native';
7-
import { AdaptiveIconResourceOptions, Platform, RunPlatformOptions, SimpleResourceOptions, filterSupportedPlatforms, validatePlatforms } from './platform';
6+
import { NativeProjectConfig } from './native';
7+
import { AdaptiveIconResourceOptions, PLATFORMS, Platform, RunPlatformOptions, SimpleResourceOptions, filterSupportedPlatforms, validatePlatforms } from './platform';
88
import { DEFAULT_RESOURCES_DIRECTORY, RESOURCE_TYPES, ResourceKey, ResourceType, Source, SourceType, validateResourceTypes } from './resources';
99
import { getOptionValue } from './utils/cli';
1010

@@ -24,23 +24,21 @@ export async function resolveOptions(args: readonly string[], directory: string,
2424
};
2525
}
2626

27-
export function parseOptions(args: readonly string[]): Options {
27+
export function parseOptions(args: readonly string[]): Required<Options> {
2828
const json = args.includes('--json');
2929
const resourcesDirectory = getOptionValue(args, '--resources', DEFAULT_RESOURCES_DIRECTORY);
3030
const platformArg = args[0] ? args[0] : undefined;
31-
const platformList = validatePlatforms(platformArg && !platformArg.startsWith('-') ? [platformArg] : []);
32-
const nativeProject: Readonly<NativeProject> = {
33-
enabled: args.includes('--copy'),
34-
androidProjectDirectory: getOptionValue(args, '--android-project', ''),
35-
iosProjectDirectory: getOptionValue(args, '--ios-project', ''),
36-
};
31+
const platformList = validatePlatforms(platformArg && !platformArg.startsWith('-') ? [platformArg] : PLATFORMS);
3732

3833
return {
34+
directory: getDirectory(),
3935
resourcesDirectory,
4036
logstream: json ? process.stderr : process.stdout,
4137
errstream: process.stderr,
42-
...platformList.length > 0 ? { platforms: generatePlatformOptions(platformList, resourcesDirectory, args) } : {},
43-
nativeProject,
38+
platforms: generatePlatformOptions(platformList, resourcesDirectory, args),
39+
projectConfig: generatePlatformProjectOptions(platformList, args),
40+
skipConfig: parseSkipConfigOption(args),
41+
copy: parseCopyOption(args),
4442
};
4543
}
4644

@@ -51,6 +49,13 @@ export function generatePlatformOptions(platforms: readonly Platform[], resource
5149
}, {} as PlatformOptions);
5250
}
5351

52+
export function generatePlatformProjectOptions(platforms: readonly Platform[], args: readonly string[]): NativeProjectConfigByPlatform {
53+
return platforms.reduce((acc, platform) => {
54+
acc[platform] = generateNativeProjectConfig(platform, args);
55+
return acc;
56+
}, {} as NativeProjectConfigByPlatform);
57+
}
58+
5459
export function generateRunOptions(platform: Platform, resourcesDirectory: string, args: readonly string[]): RunPlatformOptions {
5560
const typeOption = getOptionValue(args, '--type');
5661
const types = validateResourceTypes(typeOption ? [typeOption] : RESOURCE_TYPES);
@@ -62,6 +67,20 @@ export function generateRunOptions(platform: Platform, resourcesDirectory: strin
6267
};
6368
}
6469

70+
export function generateNativeProjectConfig(platform: Platform, args: readonly string[]): NativeProjectConfig {
71+
const directory = getOptionValue(args, `--${platform}-project`, platform);
72+
73+
return { directory };
74+
}
75+
76+
export function parseCopyOption(args: readonly string[]): boolean {
77+
return args.includes('--copy');
78+
}
79+
80+
export function parseSkipConfigOption(args: readonly string[]): boolean {
81+
return args.includes('--skip-config');
82+
}
83+
6584
export function parseAdaptiveIconResourceOptions(platform: Platform, resourcesDirectory: string, args: readonly string[]): AdaptiveIconResourceOptions | undefined {
6685
if (platform !== Platform.ANDROID) {
6786
return;

src/help.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const help = `
2-
Usage: cordova-res [ios|android] [options]
2+
Usage: cordova-res [ios|android|windows] [options]
33
44
Generate Cordova resources for native platforms.
55
@@ -28,15 +28,16 @@ const help = `
2828
2929
--type <icon|splash|adaptive-icon> ... Only generate one type of resource
3030
--resources <path> ................... Use specified directory as resources directory
31+
--skip-config ........................ Skip reading/writing to 'config.xml'
3132
3233
--icon-source <path> ................. Use specified file for icon source image
3334
--splash-source <path> ............... Use specified file for splash source image
3435
--icon-foreground-source <path> ...... Use file for foreground of adaptive icon
3536
--icon-background-source <path|hex> .. Use file or color for background of adaptive icon
3637
37-
--copy ............................... Enable process of copying generated resources to native projects
38-
--android-project <path> ............. Use specified directory for Android native project (default: 'android')
38+
--copy ............................... Copy generated resources to native projects
3939
--ios-project <path> ................. Use specified directory for iOS native project (default: 'ios')
40+
--android-project <path> ............. Use specified directory for Android native project (default: 'android')
4041
4142
-h, --help ........................... Print help for the platform, then quit
4243
--version ............................ Print version, then quit

0 commit comments

Comments
 (0)