Skip to content

fix(config): make it clear that configure-test-app performs a reset #2262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
41 changes: 37 additions & 4 deletions scripts/configure.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ export function mergeConfig(lhs, rhs) {
};
}

/**
* Returns whether `react-native.config.js` needs to be updated.
* @param {string} configPath
* @returns {boolean}
*/
export function shouldUpdateReactNativeConfig(configPath, fs = nodefs) {
if (!fs.existsSync(configPath)) {
return true;
}

const config = readTextFile(configPath, fs);
return (
!/["'`]react-native-test-app["'`]/.test(config) ||
!config.includes("configureProjects")
);
}

/**
* Sort the keys in specified object.
* @param {Record<string, unknown>} obj
Expand Down Expand Up @@ -609,15 +626,14 @@ export function updatePackageManifest(

/**
* Writes all specified files to disk.
* @param {Configuration["files"]} files
* @param {[string, string | FileCopy][]} files
* @param {string} destination
* @returns {Promise<void[]>}
*/
export function writeAllFiles(files, destination, fs = nodefs.promises) {
const options = { recursive: true, mode: 0o755 };
return Promise.all(
Object.keys(files).map(async (filename) => {
const content = files[filename];
files.map(async ([filename, content]) => {
if (!content) {
return;
}
Expand Down Expand Up @@ -665,8 +681,25 @@ export function configure(params, fs = nodefs) {
}

const { files, oldFiles } = config;
const templateFiles = Object.entries(files).filter(([filename]) => {
switch (filename) {
case "react-native.config.js": {
const configPath = path.join(packagePath, filename);
const needsUpdate = shouldUpdateReactNativeConfig(configPath);
if (!needsUpdate) {
warn(
`skipped modifying '${filename}' because it may already be configured for 'react-native-test-app'`
);
}
return needsUpdate;
}

default:
return true;
}
});

writeAllFiles(files, packagePath).then(() => {
writeAllFiles(templateFiles, packagePath).then(() => {
const packageManifest = path.join(packagePath, "package.json");
if (!fs.existsSync(packageManifest)) {
// We cannot assume that the app itself is an npm package. Some libraries
Expand Down
2 changes: 1 addition & 1 deletion test/android/gradle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async function makeProject(
init: true,
});

await writeAllFiles(files, packagePath);
await writeAllFiles(Object.entries(files), packagePath);

try {
await fsp.symlink(
Expand Down
57 changes: 57 additions & 0 deletions test/configure/shouldUpdateReactNativeConfig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ok } from "node:assert/strict";
import { afterEach, describe, it } from "node:test";
import { shouldUpdateReactNativeConfig as shouldUpdateReactNativeConfigActual } from "../../scripts/configure.mjs";
import { fs, setMockFiles } from "../fs.mock.js";

describe("shouldUpdateReactNativeConfig()", () => {
const rnConfigFile = "react-native.config.js";

const shouldUpdateReactNativeConfig = () =>
shouldUpdateReactNativeConfigActual(rnConfigFile, fs);

afterEach(() => setMockFiles());

it("returns true if `react-native.config.js` does not exist", () => {
ok(shouldUpdateReactNativeConfig());
});

it("returns true if `react-native.config.js` is not configured", () => {
setMockFiles({ [rnConfigFile]: "module.exports = {};" });

ok(shouldUpdateReactNativeConfig());
});

it("returns true if `react-native-test-app` is mentioned but not used", () => {
setMockFiles({
[rnConfigFile]: `// TODO: Use 'react-native-test-app'
module.exports = {};
`,
});

ok(shouldUpdateReactNativeConfig());
});

it("returns false if `react-native-test-app` is configured", () => {
setMockFiles({
[rnConfigFile]: `const { configureProjects } = require("react-native-test-app");
module.exports = {
project: configureProjects({
android: {
sourceDir: "android",
},
ios: {
sourceDir: "ios",
},
}),
dependencies: {
MyPackage: {
root: require("node:path").dirname(__dirname),
},
},
};
`,
});

ok(!shouldUpdateReactNativeConfig());
});
});
44 changes: 21 additions & 23 deletions test/configure/writeAllFiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ describe("writeAllFiles()", () => {
it("writes all files to disk", async () => {
setMockFiles({ "file-on-disk": "0" });
await writeAllFiles(
{
file0: { source: "file-on-disk" },
file1: "1",
file2: "2",
},
[
["file0", { source: "file-on-disk" }],
["file1", "1"],
["file2", "2"],
],
"test"
);

Expand All @@ -32,11 +32,11 @@ describe("writeAllFiles()", () => {

it("ignores files with no content", async () => {
await writeAllFiles(
{
file1: "1",
file2: "2",
file3: "",
},
[
["file1", "1"],
["file2", "2"],
["file3", ""],
],
"."
);

Expand All @@ -48,25 +48,23 @@ describe("writeAllFiles()", () => {
it("rethrows write exceptions", async () => {
await rejects(
writeAllFiles(
{
file0: {
// This entry will throw an exception
source: "Bad Arnold movies.txt",
},
file1: "1",
file2: "2",
},
[
// This entry will throw an exception
["file0", { source: "Bad Arnold movies.txt" }],
["file1", "1"],
["file2", "2"],
],
"."
)
);

await rejects(
writeAllFiles(
{
file1: "1",
file2: "2",
"": "3", // This entry will throw an exception
},
[
["file1", "1"],
["file2", "2"],
["", "3"], // This entry will throw an exception
],
"."
)
);
Expand Down
Loading