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

Open
wants to merge 44 commits into
base: master
Choose a base branch
from

Conversation

JoE11-y
Copy link
Contributor

@JoE11-y JoE11-y commented May 3, 2025

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

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@JoE11-y JoE11-y requested review from a team as code owners May 3, 2025 11:17
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 3, 2025 11:18 — with GitHub Actions Inactive
@JoE11-y
Copy link
Contributor Author

JoE11-y commented May 3, 2025

@IGI-111 this is ready for review.

I also noticed something, i was unable to trigger the lockfile update by just updating the members_manifest, it only worked when the forc.toml was already updated with new dependencies.

Copy link

codspeed-hq bot commented May 3, 2025

CodSpeed Performance Report

Merging #7143 will not alter performance

Comparing JoE11-y:feat/forc-edit-subcommands-impl (6fccaf0) with master (a70254b)

Summary

✅ 24 untouched benchmarks

@zees-dev
Copy link
Contributor

zees-dev commented May 5, 2025

You may also want to integrate with the forc.pub registry - which would be a canonical endpoint to add dependencies.
^ Or an issue should be created to integrate with forc.pub registry - if this is to be done in a future PR.
Thoughts @sdankel, @kayagokalp?

@IGI-111
Copy link
Contributor

IGI-111 commented May 5, 2025

This looks nice but you need to add some tests and fix the CI errors before we can consider merging it.

@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 5, 2025 10:42 — with GitHub Actions Inactive
@JoE11-y
Copy link
Contributor Author

JoE11-y commented May 5, 2025 via email

@JoE11-y JoE11-y requested review from a team as code owners May 5, 2025 21:22
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 5, 2025 21:23 — with GitHub Actions Inactive
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 5, 2025 22:42 — with GitHub Actions Inactive
@sdankel sdankel temporarily deployed to fuel-sway-bot May 6, 2025 20:36 — with GitHub Actions Inactive
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 6, 2025 21:25 — with GitHub Actions Inactive
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 7, 2025 09:22 — with GitHub Actions Inactive
@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 7, 2025 09:46 — with GitHub Actions Inactive
@JoshuaBatty
Copy link
Member

JoshuaBatty commented May 9, 2025

Hey @JoE11-y thanks for the PR. Just letting you know I plan to look at this properly on Monday.

@JoE11-y
Copy link
Contributor Author

JoE11-y commented May 20, 2025

@kayagokalp I removed the default semver fallback.

And just added the an error requesting user to specify version either via git or path or with version that way code still works in production pending when the registry lookup feature is up and running.

I also updated the tests to test for that too.

@kayagokalp kayagokalp changed the title Add Dependency Management Support to forc* feat: implement forc add and forc remove to add/remove dependencies May 20, 2025
Comment on lines 109 to 120
member_manifests.insert(
updated_package_manifest.project_name().to_string(),
updated_package_manifest,
);

let new_plan = pkg::BuildPlan::from_lock_and_manifests(
&lock_path,
&member_manifests,
false,
opts.offline,
&opts.ipfs_node.clone().unwrap_or_default(),
);
Copy link
Member

@kayagokalp kayagokalp May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic seems a little off to me, the dependencies are not members of build plan Members' refer to the workspace members (packages in a workspace, indivual packages might have dependenices attached to them which this PR aims to add/remove with a command. So we are not modifying the members, but the deps of the members). I will test in a bit but my guess is that this won't even work, until then i am blocking this PR so that it doesn't get merged accidentally. I'll update in a bit

Also there is probably no need to be this verbose and do these steps manually, we should be able to run build after modifying the manifest file, build will run build plan generation, lock updates, and all the extra logic you have here.

Copy link
Contributor Author

@JoE11-y JoE11-y May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off, thank you for catching that and for all the thorough reviews so far.

I really appreciate it. I wanted to share a bit of the journey behind these changes:

  • I initially pulled the target package directly from the workspace’s member_manifests() and updated it in place, expecting that to regenerate the build plan and lockfile.

  • Then I discovered that updating only the in-memory manifest wasn’t enough to trigger the lockfile update. my first comment to the pr

  • So with the help of and with subsequent revisions from @zees-dev , I was able to rework the pr, to focus on updating the toml file directly, performing the checks along the way.

