Skip to content

Commit

Permalink
Merge branch 'main' into pr/benmccann/213
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed Aug 9, 2024
2 parents c4eda51 + c0a5e5d commit 1e109d0
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 90 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-goats-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@manypkg/find-root": patch
---

Remove find-up dependency
6 changes: 6 additions & 0 deletions .changeset/spotty-owls-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@manypkg/find-root": patch
"@manypkg/tools": patch
---

Remove fs-extra from dependencies
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,64 @@ As an example, let's say there are two packages which both have a `dist` dir, `m
yarn manypkg exec rm -rf dist
```

## Configuration

Manypkg supports a number of options. Options can be provided using the `manypkg` key in your root `package.json` file:

```json
{
"name": "monorepo-root",
"private": true,
"manypkg": {}
}
```

### `defaultBranch`

Used by the [Incorrect `repository` field](#incorrect-repository-field) rule to determine the correct name for repositories. The default value is `master`.

```json
{
"manypkg": {
"defaultBranch": "master"
}
}
```

### `ignoredRules`

Used to determine which checks/fixes should ignored by the Manypkg cli. The default value is `[]` (all checks/fixes enabled).

```json
{
"manypkg": {
"ignoredRules": []
}
}
```

To ignore a rule, find the rule in the [Checks section](#checks) below and add its "Key" value to the array. For example, to disable the [External mismatch rule](#external-mismatch):

```json
{
"manypkg": {
"ignoredRules": ["EXTERNAL_MISMATCH"]
}
}
```

### `workspaceProtocol`

Used to determine whether the `workspace:` protocol for internal packages is required (`require`) or allowed (`allow`). The default value is `allow`.

```json
{
"manypkg": {
"workspaceProtocol": "allow"
}
}
```

## Dictionary

- **private package** - A package that has `private: true`/is not published. It does not refer to a package published to a private registry here.
Expand All @@ -92,6 +150,8 @@ yarn manypkg exec rm -rf dist

## External mismatch

Key: `EXTERNAL_MISMATCH`

The ranges for all dependencies(excluding `peerDependencies`) on external packages should exactly match(`===`). It's important to note that this check does not enforce that only a single version of an external package is installed, only that two versions of an external package will never be installed because they're specified as dependencies of internal packages.

### Why it's a rule
Expand Down Expand Up @@ -208,6 +268,8 @@ There are some cases where you might want to intentionally have conflicts betwee
## Internal mismatch

Key: `INTERNAL_MISMATCH`

The ranges for all regular dependencies, devDependencies and optionalDependencies(not peerDependencies) on internal packages should include the version of the internal package.

### Why it's a rule
Expand All @@ -220,6 +282,8 @@ If the range is a [caret range](https://github.com/npm/node-semver#caret-ranges-

## Invalid dev and peer dependency relationship

Key: `INVALID_DEV_AND_PEER_DEPENDENCY_RELATIONSHIP`

All `peerDependencies` should also be specified in `devDependencies` and the range specified in `devDependencies` should be a subset of the range for that dependency in `peerDependencies`.

### Why it's a rule
Expand All @@ -232,6 +296,8 @@ The range for the dependency specified in `peerDependencies` is added to `devDep

## Root has devDependencies

Key: `ROOT_HAS_DEV_DEPENDENCIES`

The root package should not have any `devDependencies`, instead all dependencies should be in `dependencies`

### Why it's a rule
Expand All @@ -244,6 +310,8 @@ All `devDependencies` in the root `package.json` are moved to `dependencies`.

## Multiple dependency types

Key: `MULTIPLE_DEPENDENCY_TYPES`

A dependency shouldn't be specified in more than one of `dependencies`, `devDependencies` or `optionalDependencies`.

### How it's fixed
Expand All @@ -252,6 +320,8 @@ The dep is removed from `devDependencies` or `optionalDependencies` if it's also

## Invalid package name

Key: `INVALID_PACKAGE_NAME`

There are rules from npm about what a package name can be and a package will fail to publish if those rules are not met.

### Why it's a rule
Expand All @@ -264,6 +334,8 @@ This requires manual fixing as automatically fixing this may lead to valid but i

## Unsorted dependencies

Key: `UNSORTED_DEPENDENCIES`

Dependencies in the dependency fields(`dependencies`, `devDependencies`, `peerDependencies`, `optionalDependencies`) should be sorted alphabetically.

