Skip to content

Commit 22866f5

Browse files
committed
Rename PathSuffixChoice to LibraryNamingChoice and add packageName option defaulting to strip
1 parent e81ee53 commit 22866f5

File tree

5 files changed

+187
-37
lines changed

5 files changed

+187
-37
lines changed

packages/host/src/node/babel-plugin/plugin.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,22 @@ import {
99
isNodeApiModule,
1010
findNodeAddonForBindings,
1111
NamingStrategy,
12-
PathSuffixChoice,
13-
assertPathSuffix,
12+
LibraryNamingChoice,
13+
assertLibraryNamingChoice,
1414
} from "../path-utils";
1515

1616
export type PluginOptions = {
17+
/**
18+
* Controls how the package name is transformed into a library name.
19+
* The transformation is needed to disambiguate and avoid conflicts between addons with the same name (but in different sub-paths or packages).
20+
*
21+
* As an example, if the package name is `@my-org/my-pkg` and the path of the addon within the package is `build/Release/my-addon.node` (and `pathSuffix` is set to `"strip"`):
22+
* - `"omit"`: Only the path within the package is used and the library name will be `my-addon`.
23+
* - `"strip"`: Scope / org gets stripped and the library name will be `my-pkg--my-addon`.
24+
* - `"keep"`: The org and name is kept and the library name will be `my-org--my-pkg--my-addon`.
25+
*/
26+
packageName?: LibraryNamingChoice;
27+
1728
/**
1829
* Controls how the path of the addon inside a package is transformed into a library name.
1930
* The transformation is needed to disambiguate and avoid conflicts between addons with the same name (but in different sub-paths or packages).
@@ -23,13 +34,16 @@ export type PluginOptions = {
2334
* - `"strip"` (default): Path gets stripped to its basename and the library name will be `my-pkg--my-addon`.
2435
* - `"keep"`: The full path is kept and the library name will be `my-pkg--build-Release-my-addon`.
2536
*/
26-
pathSuffix?: PathSuffixChoice;
37+
pathSuffix?: LibraryNamingChoice;
2738
};
2839

2940
function assertOptions(opts: unknown): asserts opts is PluginOptions {
3041
assert(typeof opts === "object" && opts !== null, "Expected an object");
3142
if ("pathSuffix" in opts) {
32-
assertPathSuffix(opts.pathSuffix);
43+
assertLibraryNamingChoice(opts.pathSuffix);
44+
}
45+
if ("packageName" in opts) {
46+
assertLibraryNamingChoice(opts.packageName);
3347
}
3448
}
3549

