Skip to content

Commit c6ea5cf

Browse files
committed
feat: add the aar target
1 parent e98ce57 commit c6ea5cf

File tree

8 files changed

+196
-8
lines changed

8 files changed

+196
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
The CLI can build code for following targets:
88

9+
- Android AAR files
910
- Generic CommonJS build
1011
- ES modules build for bundlers such as webpack
1112
- Flow definitions (copies .js files to .flow files)
@@ -40,6 +41,7 @@ To configure your project manually, follow these steps:
4041
"source": "src",
4142
"output": "lib",
4243
"targets": [
44+
["aar", {"reverseJetify": true}],
4345
["commonjs", {"flow": true}],
4446
"module",
4547
"typescript",

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
"metro-react-native-babel-preset": "^0.53.1",
3737
"yargs": "^13.2.2"
3838
},
39+
"optionalDependencies": {
40+
"jetifier": "^1.0.0-beta04.2"
41+
},
3942
"devDependencies": {
4043
"@babel/cli": "^7.2.3",
4144
"@babel/preset-env": "^7.4.2",

src/cli.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import inquirer from 'inquirer';
66
import cosmiconfig from 'cosmiconfig';
77
import isGitDirty from 'is-git-dirty';
88
import * as logger from './utils/logger';
9+
import buildAAR from './targets/aar';
910
import buildCommonJS from './targets/commonjs';
1011
import buildModule from './targets/module';
1112
import buildTypescript from './targets/typescript';
@@ -78,7 +79,7 @@ yargs
7879
type: 'checkbox',
7980
name: 'targets',
8081
message: 'Which targets do you want to build?',
81-
choices: ['commonjs', 'module', 'typescript'],
82+
choices: ['aar', 'commonjs', 'module', 'typescript'],
8283
validate: input => Boolean(input.length),
8384
},
8485
];
@@ -286,6 +287,15 @@ yargs
286287
report.info(`Building target ${chalk.blue(targetName)}`);
287288