### Why it's a rule
Expand All @@ -276,6 +348,8 @@ This is fixed by sorting deps by key alphabetically.

## Incorrect `repository` field

Key: `INCORRECT_REPOSITORY_FIELD`

If a GitHub repo URL is in the `repository` field in the root `package.json`, all of the packages should have a `repository` field which goes into the directory of the package.

### Why it's a rule
Expand All @@ -288,6 +362,8 @@ This is fixed by setting the correct URL.

## `workspace:` protocol required

Key: `WORKSPACE_REQUIRED`

If `"workspaceProtocol": "require"` is set in the `manypkg` config in the root `package.json`, all dependencies on internal packages are required to use the `workspace:` protocol.

### Why it's a rule
Expand Down
4 changes: 1 addition & 3 deletions packages/find-root/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
"main": "dist/manypkg-find-root.cjs.js",
"module": "dist/manypkg-find-root.esm.js",
"dependencies": {
"@manypkg/tools": "^1.1.1",
"find-up": "^4.1.0",
"fs-extra": "^8.1.0"
"@manypkg/tools": "^1.1.1"
},
"devDependencies": {
"@types/node": "^16.11.7",
Expand Down
42 changes: 35 additions & 7 deletions packages/find-root/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import findUp, { sync as findUpSync } from "find-up";
import path from "path";
import fs from "fs-extra";
import fs from "fs";
import fsp from "fs/promises";

import {
Tool,
Expand Down Expand Up @@ -98,7 +98,7 @@ export async function findRoot(
}
});
},
{ cwd, type: "directory" }
cwd
);

if (monorepoRoot) {
Expand All @@ -115,15 +115,15 @@ export async function findRoot(
let rootDir = await findUp(
async (directory) => {
try {
await fs.access(path.join(directory, "package.json"));
await fsp.access(path.join(directory, "package.json"));
return directory;
} catch (err) {
if (!isNoEntryError(err)) {
throw err;
}
}
},
{ cwd, type: "directory" }
cwd
);

if (!rootDir) {
Expand Down Expand Up @@ -158,7 +158,7 @@ export function findRootSync(
}
}
},
{ cwd, type: "directory" }
cwd
);

if (monorepoRoot) {
Expand All @@ -177,7 +177,7 @@ export function findRootSync(
const exists = fs.existsSync(path.join(directory, "package.json"));
return exists ? directory : undefined;
},
{ cwd, type: "directory" }
cwd
);

if (!rootDir) {
Expand All @@ -189,3 +189,31 @@ export function findRootSync(
rootDir,
};
}

async function findUp(matcher: (directory: string) => Promise<string | undefined>, cwd: string) {
let directory = path.resolve(cwd);
const { root } = path.parse(directory);

while (directory && directory !== root) {
const filePath = await matcher(directory);
if (filePath) {
return path.resolve(directory, filePath);
}

directory = path.dirname(directory);
}
}

