Skip to content

Commit 983c3b7

Browse files
Dimitar TachevDimitar Tachev
authored andcommitted
refactor: make the buildAar method shorter and more readable
1 parent cff6778 commit 983c3b7

File tree

2 files changed

+82
-90
lines changed

2 files changed

+82
-90
lines changed

lib/definitions/android-plugin-migrator.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ interface IBuildAndroidPluginData {
3333
/**
3434
* Information about tools that will be used to build the plugin, for example compile SDK version, build tools version, etc.
3535
*/
36-
androidToolsInfo: IAndroidToolsInfoData;
36+
androidToolsInfo?: IAndroidToolsInfoData;
3737
}

lib/services/android-plugin-build-service.ts

Lines changed: 81 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Builder, parseString } from "xml2js";
55
import { ILogger } from "log4js";
66

77
export class AndroidPluginBuildService implements IAndroidPluginBuildService {
8-
98
/**
109
* Required for hooks execution to work.
1110
*/
@@ -164,113 +163,101 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
164163
*/
165164
public async buildAar(options: IBuildOptions): Promise<boolean> {
166165
this.validateOptions(options);
167-
168-
// IDEA: Accept as an additional parameter the Android Support Library version from CLI, pass it on as -PsupportVersion later to the build
169-
// IDEA: apply app.gradle here in order to get any and all user-defined variables
170-
// IDEA: apply the entire include.gradle here instead of copying over the repositories {} and dependencies {} scopes
171-
172-
const shortPluginName = getShortPluginName(options.pluginName);
173-
const newPluginDir = path.join(options.tempPluginDirPath, shortPluginName);
174-
const newPluginMainSrcDir = path.join(newPluginDir, "src", "main");
175-
const defaultPackageName = "org.nativescript." + shortPluginName;
176-
177-
// find manifest file
178-
//// prepare manifest file content
179166
const manifestFilePath = this.getManifest(options.platformsAndroidDirPath);
180-
let shouldBuildAar = false;
181-
182-
// look for AndroidManifest.xml
183-
if (manifestFilePath) {
184-
shouldBuildAar = true;
185-
}
186-
187-
// look for android resources
188167
const androidSourceSetDirectories = this.getAndroidSourceDirectories(options.platformsAndroidDirPath);
168+
const shouldBuildAar = !!manifestFilePath || androidSourceSetDirectories.length > 0;
189169

190-
if (androidSourceSetDirectories.length > 0) {
191-
shouldBuildAar = true;
192-
}
193-
194-
// if a manifest OR/AND resource files are present - write files, build plugin
195170
if (shouldBuildAar) {
196-
let updatedManifestContent;
197-
this.$fs.ensureDirectoryExists(newPluginMainSrcDir);
198-
199-
if (manifestFilePath) {
200-
let androidManifestContent;
201-
try {
202-
androidManifestContent = this.$fs.readText(manifestFilePath);
203-
} catch (err) {
204-
throw new Error(
205-
`Failed to fs.readFileSync the manifest file located at ${manifestFilePath}`
206-
);
207-
}
171+
const shortPluginName = getShortPluginName(options.pluginName);
172+
const pluginTempDir = path.join(options.tempPluginDirPath, shortPluginName);
173+
const pluginTempMainSrcDir = path.join(pluginTempDir, "src", "main");
174+
175+
await this.updateManifest(manifestFilePath, pluginTempMainSrcDir, shortPluginName);
176+
this.copySourceSetDirectories(androidSourceSetDirectories, pluginTempMainSrcDir);
177+
this.setupGradle(pluginTempDir, options.platformsAndroidDirPath);
178+
await this.buildPlugin({ pluginDir: pluginTempDir, pluginName: options.pluginName });
179+
this.copyAar(shortPluginName, pluginTempDir, options.aarOutputDir);
180+
}
208181

209-
updatedManifestContent = await this.updateManifestContent(androidManifestContent, defaultPackageName);
210-
} else {
211-
updatedManifestContent = this.createManifestContent(defaultPackageName);
212-
}
182+
return shouldBuildAar;
183+
}
213184

214-
// write the AndroidManifest in the temp-dir/plugin-name/src/main
215-
const pathToNewAndroidManifest = path.join(newPluginMainSrcDir, MANIFEST_FILE_NAME);
185+
private async updateManifest(manifestFilePath: string, pluginTempMainSrcDir: string, shortPluginName: string): Promise<void> {
186+
let updatedManifestContent;
187+
this.$fs.ensureDirectoryExists(pluginTempMainSrcDir);
188+
const defaultPackageName = "org.nativescript." + shortPluginName;
189+
if (manifestFilePath) {
190+
let androidManifestContent;
216191
try {
217-
this.$fs.writeFile(pathToNewAndroidManifest, updatedManifestContent);
218-
} catch (e) {
219-
throw new Error(`Failed to write the updated AndroidManifest in the new location - ${pathToNewAndroidManifest}`);
192+
androidManifestContent = this.$fs.readText(manifestFilePath);
193+
} catch (err) {
194+
throw new Error(
195+
`Failed to fs.readFileSync the manifest file located at ${manifestFilePath}`
196+
);
220197
}
221198

222-
// copy all android sourceset directories to the new temporary plugin dir
223-
for (const dir of androidSourceSetDirectories) {
224-
// get only the last subdirectory of the entire path string. e.g. 'res', 'java', etc.
225-
const dirNameParts = dir.split(path.sep);
226-
const dirName = dirNameParts[dirNameParts.length - 1];
199+
updatedManifestContent = await this.updateManifestContent(androidManifestContent, defaultPackageName);
200+
} else {
201+
updatedManifestContent = this.createManifestContent(defaultPackageName);
202+
}
227203

228-
const destination = path.join(newPluginMainSrcDir, dirName);
229-
this.$fs.ensureDirectoryExists(destination);
204+
const pathToTempAndroidManifest = path.join(pluginTempMainSrcDir, MANIFEST_FILE_NAME);
205+
try {
206+
this.$fs.writeFile(pathToTempAndroidManifest, updatedManifestContent);
207+
} catch (e) {
208+
throw new Error(`Failed to write the updated AndroidManifest in the new location - ${pathToTempAndroidManifest}`);
209+
}
210+
}
230211

231-
this.$fs.copyFile(path.join(dir, "*"), destination);
232-
}
212+
private copySourceSetDirectories(androidSourceSetDirectories: string[], pluginTempMainSrcDir: string): void {
213+
for (const dir of androidSourceSetDirectories) {
214+
const dirNameParts = dir.split(path.sep);
215+
// get only the last subdirectory of the entire path string. e.g. 'res', 'java', etc.
216+
const dirName = dirNameParts[dirNameParts.length - 1];
217+
const destination = path.join(pluginTempMainSrcDir, dirName);
233218

234-
// copy the preconfigured gradle android library project template to the temporary android library
235-
this.$fs.copyFile(path.join(path.resolve(path.join(__dirname, AndroidPluginBuildService.ANDROID_PLUGIN_GRADLE_TEMPLATE), "*")), newPluginDir);
219+
this.$fs.ensureDirectoryExists(destination);
220+
this.$fs.copyFile(path.join(dir, "*"), destination);
221+
}
222+
}
236223

237-
// sometimes the AndroidManifest.xml or certain resources in /res may have a compile dependency to a library referenced in include.gradle. Make sure to compile the plugin with a compile dependency to those libraries
238-
const includeGradlePath = path.join(options.platformsAndroidDirPath, INCLUDE_GRADLE_NAME);
239-
if (this.$fs.exists(includeGradlePath)) {
240-
const includeGradleContent = this.$fs.readText(includeGradlePath);
241-
const repositoriesAndDependenciesScopes = this.getIncludeGradleCompileDependenciesScope(includeGradleContent);
224+
private setupGradle(pluginTempDir: string, platformsAndroidDirPath: string): void {
225+
const gradleTemplatePath = path.resolve(path.join(__dirname, AndroidPluginBuildService.ANDROID_PLUGIN_GRADLE_TEMPLATE));
226+
const allGradleTemplateFiles = path.join(gradleTemplatePath, "*");
242227

243-
// dependencies { } object was found - append dependencies scope
244-
if (repositoriesAndDependenciesScopes.length > 0) {
245-
const buildGradlePath = path.join(newPluginDir, "build.gradle");
246-
this.$fs.appendFile(buildGradlePath, "\n" + repositoriesAndDependenciesScopes.join("\n"));
247-
}
248-
}
228+
this.$fs.copyFile(allGradleTemplateFiles, pluginTempDir);
229+
this.addCompileDependencies(platformsAndroidDirPath, pluginTempDir);
230+
// TODO: replace placeholders in target destination
231+
}
249232

250-
// finally build the plugin
251-
this.$androidToolsInfo.validateInfo({ showWarningsAsErrors: true, validateTargetSdk: true });
252-
const androidToolsInfo = this.$androidToolsInfo.getToolsInfo();
253-
await this.buildPlugin( { pluginDir: newPluginDir, pluginName: options.pluginName, androidToolsInfo });
254-
255-
const finalAarName = `${shortPluginName}-release.aar`;
256-
const pathToBuiltAar = path.join(newPluginDir, "build", "outputs", "aar", finalAarName);
257-
258-
if (this.$fs.exists(pathToBuiltAar)) {
259-
try {
260-
if (options.aarOutputDir) {
261-
this.$fs.copyFile(pathToBuiltAar, path.join(options.aarOutputDir, `${shortPluginName}.aar`));
262-
}
263-
} catch (e) {
264-
throw new Error(`Failed to copy built aar to destination. ${e.message}`);
265-
}
233+
private addCompileDependencies(platformsAndroidDirPath: string, pluginTempDir: string): void {
234+
const includeGradlePath = path.join(platformsAndroidDirPath, INCLUDE_GRADLE_NAME);
235+
if (this.$fs.exists(includeGradlePath)) {
236+
const includeGradleContent = this.$fs.readText(includeGradlePath);
237+
const repositoriesAndDependenciesScopes = this.getIncludeGradleCompileDependenciesScope(includeGradleContent);
266238

267-
return true;
268-
} else {
269-
throw new Error(`No built aar found at ${pathToBuiltAar}`);
239+
if (repositoriesAndDependenciesScopes.length > 0) {
240+
const buildGradlePath = path.join(pluginTempDir, "build.gradle");
241+
this.$fs.appendFile(buildGradlePath, "\n" + repositoriesAndDependenciesScopes.join("\n"));
270242
}
271243
}
244+
}
272245

273-
return false;
246+
private copyAar(shortPluginName: string, pluginTempDir: string, aarOutputDir: string): void {
247+
const finalAarName = `${shortPluginName}-release.aar`;
248+
const pathToBuiltAar = path.join(pluginTempDir, "build", "outputs", "aar", finalAarName);
249+
250+
if (this.$fs.exists(pathToBuiltAar)) {
251+
try {
252+
if (aarOutputDir) {
253+
this.$fs.copyFile(pathToBuiltAar, path.join(aarOutputDir, `${shortPluginName}.aar`));
254+
}
255+
} catch (e) {
256+
throw new Error(`Failed to copy built aar to destination. ${e.message}`);
257+
}
258+
} else {
259+
throw new Error(`No built aar found at ${pathToBuiltAar}`);
260+
}
274261
}
275262

276263
/**
@@ -307,6 +294,11 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
307294

308295
@hook("buildAndroidPlugin")
309296
private async buildPlugin(pluginBuildSettings: IBuildAndroidPluginData): Promise<void> {
297+
if (!pluginBuildSettings.androidToolsInfo) {
298+
this.$androidToolsInfo.validateInfo({ showWarningsAsErrors: true, validateTargetSdk: true });
299+
pluginBuildSettings.androidToolsInfo = this.$androidToolsInfo.getToolsInfo();
300+
}
301+
310302
const gradlew = this.$hostInfo.isWindows ? "gradlew.bat" : "./gradlew";
311303

312304
const localArgs = [

0 commit comments

Comments
 (0)