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

renv setup - Provide users with an easy solution for renv errors #2560

Merged
merged 4 commits into from
Jan 28, 2025

Conversation

marcosnav
Copy link
Collaborator

Intent

PR with the goal to provide immediate help to users when renv errors show up while trying to deploy.

Common scenarios that it handles, providing the option within the error message to set it up easily:

  1. No renv installed at all. Installs renv and runs init.
  2. renv is installed but project requires init, we do the init for the user.
  3. renv environment exists, but lockfile does not. We help with snapshot.

For any other case outside the common and known issues, we provide the user with guidance and set up the renv::status command to get more information.

Jan-28-2025.10-29-46.mp4

Resolves #2543

Type of Change

    • Bug Fix
    • New Feature
    • Breaking Change
    • Documentation
    • Refactor
    • Tooling

Approach

Rely more on the information renv::status provides to help users with common scenarios.

User Impact

Users with project using R and that the deployment requires a lockfile. When the lockfile or an renv environment do not exist, it'll be a matter of a click to get up to speed and continue the deployment.

Automated Tests

Created and updated unit tests for these changes.

Directions for Reviewers

The following checklist assumes you have a project that requires R:

  • With no renv installed at all and no lockfile on the project. (It can be uninstalled with remove.packages("renv"))
    • Attempt to deploy the project. An error message should show up with an option to set things up.
    • Hitting the "Setup renv" button installs and initializes the project.
    • Trying to deploy one more time succeeds.
  • renv is installed but project does not have lockfile nor renv/.
    • Attempt to deploy the project. An error message should show up with an option to set things up.
    • Hitting the "Setup renv" button initializes the project.
    • Trying to deploy one more time succeeds.
  • renv environment exists, but lockfile is not present.
    • Attempt to deploy the project. An error message should show up with an option to set things up.
    • Hitting the "Setup renv" button initializes the project.
    • Trying to deploy one more time succeeds.

Checklist

@marcosnav marcosnav changed the title renv setup - Provide users with immediate solutions for renv errors renv setup - Provide users with an easy solution for renv errors Jan 28, 2025
Copy link
Collaborator

@dotNomad dotNomad left a comment

Choose a reason for hiding this comment

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

This is looking great. I tried out each of the states you described in your reviewer directions and each worked great.

I did hit an odd case with renv attempting to activate via an R profile that had an unhelpful error, but I don't think that should hold up this PR given how much this improves setting up renv

I had a few comments that are minor suggestions you can take or leave prior to merging.

Comment on lines +188 to +191
const deploymentFailureRenvHandler = new DeploymentFailureRenvHandler();
if (deploymentFailureRenvHandler.shouldHandleEventMsg(msg)) {
return deploymentFailureRenvHandler.handle(msg).then(this.refresh);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This pattern is really clean between this and the deployHandlers file. 💯

@@ -246,3 +258,18 @@ func (m *defaultPackageMapper) GetManifestPackages(
}
return manifestPackages, nil
}

func (m *defaultPackageMapper) renvEnvironmentCheck(
base util.AbsolutePath,
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like base is unused here, can we remove it?

}

func (i *defaultRInterpreter) isRenvInstalled(rexecPath string) *types.AgentError {
args := []string{"-s", "-e", "cat(system.file(package = \"renv\"))"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

When I had an R profile lingering after removing renv I got a nice exit 1 error when running this. I think that is an edge case, and more about my poor job cleaning up renv, but worth noting here as a potential improvement.

Comment on lines +260 to +261
// The default command suggested is renv::status()
renvDescError := errors.New("the renv environment for this project is not in a healthy state. Run renv::status() for more details")
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a fantastic fallback here 👍

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fantastic tests here. The mocking was a lot of work, but it is very much appreciated.

Comment on lines +60 to +64
test("showErrorMessageWithTroubleshoot", () => {
showErrorMessageWithTroubleshoot("Bad things happened");
expect(window.showErrorMessage).toHaveBeenCalledWith(
"Bad things happened. See [Troubleshooting docs](https://github.com/posit-dev/publisher/blob/main/docs/troubleshooting.md) for help.",
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for adding a test here. I should have done it with the introduction of the function 😅

Comment on lines 26 to 27
cancellable: boolean = false,
onCancel?: () => void,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor suggestion: could we combine the cancellable and onCancel and rely on the onCancel to determine if the handler is cancellable? If onCancel was passed it is cancellable, if not it isn't.

Copy link
Collaborator

@dotNomad dotNomad 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 those changes. Everything is a toucher cleaner now 🧹

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle initial renv infrastructure for users
2 participants