@@ -57,7 +71,7 @@ export function plugin(): PluginObj {
5771
visitor: {
5872
CallExpression(p) {
5973
assertOptions(this.opts);
60-
const { pathSuffix = "strip" } = this.opts;
74+
const { pathSuffix = "strip", packageName = "strip" } = this.opts;
6175
if (typeof this.filename !== "string") {
6276
// This transformation only works when the filename is known
6377
return;
@@ -80,6 +94,7 @@ export function plugin(): PluginObj {
8094
const resolvedPath = findNodeAddonForBindings(id, from);
8195
if (typeof resolvedPath === "string") {
8296
replaceWithRequireNodeAddon(p.parentPath, resolvedPath, {
97+
packageName,
8398
pathSuffix,
8499
});
85100
}
@@ -89,7 +104,10 @@ export function plugin(): PluginObj {
89104
isNodeApiModule(path.join(from, id))
90105
) {
91106
const relativePath = path.join(from, id);
92-
replaceWithRequireNodeAddon(p, relativePath, { pathSuffix });
107+
replaceWithRequireNodeAddon(p, relativePath, {
108+
packageName,
109+
pathSuffix,
110+
});
93111
}
94112
}
95113
},
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
import { Option } from "@react-native-node-api/cli-utils";
22

3-
import { assertPathSuffix, PATH_SUFFIX_CHOICES } from "../path-utils";
3+
import {
4+
assertLibraryNamingChoice,
5+
LIBRARY_NAMING_CHOICES,
6+
} from "../path-utils";
47

5-
const { NODE_API_PATH_SUFFIX } = process.env;
8+
const { NODE_API_PACKAGE_NAME, NODE_API_PATH_SUFFIX } = process.env;
9+
if (typeof NODE_API_PACKAGE_NAME === "string") {
10+
assertLibraryNamingChoice(NODE_API_PACKAGE_NAME);
11+
}
612
if (typeof NODE_API_PATH_SUFFIX === "string") {
7-
assertPathSuffix(NODE_API_PATH_SUFFIX);
13+
assertLibraryNamingChoice(NODE_API_PATH_SUFFIX);
814
}
915

16+
export const packageNameOption = new Option(
17+
"--package-name <strategy>",
18+
"Controls how the package name is transformed into a library name",
19+
)
20+
.choices(LIBRARY_NAMING_CHOICES)
21+
.default(NODE_API_PACKAGE_NAME || "strip");
22+
1023
export const pathSuffixOption = new Option(
1124
"--path-suffix <strategy>",
1225
"Controls how the path of the addon inside a package is transformed into a library name",
1326
)
14-
.choices(PATH_SUFFIX_CHOICES)
27+
.choices(LIBRARY_NAMING_CHOICES)
1528
.default(NODE_API_PATH_SUFFIX || "strip");

packages/host/src/node/cli/program.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
} from "../path-utils";
2424

2525
import { command as vendorHermes } from "./hermes";
26-
import { pathSuffixOption } from "./options";
26+
import { packageNameOption, pathSuffixOption } from "./options";
2727
import { linkModules, pruneLinkedModules, ModuleLinker } from "./link-modules";
2828
import { linkXcframework } from "./apple";
2929
import { linkAndroidDir } from "./android";
@@ -70,10 +70,14 @@ program
7070
)
7171
.option("--android", "Link Android modules")
7272
.option("--apple", "Link Apple modules")
73+
.addOption(packageNameOption)
7374
.addOption(pathSuffixOption)
7475
.action(
7576
wrapAction(
76-
async (pathArg, { force, prune, pathSuffix, android, apple }) => {
77+
async (
78+
pathArg,
79+
{ force, prune, pathSuffix, android, apple, packageName },
80+
) => {
7781
console.log("Auto-linking Node-API modules from", chalk.dim(pathArg));
7882
const platforms: PlatformName[] = [];
7983
if (android) {
@@ -101,7 +105,7 @@ program
101105
platform,
102106
fromPath: path.resolve(pathArg),
103107
incremental: !force,
104-
naming: { pathSuffix },
108+
naming: { packageName, pathSuffix },
105109
linker: getLinker(platform),
106110
}),
107111
{
@@ -173,9 +177,10 @@ program
173177
.description("Lists Node-API modules")
174178
.argument("[from-path]", "Some path inside the app package", process.cwd())
175179
.option("--json", "Output as JSON", false)
180+
.addOption(packageNameOption)
176181
.addOption(pathSuffixOption)
177182
.action(
178-
wrapAction(async (fromArg, { json, pathSuffix }) => {
183+
wrapAction(async (fromArg, { json, pathSuffix, packageName }) => {
179184
const rootPath = path.resolve(fromArg);
180185
const dependencies = await findNodeApiModulePathsByDependency({
181186
fromPath: rootPath,
@@ -210,7 +215,7 @@ program
210215
);
211216
logModulePaths(
212217
dependency.modulePaths.map((p) => path.join(dependency.path, p)),
213-
{ pathSuffix },
218+
{ packageName, pathSuffix },
214219
);
215220
}
216221
}
@@ -222,21 +227,22 @@ program
222227
.description(
223228
"Utility to print, module path, the hash of a single Android library",
224229
)
230+
.addOption(packageNameOption)
225231
.addOption(pathSuffixOption)
226232
.action(
227-
wrapAction((pathInput, { pathSuffix }) => {
233+
wrapAction((pathInput, { pathSuffix, packageName }) => {
228234
const resolvedModulePath = path.resolve(pathInput);
229235
const normalizedModulePath = normalizeModulePath(resolvedModulePath);
230-
const { packageName, relativePath } =
231-
determineModuleContext(resolvedModulePath);
236+
const context = determineModuleContext(resolvedModulePath);
232237
const libraryName = getLibraryName(resolvedModulePath, {
238+
packageName,
233239
pathSuffix,
234240
});
235241
console.log({
236242
resolvedModulePath,
237243
normalizedModulePath,
238-
packageName,
239-
relativePath,
244+
packageName: context.packageName,
245+
relativePath: context.relativePath,
240246
libraryName,
241247
});
242248
}),

packages/host/src/node/path-utils.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,15 @@ describe("getLibraryName", () => {
209209
});
210210
assert.equal(
211211
getLibraryName(path.join(tempDirectoryPath, "addon"), {
212+
packageName: "keep",
212213
pathSuffix: "keep",
213214
}),
214215
"my-package--addon",
215216
);
216217

217218
assert.equal(
218219
getLibraryName(path.join(tempDirectoryPath, "sub-directory/addon"), {
220+
packageName: "keep",
219221
pathSuffix: "keep",
220222
}),
221223
"my-package--sub-directory-addon",
@@ -231,13 +233,15 @@ describe("getLibraryName", () => {
231233
});
232234
assert.equal(
233235
getLibraryName(path.join(tempDirectoryPath, "addon"), {
236+
packageName: "keep",
234237
pathSuffix: "strip",
235238
}),
236239
"my-package--addon",
237240
);
238241

239242
assert.equal(
240243
getLibraryName(path.join(tempDirectoryPath, "sub-directory", "addon"), {
244+
packageName: "keep",
241245
pathSuffix: "strip",
242246
}),
243247
"my-package--addon",
@@ -253,18 +257,62 @@ describe("getLibraryName", () => {
253257
});
254258
assert.equal(
255259
getLibraryName(path.join(tempDirectoryPath, "addon"), {
260+
packageName: "keep",
256261
pathSuffix: "omit",
257262
}),
258263
"my-package",
259264
);
260265

261266
assert.equal(
262267
getLibraryName(path.join(tempDirectoryPath, "sub-directory", "addon"), {
268+
packageName: "keep",
263269
pathSuffix: "omit",
264270
}),
265271
"my-package",
266272
);
267273
});
274+
275+
it("keeps and escapes scope from package name", (context) => {
276+
const tempDirectoryPath = setupTempDirectory(context, {
277+
"package.json": `{ "name": "@my-org/my-package" }`,
278+
"addon.apple.node/addon.node": "// This is supposed to be a binary file",
279+
});
280+
assert.equal(
281+
getLibraryName(path.join(tempDirectoryPath, "addon"), {
282+
packageName: "keep",
283+
pathSuffix: "strip",
284+
}),
285+
"my-org--my-package--addon",
286+
);
287+
});
288+
289+
it("strips scope from package name", (context) => {
290+
const tempDirectoryPath = setupTempDirectory(context, {
291+
"package.json": `{ "name": "@my-org/my-package" }`,
292+
"addon.apple.node/addon.node": "// This is supposed to be a binary file",
293+
});
294+
assert.equal(
295+
getLibraryName(path.join(tempDirectoryPath, "addon"), {
296+
packageName: "strip",
297+
pathSuffix: "strip",
298+
}),
299+
"my-package--addon",
300+
);
301+
});
302+
303+
it("omits scope from package name", (context) => {
304+
const tempDirectoryPath = setupTempDirectory(context, {
305+
"package.json": `{ "name": "@my-org/my-package" }`,
306+
"addon.apple.node/addon.node": "// This is supposed to be a binary file",
307+
});
308+
assert.equal(
309+
getLibraryName(path.join(tempDirectoryPath, "addon"), {
310+
packageName: "omit",
311+
pathSuffix: "strip",
312+
}),
313+
"addon",
314+
);
315+
});
268316
});
269317

270318
describe("findPackageDependencyPaths", () => {

0 commit comments

Comments
 (0)