Skip to content

feat: implement forc add and forc remove to add/remove dependencies #7143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ thiserror = "1.0"
tikv-jemallocator = "0.6"
tokio = "1.12"
toml = "0.8"
toml_edit = "0.22"
toml_edit = { version = "0.22", features = ["serde"] }
tower = { version = "0.5", default-features = false }
tower-lsp = "0.20"
tracing = "0.1"
Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
- [Workspaces](./forc/workspaces.md)
- [Dependencies](./forc/dependencies.md)
- [Commands](./forc/commands/index.md)
- [forc add](./forc/commands/forc_add.md)
- [forc remove](./forc/commands/forc_remove.md)
- [forc addr2line](./forc/commands/forc_addr2line.md)
- [forc build](./forc/commands/forc_build.md)
- [forc check](./forc/commands/forc_check.md)
Expand Down
32 changes: 32 additions & 0 deletions docs/book/src/forc/commands/forc_add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# forc add

Adds one or more dependencies to a `Forc.toml` manifest.

## **Usage**

```bash
forc add [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies in the format `name[@version]` (e.g., `[email protected]`, `custom_contract`)

## **Options**

* `--path <PATH>`: Add a local path dependency.
* `--git <URI>`: Add a Git-based dependency.

* Can be combined with one of:

* `--branch <branch>`
* `--tag <tag>`
* `--rev <rev>`
* `--ipfs <CID>`: Add a dependency sourced from IPFS.
* `--contract-dep`: Add to `[contract-dependencies]` instead of `[dependencies]`.
* `--salt <SALT>`: Salt to use for contract deployment (only applies to contract dependencies).
* `--package <SPEC>`: Apply change to a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Show what would be changed without writing to the file.
* `--offline`: Do not fetch any remote dependencies.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for IPFS-sourced dependencies.
22 changes: 22 additions & 0 deletions docs/book/src/forc/commands/forc_remove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# forc remove

Removes one or more dependencies from a `Forc.toml` manifest.

## **Usage**

```bash
forc remove [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies to remove by name (e.g., `custom_lib`, `custom_contract`)

## **Options**

* `--contract-dep`: Remove from `[contract-dependencies]` instead of `[dependencies]`.
* `--package <SPEC>`: Target a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Preview what would be removed without making any changes.
* `--offline`: Prevent forc from fetching metadata or resolving versions remotely.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for reference.
117 changes: 92 additions & 25 deletions docs/book/src/forc/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,122 @@
# Dependencies

Forc has a dependency management system which can pull packages using `git`, `ipfs` or `registry`. This allows users to build and share Forc libraries.
Forc has a dependency management system which can pull packages using `git`, `ipfs`, `path`, or the community `registry`. This allows users to build and share Forc libraries.

## Adding a dependency
## Adding Dependencies

If your `Forc.toml` doesn't already have a `[dependencies]` table, add one. Below, list the package name alongside its source. Currently, `forc` supports `git`, `ipfs`, `path` and `registry` sources.
You can add dependencies manually in your `Forc.toml`, or by using the `forc add` command.

If a `git` source is specified, `forc` will fetch the git repository at the given URL and then search for a `Forc.toml` for a package with the given name anywhere inside the git repository.
### Using `forc add`

The following example adds a library dependency named `custom_lib`. For git dependencies you may optionally specify a `branch`, `tag`, or `rev` (i.e. commit hash) reference.
The `forc add` CLI supports various sources and optional flags:

```toml
[dependencies]
custom_lib = { git = "https://github.com/FuelLabs/custom_lib", branch = "master" }
# custom_lib = { git = "https://github.com/FuelLabs/custom_lib", tag = "v0.0.1" }
# custom_lib = { git = "https://github.com/FuelLabs/custom_lib", rev = "87f80bdf323e2d64e213895d0a639ad468f4deff" }
```bash
forc add <dep> [--path <PATH>] [--git <URL> --tag <TAG>] [--ipfs <CID>] [--contract-dep]
```

Depending on a local library using `path`:
#### Add Examples

* From a Git branch:

```bash
forc add custom_lib --git https://github.com/FuelLabs/custom_lib --branch master
```

* From a local path:

```bash
forc add custom_lib --path ../custom_lib
```

* From IPFS:

```bash
forc add custom_lib --ipfs QmYwAPJzv5CZsnA...
```

* From registry (forc.pub):

```bash
forc add [email protected]
```

* Add as a contract dependency:

```bash
forc add my_contract --git https://github.com/example/contract --contract-dep
```

Optional:

* `--salt <HEX>` for custom contract salt.
* `--package <NAME>` to target a specific package in a workspace.
* `--manifest-path <PATH>` to specify a manifest file.

> ⚠️ **Note:**
> We do not currently support offline mode for projects that use **registry** sources.
> Also wildcard declarations `(ex: custom_lib = *)` to get the latest version available for that package or caret declarations `(ex: custom_lib = ^0.1)` to get `SemVer` compatible latest available option for a given dependency is not supported yet.
Once the package is added, running `forc build` will automatically fetch and resolve the dependencies.

### Manually Editing `Forc.toml`

If your `Forc.toml` doesn't already have a `[dependencies]` or `[contract-dependencies]` table, add one. Below, list the package name and its source.

#### Local Path

```toml
[dependencies]
custom_lib = { path = "../custom_lib" }
```

For `ipfs` sources, `forc` will fetch the specified `cid` using either a local `ipfs` node or a public gateway. `forc` automatically tries to connect to local `ipfs` node. If it fails, it defaults to using `https://ipfs.io/` as a gateway.

The following example adds a dependency with an `ipfs` source.
#### IPFS Source

```toml
[dependencies]
custom_lib = { ipfs = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG" }
custom_lib = { ipfs = "QmYwAPJzv5CZsnA..." }
```

For `registry` sources, `forc` will first resolve the source declared by its name and version. This is done using the forc.pub-index repo (located at `https://github.com/FuelLabs/forc.pub-index`). The package name and version is used to convert the declaration to an IPFS CID. The resolved IPFS CID is then used by either a local IPFS node or an IPFS gateway that fuel operates (`https://ipfs.forc.pub/`) to actually fetch the package.

Available packages can be found at `https://forc.pub`.

The following example adds a dependency with a `registry` source.
#### Registry Source (forc.pub)

```toml
[dependencies]
custom_lib = "0.0.1"
```

In the example above the package `custom_lib v0.0.1` will be fetched from `forc.pub` using IPFS.
## Removing Dependencies

You can remove one or more dependencies using the `forc remove` command:

```bash
forc remove <dep> [--contract-dep] [--package <NAME>] [--manifest-path <PATH>]
```

### Remove Examples

* Remove from `[dependencies]`:

```bash
forc remove custom_lib
```

* Remove from `[contract-dependencies]`:

We do not currently support `offline` mode of operation for project that uses `registry` sources. Also wildcard declarations (ex: `custom_lib = *`) to get the latest version available for that package or caret declarations (ex: `custom_lib = ^0.1`) to get `SemVer` compatible latest available option for a given dependency is not supported yet.
```bash
forc remove my_contract --contract-dep
```

Once the package is added, running `forc build` will automatically download added dependencies.
* Target a specific package in a workspace:

## Updating dependencies
```bash
forc remove custom_lib --package my_project
```

## Updating Dependencies

To update dependencies in your Forc directory you can run:

```bash
forc update
```

To update dependencies in your Forc directory you can run `forc update`. For `path` and `ipfs` dependencies this will have no effect. For `git` dependencies with a `branch` reference, this will update the project to use the latest commit for the given branch.
For path and ipfs dependencies this will have no effect. For git dependencies with a branch reference, this will update the project to use the latest commit for the given branch.
2 changes: 1 addition & 1 deletion forc-pkg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sway-types.workspace = true
sway-utils.workspace = true
tar.workspace = true
toml = { workspace = true, features = ["parse"] }
toml_edit.workspace = true
tracing.workspace = true
url = { workspace = true, features = ["serde"] }
vec1.workspace = true
Expand All @@ -48,4 +49,3 @@ tempfile.workspace = true

[target.'cfg(not(target_os = "macos"))'.dependencies]
sysinfo.workspace = true

Loading
Loading