elves / elvish

Powerful scripting language & versatile interactive shell
https://elv.sh/
BSD 2-Clause "Simplified" License
5.57k stars 297 forks source link

Pin epm package to commit/tag #797

Open vendion opened 5 years ago

vendion commented 5 years ago

The inclusion of the elvish package manager is nice, but for users that stick to the released version of Elvish the current implementation can be problematic as it seems to grab the most recent commit.

Example using Elvish 0.12 and git plugin from github.com/zzamboni/elvish-completions they may be incompatible as zzamboni may have pushed updates to make it compatible with Elvish's HEAD with may include breaking changes with the most recent release. Some possible ways around this is by specifying the commit to use like

epm:install github.com/zzamboni/elvish-completions@794ab5

or in the metadata.json file add a target directive:

{
  "description": "zzamboni's Elvish completion definitions",
  "maintainers": ["Diego Zamboni <diego@zzamboni.org>"],
  "dependencies": ["github.com/zzamboni/elvish-modules", "github.com/muesli/elvish-libs"],
  "target":"v0.12"
}

With a target of master or head meaning no specific Elvish release (built from Git).

I don't know if this is already planned and waiting for Elvish's API to stabilize or not, but didn't see this in the issue queue.

zzamboni commented 5 years ago

Version management is tricky, which is why I left it out of the initial implementation of epm :)

The general agreement was that we would wait until Elvish stabilizes before worrying too much about this, but it's not a bad idea to start thinking about it. Here are some questions off the top of my head:

vendion commented 4 years ago

Sorry for the delayed response, I agree that version management is tricky but the good thing is that the epm implamentation can take lessions learned by other similar tools (npm, composer, cario, go get, etc).

How to map plugin versions/commits to Elvish versions? E.g. maybe metadata.json specifies a target of master, but some previous commit targets the latest Elvish release.

The way I see it working is the metadata.json file in the package specifies the version of Elvish it targets, and it's up to the user to find the correct version (thus avoiding epm having to scan the entire repo history on install/upgrade to find the latest version that supports what ever version of Elvish currently being ran). As long as the version information is set with Elvish is built (this is true for the official Elvish binary and hopefully true for ports for Linux distros, BSDs, Homebrew/macports, etc) then the shell already should know what version is being ran.

As an example I'll use your chain theme zzamboni, say commit 1010ad targets a minimal Elvish version of 0.13 the metadata.json file could specify it like so:

{
    "description": "zzamboni's Elvish themes",
    "maintainers": ["Diego Zamboni <diego@zzamboni.org>"],
    "dependencies": ["github.com/href/elvish-gitstatus"],
    "elvish": "v0.13"
}

This means that it can be insalled with epm:install if the version of Elvish is v0.13 or newer (including tracking Elvish's HEAD). Now lets say that commit 1010ad for your Chain theme had a tag of v0.1.0 this should make the package installable with epm by the user giving the tag or commit sha/revision information. Example of such can be demistrated with the following commands

epm:{install|upgrade} github.com/zzamboni/elvish-themes@v0.1.0
-- or --
epm:{install|upgrade} github.com/zzamboni/elvish-themes@1010ad

If no version is given or a branch name is given (like master) then the latest version for the branch (defaulting to master) will be checked out like how epm currently works.

Using the metadata.json above if a user running Elvish v0.12 or older than epm can throw an error due to the version mismatch.

How would you go about finding out which commit is the correct one (one idea: rely on git tags for this, but this only works if you are getting the plugin from a git repo).

Using the suggestion above most of that is left up to the user to find a version of the package that works with their verson of Elvish. As for the question of using git tags, I don't know what all VCS are currently supported by epm but if git is only currently supported I think building around that and if support for subversion, mercurial, cvs, etc is wanted it can be added later. Although we (using inclusive "we" to mean the community) can use how go get post Go 1.13 handles those other VCS to work out a good way to best handle them.

Is it worth worrying about this until Elvish's user base grows a lot more? Are we introducing unnecessary complexity? (one could make the case that having proper versioning would help increase Elvish's popularity and user base by making it more approachable to "regular users")

Elvish and its community may not be to the point where this needs worried about now, and I agree waiting until Elvish core API stabilizes more, but as we get closer to this point (and seeing as how xiaq is talking about what Elvish v1.0.0 means) this should at least be talked about which is why I originally started this issue to get the disscussion started.