зеркало из https://github.com/microsoft/rnx-kit.git
feat(tools-workspaces): slimmer workspaces package (#1717)
| @rnx-kit/dep-check w/ | workspace-tools | @rnx-kit/tools-workspaces | | ------------------------ | --------------: | ------------------------: | | Bundle size (unminified) | 1 531 380 | 1 063 232 | | Find ~1000 packages | ~367 ms | ~120 ms | | Package footprint | 368 KB | 100 KB |
This commit is contained in:
Родитель
f9ba2aa56f
Коммит
37245c33c6
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
"@rnx-kit/tools-workspaces": minor
|
||||
"@rnx-kit/dep-check": patch
|
||||
---
|
||||
|
||||
Introducing `@rnx-kit/tools-workspaces`, a collection of tools for working with workspaces.
|
|
@ -29,8 +29,7 @@
|
|||
"publish:changesets": "changeset publish",
|
||||
"rnx-dep-check": "yarn build-scope @rnx-kit/dep-check && scripts/rnx-dep-check.js",
|
||||
"test": "nx run-many --target test --output-style stream --all",
|
||||
"update-readme": "yarn update-readme:main && nx run-many --target update-readme --all",
|
||||
"update-readme:main": "node scripts/update-readme.js",
|
||||
"update-readme": "nx run-many --target update-readme --all",
|
||||
"version:changesets": "changeset version"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"@rnx-kit/scripts": "*",
|
||||
"@rnx-kit/tools-language": "*",
|
||||
"@rnx-kit/tools-node": "*",
|
||||
"@rnx-kit/tools-workspaces": "*",
|
||||
"@types/jest": "^27.0.0",
|
||||
"@types/lodash": "^4.14.172",
|
||||
"@types/pacote": "^11.0.0",
|
||||
|
@ -47,7 +48,6 @@
|
|||
"pacote": "^12.0.0",
|
||||
"prompts": "^2.4.0",
|
||||
"semver": "^7.0.0",
|
||||
"workspace-tools": "^0.18.3",
|
||||
"yargs": "^16.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -4,9 +4,12 @@ import type { KitType } from "@rnx-kit/config";
|
|||
import { error } from "@rnx-kit/console";
|
||||
import { hasProperty } from "@rnx-kit/tools-language/properties";
|
||||
import { findPackageDir } from "@rnx-kit/tools-node/package";
|
||||
import {
|
||||
findWorkspacePackages,
|
||||
findWorkspaceRoot,
|
||||
} from "@rnx-kit/tools-workspaces";
|
||||
import isString from "lodash/isString";
|
||||
import * as path from "path";
|
||||
import { getAllPackageJsonFiles, getWorkspaceRoot } from "workspace-tools";
|
||||
import { makeCheckCommand } from "./check";
|
||||
import { initializeConfig } from "./initialize";
|
||||
import { resolveCustomProfiles } from "./profiles";
|
||||
|
@ -24,9 +27,9 @@ function ensureKitType(type: string): KitType | undefined {
|
|||
}
|
||||
}
|
||||
|
||||
function getManifests(
|
||||
async function getManifests(
|
||||
packageJson: string | number | undefined
|
||||
): string[] | undefined {
|
||||
): Promise<string[] | undefined> {
|
||||
if (isString(packageJson) && packageJson) {
|
||||
return [packageJson];
|
||||
}
|
||||
|
@ -40,7 +43,7 @@ function getManifests(
|
|||
// package that just happened to be part of a workspace.
|
||||
const currentPackageJson = path.join(packageDir, "package.json");
|
||||
try {
|
||||
if (getWorkspaceRoot(packageDir) !== packageDir) {
|
||||
if ((await findWorkspaceRoot()) !== packageDir) {
|
||||
return [currentPackageJson];
|
||||
}
|
||||
} catch (_) {
|
||||
|
@ -48,7 +51,9 @@ function getManifests(
|
|||
}
|
||||
|
||||
try {
|
||||
const allPackages = getAllPackageJsonFiles(packageDir) ?? [];
|
||||
const allPackages = (await findWorkspacePackages()).map((p) =>
|
||||
path.join(p, "package.json")
|
||||
);
|
||||
allPackages.push(currentPackageJson);
|
||||
return allPackages;
|
||||
} catch (e) {
|
||||
|
@ -147,7 +152,7 @@ export async function cli({
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const manifests = getManifests(packageJson);
|
||||
const manifests = await getManifests(packageJson);
|
||||
if (!manifests) {
|
||||
error("Could not find package root");
|
||||
process.exit(1);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<!--remove-block start-->
|
||||
|
||||
# @rnx-kit/tools-workspaces
|
||||
|
||||
[![Build](https://github.com/microsoft/rnx-kit/actions/workflows/build.yml/badge.svg)](https://github.com/microsoft/rnx-kit/actions/workflows/build.yml)
|
||||
[![npm version](https://img.shields.io/npm/v/@rnx-kit/tools-workspaces)](https://www.npmjs.com/package/@rnx-kit/tools-workspaces)
|
||||
|
||||
<!--remove-block end-->
|
||||
|
||||
`@rnx-kit/tools-workspaces` is a collection of tools for working with
|
||||
workspaces.
|
||||
|
||||
It currently supports:
|
||||
|
||||
- [Lerna](https://lerna.js.org/docs/configuration)
|
||||
- [npm](https://docs.npmjs.com/cli/v8/using-npm/workspaces)
|
||||
- [pnpm](https://pnpm.io/pnpm-workspace_yaml)
|
||||
- [Rush](https://rushjs.io/pages/configs/rush_json/)
|
||||
- [Yarn](https://yarnpkg.com/configuration/manifest#workspaces)
|
||||
|
||||
<!-- The following table can be updated by running `yarn update-readme` -->
|
||||
<!-- @rnx-kit/api start -->
|
||||
|
||||
| Category | Function | Description |
|
||||
| -------- | ------------------------- | ------------------------------------------------------------------ |
|
||||
| - | `findWorkspacePackages()` | Returns a list of all packages declared under workspaces. |
|
||||
| - | `findWorkspaceRoot()` | Returns the root of the workspace; `undefined` if not a workspace. |
|
||||
|
||||
<!-- @rnx-kit/api end -->
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "@rnx-kit/tools-workspaces",
|
||||
"version": "0.0.1",
|
||||
"description": "A collection of tools for working with workspaces",
|
||||
"homepage": "https://github.com/microsoft/rnx-kit/tree/main/packages/tools-workspaces#readme",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Microsoft Open Source",
|
||||
"email": "microsoftopensource@users.noreply.github.com"
|
||||
},
|
||||
"files": [
|
||||
"lib/*"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/rnx-kit",
|
||||
"directory": "packages/tools-workspaces"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rnx-kit-scripts build",
|
||||
"format": "rnx-kit-scripts format",
|
||||
"lint": "rnx-kit-scripts lint",
|
||||
"test": "rnx-kit-scripts test",
|
||||
"update-readme": "rnx-kit-scripts update-api-readme"
|
||||
},
|
||||
"dependencies": {
|
||||
"fast-glob": "^3.2.7",
|
||||
"find-up": "^5.0.0",
|
||||
"read-yaml-file": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rnx-kit/scripts": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "@rnx-kit/eslint-config"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@rnx-kit/scripts"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import fg from "fast-glob";
|
||||
import findUp from "find-up";
|
||||
import * as path from "node:path";
|
||||
|
||||
type PackageManager = {
|
||||
findWorkspacePackages: (sentinel: string) => Promise<string[]>;
|
||||
};
|
||||
|
||||
export const LERNA_JSON = "lerna.json";
|
||||
export const PACKAGE_LOCK_JSON = "package-lock.json";
|
||||
export const PNPM_WORKSPACE_YAML = "pnpm-workspace.yaml";
|
||||
export const RUSH_JSON = "rush.json";
|
||||
export const YARN_LOCK = "yarn.lock";
|
||||
|
||||
export const WORKSPACE_ROOT_SENTINELS = [
|
||||
LERNA_JSON,
|
||||
RUSH_JSON,
|
||||
YARN_LOCK,
|
||||
PACKAGE_LOCK_JSON,
|
||||
PNPM_WORKSPACE_YAML,
|
||||
];
|
||||
|
||||
export async function findPackages(
|
||||
patterns: string[] | undefined,
|
||||
cwd: string
|
||||
): Promise<string[]> {
|
||||
if (!Array.isArray(patterns)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await fg(patterns, {
|
||||
cwd,
|
||||
ignore: ["**/Pods/**", "**/bower_components/**", "**/node_modules/**"],
|
||||
absolute: true,
|
||||
onlyDirectories: true,
|
||||
});
|
||||
}
|
||||
|
||||
export const findSentinel = (() => {
|
||||
let result: Promise<string | undefined>;
|
||||
return () => {
|
||||
if (process.env.JEST_WORKER_ID || !result) {
|
||||
result = findUp(WORKSPACE_ROOT_SENTINELS);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
|
||||
export function getImplementation(sentinel: string): Promise<PackageManager> {
|
||||
switch (path.basename(sentinel)) {
|
||||
case PACKAGE_LOCK_JSON: // fallthrough - logic defining workspaces config is the same for npm and yarn
|
||||
case YARN_LOCK:
|
||||
return import("./yarn");
|
||||
|
||||
case LERNA_JSON:
|
||||
return import("./lerna");
|
||||
|
||||
case PNPM_WORKSPACE_YAML:
|
||||
return import("./pnpm");
|
||||
|
||||
case RUSH_JSON:
|
||||
return import("./rush");
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`This should not happen - did we forget to add a switch case for '${sentinel}'?`
|
||||
);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import * as path from "node:path";
|
||||
import { findSentinel, getImplementation } from "./common";
|
||||
|
||||
/**
|
||||
* Returns a list of all packages declared under workspaces.
|
||||
*/
|
||||
export async function findWorkspacePackages(): Promise<string[]> {
|
||||
const sentinel = await findSentinel();
|
||||
if (!sentinel) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { findWorkspacePackages } = await getImplementation(sentinel);
|
||||
return await findWorkspacePackages(sentinel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root of the workspace; `undefined` if not a workspace.
|
||||
*/
|
||||
export async function findWorkspaceRoot(): Promise<string | undefined> {
|
||||
const sentinel = await findSentinel();
|
||||
return sentinel && path.dirname(sentinel);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { existsSync as fileExists } from "node:fs";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import {
|
||||
findPackages,
|
||||
getImplementation,
|
||||
LERNA_JSON,
|
||||
WORKSPACE_ROOT_SENTINELS,
|
||||
} from "./common";
|
||||
|
||||
// https://lerna.js.org/docs/configuration
|
||||
export async function findWorkspacePackages(
|
||||
configFile: string
|
||||
): Promise<string[]> {
|
||||
const config = await fs.readFile(configFile, { encoding: "utf-8" });
|
||||
const { packages, useWorkspaces } = JSON.parse(config);
|
||||
if (!useWorkspaces) {
|
||||
return await findPackages(packages, path.dirname(configFile));
|
||||
}
|
||||
|
||||
const root = path.dirname(configFile);
|
||||
const sentinels = WORKSPACE_ROOT_SENTINELS.filter(
|
||||
(sentinel) => sentinel !== LERNA_JSON
|
||||
);
|
||||
for (const sentinel of sentinels) {
|
||||
const filename = path.join(root, sentinel);
|
||||
if (fileExists(filename)) {
|
||||
const { findWorkspacePackages } = await getImplementation(filename);
|
||||
return await findWorkspacePackages(filename);
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import * as path from "node:path";
|
||||
import readYamlFile from "read-yaml-file";
|
||||
import { findPackages } from "./common";
|
||||
|
||||
type PnpmWorkspace = {
|
||||
packages?: string[];
|
||||
};
|
||||
|
||||
// https://pnpm.io/pnpm-workspace_yaml
|
||||
export async function findWorkspacePackages(
|
||||
workspaceYaml: string
|
||||
): Promise<string[]> {
|
||||
const { packages } = await readYamlFile<PnpmWorkspace>(workspaceYaml);
|
||||
return await findPackages(packages, path.dirname(workspaceYaml));
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
|
||||
type RushProject = {
|
||||
packageName: string;
|
||||
projectFolder: string;
|
||||
};
|
||||
|
||||
// https://rushjs.io/pages/configs/rush_json/
|
||||
export async function findWorkspacePackages(
|
||||
configFile: string
|
||||
): Promise<string[]> {
|
||||
const config = await fs.readFile(configFile, { encoding: "utf-8" });
|
||||
const { projects } = JSON.parse(config);
|
||||
const root = path.dirname(configFile);
|
||||
return projects.map((project: RushProject) =>
|
||||
path.join(root, project.projectFolder)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { findPackages } from "./common";
|
||||
|
||||
type Manifest = {
|
||||
workspaces?: string[] | { packages: string[] };
|
||||
};
|
||||
|
||||
async function readPackageManifest(root: string): Promise<Manifest> {
|
||||
const filename = path.join(root, "package.json");
|
||||
const manifest = await fs.readFile(filename, { encoding: "utf-8" });
|
||||
return JSON.parse(manifest);
|
||||
}
|
||||
|
||||
// https://docs.npmjs.com/cli/v8/using-npm/workspaces
|
||||
// https://yarnpkg.com/configuration/manifest#workspaces
|
||||
export async function findWorkspacePackages(
|
||||
lockfile: string
|
||||
): Promise<string[]> {
|
||||
const root = path.dirname(lockfile);
|
||||
const { workspaces } = await readPackageManifest(root);
|
||||
const patterns = Array.isArray(workspaces)
|
||||
? workspaces
|
||||
: workspaces?.packages;
|
||||
return await findPackages(patterns, root);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-packages-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-packages-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-packages-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-packages-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-packages-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"useWorkspaces": true
|
||||
}
|
0
packages/tools-workspaces/test/__fixtures__/lerna-workspaces/package-lock.json
сгенерированный
Normal file
0
packages/tools-workspaces/test/__fixtures__/lerna-workspaces/package-lock.json
сгенерированный
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-workspaces-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-workspaces-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-workspaces-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-workspaces-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "lerna-workspaces-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "npm-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "npm-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "npm-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "npm-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "npm-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "pnpm-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "pnpm-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "pnpm-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "pnpm-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "pnpm-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
packages:
|
||||
- 'packages/*'
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "rush-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "rush-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "rush-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "rush-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "rush-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"projects": [
|
||||
{
|
||||
"packageName": "rush-conan",
|
||||
"projectFolder": "packages/conan"
|
||||
},
|
||||
{
|
||||
"packageName": "rush-dutch",
|
||||
"projectFolder": "packages/dutch"
|
||||
},
|
||||
{
|
||||
"packageName": "rush-john",
|
||||
"projectFolder": "packages/john"
|
||||
},
|
||||
{
|
||||
"packageName": "rush-quaid",
|
||||
"projectFolder": "packages/quaid"
|
||||
},
|
||||
{
|
||||
"packageName": "rush-t-800",
|
||||
"projectFolder": "packages/t-800"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "yarn-conan",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "yarn-dutch",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "yarn-john",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "yarn-quaid",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "yarn-t-800",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { findPackages, findSentinel } from "../src/common";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findPackages", () => {
|
||||
test("returns an empty array when passed no patterns", () => {
|
||||
expect(findPackages(undefined, "/")).resolves.toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findSentinel", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns sentinel for Lerna", async () => {
|
||||
setFixture("lerna-packages");
|
||||
expect(await findSentinel()).toMatch(/[/\\]lerna.json$/);
|
||||
|
||||
setFixture("lerna-workspaces");
|
||||
expect(await findSentinel()).toMatch(/[/\\]lerna.json$/);
|
||||
});
|
||||
|
||||
test("returns sentinel for npm", async () => {
|
||||
setFixture("npm");
|
||||
expect(await findSentinel()).toMatch(/[/\\]package-lock.json$/);
|
||||
});
|
||||
|
||||
test("returns sentinel for pnpm", async () => {
|
||||
setFixture("pnpm");
|
||||
expect(await findSentinel()).toMatch(/[/\\]pnpm-workspace.yaml$/);
|
||||
});
|
||||
|
||||
test("returns sentinel for Rush", async () => {
|
||||
setFixture("rush");
|
||||
expect(await findSentinel()).toMatch(/[/\\]rush.json$/);
|
||||
});
|
||||
|
||||
test("returns sentinel for Yarn", async () => {
|
||||
setFixture("yarn");
|
||||
expect(await findSentinel()).toMatch(/[/\\]yarn.lock$/);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import * as path from "node:path";
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
export function setFixture(name: string): void {
|
||||
process.chdir(path.join(__dirname, "__fixtures__", name));
|
||||
}
|
||||
|
||||
export function unsetFixture(): void {
|
||||
process.chdir(cwd);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import { findWorkspacePackages, findWorkspaceRoot } from "../src/index";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findWorkspacePackages", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns packages for Lerna workspaces", async () => {
|
||||
setFixture("lerna-packages");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]conan$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]dutch$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]john$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]quaid$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-packages[/\\]packages[/\\]t-800$/
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
test("returns packages for delegated workspaces", async () => {
|
||||
setFixture("lerna-workspaces");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]conan$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]dutch$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]john$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]quaid$/
|
||||
),
|
||||
expect.stringMatching(
|
||||
/__fixtures__[/\\]lerna-workspaces[/\\]packages[/\\]t-800$/
|
||||
),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findWorkspaceRoot", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns workspace root for Lerna workspaces", async () => {
|
||||
setFixture("lerna-packages");
|
||||
expect(await findWorkspaceRoot()).toMatch(
|
||||
/__fixtures__[/\\]lerna-packages$/
|
||||
);
|
||||
});
|
||||
|
||||
test("returns workspace root for delegated workspaces", async () => {
|
||||
setFixture("lerna-workspaces");
|
||||
expect(await findWorkspaceRoot()).toMatch(
|
||||
/__fixtures__[/\\]lerna-workspaces$/
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { findWorkspacePackages, findWorkspaceRoot } from "../src/index";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findWorkspacePackages", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns packages for npm workspaces", async () => {
|
||||
setFixture("npm");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]conan$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]dutch$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]john$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]quaid$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]npm[/\\]packages[/\\]t-800$/),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findWorkspaceRoot", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns workspace root for npm workspaces", async () => {
|
||||
setFixture("npm");
|
||||
expect(await findWorkspaceRoot()).toMatch(/__fixtures__[/\\]npm$/);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { findWorkspacePackages, findWorkspaceRoot } from "../src/index";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findWorkspacePackages", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns packages", async () => {
|
||||
setFixture("pnpm");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]conan$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]dutch$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]john$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]quaid$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]pnpm[/\\]packages[/\\]t-800$/),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findWorkspaceRoot", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns workspace root for pnpm workspaces", async () => {
|
||||
setFixture("pnpm");
|
||||
expect(await findWorkspaceRoot()).toMatch(/__fixtures__[/\\]pnpm$/);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { findWorkspacePackages, findWorkspaceRoot } from "../src/index";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findWorkspacePackages", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns packages for Rush workspaces", async () => {
|
||||
setFixture("rush");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]conan$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]dutch$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]john$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]quaid$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]rush[/\\]packages[/\\]t-800$/),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findWorkspaceRoot", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns workspace root for Rush workspaces", async () => {
|
||||
setFixture("rush");
|
||||
expect(await findWorkspaceRoot()).toMatch(/__fixtures__[/\\]rush$/);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { findWorkspacePackages, findWorkspaceRoot } from "../src/index";
|
||||
import { setFixture, unsetFixture } from "./helper";
|
||||
|
||||
describe("findWorkspacePackages", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns packages for Yarn workspaces", async () => {
|
||||
setFixture("yarn");
|
||||
expect(await findWorkspacePackages()).toEqual([
|
||||
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]conan$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]dutch$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]john$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]quaid$/),
|
||||
expect.stringMatching(/__fixtures__[/\\]yarn[/\\]packages[/\\]t-800$/),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findWorkspaceRoot", () => {
|
||||
afterEach(() => {
|
||||
unsetFixture();
|
||||
});
|
||||
|
||||
test("returns workspace root for Yarn workspaces", async () => {
|
||||
setFixture("yarn");
|
||||
expect(await findWorkspaceRoot()).toMatch(/__fixtures__[/\\]yarn$/);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "@rnx-kit/scripts/tsconfig-shared.json",
|
||||
"include": ["src"]
|
||||
}
|
|
@ -27,7 +27,6 @@
|
|||
"markdown-table": "^2.0.0",
|
||||
"midgard-yarn": "^1.23.24",
|
||||
"typescript": "^4.0.0",
|
||||
"workspace-tools": "^0.18.3",
|
||||
"yargs": "^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -41,8 +40,7 @@
|
|||
"@rnx-kit/jest-preset",
|
||||
"jest",
|
||||
"midgard-yarn",
|
||||
"typescript",
|
||||
"workspace-tools"
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
|
|
@ -217,7 +217,8 @@ function updateApiReadme() {
|
|||
const exportedTypes = [];
|
||||
|
||||
findSourceFiles().forEach((file) => {
|
||||
const category = path.basename(file, ".ts");
|
||||
const filename = path.basename(file, ".ts");
|
||||
const category = filename === "index" ? "-" : filename;
|
||||
const content = fs.readFileSync(file, { encoding: "utf-8" });
|
||||
babelParser
|
||||
.parse(content, {
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const markdownTable = require("markdown-table");
|
||||
const path = require("path");
|
||||
const { getAllPackageJsonFiles, getWorkspaceRoot } = require("workspace-tools");
|
||||
|
||||
const PACKAGE_JSON = "package.json";
|
||||
const README = "README.md";
|
||||
const TOKEN_START = "<!-- @rnx-kit start -->";
|
||||
const TOKEN_END = "<!-- @rnx-kit end -->";
|
||||
const TOKEN_EXPERIMENTAL_START = "<!-- @rnx-kit experimental start -->";
|
||||
const TOKEN_EXPERIMENTAL_END = "<!-- @rnx-kit experimental end -->";
|
||||
|
||||
function readFile(path) {
|
||||
return fs.readFileSync(path, { encoding: "utf-8" });
|
||||
}
|
||||
|
||||
const repoUrl = (() => {
|
||||
const manifest = JSON.parse(readFile(PACKAGE_JSON));
|
||||
return manifest.repository.url.replace(/\.git$/, "");
|
||||
})();
|
||||
|
||||
const repoRoot = getWorkspaceRoot();
|
||||
const experimentalPackages = [];
|
||||
const packages = getAllPackageJsonFiles(repoRoot).reduce(
|
||||
(packages, manifestPath) => {
|
||||
const content = readFile(manifestPath);
|
||||
const manifest = JSON.parse(content);
|
||||
const { private, name, description, experimental } = manifest;
|
||||
if (!private && !name.startsWith("@types/")) {
|
||||
const packagePath = path.relative(repoRoot, path.dirname(manifestPath));
|
||||
const link = `[${name}](${repoUrl}/tree/main/${packagePath})`;
|
||||
if (experimental) {
|
||||
experimentalPackages.push([link, description.substring(34)]);
|
||||
} else {
|
||||
packages.push([link, description]);
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const table = markdownTable([["Name", "Description"], ...packages]);
|
||||
const experimentalTable = markdownTable([
|
||||
["Name", "Description"],
|
||||
...experimentalPackages,
|
||||
]);
|
||||
|
||||
const readme = readFile(README);
|
||||
|
||||
const updatedMainTableReadme = readme.replace(
|
||||
new RegExp(`${TOKEN_START}([^]+)${TOKEN_END}`),
|
||||
`${TOKEN_START}\n\n${table}\n\n${TOKEN_END}`
|
||||
);
|
||||
|
||||
const fullyUpdatedReadme = updatedMainTableReadme.replace(
|
||||
new RegExp(`${TOKEN_EXPERIMENTAL_START}([^]+)${TOKEN_EXPERIMENTAL_END}`),
|
||||
`${TOKEN_EXPERIMENTAL_START}\n\n${experimentalTable}\n\n${TOKEN_EXPERIMENTAL_END}`
|
||||
);
|
||||
|
||||
if (fullyUpdatedReadme !== readme) {
|
||||
fs.writeFileSync(README, fullyUpdatedReadme);
|
||||
}
|
|
@ -13841,7 +13841,7 @@ read-yaml-file@^1.1.0:
|
|||
pify "^4.0.1"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
read-yaml-file@^2.0.0:
|
||||
read-yaml-file@^2.0.0, read-yaml-file@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/read-yaml-file/-/read-yaml-file-2.1.0.tgz#c5866712db9ef5343b4d02c2413bada53c41c4a9"
|
||||
integrity sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==
|
||||
|
|
Загрузка…
Ссылка в новой задаче