Skip to content

Commit

Permalink
feat: add the aar target
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-oakes committed Jun 10, 2019
1 parent e98ce57 commit c6ea5cf
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 8 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

The CLI can build code for following targets:

- Android AAR files
- Generic CommonJS build
- ES modules build for bundlers such as webpack
- Flow definitions (copies .js files to .flow files)
Expand Down Expand Up @@ -40,6 +41,7 @@ To configure your project manually, follow these steps:
"source": "src",
"output": "lib",
"targets": [
["aar", {"reverseJetify": true}],
["commonjs", {"flow": true}],
"module",
"typescript",
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"metro-react-native-babel-preset": "^0.53.1",
"yargs": "^13.2.2"
},
"optionalDependencies": {
"jetifier": "^1.0.0-beta04.2"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/preset-env": "^7.4.2",
Expand Down
12 changes: 11 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import inquirer from 'inquirer';
import cosmiconfig from 'cosmiconfig';
import isGitDirty from 'is-git-dirty';
import * as logger from './utils/logger';
import buildAAR from './targets/aar';
import buildCommonJS from './targets/commonjs';
import buildModule from './targets/module';
import buildTypescript from './targets/typescript';
Expand Down Expand Up @@ -78,7 +79,7 @@ yargs
type: 'checkbox',
name: 'targets',
message: 'Which targets do you want to build?',
choices: ['commonjs', 'module', 'typescript'],
choices: ['aar', 'commonjs', 'module', 'typescript'],
validate: input => Boolean(input.length),
},
];
Expand Down Expand Up @@ -286,6 +287,15 @@ yargs
report.info(`Building target ${chalk.blue(targetName)}`);

switch (targetName) {
case 'aar':
await buildAAR({
root,
source: path.resolve(root, source as string),
output: path.resolve(root, output as string, 'aar'),
options: targetOptions,
report,
});
break;
case 'commonjs':
await buildCommonJS({
root,
Expand Down
96 changes: 96 additions & 0 deletions src/targets/aar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import path from 'path';
import chalk from 'chalk';
import fs from 'fs-extra';
import del from 'del';
import androidAssemble from '../utils/androidAssemble';
import { Input } from '../types';
import jetifier from '../utils/jetifier';

type TargetOptions = {
androidPath: string,
reverseJetify: boolean
};

const defaultOptions: TargetOptions = {
androidPath: "android",
reverseJetify: false
};

type Options = Input & {
options?: Partial<TargetOptions>;
};

async function createGradleFile(file: string) {
await fs.createFile(file);
await fs.writeFile(file, 'configurations.maybeCreate("default")\nartifacts.add("default", file(\'android.aar\'))')
}

export default async function build({
root,
output,
options,
report,
}: Options) {
const targetOptions = {
...defaultOptions,
...options
};

report.info(
`Cleaning up previous build at ${chalk.blue(path.relative(root, output))}`
);

await del([output]);

await androidAssemble({ root, androidPath: targetOptions.androidPath, report });

report.info(
`Creating new output directory at ${chalk.blue(path.relative(root, output))}`
);
await fs.mkdir(output);

const sourceAar = path.join(targetOptions.androidPath, 'build', 'outputs', 'aar', 'android.aar');
const targetAar = path.join(output, 'android.aar');

report.info(
`Copying AAR from ${chalk.blue(path.relative(root, sourceAar))} to ${chalk.blue(path.relative(root, targetAar))}`
);
await fs.copyFile(sourceAar, targetAar);

const gradleFile = path.join(output, 'build.gradle');
report.info(
`Creating AAR Gradle file at ${chalk.blue(path.relative(root, gradleFile))}`
);
await createGradleFile(gradleFile);

if (targetOptions.reverseJetify) {
const supportOutputPath = path.join(output, 'support');
report.info(
`Creating new support output directory at ${chalk.blue(path.relative(root, supportOutputPath))}`
);
await fs.mkdir(supportOutputPath);

const supportAar = path.join(supportOutputPath, 'android.aar');
report.info(
`Using Jetifier to convert AAR from AndroidX to Support AAR at ${chalk.blue(path.relative(root, supportAar))}`
);

await jetifier({
root,
report,
input: targetAar,
output: supportAar,
reverse: true
});

const supportGradleFile = path.join(supportOutputPath, 'build.gradle');
report.info(
`Creating Support AAR Gradle file at ${chalk.blue(path.relative(root, supportGradleFile))}`
);
await createGradleFile(supportGradleFile);
}

report.success(
`Wrote files to ${chalk.blue(path.relative(root, output))}`
);
}
15 changes: 8 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
export type Log = (message: string) => void;
export type Report = {
info: Log;
warn: Log;
success: Log;
error: Log;
};

export type Input = {
root: string;
source: string;
output: string;
report: {
info: Log;
warn: Log;
success: Log;
error: Log;
};
report: Report;
};

export type Target = 'commonjs' | 'module' | 'typescript';
export type Target = 'aar' | 'commonjs' | 'module' | 'typescript';

export type Options = {
source?: string;
Expand Down
35 changes: 35 additions & 0 deletions src/utils/androidAssemble.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import path from 'path';
import chalk from 'chalk';
import fs from 'fs-extra';
import { execFileSync } from 'child_process';
import { platform } from 'os';
import { Report } from '../types';

type Options = {
root: string;
androidPath: string;
report: Report;
};

export default async function androidAssemble({ root, androidPath, report }: Options) {
const cwd = path.relative(root, androidPath)

report.info(
`Assembling Android project in ${chalk.blue(cwd)} with ${chalk.blue('gradle')}`
);

const gradleWrapper = './gradlew' + ((platform() === "win32") ? './gradlew.bat' : '');
if (await fs.pathExists(path.join(androidPath, gradleWrapper))) {
execFileSync(gradleWrapper, ['assemble'], { cwd: androidPath });
} else {
throw new Error(
`The ${chalk.blue(
'gradlew'
)} script doesn't seem to present in ${chalk.blue(
androidPath
)}. Make sure you have added it by running ${chalk.blue(
'gradle wrapper'
)} in that directory.`
);
}
}
36 changes: 36 additions & 0 deletions src/utils/jetifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import path from 'path';
import chalk from 'chalk';
import { execFileSync } from 'child_process';
import fs from 'fs-extra';
import { Report } from '../types';

type Options = {
root: string;
input: string;
output: string;
reverse: boolean;
report: Report;
};

export default async function jetifier({ root, input, output, reverse }: Options) {
const jetifierStandalone = path.join(root, 'node_modules', '.bin', 'jetifier-standalone')

if (await fs.pathExists(jetifierStandalone)) {
const args = ['-i', input, '-o', output];
if (reverse) {
args.push("-r");
}

execFileSync(jetifierStandalone, args);
} else {
throw new Error(
`The ${chalk.blue(
'jetifier'
)} binary doesn't seem to be installed under ${chalk.blue(
'node_modules'
)}. Make sure you have added ${chalk.blue(
'jetifier'
)} to your ${chalk.blue('devDependencies')}.`
);
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3092,6 +3092,11 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=

jetifier@^1.0.0-beta04.2:
version "1.0.0-beta04.2"
resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.0.0-beta04.2.tgz#c1bc0adb0fa1a334bb9dd114dcd813c26ac68325"
integrity sha512-4dlUoWJRq3k0A0SaQ11Drh3D/eYcwBt+3N0QeTcE9t2Xe8GkQMrh19/GPzNjE21Q5gDNZFqBcIvjAzB73iwuhw==

js-levenshtein@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
Expand Down

0 comments on commit c6ea5cf

Please sign in to comment.