function findUpSync(matcher: (directory: string) => string | undefined, cwd: string) {
let directory = path.resolve(cwd);
const { root } = path.parse(directory);

while (directory && directory !== root) {
const filePath = matcher(directory);
if (filePath) {
return path.resolve(directory, filePath);
}

directory = path.dirname(directory);
}
}
1 change: 0 additions & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"license": "MIT",
"main": "dist/manypkg-tools.cjs.js",
"dependencies": {
"fs-extra": "^8.1.0",
"globby": "^11.0.0",
"jju": "^1.4.0",
"js-yaml": "^4.1.0"
Expand Down
18 changes: 5 additions & 13 deletions packages/tools/src/BoltTool.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import path from "path";
import fs from "fs-extra";

import { Tool, PackageJSON, Packages, InvalidMonorepoError } from "./Tool";
import {
expandPackageGlobs,
expandPackageGlobsSync,
} from "./expandPackageGlobs";
import { readJson, readJsonSync } from "./utils";

export interface BoltPackageJSON extends PackageJSON {
bolt?: {
Expand All @@ -18,9 +18,7 @@ export const BoltTool: Tool = {

async isMonorepoRoot(directory: string): Promise<boolean> {
try {
const pkgJson = (await fs.readJson(
path.join(directory, "package.json")
)) as BoltPackageJSON;
const pkgJson = await readJson(directory, "package.json") as BoltPackageJSON;
if (pkgJson.bolt && pkgJson.bolt.workspaces) {
return true;
}
Expand All @@ -35,9 +33,7 @@ export const BoltTool: Tool = {

isMonorepoRootSync(directory: string): boolean {
try {
const pkgJson = fs.readJsonSync(
path.join(directory, "package.json")
) as BoltPackageJSON;
const pkgJson = readJsonSync(directory, "package.json") as BoltPackageJSON;
if (pkgJson.bolt && pkgJson.bolt.workspaces) {
return true;
}
Expand All @@ -54,9 +50,7 @@ export const BoltTool: Tool = {
const rootDir = path.resolve(directory);

try {
const pkgJson = (await fs.readJson(
path.join(rootDir, "package.json")
)) as BoltPackageJSON;
const pkgJson = await readJson(rootDir, "package.json") as BoltPackageJSON;
if (!pkgJson.bolt || !pkgJson.bolt.workspaces) {
throw new InvalidMonorepoError(
`Directory ${rootDir} is not a valid ${BoltTool.type} monorepo root: missing bolt.workspaces entry`
Expand Down Expand Up @@ -88,9 +82,7 @@ export const BoltTool: Tool = {
const rootDir = path.resolve(directory);

try {
const pkgJson = fs.readJsonSync(
path.join(rootDir, "package.json")
) as BoltPackageJSON;
const pkgJson = readJsonSync(rootDir, "package.json") as BoltPackageJSON;
if (!pkgJson.bolt || !pkgJson.bolt.workspaces) {
throw new InvalidMonorepoError(
`Directory ${directory} is not a valid ${BoltTool.type} monorepo root: missing bolt.workspaces entry`
Expand Down
25 changes: 7 additions & 18 deletions packages/tools/src/LernaTool.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import path from "path";
import fs from "fs-extra";

import {
Tool,
Package,
PackageJSON,
Packages,
InvalidMonorepoError,
Expand All @@ -12,6 +10,7 @@ import {
expandPackageGlobs,
expandPackageGlobsSync,
} from "./expandPackageGlobs";
import { readJson, readJsonSync } from "./utils";

export interface LernaJson {
useWorkspaces?: boolean;
Expand All @@ -23,9 +22,7 @@ export const LernaTool: Tool = {

async isMonorepoRoot(directory: string): Promise<boolean> {
try {
const lernaJson = (await fs.readJson(
path.join(directory, "lerna.json")
)) as LernaJson;
const lernaJson = await readJson(directory, "lerna.json") as LernaJson;
if (lernaJson.useWorkspaces !== true) {
return true;
}
Expand All @@ -40,9 +37,7 @@ export const LernaTool: Tool = {

isMonorepoRootSync(directory: string): boolean {
try {
const lernaJson = fs.readJsonSync(
path.join(directory, "lerna.json")
) as LernaJson;
const lernaJson = readJsonSync(directory, "lerna.json") as LernaJson;
if (lernaJson.useWorkspaces !== true) {
return true;
}
Expand All @@ -59,10 +54,8 @@ export const LernaTool: Tool = {
const rootDir = path.resolve(directory);

try {
const lernaJson = await fs.readJson(path.join(rootDir, "lerna.json"));
const pkgJson = (await fs.readJson(
path.join(rootDir, "package.json")
)) as PackageJSON;
const lernaJson = await readJson(rootDir, "lerna.json") as LernaJson;
const pkgJson = await readJson(rootDir, "package.json") as PackageJSON;
const packageGlobs: string[] = lernaJson.packages || ["packages/*"];

return {
Expand All @@ -89,12 +82,8 @@ export const LernaTool: Tool = {
const rootDir = path.resolve(directory);

try {
const lernaJson = fs.readJsonSync(
path.join(rootDir, "lerna.json")
) as LernaJson;
const pkgJson = fs.readJsonSync(
path.join(rootDir, "package.json")
) as PackageJSON;
const lernaJson = readJsonSync(rootDir, "lerna.json") as LernaJson;
const pkgJson = readJsonSync(rootDir, "package.json") as PackageJSON;
const packageGlobs: string[] = lernaJson.packages || ["packages/*"];

return {
Expand Down
Loading

0 comments on commit 1e109d0

Please sign in to comment.