Skip to content

Commit

Permalink
fix(align-deps): add profile for 0.76
Browse files Browse the repository at this point in the history
  • Loading branch information
tido64 committed Oct 15, 2024
1 parent 35782e1 commit 28de312
Show file tree
Hide file tree
Showing 14 changed files with 293 additions and 116 deletions.
5 changes: 5 additions & 0 deletions .changeset/forty-shrimps-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/tools-shell": patch
---

Added function for extracting tar files
5 changes: 5 additions & 0 deletions .changeset/wise-pillows-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/align-deps": patch
---

Added profile for 0.76
100 changes: 50 additions & 50 deletions packages/align-deps/README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/align-deps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@rnx-kit/scripts": "*",
"@rnx-kit/tools-language": "*",
"@rnx-kit/tools-node": "*",
"@rnx-kit/tools-shell": "*",
"@rnx-kit/tools-workspaces": "*",
"@rnx-kit/tsconfig": "*",
"@types/jest": "^29.2.1",
Expand Down
143 changes: 82 additions & 61 deletions packages/align-deps/scripts/update-profile.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env node
// @ts-check

import { untar } from "@rnx-kit/tools-shell";
import * as fs from "node:fs";
import * as https from "node:https";
import * as path from "node:path";
import { URL } from "node:url";
import { URL, fileURLToPath } from "node:url";
import packageJson from "package-json";
import semverCoerce from "semver/functions/coerce.js";
import semverCompare from "semver/functions/compare.js";
Expand All @@ -19,6 +21,7 @@ import semverCompare from "semver/functions/compare.js";
* latest: string;
* modified: string;
* homepage?: string;
* tarball: string;
* dependencies?: Record<string, string>;
* peerDependencies?: Record<string, string>;
* }} PackageInfo
Expand Down Expand Up @@ -59,6 +62,7 @@ async function fetchPackageInfo(pkg, targetVersion = "latest") {
const {
version: latest,
homepage,
dist: { tarball },
dependencies,
peerDependencies,
time,
Expand All @@ -76,6 +80,7 @@ async function fetchPackageInfo(pkg, targetVersion = "latest") {
homepage,
dependencies: Optional(dependencies),
peerDependencies: Optional(peerDependencies),
tarball,
};
}

Expand Down Expand Up @@ -294,93 +299,115 @@ export const profile: Profile = {
* @returns {Promise<string>}
*/
async function getCurrentMetroVersion(dependencies) {
const metroVersionDependencyChains = [
// 0.73+
["@react-native/community-cli-plugin"],
// 0.65 - 0.72
["@react-native-community/cli", "@react-native-community/cli-plugin-metro"],
];

for (const chain of metroVersionDependencyChains) {
const deps = await chain.reduce(
(p, packageName) =>
p.then(async (dependencies) => {
if (!dependencies) {
return undefined;
}
const chain = ["react-native", "@react-native/community-cli-plugin"];
const deps = await chain.reduce(
(p, packageName) =>
p.then(async (dependencies) => {
if (!dependencies) {
return undefined;
}

try {
try {
const packageInfo = await packageJson(packageName, {
version: getPackageVersion(packageName, dependencies),
fullMetadata: true,
});
return Optional(packageInfo.dependencies);
} catch (e) {
if (e.code === "ETARGET" || e.name === "VersionNotFoundError") {
// Some packages, such as `@react-native-community/cli`, are still
// in alpha or beta while react-native is in pre-release. Try
// again with the `next` tag.
const packageInfo = await packageJson(packageName, {
version: getPackageVersion(packageName, dependencies),
version: "next",
fullMetadata: true,
});
return Optional(packageInfo.dependencies);
} catch (e) {
if (e.code === "ETARGET" || e.name === "VersionNotFoundError") {
// Some packages, such as `@react-native-community/cli`, are still
// in alpha or beta while react-native is in pre-release. Try
// again with the `next` tag.
const packageInfo = await packageJson(packageName, {
version: "next",
fullMetadata: true,
});
return Optional(packageInfo.dependencies);
} else {
return undefined;
}
} else {
return undefined;
}
}),
Promise.resolve(Optional(dependencies))
);
}
}),
Promise.resolve(Optional(dependencies))
);

if (deps) {
return getPackageVersion("metro", deps);
}
if (!deps) {
throw new Error("Failed to get 'metro' version");
}

throw new Error("Failed to get 'metro' version");
return getPackageVersion("metro", deps);
}

/**
* Fetches package versions for specified react-native version.
* @param {string} preset
* @param {string} targetVersion
* @param {Profile} latestProfile
* @returns {Promise<string | undefined>}
*/
async function makeProfile(preset, targetVersion, latestProfile) {
const reactNativeInfo = await fetchPackageInfo(
latestProfile["core"],
`^${targetVersion}.0-0`
);
if (!reactNativeInfo) {
throw new Error(`Failed to get manifest of 'react-native@${targetVersion}`);
async function makeProfile(preset, targetVersion) {
const templatePkg = {
name: "@react-native-community/template",
version: "0.0.0",
};
const template = await fetchPackageInfo(templatePkg, `^${targetVersion}.0-0`);
if (!template) {
throw new Error(
`Failed to get manifest of '${templatePkg.name}@${targetVersion}`
);
}

const { dependencies, peerDependencies } = reactNativeInfo;
const { tarball } = template;
const templateDir = await new Promise((resolve, reject) => {
https
.get(tarball, (res) => {
const tmpUrl = new URL("../node_modules/.tmp", import.meta.url);
fs.mkdirSync(tmpUrl, { recursive: true });

const tmpDir = fileURLToPath(tmpUrl);
const dest = path.join(fileURLToPath(tmpUrl), path.basename(tarball));
const fh = fs.createWriteStream(dest);
res.pipe(fh);
fh.on("finish", () => {
fh.close();
untar(dest);
resolve(path.join(tmpDir, "package"));
});
})
.on("error", (err) => reject(err));
});

const manifestPath = path.join(templateDir, "template", "package.json");
const manifest = JSON.parse(
fs.readFileSync(manifestPath, { encoding: "utf-8" })
);

const { dependencies, devDependencies } = manifest;
if (!dependencies) {
throw new Error(
`Failed to get dependencies of 'react-native@${targetVersion}`
`Failed to get dependencies of '${templatePkg.name}@${targetVersion}`
);
}
if (!peerDependencies) {
if (!devDependencies) {
throw new Error(
`Failed to get peer dependencies of 'react-native@${targetVersion}`
`Failed to get dev dependencies of '${templatePkg.name}@${targetVersion}`
);
}

return generateFromTemplate({
preset,
targetVersion,
reactVersion: getPackageVersion("react", peerDependencies),
cliVersion: getPackageVersion("@react-native-community/cli", dependencies),
reactVersion: getPackageVersion("react", dependencies),
cliVersion: getPackageVersion(
"@react-native-community/cli",
devDependencies
),
cliAndroidVersion: getPackageVersion(
"@react-native-community/cli-platform-android",
dependencies
devDependencies
),
cliIOSVersion: getPackageVersion(
"@react-native-community/cli-platform-ios",
dependencies
devDependencies
),
metroVersion: await getCurrentMetroVersion(dependencies),
});
Expand Down Expand Up @@ -409,8 +436,6 @@ async function main({
.reverse()
);

const latestProfile = preset[allVersions[0]];

if (targetVersion) {
if (!force && preset[targetVersion]) {
console.error(
Expand All @@ -420,11 +445,7 @@ async function main({
}

try {
const newProfile = await makeProfile(
presetName,
targetVersion,
latestProfile
);
const newProfile = await makeProfile(presetName, targetVersion);
if (newProfile) {
const [dst, presetFile] = getProfilePath(presetName, targetVersion);
fs.writeFile(dst, newProfile, () => {
Expand Down Expand Up @@ -505,7 +526,7 @@ async function main({
/** @type {[string, TableRow][]} */
const delta = [];
await Promise.all(
Object.entries(latestProfile)
Object.entries(preset[allVersions[0]])
.filter(([capability]) => !ignoredCapabilities.includes(capability))
.map(async ([capability, pkg]) => {
await fetchPackageInfo(pkg).then((info) => {
Expand Down
2 changes: 2 additions & 0 deletions packages/align-deps/src/presets/microsoft/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { profile as profile_0_72 } from "./react-native/profile-0.72";
import { profile as profile_0_73 } from "./react-native/profile-0.73";
import { profile as profile_0_74 } from "./react-native/profile-0.74";
import { profile as profile_0_75 } from "./react-native/profile-0.75";
import { profile as profile_0_76 } from "./react-native/profile-0.76";

// Also export this by name for scripts to work around a bug where this module
// is wrapped twice, i.e. `{ default: { default: preset } }`, when imported as
Expand All @@ -34,4 +35,5 @@ export const preset: Readonly<Preset> = {
"0.73": profile_0_73,
"0.74": profile_0_74,
"0.75": profile_0_75,
"0.76": profile_0_76,
};
103 changes: 103 additions & 0 deletions packages/align-deps/src/presets/microsoft/react-native/profile-0.76.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import type { Package, Profile } from "../../../types";
import { profile as profile_0_75 } from "./profile-0.75";

const reactNative: Package = {
name: "react-native",
version: "^0.76.0",
capabilities: ["react", "core/metro-config", "community/cli"],
};

export const profile: Profile = {
...profile_0_75,
react: {
name: "react",
version: "18.3.1",
},
"react-dom": {
name: "react-dom",
version: "^18.3.1",
capabilities: ["react"],
},
"react-test-renderer": {
name: "react-test-renderer",
version: "18.3.1",
capabilities: ["react"],
devOnly: true,
},

core: reactNative,
"core-android": reactNative,
"core-ios": reactNative,
"core-macos": {
name: "react-native-macos",
version: "^0.76.0",
capabilities: ["react"],
},
"core-visionos": {
name: "@callstack/react-native-visionos",
version: "^0.76.0",
capabilities: ["react"],
},
"core-windows": {
name: "react-native-windows",
version: "^0.76.0",
capabilities: ["core"],
},
"core/metro-config": {
name: "@react-native/metro-config",
version: "^0.76.0",
devOnly: true,
},

"babel-preset-react-native": {
name: "@react-native/babel-preset",
version: "^0.76.0",
devOnly: true,
},
"community/cli": {
name: "@react-native-community/cli",
version: "^15.0.0",
capabilities: ["community/cli-android", "community/cli-ios"],
devOnly: true,
},
"community/cli-android": {
name: "@react-native-community/cli-platform-android",
version: "^15.0.0",
devOnly: true,
},
"community/cli-ios": {
name: "@react-native-community/cli-platform-ios",
version: "^15.0.0",
devOnly: true,
},
metro: {
name: "metro",
version: "^0.81.0",
devOnly: true,
},
"metro-config": {
name: "metro-config",
version: "^0.81.0",
devOnly: true,
},
"metro-core": {
name: "metro-core",
version: "^0.81.0",
devOnly: true,
},
"metro-react-native-babel-transformer": {
name: "@react-native/metro-babel-transformer",
version: "^0.76.0",
devOnly: true,
},
"metro-resolver": {
name: "metro-resolver",
version: "^0.81.0",
devOnly: true,
},
"metro-runtime": {
name: "metro-runtime",
version: "^0.81.0",
devOnly: true,
},
};
3 changes: 3 additions & 0 deletions packages/align-deps/test/preset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { profile as profile_0_72 } from "../src/presets/microsoft/react-native/p
import { profile as profile_0_73 } from "../src/presets/microsoft/react-native/profile-0.73";
import { profile as profile_0_74 } from "../src/presets/microsoft/react-native/profile-0.74";
import { profile as profile_0_75 } from "../src/presets/microsoft/react-native/profile-0.75";
import { profile as profile_0_76 } from "../src/presets/microsoft/react-native/profile-0.76";

describe("filterPreset()", () => {
test("returns no profiles if requirements cannot be satisfied", () => {
Expand Down Expand Up @@ -39,6 +40,7 @@ describe("filterPreset()", () => {
"0.73": profile_0_73,
"0.74": profile_0_74,
"0.75": profile_0_75,
"0.76": profile_0_76,
});
});

Expand All @@ -52,6 +54,7 @@ describe("filterPreset()", () => {
"0.73": profile_0_73,
"0.74": profile_0_74,
"0.75": profile_0_75,
"0.76": profile_0_76,
});
});

Expand Down
Loading

0 comments on commit 28de312

Please sign in to comment.