Skip to content

Commit

Permalink
feat!: Migrate to use the Pub workspaces feature (#816)
Browse files Browse the repository at this point in the history
<!--
  Thanks for contributing!

Provide a description of your changes below and a general summary in the
title

Please look at the following checklist to ensure that your PR can be
accepted quickly:
-->

## Description

This PR migrates so that we rely on the pub workspaces feature instead
of creating the pubspec_overrides.yaml file.

Docs update and migration instructions are soon coming up.

Closes: #747 

## Type of Change

<!--- Put an `x` in all the boxes that apply: -->

- [x] ✨ `feat` -- New feature (non-breaking change which adds
functionality)
- [ ] 🛠️ `fix` -- Bug fix (non-breaking change which fixes an issue)
- [x] ❌ `!` -- Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] 🧹 `refactor` -- Code refactor
- [ ] ✅ `ci` -- Build configuration change
- [ ] 📝 `docs` -- Documentation
- [ ] 🗑️ `chore` -- Chore
  • Loading branch information
spydon authored Jan 7, 2025
1 parent b26f310 commit 3602d90
Show file tree
Hide file tree
Showing 35 changed files with 780 additions and 1,581 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1
with:
sdk: 3.2.0 # Update when min sdk supported version of `melos` package changes.
sdk: 3.6.0 # Update when min sdk supported version of `melos` package changes.
- name: Run Melos
run: ./.github/workflows/scripts/install-tools.sh

Expand Down
60 changes: 27 additions & 33 deletions docs/commands/bootstrap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,43 @@ description: Learn more about the `bootstrap` command in Melos.

<Info>Supports all [Melos filtering](/filters) flags.</Info>

This command initializes the workspace, links local packages together and
installs remaining package dependencies.
This command initializes the workspace and installs remaining package
dependencies.

```bash
melos bootstrap
# or
melos bs
```

Bootstrapping has two primary functions:
Bootstrapping has three primary functions:

1. Installing all package dependencies (internally using `pub get`).
2. Locally linking any packages together via path dependency overrides _without
having to edit your pubspec.yaml_.
2. Syncing shared dependencies between packages.
3. Running any bootstrap lifecycle scripts.

## Why is bootstrapping required?

In normal projects, packages can be linked by providing a `path` within the
`pubspec.yaml`. This works for small projects however presents a problem at
scale. Packages cannot be published with a locally defined path, meaning once
you're ready to publish your packages you'll need to manually update all the
packages `pubspec.yaml` files with the versions. If your packages are also
tightly coupled (dependencies of each other), you'll also have to manually check
which versions should be updated. Even with a few of packages this can become a
long and error-prone task.

