npm package: @mono-repo/utils
Description: Core util functions to aid writing tools and libraries for managing mono repos.
Latest version: 1.4.4

<p align="center">
  <img 
    src="https://raw.githubusercontent.com/mono-repo-dev/assets/master/logo-alt.png"
    alt="mono-repo logo" 
    width="130"
    height="141"
  />
</p>
<h1 align="center"> @mono-repo/utils</h1>
<p align="center">
  <img style="display: inline-block; margin-right: 5px;" src="https://github.com/mono-repo-dev/mono-repo/workflows/Verify/badge.svg" />
  <img style="display: inline-block; margin-right: 5px;" src="https://github.com/mono-repo-dev/mono-repo/workflows/Publish/badge.svg" />
  <img style="display: inline-block; margin-right: 5px;" src="https://badgen.net/github/release/mono-repo-dev/mono-repo" />
</p>

Core util functions to aid writing tools and libraries for managing mono repos.

## Getting started

```sh
yarn add @mono-repo/utils
```

## Usage

### `findMonoRepo({ cwd: string })`

Walks up directories until it finds a mono repo root directory then returns it's config.

```ts
import { findMonoRepo } from "@mono-repo/utils";

const monoRepo = await findMonoRepo({
  cwd: process.cwd(), // default
});

console.log(monoRepo);

/**
 * {
 *   dir: "/absolute/path/to/root",
 *   packageGlobs: ["packages/**"],
 * }
 */
```

**Currently only supports using Yarn Workspaces config.**

### `findPackages(monoRepo, { order: "alphabetical" | "dependency-graph", scope: package | undefined })`

Find packages within a mono repo.

By default packages are returned in alphabetical order.

```ts
import { findMonoRepo, findPackages } from "@mono-repo/utils";

const monoRepo = await findMonoRepo();
const packages = await findPackages(monoRepo, { order: "alphabetical" });

console.log(packages);

/**
 * [
 *   {
 *     dir: "/absolute/path/to/package/a",
 *     json: {
 *       name: "a",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       ...
 *     }
 *   },
 *   {
 *     dir: "/absolute/path/to/package/b",
 *     json: {
 *       name: "b",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       ...
 *     }
 *   }
 * ]
 *
 *
 */
```

You can also return packages in dependency-graph order. This is very useful for getting all packages in a mono repo in an optimal build order.

```ts
import { findMonoRepo, findPackages } from "@mono-repo/utils";

const monoRepo = await findMonoRepo();
const packages = await findPackages(monoRepo, { order: "dependency-graph" });

console.log(packages);

/**
 * [
 *   {
 *     dir: "/absolute/path/to/package/b",
 *     json: {
 *       name: "b",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       ...
 *     }
 *   },
 *   {
 *     dir: "/absolute/path/to/package/a",
 *     json: {
 *       name: "a",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       dependencies: {
 *         "b": "1.0.0"
 *       }
 *       ...
 *     }
 *   }
 * ]
 */
```

You can also return packages that are in the dependency tree on a particular package. This is very useful for getting all the packages required to build just a particular particular package in an optimal build order.

```ts
import { findMonoRepo, findPackages } from "@mono-repo/utils";

const monoRepo = await findMonoRepo();
const packages = await findPackages(monoRepo);

console.log(packages);

/**
 * [
 *   {
 *     dir: "/absolute/path/to/package/a",
 *     json: {
 *       name: "a",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       dependencies: {
 *         "b": "1.0.0"
 *       }
 *       ...
 *     }
 *   },
 *   {
 *     dir: "/absolute/path/to/package/b",
 *     json: {
 *       name: "b",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       ...
 *     }
 *   },
 *   {
 *     dir: "/absolute/path/to/package/c",
 *     json: {
 *       name: "c",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       dependencies: {
 *         "a": "1.0.0"
 *       }
 *       ...
 *     }
 *   },
 * ]
 */

const packageADependencies = await findPackages(monoRepo, {
  order: "dependency-graph",
  scope: packages[0],
});

console.log(packageADependencies);

/**
 * [
 *   {
 *     dir: "/absolute/path/to/package/b",
 *     json: {
 *       name: "b",
 *       version: "1.0.0",
 *       license: "MIT",
 *       public: true,
 *       ...
 *     }
 *   },
 * ]
 */
```

### `findPackageGroups(monoRepo, { groupBy: "parallelizable" })`

Find packages within a mono repo and group them in groups that are safe to perform parallel tasks on such as building in dependency order efficiently.

```ts
import { findMonoRepo, findPackageGroups } from "@mono-repo/utils";

const monoRepo = await findMonoRepo();
const packageGroups = await findPackageGroups(monoRepo, {
  order: "parallelizable",
});

console.log(packageGroups);

/**
 * [
 *   [
 *     {
 *       dir: "/absolute/path/to/package/b",
 *       json: {
 *         name: "b",
 *         version: "1.0.0",
 *         license: "MIT",
 *         public: true,
 *         ...
 *       }
 *     },
 *     {
 *       dir: "/absolute/path/to/package/c",
 *       json: {
 *         name: "c",
 *         version: "1.0.0",
 *         license: "MIT",
 *         public: true,
 *         ...
 *       }
 *     }
 *   ],
 *   [
 *     {
 *       dir: "/absolute/path/to/package/a",
 *       json: {
 *         name: "a",
 *         version: "1.0.0",
 *         license: "MIT",
 *         public: true,
 *         dependencies: {
 *           "b": "1.0.0"
 *         }
 *         ...
 *       }
 *     }
 *   ]
 * ]
 */
```