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

Support installing plugins from specific ref; and from local path #1743

Merged
merged 11 commits into from
Jan 30, 2025

Conversation

emlys
Copy link
Member

@emlys emlys commented Jan 21, 2025

Description

Fixes #1651
image
Updates the "Manage plugins" modal and the plugin installation function to support installing plugins from a branch or revision on a remote git server, or from a local filepath.

The ReadTheDocs build has been failing on branches off of feature/plugins for a while now, so it's unrelated to these changes.

Checklist

  • Updated HISTORY.rst and link to any relevant issue (if these changes are user-facing)
  • Updated the user's guide (if needed)
  • Tested the Workbench UI (if relevant)

@emlys emlys changed the base branch from main to feature/plugins January 21, 2025 22:36
@emlys emlys self-assigned this Jan 23, 2025
@emlys emlys marked this pull request as ready for review January 23, 2025 00:01
Copy link
Member

@emilyanndavis emilyanndavis left a comment

Choose a reason for hiding this comment

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

Looks good, @emlys! Just a handful of small suggestions.

<Form.Control
id="url"
type="text"
placeholder="https://github.com/foo/bar.git"
Copy link
Member

Choose a reason for hiding this comment

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

I think a placeholder is useful here so that people understand the expected format (and don't try use a URL prefixed with git@, for example), but could we change it slightly to make it a little clearer what the parts of the URL are? Maybe something like https://github.com/owner/repo.git?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good suggestion!

<Form.Control
id="branch"
type="text"
placeholder={t('default')}
Copy link
Member

Choose a reason for hiding this comment

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

Here I'm not sure we need a placeholder, and it might even be confusing, leading some people to think they need to enter default or main when they can just leave it blank. If it were me, I'd remove the placeholder and also add (optional) to the label, just to make it extra clear.

id="path"
type="text"
placeholder={
window.Workbench.OS === 'darwin' ? '/Users/natcap/foo/bar/' : 'C:\\Documents\\foo\\bar\\'
Copy link
Member

Choose a reason for hiding this comment

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

Like with the sample git URL, I'd recommend updating these sample paths as well. Maybe something along the lines of /Users/username/path/to/plugin/ and C:\\Documents\\path\\to\\plugin\\.

Copy link
Member Author

Choose a reason for hiding this comment

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

That does look better!

<>
<Form.Row>
<Form.Group as={Col} xs={7} className="mb-1">
<Form.Label>Git URL</Form.Label>
Copy link
Member

Choose a reason for hiding this comment

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

Let's make sure this label is associated with its form field with htmlFor="url".

/>
</Form.Group>
<Form.Group as={Col} className="mb-1">
<Form.Label>Branch, tag, or commit</Form.Label>
Copy link
Member

Choose a reason for hiding this comment

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

This label needs an htmlFor attribute as well.

} else {
pluginFields = (
<Form.Group className="px-0 mb-1">
<Form.Label>Local absolute path</Form.Label>
Copy link
Member

Choose a reason for hiding this comment

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

This label needs an htmlFor attribute as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Making a note to pay attention to htmlFor!

<Form.Text className="text-muted">
{t('This may take several minutes')}
</Form.Text>
<Form.Label className="col-form-label-lg" htmlFor="url">{t('Add a plugin')}</Form.Label>
Copy link
Member

Choose a reason for hiding this comment

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

Looks like this label's htmlFor is still pointing to the url form field.

Now that the form's been restructured, I'd almost argue that "Add a plugin" isn't really a label anymore; it's more of a heading. But if we made it a heading, we'd want to add a separate label for the "Install from..." dropdown, and we'd want to make similar changes to the "Remove a plugin" section, for consistency. Happy to talk through those details (and the motivations behind them) if you want! But...

...for now, the simplest thing would be to update the "Add a plugin" label's htmlFor to point to the "Install from..." dropdown.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree it makes more sense as a heading. I changed "Add a plugin" and "Remove a plugin" to headings, and made a label "Install from" for the install options dropdown. I made the dropdown in line with the "Install from" label, but I couldn't get it perfectly aligned - which do you think looks better?
image
image

Copy link
Member

Choose a reason for hiding this comment

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

Awesome! I would vote for the second option, with the label stacked above the form field, since that's consistent with the other fields in this form. If the alignment isn't quite working like you expect, you might try mimicking the structure you've used elsewhere in the form, i.e., adding as={Col} to the Form.Group and nesting that inside a Form.Row ... and/or seeing if you are using any utility classes (such as mx-1) you no longer need.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay, I changed it to the second option, removed some unneeded styling, and it does look better now!

} else { // install from local path
logger.info(`adding plugin from ${path}`);
installString = path;
// Read in the plugin's pyproject.toml, then delete it
Copy link
Member

Choose a reason for hiding this comment

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

It looks like you're not deleting pyproject.toml when installing from a local path... which seems correct. Does this comment just need an update?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ooh yep, thanks

// Access plugin metadata from the pyproject.toml
const pluginID = pyprojectTOML.tool.natcap.invest.model_id;
const pluginName = pyprojectTOML.tool.natcap.invest.model_name;
const pluginPyName = pyprojectTOML.tool.natcap.invest.pyname;

// Create a conda env containing the plugin and its dependencies
const envName = `invest_plugin_${pluginID}`;
await spawnWithLogging(
Copy link
Member

Choose a reason for hiding this comment

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

Forgive me: this isn't related to this PR, and you might even have created an issue for this already, in which case, please ignore!

It looks like this call to create the micromamba env is referencing specific version restrictions for Python & GDAL. Seems like it would be a good idea to store these args someplace that's easier to keep up to date rather than hard-coding them here.

Copy link
Member Author

Choose a reason for hiding this comment

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

You're absolutely right, we hard-coded those just to get something working, but as of #1733 we'll read them from the pyproject.toml.

@emlys emlys requested a review from emilyanndavis January 24, 2025 18:36
</Form.Group>
<hr />
<Form.Group className="mb-3">
<Form.Label htmlFor="plugin-select">{t('Remove a plugin')}</Form.Label>
<h5 className="mb-3">{t('Remove a plugin')}</h5>
Copy link
Member

Choose a reason for hiding this comment

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

I think it's great that you converted this (and "Add a plugin") to a heading, but now the plugin dropdown is technically missing a label. A visible label (marked up as a <label>) is usually best, but we do have a few options in this case:

  1. Add a <Form.Label> with htmlFor="plugin-select". What that label says is up to you, as long as it describes the purpose of the form field ("Select a plugin", "Plugin to remove", etc.).
  2. OR add an aria-label to the <Form.Control>, with its value set to something that describes the purpose of the form field (i.e., whatever you would use for a visible label, if you chose option 1).
  3. OR add an id to the "Remove a plugin" heading, and add aria-labelledby to the <Form.Control>, with its value set to the heading's id. This tells assistive technologies (screen readers, voice input control, etc.) to associate the form field with the heading, essentially allowing the "Remove a plugin" heading to act both as a heading and as a label for the form field.

Copy link
Member Author

Choose a reason for hiding this comment

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

I went with option 1 (and changed the id to be a little more specific)

Copy link
Member

Choose a reason for hiding this comment

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

Great, thank you!

Copy link
Member

@emilyanndavis emilyanndavis 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 making those changes, @emlys! Just one more request!

@emlys emlys requested a review from emilyanndavis January 24, 2025 22:45
@emilyanndavis
Copy link
Member

emilyanndavis commented Jan 24, 2025

Looks like all those label changes broke some of the workbench tests. As soon as those are passing, I'll happily approve!

Copy link
Member

@dcdenu4 dcdenu4 left a comment

Choose a reason for hiding this comment

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

Thanks @emlys ! I had one quick curiosity question. And just noting that I merged the other git PR which has introduced some conflicts!

workbench/src/main/setupAddRemovePlugin.js Show resolved Hide resolved
@emlys emlys requested a review from dcdenu4 January 27, 2025 20:30
Copy link
Member

@dcdenu4 dcdenu4 left a comment

Choose a reason for hiding this comment

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

Thanks @emlys and @emilyanndavis !

@dcdenu4 dcdenu4 merged commit 764477b into natcap:feature/plugins Jan 30, 2025
28 of 29 checks passed
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.

Plugins: should be able to install from different kinds of paths
3 participants