I’ve spent countless hours on this iteration, tweaking, testing, and making sure it behaves exactly like its sibling commands. I’m confident that this approach is rock solid.

And yes that logic was from the old design.

simply shadowing it with the updatedPackageManifest will clear it up

let member_manifests = updated_package_manifest.member_manifests()?;

Thanks again for your patience and feedback. I’m excited to get this merged! ❤️

Copy link
Member

@kayagokalp kayagokalp May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey again, what i meant was that you shouldn't need to modify member_manifest at all because:

  1. What you are implementing here is not related to member manifests, added dependency should not be part of member manifest.
  2. It is not needed to do this manually, build plan generation handles all the steps you are doing manually, you just need to update the manifest file (forc.toml) and regenerate the build plan that will take care of everything :)

I would simply write the updated forc.toml to the disk and call build/check, or if you want to BuildPlan::from_pkg_options, this way you don't have to manage anything yourself.

If this doesn't help, give me some time, I'll prepare you a moredetaild write up

Copy link
Contributor Author

@JoE11-y JoE11-y May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh for

  1. that was the old design.

It's only being used to properly verify the package path.

As we know from cargo.

We can call the add command from either the root of a workspace or from the root of a package.

So if called from root of a workspace the package where the dependency is to be added/removed should be specified with the --package flag.

So checks to ensure that specified package is included in member_manifests are required.

Then also when you want to add another member of a workspace as a dependency to another member.

Those scenarios are where we need to access the member_manifests

That insert was part of the old design where I figured I could take out the exact manifest and then update.

  1. Yeah that could work.

Copy link
Member

@kayagokalp kayagokalp May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tested the version at 6a78549 seems to be working, i am fine to keep it working and get it merged we can clean it later on :) Let's revert back to it, and I will do a refactor over your code after merging it.

@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 20, 2025 22:23 — with GitHub Actions Inactive
@JoE11-y JoE11-y requested a review from kayagokalp May 20, 2025 22:31
kayagokalp
kayagokalp previously approved these changes May 20, 2025
Copy link
Member

@kayagokalp kayagokalp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this! Thanks :) Approving this as this is getting unnecessarily long PR history, and the feature seems to be working.

My final comments are:

  1. The logic to add/remove packages a little too convoluted and there are areas of improvements to seriously cut down the code size.
  2. forc add without any dep to add doesn't produce any error/warning simply does nothing silently which is not great
  3. The way the feature is implemented will be removing all the comments present in the Forc.toml

But given that you already put so much work on this, I think we can merge this as it is, and later on I can do a small refactor to keep this code section little bit smaller by using the existing code-paths.

zees-dev
zees-dev previously approved these changes May 20, 2025
Copy link
Contributor

@zees-dev zees-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving again; thanks for your contribution @JoE11-y!

Any additional work required should probably be captured in a TODO and/or GH issue - so it can be addressed at some point.

@JoE11-y
Copy link
Contributor Author

JoE11-y commented May 20, 2025

I think we can handle the forc add/remove failure by adding the required field in clap for them.

#[clap(value_enum, value_name = "DEP_SPEC", required = true)]
pub dependencies: Vec<String>

Thank you @zees-dev and @kayagokalp ❤️

@JoE11-y JoE11-y dismissed stale reviews from kayagokalp and zees-dev via 06f1535 May 21, 2025 00:32
@JoE11-y
Copy link
Contributor Author

JoE11-y commented May 21, 2025

@zees-dev @kayagokalp resolved the comment removal issue and the forc add without dep failure.

Thanks for helping reach this stage of the pr.
It's been an exciting one.

And my apologies for being a little over zealous.🫡

@JoE11-y JoE11-y temporarily deployed to fuel-sway-bot May 21, 2025 00:34 — with GitHub Actions Inactive
@JoE11-y JoE11-y requested review from kayagokalp and zees-dev May 21, 2025 01:08
@fuel-cla-bot
Copy link

fuel-cla-bot bot commented May 22, 2025

Thanks for the contribution! Before we can merge this, we need @sdankel to sign the Fuel Labs Contributor License Agreement.

@JoshuaBatty JoshuaBatty enabled auto-merge (squash) May 22, 2025 02:21
@JoshuaBatty JoshuaBatty deployed to fuel-sway-bot May 22, 2025 02:21 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a subcommand to forc to edit third party dependencies similar to Cargo
6 participants