Skip to content
Open
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
7 changes: 7 additions & 0 deletions lib/definitions/android-plugin-migrator.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ interface IAndroidBuildOptions {
tempPluginDirPath: string;
gradlePath?: string;
gradleArgs?: string;
/**
* Appended to the plugin name before it is shortened into the name of the
* produced `.aar`. The npm scope is dropped when shortening, so two plugins
* from different scopes can end up with the same `.aar` - a suffix tells
* them apart.
*/
aarSuffix?: string;
}

interface IAndroidPluginBuildService {
Expand Down
16 changes: 16 additions & 0 deletions lib/definitions/project.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { ICheckEnvironmentRequirementsOutput, IPlatformData } from "./platform";
import { IPluginData, IBasePluginData } from "./plugins";
import {
IDictionary,
IStringDictionary,
IProjectDir,
IDeviceIdentifier,
Expand Down Expand Up @@ -179,6 +180,21 @@ interface INsConfigAndroid extends INsConfigPlaform {
* Custom runtime package name
*/
runtimePackageName?: string;

/**
* Per plugin build options, keyed by the plugin's npm package name.
*/
plugins?: IDictionary<INsConfigAndroidPlugin>;
}

interface INsConfigAndroidPlugin {
/**
* Appended to the plugin name before it is shortened into the name of the
* produced `.aar`. The npm scope is dropped when shortening, so
* `@foo/plugin` and `@bar/plugin` both build a `plugin.aar` and overwrite
* each other - a suffix tells them apart.
*/
aarSuffix?: string;
}

interface INsConfigHooks {
Expand Down
10 changes: 7 additions & 3 deletions lib/services/android-plugin-build-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
const androidSourceDirectories = this.getAndroidSourceDirectories(
options.platformsAndroidDirPath,
);
const shortPluginName = getShortPluginName(options.pluginName);
// the npm scope is dropped when shortening, so an optional suffix is what
// keeps two same-named plugins from overwriting each other's `.aar`
const shortPluginName = getShortPluginName(
`${options.pluginName}${options.aarSuffix || ""}`,
);
const pluginTempDir = path.join(options.tempPluginDirPath, shortPluginName);
const pluginSourceFileHashesInfo = await this.getSourceFilesHashes(
options.platformsAndroidDirPath,
Expand Down Expand Up @@ -260,6 +264,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
options.platformsAndroidDirPath,
options.projectDir,
options.pluginName,
shortPluginName,
);
await this.buildPlugin({
gradlePath: options.gradlePath,
Expand Down Expand Up @@ -401,6 +406,7 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
platformsAndroidDirPath: string,
projectDir: string,
pluginName: string,
shortPluginName: string,
): Promise<void> {
const gradleTemplatePath = path.resolve(
path.join(__dirname, "../../vendor/gradle-plugin"),
Expand All @@ -425,8 +431,6 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService {
this.replaceFileContent(settingsGradlePath, "{{pluginName}}", pluginName);

// gets the package from the AndroidManifest to use as the namespace or fallback to the `org.nativescript.${shortPluginName}`
const shortPluginName = getShortPluginName(pluginName);

const manifestPath = path.join(
pluginTempDir,
"src",
Expand Down
3 changes: 3 additions & 0 deletions lib/services/android-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
AndroidProjectService.ANDROID_PLATFORM_NAME
);
if (this.$fs.exists(pluginPlatformsFolderPath)) {
const pluginConfig =
(projectData.nsConfig?.android?.plugins || {})[pluginData.name] || {};
const options: IPluginBuildOptions = {
gradlePath: this.$options.gradlePath,
gradleArgs: this.$options.gradleArgs,
Expand All @@ -696,6 +698,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
platformsAndroidDirPath: pluginPlatformsFolderPath,
aarOutputDir: pluginPlatformsFolderPath,
tempPluginDirPath: path.join(projectData.platformsDir, "tempPlugin"),
...pluginConfig,
};

if (await this.$androidPluginBuildService.buildAar(options)) {
Expand Down
37 changes: 33 additions & 4 deletions test/services/android-plugin-build-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe("androidPluginBuildService", () => {
const pluginName = "my-plugin";
const shortPluginName = getShortPluginName(pluginName);
let spawnFromEventCalled = false;
let builtPluginDirName: string = null;
let fs: IFileSystem;
let androidBuildPluginService: AndroidPluginBuildService;
let tempFolder: string;
Expand All @@ -46,6 +47,7 @@ describe("androidPluginBuildService", () => {
}): IPluginBuildOptions {
options = options || {};
spawnFromEventCalled = false;
builtPluginDirName = null;
tempFolder = mkdtempSync(
path.join(tmpdir(), "androidPluginBuildService-temp-"),
);
Expand Down Expand Up @@ -75,11 +77,16 @@ describe("androidPluginBuildService", () => {
const testInjector: IInjector = new stubs.InjectorStub();
testInjector.register("fs", FsLib.FileSystem);
testInjector.register("childProcess", {
spawnFromEvent: async (command: string): Promise<ISpawnResult> => {
const finalAarName = `${shortPluginName}-release.aar`;
spawnFromEvent: async (
command: string,
args: string[],
): Promise<ISpawnResult> => {
// the plugin dir gradle was pointed at is what names the built aar
const pluginDir = args[args.indexOf("-p") + 1];
builtPluginDirName = path.basename(pluginDir);
const finalAarName = `${builtPluginDirName}-release.aar`;
const aar = path.join(
tempFolder,
shortPluginName,
pluginDir,
"build",
"outputs",
"aar",
Expand Down Expand Up @@ -269,6 +276,28 @@ dependencies {
assert.isTrue(spawnFromEventCalled);
});

it("builds an aar named after the plugin", async () => {
const config: IPluginBuildOptions = setup({ addManifest: true });

await androidBuildPluginService.buildAar(config);

assert.deepStrictEqual(builtPluginDirName, shortPluginName);
assert.isTrue(
fs.exists(path.join(pluginFolder, `${shortPluginName}.aar`)),
);
});

it("appends aarSuffix to the name of the built aar", async () => {
const config: IPluginBuildOptions = setup({ addManifest: true });
config.aarSuffix = "-v2";

await androidBuildPluginService.buildAar(config);

const expectedName = getShortPluginName(`${pluginName}-v2`);
assert.deepStrictEqual(builtPluginDirName, expectedName);
assert.isTrue(fs.exists(path.join(pluginFolder, `${expectedName}.aar`)));
});

it("does not build aar when there are no supported files in the plugin", async () => {
const config: IPluginBuildOptions = setup();

Expand Down