Melos solves this problem by overriding local files which the Dart analyzer uses
to read packages from. If a local package exists (defined in the `melos.yaml`
file) and a different local package has it listed as a dependency, it will be
linked regardless of whether a version has been specified.
After the [Pub Workspaces feature](https://dart.dev/tools/pub/workspaces) was
introduced in Dart 3.6.0, it is no longer strictly necessary to run `melos
bootstrap`, since all the packages are already linked together. However, there
are still some benefits to running `melos bootstrap`, because you need to run
`pub get` in each package to initialize the workspace, and `melos bootstrap`
will do that for you.

### Benefits

- All local packages in the repository can be interlinked by Melos to point to
their local directories rather than 'remote' _without pubspec.yaml
modifications_.
Why would I want to use a monorepo?

- All local packages in the repository can be interlinked to point to their
local directories rather than 'remote' _without pubspec.yaml modifications_.
- **Example Scenario**: In a repository, package `A` depends on package `B`.
Both packages `A` & `B` exist in the monorepo. However, if you `pub get`
inside package `A`, `pub` will retrieve package `B` from the pub.dev
registry as it's unaware of `B` existing locally. However, with Melos, it's
aware that package `B` exists locally too, so it will generate the various
pub files to point to a relative path in the local repository.
registry as it's unaware of `B` existing locally. However, with Melos and
pub workspaces, it's aware that package `B` exists locally too, so it will
generate the various pub files to point to a relative path in the local
repository.
- If you wanted to use pub you could of course define a dependency override
in the pubspec of package `A` that sets a path for package `B` but, then
you'd have to do this manually every time and then manually remove it
Expand Down Expand Up @@ -86,20 +81,19 @@ melos bootstrap --diff="main"

## Bootstrap flags

- The `--no-example` flag is used to exclude flutter package's example's dependencies
(https://github.com/dart-lang/pub/pull/3856)
- The `--no-example` flag is used to exclude flutter package's example's
dependencies (https://github.com/dart-lang/pub/pull/3856)
- This will run `pub get` with the `--no-example` flag.
- The `--enforce-lockfile` flag is used to enforce versions from `.lock` files.
- Ensure .lock files exist, as failure may occur if they're not checked in.
- The `--no-enforce-lockfile` flag is used to disregard versions from `.lock` files if
`enforce-lockfile` is configured in the `melos.yaml` file.
- The `--skip-linking` flag is used to skip the local linking of workspace packages.
- The `--offline` flag is used to only resolve dependencies from the local cache by running
`pub get` with the `--offline` flag.
- The `--no-enforce-lockfile` flag is used to disregard versions from `.lock`
files if `enforce-lockfile` is configured in the `melos.yaml` file.
- The `--offline` flag is used to only resolve dependencies from the local
cache by running `pub get` with the `--offline` flag.


In addition to the above flags, the `melos bootstrap` command supports a few different flags that
can be defined in your `melos.yaml` file.
In addition to the above flags, the `melos bootstrap` command supports a few
different configurations that can be defined in your `melos.yaml` file.


### Shared dependencies
Expand Down
72 changes: 39 additions & 33 deletions docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ description: Learn how to start using Melos in your project
Melos requires a few one-off steps to be completed before you can start using
it.

## Pub Workspaces

First start by reading the short Pub Workspaces guide for how to get your
monorepo ready to be used with Melos and Pub Workspaces, the guide can be
found on the [Dart website](https://dart.dev/tools/pub/workspaces).

## Installation

Install Melos as a
Expand Down Expand Up @@ -59,11 +65,18 @@ now:

```yaml
name: my_project

publish_to: none
environment:
sdk: '>=3.0.0 <4.0.0'
sdk: ^3.6.0
workspace:
- packages/helper
- packages/client_package
- packages/server_package
```
Where `packages/helper`, `packages/client_package` and `packages/server_package`
are the paths to the packages in your workspace.

The corresponding `pubspec.lock` file should also be committed. Make sure to
exclude it from the `.gitignore` file.

Expand All @@ -73,6 +86,18 @@ Add Melos as a development dependency by running the following command:
dart pub add melos --dev
```

### Configure your packages

Next, in all your packages `pubspec.yaml` files, add the
`resolution: workspace` field:

```yaml
name: my_package
resolution: workspace
...
```

### Configure the workspace

Next create a `melos.yaml` file at the repository root. Within the `melos.yaml`
Expand All @@ -90,43 +115,23 @@ The `packages` list should contain paths to the individual packages within your
project. Each path can be defined using the
[glob](https://docs.python.org/3/library/glob.html) pattern expansion format.

Melos generates `pubspec_overrides.yaml` files to link local packages for
development. Typically these files should be ignored by git. To ignore these
files, add the following to your `.gitignore` file:

```
pubspec_overrides.yaml
```

## Bootstrapping

Once installed & setup, Melos needs to be bootstrapped. Bootstrapping has 2
primary roles:
Once installed & setup, Melos needs to be bootstrapped. Bootstrapping has
three primary functions:

1. Installing all package dependencies (internally using `pub get`).
2. Locally linking any packages together.
2. Syncing shared dependencies between packages.
3. Running any bootstrap lifecycle scripts.

Bootstrap your project by running the following command:
Bootstrap your project by running the following command:

```bash
melos bootstrap
```

### Why do I need to bootstrap?

In normal projects, packages can be linked by providing a `path` within the
`pubspec.yaml`. This works for small projects however presents a problem at
scale. Packages cannot be published with a locally defined path, meaning once
you're ready to publish your packages you'll need to manually update all the
packages `pubspec.yaml` files with the versions. If your packages are also
tightly coupled (dependencies of each other), you'll also have to manually check
which versions should be updated. Even with a few packages this can become a
long and error-prone task.

Melos solves this problem by overriding local files which the Dart analyzer uses
to read packages from. If a local package exists (defined in the `melos.yaml`
file) and a different local package has it listed as a dependency, it will be
linked regardless of whether a version has been specified.
If you wonder why bootrapping is needed you can read more about it in the
[Bootstrap section](/commands/bootstrap).

## Next steps

Expand All @@ -146,15 +151,16 @@ packages:
- packages/**
scripts:
analyze:
exec: dart analyze .
generate:
run: melos exec -c 1 --depends-on build_runner -- dart run build_runner build
```

Then execute the command by running `melos run analyze`.
Then execute the command by running `melos generate`.

If you're looking for some inspiration as to what scripts can help with, check
out the
[FlutterFire repository](https://github.com/firebase/flutterfire/blob/master/melos.yaml).
[FlutterFire repository](https://github.com/firebase/flutterfire/blob/main/melos.yaml)
or the [Flame repository](https://github.com/flame-engine/flame/blob/main/melos.yaml).

If you are using VS Code, there is an [extension](/ide-support#vs-code)
available, to integrate Melos with VS Code.
35 changes: 35 additions & 0 deletions docs/guides/migrations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,41 @@ description: How to migrate between major versions of Melos.

# Migrations

## 6.x.x to 7.x.x

Since the [pub workspaces](https://dart.dev/tools/pub/workspaces) feature has
been released, Melos has been updated to rely on that instead of creating
`pubspec_overrides.yaml` files and thus some migration is needed.

The main difference is that you now have to add `resolution: workspace` to all
of your packages' `pubspec.yaml` files and add a list of all your packages to
the root `pubspec.yaml` file, similar to this:

Package `pubspec.yaml` file:
```yaml
name: my_package
environment:
sdk: ^3.6.0
resolution: workspace
```
Workspace root `pubspec.yaml` file:
```yaml
name: my_workspace
publish_to: none
environment:
sdk: ^3.6.0
workspace:
- packages/helper
- packages/client_package
- packages/server_package
dev_dependencies:
melos: ^7.0.0
```

> [!NOTE]
> You have to use Dart SDK 3.6.0 or newer to use pub workspaces.

## 3.0.0 to 4.0.0

### `--no-git-tag-version` behavior change
Expand Down
3 changes: 2 additions & 1 deletion docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ other. Features include:
- Listing of local packages & their dependencies.

Melos also works great on CI/CD environments to help automate complex tasks and
challenges.
challenges. If you're using GitHub you can check out the
[Melos GitHub Action](https://github.com/bluefireteam/melos-action).

## Projects using Melos

Expand Down
43 changes: 23 additions & 20 deletions melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,38 @@ categories:
command:
bootstrap:
environment:
sdk: ">=3.2.0 <4.0.0"
sdk: ^3.6.0
dependencies:
ansi_styles: ^0.3.2+1
args: ^2.4.2
args: ^2.6.0
cli_launcher: ^0.3.1
cli_util: ^0.4.1
collection: ^1.18.0
cli_util: ^0.4.2
collection: any
conventional_commit: ^0.6.0+1
file: ^7.0.0
file: ^7.0.1
glob: ^2.1.2
graphs: ^2.3.1
http: ^1.1.0
meta: ^1.10.0
graphs: ^2.3.2
http: ^1.2.2
meta: any
mustache_template: ^2.0.0
path: ^1.8.3
platform: ^3.1.4
path: any
platform: ^3.1.6
pool: ^1.5.1
prompts: ^2.0.0
pub_semver: ^2.1.4
pub_updater: ^0.4.0
pubspec_parse: ^1.4.0
string_scanner: ^1.2.0
yaml: ^3.1.2
yaml_edit: ^2.1.1
pub_semver: ^2.1.5
pub_updater: ^0.5.0
pubspec_parse:
git:
url: https://github.com/dart-lang/tools.git
path: pkgs/pubspec_parse
string_scanner: ^1.3.0
yaml: ^3.1.3
yaml_edit: ^2.2.2
dev_dependencies:
mockito: ^5.4.2
test: ^1.24.9
path: ^1.9.0
yaml: ^3.1.2
mockito: ^5.4.5
test: any
path: ^1.9.1
yaml: ^3.1.3
version:
# Generate commit links in package changelogs.
linkToCommits: true
Expand Down
5 changes: 3 additions & 2 deletions packages/conventional_commit/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ description:
version: 0.6.0+1
repository: https://github.com/invertase/melos/tree/main/packages/conventional_commit
issue_tracker: https://github.com/invertase/melos/issues
resolution: workspace

environment:
sdk: ">=3.2.0 <4.0.0"
sdk: ^3.6.0

dev_dependencies:
test: ^1.24.9
test: any
35 changes: 35 additions & 0 deletions packages/melos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,41 @@ bases into multi-package repositories (sometimes called
**Melos is a tool that optimizes the workflow around managing multi-package
repositories with git and Pub.**

## Migrate to Melos 7.x.x

Since the [pub workspaces](https://dart.dev/tools/pub/workspaces) feature has
been released, Melos has been updated to rely on that instead of creating
`pubspec_overrides.yaml` files and thus some migration is needed.

The main difference is that you now have to add `resolution: workspace` to all
of your packages' `pubspec.yaml` files and add a list of all your packages to
the root `pubspec.yaml` file, similar to this:

Package `pubspec.yaml` file:
```yaml
name: my_package
environment:
sdk: ^3.6.0
resolution: workspace
```
Workspace root `pubspec.yaml` file:
```yaml
name: my_workspace
publish_to: none
environment:
sdk: ^3.6.0
workspace:
- packages/helper
- packages/client_package
- packages/server_package
dev_dependencies:
melos: ^7.0.0
```

> [!NOTE]
> You have to use Dart SDK 3.6.0 or newer to use pub workspaces.

## Github Action

If you're planning on using Melos in your GitHub Actions workflows, you can use
Expand Down
Loading

0 comments on commit 3602d90

Please sign in to comment.