Skip to content
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

Prevent failure while creating BuildPlan from lock file in the case of a dependency removal #1974

Closed
wants to merge 25 commits into from

Conversation

kayagokalp
Copy link
Member

@kayagokalp kayagokalp commented Jun 14, 2022

About this PR

Still in WIP, opening up for visibility. I will be adding testing steps

closes #1778.

Motivation

Before this PR, BuildPlan generation from the lock file was failing if after the lock file is generated, a dependency is removed from the manifest file (specifically if the removed dependency is a path dependency).

This was resulting in the BuildPlan being generated from scratch. To generate the BuildPlan from scratch we generally need connectivity since std is implicitly added as a git dependency (if we do not explicitly prevent it with implicit-std = false). Ideally, we should be able to remove any dependency in offline mode.

With this PR, we should be able to create the BuildPlan from the lock file even if a path dependency is removed. This should mean apply_pkg_diff will be able to remove any dependency in offline mode.

To Test

  1. run forc new parent
  2. run forc new --library child
  3. add child as a dependency to parent
  4. run forc build in parent
  5. remove the child from parent's dependencies
  6. run forc build in parent

This should output something like

Creating a new `Forc.lock` file. (Cause: lock file did not match manifest `diff`)

Rather than

Creating a new `Forc.lock` file. (Cause: dependency required for path reconstruction has been removed from the manifest)

@kayagokalp kayagokalp added bug Something isn't working forc dependencies labels Jun 14, 2022
@kayagokalp kayagokalp self-assigned this Jun 14, 2022
@kayagokalp
Copy link
Member Author

I found out a bug about this one (as it can be seen from CI failure) so leaving this as a draft and will come back to here after I am done with some formatter stuff.

@kayagokalp kayagokalp requested review from ra0x3 and a team June 16, 2022 18:12
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
@kayagokalp kayagokalp marked this pull request as ready for review June 16, 2022 18:13
@kayagokalp kayagokalp requested a review from eureka-cpu June 16, 2022 18:16
@kayagokalp kayagokalp enabled auto-merge (squash) June 16, 2022 21:35
Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

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

Thanks for diving into this @kayagokalp, it's certainly a bit of an awkward one to address.

I'm starting to wonder if we should be doing the validate step as a part of the BuildPlan construction... Ideally it shouldn't be possible to construct a BuildPlan that is invalid. I think originally the idea behind having the validate method be in a following step was to allow for the comparison of the build plans to work out the package diff to print to the user, but perhaps this can just be returned alongside the BuildPlan constructor?

forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
@kayagokalp
Copy link
Member Author

I am applying the changes requested rn and while doing so realized that introduction of #1836 will have a tiny effect on this one. So I would like to merge that one first if possible so that I can add the required changes in this PR as well

@kayagokalp kayagokalp disabled auto-merge June 17, 2022 15:07
@kayagokalp kayagokalp marked this pull request as draft June 17, 2022 15:09
@kayagokalp
Copy link
Member Author

kayagokalp commented Jun 17, 2022

I'm starting to wonder if we should be doing the validate step as a part of the BuildPlan construction... Ideally it shouldn't be possible to construct a BuildPlan that is invalid. I think originally the idea behind having the validate method be in a following step was to allow for the comparison of the build plans to work out the package diff to print to the user, but perhaps this can just be returned alongside the BuildPlan constructor?

@mitchmindtree, that sounds better to me as I feel like it would allow us to do some extra cleaning as well. Should I file an issue and address it with a separate PR or do you think we should have it with this one?

Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

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

Should I file an issue and address it with a separate PR or do you think we should have it with this one?

Yeah I think it would be great if we could address it in this PR!

forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Show resolved Hide resolved
@kayagokalp kayagokalp marked this pull request as ready for review June 20, 2022 15:45
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
forc-pkg/src/pkg.rs Show resolved Hide resolved
forc-pkg/src/pkg.rs Show resolved Hide resolved
@kayagokalp
Copy link
Member Author

I can use a re-review at this point, especially about #1974 (comment).

Also, I will apply #1974 (comment) too other than that I believe It started to look a lot better. Thanks for the extensive reviews so far 🙌