288289
switch (targetName) {
290+
case 'aar':
291+
await buildAAR({
292+
root,
293+
source: path.resolve(root, source as string),
294+
output: path.resolve(root, output as string, 'aar'),
295+
options: targetOptions,
296+
report,
297+
});
298+
break;
289299
case 'commonjs':
290300
await buildCommonJS({
291301
root,

src/targets/aar.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import path from 'path';
2+
import chalk from 'chalk';
3+
import fs from 'fs-extra';
4+
import del from 'del';
5+
import androidAssemble from '../utils/androidAssemble';
6+
import { Input } from '../types';
7+
import jetifier from '../utils/jetifier';
8+
9+
type TargetOptions = {
10+
androidPath: string,
11+
reverseJetify: boolean
12+
};
13+
14+
const defaultOptions: TargetOptions = {
15+
androidPath: "android",
16+
reverseJetify: false
17+
};
18+
19+
type Options = Input & {
20+
options?: Partial<TargetOptions>;
21+
};
22+
23+
async function createGradleFile(file: string) {
24+
await fs.createFile(file);
25+
await fs.writeFile(file, 'configurations.maybeCreate("default")\nartifacts.add("default", file(\'android.aar\'))')
26+
}
27+
28+
export default async function build({
29+
root,
30+
output,
31+
options,
32+
report,
33+
}: Options) {
34+
const targetOptions = {
35+
...defaultOptions,
36+
...options
37+
};
38+
39+
report.info(
40+
`Cleaning up previous build at ${chalk.blue(path.relative(root, output))}`
41+
);
42+
43+
await del([output]);
44+
45+
await androidAssemble({ root, androidPath: targetOptions.androidPath, report });
46+
47+
report.info(
48+
`Creating new output directory at ${chalk.blue(path.relative(root, output))}`
49+
);
50+
await fs.mkdir(output);
51+
52+
const sourceAar = path.join(targetOptions.androidPath, 'build', 'outputs', 'aar', 'android.aar');
53+
const targetAar = path.join(output, 'android.aar');
54+
55+
report.info(
56+
`Copying AAR from ${chalk.blue(path.relative(root, sourceAar))} to ${chalk.blue(path.relative(root, targetAar))}`
57+
);
58+
await fs.copyFile(sourceAar, targetAar);
59+
60+
const gradleFile = path.join(output, 'build.gradle');
61+
report.info(
62+
`Creating AAR Gradle file at ${chalk.blue(path.relative(root, gradleFile))}`
63+
);
64+
await createGradleFile(gradleFile);
65+
66+
if (targetOptions.reverseJetify) {
67+
const supportOutputPath = path.join(output, 'support');
68+
report.info(
69+
`Creating new support output directory at ${chalk.blue(path.relative(root, supportOutputPath))}`
70+
);
71+
await fs.mkdir(supportOutputPath);
72+
73+
const supportAar = path.join(supportOutputPath, 'android.aar');
74+
report.info(
75+
`Using Jetifier to convert AAR from AndroidX to Support AAR at ${chalk.blue(path.relative(root, supportAar))}`
76+
);
77+
78+
await jetifier({
79+
root,
80+
report,
81+
input: targetAar,
82+
output: supportAar,
83+
reverse: true
84+
});
85+
86+
const supportGradleFile = path.join(supportOutputPath, 'build.gradle');
87+
report.info(
88+
`Creating Support AAR Gradle file at ${chalk.blue(path.relative(root, supportGradleFile))}`
89+
);
90+
await createGradleFile(supportGradleFile);
91+
}
92+
93+
report.success(
94+
`Wrote files to ${chalk.blue(path.relative(root, output))}`
95+
);
96+
}

src/types.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
export type Log = (message: string) => void;
2+
export type Report = {
3+
info: Log;
4+
warn: Log;
5+
success: Log;
6+
error: Log;
7+
};
28

39
export type Input = {
410
root: string;
511
source: string;
612
output: string;
7-
report: {
8-
info: Log;
9-
warn: Log;
10-
success: Log;
11-
error: Log;
12-
};
13+
report: Report;
1314
};
1415

15-
export type Target = 'commonjs' | 'module' | 'typescript';
16+
export type Target = 'aar' | 'commonjs' | 'module' | 'typescript';
1617

1718
export type Options = {
1819
source?: string;

src/utils/androidAssemble.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import path from 'path';
2+
import chalk from 'chalk';
3+
import fs from 'fs-extra';
4+
import { execFileSync } from 'child_process';
5+
import { platform } from 'os';
6+
import { Report } from '../types';
7+
8+
type Options = {
9+
root: string;
10+
androidPath: string;
11+
report: Report;
12+
};
13+
14+
export default async function androidAssemble({ root, androidPath, report }: Options) {
15+
const cwd = path.relative(root, androidPath)
16+
17+
report.info(
18+
`Assembling Android project in ${chalk.blue(cwd)} with ${chalk.blue('gradle')}`
19+
);
20+
21+
const gradleWrapper = './gradlew' + ((platform() === "win32") ? './gradlew.bat' : '');
22+
if (await fs.pathExists(path.join(androidPath, gradleWrapper))) {
23+
execFileSync(gradleWrapper, ['assemble'], { cwd: androidPath });
24+
} else {
25+
throw new Error(
26+
`The ${chalk.blue(
27+
'gradlew'
28+
)} script doesn't seem to present in ${chalk.blue(
29+
androidPath
30+
)}. Make sure you have added it by running ${chalk.blue(
31+
'gradle wrapper'
32+
)} in that directory.`
33+
);
34+
}
35+
}

src/utils/jetifier.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import path from 'path';
2+
import chalk from 'chalk';
3+
import { execFileSync } from 'child_process';
4+
import fs from 'fs-extra';
5+
import { Report } from '../types';
6+
7+
type Options = {
8+
root: string;
9+
input: string;
10+
output: string;
11+
reverse: boolean;
12+
report: Report;
13+
};
14+
15+
export default async function jetifier({ root, input, output, reverse }: Options) {
16+
const jetifierStandalone = path.join(root, 'node_modules', '.bin', 'jetifier-standalone')
17+
18+
if (await fs.pathExists(jetifierStandalone)) {
19+
const args = ['-i', input, '-o', output];
20+
if (reverse) {
21+
args.push("-r");
22+
}
23+
24+
execFileSync(jetifierStandalone, args);
25+
} else {
26+
throw new Error(
27+
`The ${chalk.blue(
28+
'jetifier'
29+
)} binary doesn't seem to be installed under ${chalk.blue(
30+
'node_modules'
31+
)}. Make sure you have added ${chalk.blue(
32+
'jetifier'
33+
)} to your ${chalk.blue('devDependencies')}.`
34+
);
35+
}
36+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,6 +3092,11 @@ isobject@^3.0.0, isobject@^3.0.1:
30923092
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
30933093
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
30943094

3095+
jetifier@^1.0.0-beta04.2:
3096+
version "1.0.0-beta04.2"
3097+
resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.0.0-beta04.2.tgz#c1bc0adb0fa1a334bb9dd114dcd813c26ac68325"
3098+
integrity sha512-4dlUoWJRq3k0A0SaQ11Drh3D/eYcwBt+3N0QeTcE9t2Xe8GkQMrh19/GPzNjE21Q5gDNZFqBcIvjAzB73iwuhw==
3099+
30953100
js-levenshtein@^1.1.3:
30963101
version "1.1.6"
30973102
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"

0 commit comments

Comments
 (0)