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:
Tommy Nguyen 2022-07-05 16:07:43 +02:00 коммит произвёл GitHub
Родитель f9ba2aa56f
Коммит 37245c33c6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
67 изменённых файлов: 707 добавлений и 77 удалений

Просмотреть файл

@ -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,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
packages/tools-workspaces/test/__fixtures__/npm/package-lock.json сгенерированный Normal file
Просмотреть файл

Просмотреть файл

@ -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==