@kayagokalp kayagokalp requested a review from mitchmindtree June 23, 2022 09:55
Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

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

Now that we have a load_from_manifest constructor, perhaps we can make the from_lock and from_lock_file constructors private to avoid exposing an invalid BuildPlan to downstream users? We can probably also make the apply_pkg_diff and generate_diff methods private now too.

forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
@kayagokalp
Copy link
Member Author

I think this should be good to go for a final review but I couldn't make the from_lock_file private since sway-lsp uses it.

@kayagokalp kayagokalp requested a review from mitchmindtree June 27, 2022 09:35
@kayagokalp kayagokalp enabled auto-merge (squash) June 27, 2022 09:36
/// Attempt to find the difference between the graph constructed from the lock file
/// and the graph that is described by the manifest file. The difference is used to
/// update BuildPlan.
pub fn generate_diff(&self, manifest: &Manifest) -> Result<PkgDiff> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can make this private too

@@ -162,7 +162,7 @@ impl TextDocument {
pkg::ManifestFile::from_dir(&manifest_dir, forc::utils::SWAY_GIT_TAG).unwrap();
let lock_path = forc_util::lock_path(manifest.dir());
let plan = pkg::BuildPlan::from_lock_file(&lock_path, forc::utils::SWAY_GIT_TAG).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh I wonder if this BuildPlan should be constructed via load_from_manifest rather than from_lock_file - otherwise LSP won't pick up changes to the manifest until the user manually triggers a build and updates the lock file again. @JoshuaBatty does this sound right?

If we can change this over to load_from_manifest, we should be able to make from_lock_file private.

Copy link
Member Author

Choose a reason for hiding this comment

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

Depending on the input from @JoshuaBatty maybe we can do something like

let plan =
  pkg::BuildPlan::load_from_manifest(&manifest, false, false, forc::utils::SWAY_GIT_TAG)
      .unwrap_or_else(|_| {
          pkg::BuildPlan::from_lock_file(&lock_path, forc::utils::SWAY_GIT_TAG)
              .map(|plan| plan.0)
              .unwrap()
      });

Copy link
Contributor

Choose a reason for hiding this comment

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

I think rather than falling back to from_lock_file, we might be better off producing an error from LSP to the user so that they're aware of whatever the failure is. It might be a bit unexpected if LSP keeps using an old BuildPlan after they've updated the manifest.

Copy link
Member

@JoshuaBatty JoshuaBatty Jun 29, 2022

Choose a reason for hiding this comment

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

If I add a crate to the Cargo.toml file and save it in a rust project then I am able to start using types from that crate and even jump to the definition of items in that crate without needing to build the project again. Not sure if it's rust or rust-analyzer that is downloading the added crate once the manifest file has been saved. It would be nice if we could replicate this behavior somehow.

Copy link
Contributor

@mitchmindtree mitchmindtree Jun 29, 2022

Choose a reason for hiding this comment

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

In that case it sounds like we do want to change the use of from_lock_file to load_from_manifest here - @kayagokalp are you happy to do so in this PR so we can make from_lock_file private too?

Copy link
Member Author

Choose a reason for hiding this comment

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

Should be good to go but didn't add an explicit error throwing for the failure as we didn't have one for the current version too:

let plan = pkg::BuildPlan::from_lock_file(&lock_path, forc::utils::SWAY_GIT_TAG).unwrap();

Should we change the current behavior and explicitly return an error? or keep the current logic there (which is simply unwrapping)

@mitchmindtree
Copy link
Contributor

Hey @kayagokalp, just a heads up that I have my eyes on this! I'm working on a PR with some refactoring in an attempt to simplify all of this a little further and cover a few more failure cases, aiming to post tonight or tomorrow.

@mitchmindtree
Copy link
Contributor

Closing as these commits were all included as a part of #2234.

auto-merge was automatically disabled July 7, 2022 11:47

Pull request was closed

@kayagokalp kayagokalp deleted the kayagokalp/1778 branch August 30, 2022 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working dependencies forc
Projects
Archived in project
4 participants