Skip to content

Commit

Permalink
Add documentation
Browse files Browse the repository at this point in the history
Those of us that have worked on the monorepo have a lot of context
around why it exists, what it does, and how to work with it, but
for everyone else, this context may not exist. The set of guides in this
commit aims to fill in the missing gaps. I've also included a bit around
preview builds at the end. We may also need an expanded section on
creating new releases, as people may not immediately jump to the docs
for `create-release-branch`, and those docs may not be as comprehensive
as they could be. This could come in a future PR, however.
  • Loading branch information
mcmire committed Nov 24, 2022
1 parent fe822ff commit 01454db
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 9 deletions.
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ package-lock.json
.eslintcache

.DS_STORE
coverage
dist
docs
packages/*/coverage
packages/*/dist
packages/*/docs

# yarn v3 (w/o zero-install)
# See: https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
Expand All @@ -26,4 +26,4 @@ docs
!.yarn/versions

# typescript
*.tsbuildinfo
packages/*/*.tsbuildinfo
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A collection of platform-agnostic modules for creating secure data models for cr

## Modules

This is a monorepo that houses the following packages. Please refer to the READMEs for these packages for installation and usage instructions:
This repo houses the following packages, which you can examine for installation and usage instructions:

- [`@metamask/address-book-controller`](packages/address-book-controller)
- [`@metamask/announcement-controller`](packages/announcement-controller)
Expand All @@ -26,13 +26,23 @@ This is a monorepo that houses the following packages. Please refer to the READM
- [`@metamask/subject-metadata-controller`](packages/subject-metadata-controller)
- [`@metamask/transaction-controller`](packages/transaction-controller)

Here is a graph that shows the dependencies among all packages:
Or, in graph form:

![Dependency graph](assets/dependency-graph.png)

> **Note**
> To regenerate this graph, run `yarn generate-dependency-graph`.
## Architecture

This is a monorepo that houses multiple packages published under the `@metamask` namespace on NPM. Here are some topics you may find useful when developing:

- [What is a controller and how are they used?](docs/what.md)
- [Why we're using a monorepo](docs/why.md)
- [How the monorepo works](docs/how.md)
- [Common tasks you may need to perform when working on a package](docs/common-tasks.md)
- [How to test in-progress changes to a package within a project](docs/preview-builds.md)

## Contributing

### Setup
Expand All @@ -41,17 +51,17 @@ Here is a graph that shows the dependencies among all packages:
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
- Install [Yarn v3](https://yarnpkg.com/getting-started/install).
- Run `yarn install` to install dependencies and run any required post-install scripts.
- Run `yarn simple-git-hooks` to add a [Git hook](https://github.com/toplenboren/simple-git-hooks#what-is-a-git-hook) which will ensure that all files pass the linter before you push a branch.
- Run `yarn simple-git-hooks` to add a [Git hook](https://github.com/toplenboren/simple-git-hooks#what-is-a-git-hook) to your local development environment which will ensure that all files pass the linter before you push a branch.

### Testing and Linting

Run `yarn test` to run tests for all packages. Run `yarn workspace <package-name> run test` to run tests for a single package.
Run `yarn test` to run tests for all packages. Run `yarn workspace <package-name> run test` to run tests for a single package (where `<package-name>` is the published name of a package, e.g. `@metamask/announcement-controller`, not its location within the monorepo, e.g. `packages/announcement-controller`).

Run `yarn lint` to lint all files and show possible violations, or run `yarn lint:fix` to fix any automatically fixable violations.

### Release & Publishing

This project follows a unique release process. The [`create-release-branch`](https://github.com/MetaMask/create-release-branch) tool and [`action-publish-release`](https://github.com/MetaMask/action-publish-release) GitHub action are used to automate the release process; see those repositories for more information about how they work.
This project follows a process which is unique to this repo. The [`create-release-branch`](https://github.com/MetaMask/create-release-branch) tool and [`action-publish-release`](https://github.com/MetaMask/action-publish-release) GitHub action are used to automate the release process; see those repositories for more information about how they work.

1. To begin the release process, run `create-release-branch`, specifying the packages you want to release. This tool will bump versions and update changelogs across the monorepo automatically, then create a new branch for you.

Expand Down
76 changes: 76 additions & 0 deletions docs/common-tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Common monorepo tasks

When working with the monorepo, you will always be concerned with one of two needs:

- How do I do something for only one package?
- How do I do the same thing across all packages?

If you've read the ["How"](./how.md) section you know that we can use Yarn for both of these, because it treats the monorepo as a workspace of workspaces.

## Doing something for only one package

Use `yarn workspace <package> <rest...>`.

That `package` argument is important: it's the name of the package you want to target, not the directory where the package is located.

As for the `rest`, it depends on what you want to do:

- If you want to run a package script (a command configured under the package's `scripts` field) or an executable (a command that a dependency provides), use `run` followed by the name of the script and the arguments.
- If you want to run an arbitrary command, use `exec` followed by the name of the command and the arguments.

### Examples

We'll assume you're working with the package `@metamask/address-book-controller`:

If you want to use the package script `test` to run all tests:

```
yarn workspace @metamask/address-book-controller run test
```

If you want to use the `jest` executable to run Jest directly instead:

```
yarn workspace @metamask/address-book-controller run jest
```

If you want to read `package.json` and run it through `jq` to grab the current version:

```
yarn workspace @metamask/address-book-controller exec cat package.json | jq '.version'
```

## Doing the same thing across all packages

Use `yarn workspaces foreach <rest...>` (notice the `s`).

As with `yarn workspace`, it depends on what you want to do:

- If you want to run a package script, use `run` followed by the name of the script and the arguments.
- If you want to run an arbitrary command, use `exec` followed by the name of the command and the arguments.

This command takes a bunch of options, but these are the ones we've found useful:

- `--verbose` is practically necessary, because without it, you won't know which part of the output came from which package.
- `--parallel` will run the command across a set pool of packages at the same time. This can be handy for speeding up your run.
- `--topological` / `--topological-dev` is neat because it will sort packages in dependency order. This means that the command will run first for packages that do not depend on any other packages, then it will run the command for all of the packages that depend on those packages, etc. (The `-dev` variant includes `devDependencies` when determining what a package's dependencies are, otherwise they are ignored.)

### Examples

If you want to use the package script `test` to run all tests across all packages (note: the `yarn test` command does this already):

```
yarn workspaces foreach --verbose test
```

If you want to use the `jest` executable to run Jest directly for all packages:

```
yarn workspaces foreach --verbose run jest
```

If you want to read `package.json` and run it through `jq` to grab the current version for all packages in parallel (note the double quotes):

```
yarn workspaces foreach --verbose --parallel exec "cat package.json | jq '.version'"
```
Loading

0 comments on commit 01454db

Please sign in to comment.