Skip to content

Commit ee565f9

Browse files
authored
feat: implement forc add and forc remove to add/remove dependencies (#7143)
## Description Close #2369 **Summary:** Implements functionality for `forc` to add remove dependencies through cli, similar to Cargo's `add` and `remove` commands. **Work Done:** * ✅ Added `forc add` command to support adding both regular and contract dependencies from path, git, IPFS, or version. * ✅ Implemented conflict checks for version + source collisions (e.g., version + git). * ✅ Added automatic fallback to workspace-relative path for local packages. * ✅ Introduced `forc remove` to cleanly remove specified dependencies from the manifest. * ✅ Modularized update logic using `DepSection` enum for unified regular/contract dependency handling. * ✅ Used `toml_edit` to update the manifest file while preserving formatting. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent 07f8fc3 commit ee565f9

File tree

14 files changed

+1724
-31
lines changed

14 files changed

+1724
-31
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ thiserror = "1.0"
238238
tikv-jemallocator = "0.6"
239239
tokio = "1.12"
240240
toml = "0.8"
241-
toml_edit = "0.22"
241+
toml_edit = { version = "0.22", features = ["serde"] }
242242
tower = { version = "0.5", default-features = false }
243243
tower-lsp = "0.20"
244244
tracing = "0.1"

docs/book/src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
- [Workspaces](./forc/workspaces.md)
8181
- [Dependencies](./forc/dependencies.md)
8282
- [Commands](./forc/commands/index.md)
83+
- [forc add](./forc/commands/forc_add.md)
84+
- [forc remove](./forc/commands/forc_remove.md)
8385
- [forc addr2line](./forc/commands/forc_addr2line.md)
8486
- [forc build](./forc/commands/forc_build.md)
8587
- [forc check](./forc/commands/forc_check.md)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# forc add
2+
3+
Adds one or more dependencies to a `Forc.toml` manifest.
4+
5+
## **Usage**
6+
7+
```bash
8+
forc add [OPTIONS] <DEP_SPEC>...
9+
```
10+
11+
## **Arguments**
12+
13+
* `<DEP_SPEC>`: List of dependencies in the format `name[@version]` (e.g., `[email protected]`, `custom_contract`)
14+
15+
## **Options**
16+
17+
* `--path <PATH>`: Add a local path dependency.
18+
* `--git <URI>`: Add a Git-based dependency.
19+
20+
* Can be combined with one of:
21+
22+
* `--branch <branch>`
23+
* `--tag <tag>`
24+
* `--rev <rev>`
25+
* `--ipfs <CID>`: Add a dependency sourced from IPFS.
26+
* `--contract-dep`: Add to `[contract-dependencies]` instead of `[dependencies]`.
27+
* `--salt <SALT>`: Salt to use for contract deployment (only applies to contract dependencies).
28+
* `--package <SPEC>`: Apply change to a specific package in a workspace.
29+
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
30+
* `--dry-run`: Show what would be changed without writing to the file.
31+
* `--offline`: Do not fetch any remote dependencies.
32+
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for IPFS-sourced dependencies.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# forc remove
2+
3+
Removes one or more dependencies from a `Forc.toml` manifest.
4+
5+
## **Usage**
6+
7+
```bash
8+
forc remove [OPTIONS] <DEP_SPEC>...
9+
```
10+
11+
## **Arguments**
12+
13+
* `<DEP_SPEC>`: List of dependencies to remove by name (e.g., `custom_lib`, `custom_contract`)
14+
15+
## **Options**
16+
17+
* `--contract-dep`: Remove from `[contract-dependencies]` instead of `[dependencies]`.
18+
* `--package <SPEC>`: Target a specific package in a workspace.
19+
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
20+
* `--dry-run`: Preview what would be removed without making any changes.
21+
* `--offline`: Prevent forc from fetching metadata or resolving versions remotely.
22+
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for reference.

docs/book/src/forc/dependencies.md

Lines changed: 92 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,122 @@
11
# Dependencies
22

3-
Forc has a dependency management system which can pull packages using `git`, `ipfs` or `registry`. This allows users to build and share Forc libraries.
3+
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.
44

5-
## Adding a dependency
5+
## Adding Dependencies
66

7-
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.
7+
You can add dependencies manually in your `Forc.toml`, or by using the `forc add` command.
88

9-
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.
9+
### Using `forc add`
1010

11-
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.
11+
The `forc add` CLI supports various sources and optional flags:
1212

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

20-
Depending on a local library using `path`:
17+
#### Add Examples
18+
19+
* From a Git branch:
20+
21+
```bash
22+
forc add custom_lib --git https://github.com/FuelLabs/custom_lib --branch master
23+
```
24+
25+
* From a local path:
26+
27+
```bash
28+
forc add custom_lib --path ../custom_lib
29+
```
30+
31+
* From IPFS:
32+
33+
```bash
34+
forc add custom_lib --ipfs QmYwAPJzv5CZsnA...
35+
```
36+
37+
* From registry (forc.pub):
38+
39+
```bash
40+
41+
```
42+
43+
* Add as a contract dependency:
44+
45+
```bash
46+
forc add my_contract --git https://github.com/example/contract --contract-dep
47+
```
48+
49+
Optional:
50+
51+
* `--salt <HEX>` for custom contract salt.
52+
* `--package <NAME>` to target a specific package in a workspace.
53+
* `--manifest-path <PATH>` to specify a manifest file.
54+
55+
> ⚠️ **Note:**
56+
> We do not currently support offline mode for projects that use **registry** sources.
57+
> 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.
58+
59+
Once the package is added, running `forc build` will automatically fetch and resolve the dependencies.
60+
61+
### Manually Editing `Forc.toml`
62+
63+
If your `Forc.toml` doesn't already have a `[dependencies]` or `[contract-dependencies]` table, add one. Below, list the package name and its source.
64+
65+
#### Local Path
2166

2267
```toml
2368
[dependencies]
2469
custom_lib = { path = "../custom_lib" }
2570
```
2671

27-
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.
28-
29-
The following example adds a dependency with an `ipfs` source.
72+
#### IPFS Source
3073

3174
```toml
3275
[dependencies]
33-
custom_lib = { ipfs = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG" }
76+
custom_lib = { ipfs = "QmYwAPJzv5CZsnA..." }
3477
```
3578

36-
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.
37-
38-
Available packages can be found at `https://forc.pub`.
39-
40-
The following example adds a dependency with a `registry` source.
79+
#### Registry Source (forc.pub)
4180

4281
```toml
4382
[dependencies]
4483
custom_lib = "0.0.1"
4584
```
4685

47-
In the example above the package `custom_lib v0.0.1` will be fetched from `forc.pub` using IPFS.
86+
## Removing Dependencies
87+
88+
You can remove one or more dependencies using the `forc remove` command:
89+
90+
```bash
91+
forc remove <dep> [--contract-dep] [--package <NAME>] [--manifest-path <PATH>]
92+
```
93+
94+
### Remove Examples
95+
96+
* Remove from `[dependencies]`:
97+
98+
```bash
99+
forc remove custom_lib
100+
```
101+
102+
* Remove from `[contract-dependencies]`:
48103

49-
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.
104+
```bash
105+
forc remove my_contract --contract-dep
106+
```
50107

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

53-
## Updating dependencies
110+
```bash
111+
forc remove custom_lib --package my_project
112+
```
113+
114+
## Updating Dependencies
115+
116+
To update dependencies in your Forc directory you can run:
117+
118+
```bash
119+
forc update
120+
```
54121

55-
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.
122+
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.

forc-pkg/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ sway-types.workspace = true
3737
sway-utils.workspace = true
3838
tar.workspace = true
3939
toml = { workspace = true, features = ["parse"] }
40+
toml_edit.workspace = true
4041
tracing.workspace = true
4142
url = { workspace = true, features = ["serde"] }
4243
vec1.workspace = true
@@ -48,4 +49,3 @@ tempfile.workspace = true
4849

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

0 commit comments

Comments
 (0)