Files
react-native/scripts/utils/monorepo.js
T
Alex Hunt 4e677f021a Update set-version script to version private packages and workspace deps
Summary:
Addresses a gap when using the `set-version` script to update all packages on `main` (i.e. post branch cut):
- Package versions were not being set consistently. It is safe to version all workspace packages, including `"private"`.
    - Our publishing workflow is independent from this, and only considers public packages for submission to npm.
- We also need to update the root `package.json`, which includes `devDependencies` referencing workspace dependencies.

Unblocks https://github.com/facebook/react-native/pull/43132.

Changelog: [Internal]

Reviewed By: lunaleaps

Differential Revision: D54419456

fbshipit-source-id: 93eee669c5cf7c2f16b68a2bf41e9a8ace5521bf
2024-03-18 11:09:04 +00:00

111 lines
2.4 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
* @oncall react_native
*/
const {REPO_ROOT} = require('../consts');
const fs = require('fs');
const glob = require('glob');
const path = require('path');
const WORKSPACES_CONFIG = 'packages/*';
/*::
export type PackageJson = {
name: string,
version: string,
private?: boolean,
dependencies?: Record<string, string>,
devDependencies?: Record<string, string>,
...
};
type PackagesFilter = $ReadOnly<{
includeReactNative: boolean,
includePrivate?: boolean,
}>;
export type PackageInfo = {
// The name of the package
name: string,
// The absolute path to the package
path: string,
// The parsed package.json contents
packageJson: PackageJson,
};
type ProjectInfo = {
[packageName: string]: PackageInfo,
};
*/
/**
* Locates monrepo packages and returns a mapping of package names to their
* metadata. Considers Yarn workspaces under `packages/`.
*/
async function getPackages(
filter /*: PackagesFilter */,
) /*: Promise<ProjectInfo> */ {
const {includeReactNative, includePrivate = false} = filter;
const packagesEntries = await Promise.all(
glob
.sync(`${WORKSPACES_CONFIG}/package.json`, {
cwd: REPO_ROOT,
absolute: true,
ignore: includeReactNative
? []
: ['packages/react-native/package.json'],
})
.map(parsePackageInfo),
);
return Object.fromEntries(
packagesEntries.filter(
([_, {packageJson}]) => packageJson.private !== true || includePrivate,
),
);
}
/**
* Get the parsed package metadata for the workspace root.
*/
async function getWorkspaceRoot() /*: Promise<PackageInfo> */ {
const [, packageInfo] = await parsePackageInfo(
path.join(REPO_ROOT, 'package.json'),
);
return packageInfo;
}
async function parsePackageInfo(
packageJsonPath /*: string */,
) /*: Promise<[string, PackageInfo]> */ {
const packagePath = path.dirname(packageJsonPath);
const packageJson /*: PackageJson */ = JSON.parse(
await fs.promises.readFile(packageJsonPath, 'utf-8'),
);
return [
packageJson.name,
{
name: packageJson.name,
path: packagePath,
packageJson,
},
];
}
module.exports = {
getPackages,
getWorkspaceRoot,
};