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

Expand instructions for using custom-compiled elixir #63

Merged
merged 2 commits into from
May 17, 2019
Merged

Expand instructions for using custom-compiled elixir #63

merged 2 commits into from
May 17, 2019

Conversation

nathanl
Copy link
Contributor

@nathanl nathanl commented May 14, 2019

Thanks to @TheFirstAvenger and @bitwalker for explaining this to me

@TheFirstAvenger
Copy link

README.md Outdated

```
ln -s /path/to/elixir ~/.asdf/installs/elixir/master
asdf reshim elixir master
Copy link
Member

Choose a reason for hiding this comment

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

This is a hack and is not the recommended way of doing things. You should instead use the path:<path> version format to specify that you want to use your own version of Elixir https://asdf-vm.com/#/core-configuration?id=tool-versions Doing this will still allow you to checkout any version of Elixir and recompile on the fly without having to reconfigure asdf.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is indeed a hack but I don't think you have to reconfigure asdf if you change version or recompile elixir?

Choose a reason for hiding this comment

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

Agreed, plus asdf local elixir master is much cleaner than asdf local elixir path:/let/me/remember/the/path/to/my/elixir/repo

Copy link
Member

@Stratus3D Stratus3D May 15, 2019

Choose a reason for hiding this comment

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

With either approach (linking as shown here, or using the path:<path> syntax in your .tool-versions file) you will be free to checkout different refs and recompile Elixir without having to change anything else.

Manually altering anything inside your asdf data dir (~/.asdf/) is not recommended. asdf is simple enough that it will recognize the master directory if you create it, but it's ultimately hack. If you try to uninstall master asdf will probably try to delete whatever you have in your /path/to/elixir (I've not tried this, but I don't think we guard against this).

Copy link
Member

Choose a reason for hiding this comment

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

@TheFirstAvenger you shouldn't need to run that command very often. Once you've got the version set for your project you shouldn't ever need to run that command again. If you find yourself needing to use that version in a lot of different projects, you can set that as the global version, or define an shell alias for that asdf local command to make it easier to run.

Copy link
Member

Choose a reason for hiding this comment

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

There is also ref:master, but I don't think that is what you want here - https://www.amberbit.com/blog/2017/10/30/trying-out-upcoming-elixir-releases/

@danhper
Copy link
Member

danhper commented May 16, 2019

@nathanl @TheFirstAvenger @ericmj Is there any reason why path:/path/to/elixir is not good enough?
I am not convinced that asdf local elixir path:/path/to/elixir being too long is a real issue.
If there is actually a limitation on the asdf side, I am happy to try to improve the situation but I would rather avoid adding workarounds to the documentation.

@TheFirstAvenger
Copy link

I wonder if adding the concept of local aliases to asdf would be the right route, i.e. asdf alias elixir add my-clone path:/path/to/my/cloned/repo that way asdf local elixir local-master would still be possible without the hack.

@Stratus3D
Copy link
Member

@TheFirstAvenger generally if something can be done with the asdf API it should be done outside of asdf. So in the case of aliases, it is probably better to define shell aliases or functions to help with this. Something like:

asdf-elixir-master() {
  asdf local elixir path:/path/to/elixir
}

@bitwalker
Copy link

I think there is an argument to be made that the path:<path> "version" should really accept a short name. Having to create aliases to make the usage ergonomic shouldn't be necessary for something this tool is essentially trying to solve for. I use asdf to manage language versions because it makes tasks like that simple and easy to use. We could just as well make the argument that one should write shell aliases to do the same thing asdf does, but that's not why any of us are here.

My take is that it should be a supported feature to do asdf install path:<path> --alias=<alias> which essentially just sets up the symlink, and then be able to do asdf local elixir <alias> to use it just like any other installed version. On the tail end, asdf uninstall elixir <alias> can just unlink the symlink. For installs which use a "proper" version, i.e. 1.8.2 or whatever, --alias would be a no-op (it would be easy enough to warn or error on that usage to make it user-friendly).

I think there is also value in supporting --alias=<alias> for the ref:<ref> version scheme as well, since refs which aren't tags/branches are obviously not something you'll remember, and those types of installs are likely too short term for aliases to make for a convenient solution (i.e. you might install a specific commit while you work on an issue related to that commit, then blow it away when done).

I'd be happy to make the PR for the above, but I'd be interested to hear the arguments as to why it isn't desirable to do so first. If it is just a matter of not having time, that's understandable, and solvable; but if it's something fundamental, that would be good to know.

@whatyouhide
Copy link

Agreed with @bitwalker here. I won't type asdf local elixir path:/path/to/elixir and setting up an alias means that I would have to set that up for local/global/shell as well. I think aliases support in asdf is the way to go as well.

@Stratus3D
Copy link
Member

Ok, so a little history on the local and global commands. Neither of them were present in the first version of asdf. When asdf was first created everyone just edited their .tool-versions files using the editor of their choice. The file format is simple and easy to understand. The different version formats like 1.2.3 ref:abcdef1 and path:/path/to/version are simple and easy to understand. Eventually someone decided it would be nice to have commands to set versions without having to edit the .tool-versions file, so local and global were created. There is not wrong with them, but people are abusing them, likely because they don't really understand how asdf works, even though it's plainly documented.

Having to create aliases to make the usage ergonomic shouldn't be necessary for something this tool is essentially trying to solve for. I use asdf to manage language versions because it makes tasks like that simple and easy to use.

@bitwalker the goal of asdf is to make version management simple, that usually results in it being fairly easy to use too, but being easy to use is a side affect of being simple and well designed.

I'd be happy to make the PR for the above, but I'd be interested to hear the arguments as to why it isn't desirable to do so first. If it is just a matter of not having time, that's understandable, and solvable; but if it's something fundamental, that would be good to know.

It is fundamental.

  • Part of being simple is only doing one thing, and for asdf that one thing is extendable version management. Adding support for an --alias flag would add a lot of complexity to the code for a feature isn't central to the purpose of asdf. There are plenty of other tools for creating and managing aliases, these can be used in combination with asdf if users have the desire. asdf provides a good API, there is nothing preventing you from writing a shell script to make it do what you want.
  • Adding an --alias flag would fundamental change what a version in asdf actual is. Currently a version is exactly what it says it is. If you specify elixir 1.7.1, you can be sure you'll get the 1.7.1 release of Elixir, if you use elixir ref:abcdef1, you can be assured you will get that ref of Elixir. Using aliases would mean .tool-versions files would not contain versions, they'd contain identifiers which may be literal versions or may be aliases. There is also the issue with aliases conflicting with actual versions. So I could create an alias named 1.7.1 and point it at my local 1.7.1 build directory. If I later changed the version of Elixir in that directory all projects that specified 1.7.1 would not be using 1.7.1. Without knowing what all the future versions will be there is no way to prevent conflicts from aliases and literal versions.

The asdf global and asdf local commands should only be run when you need to change the version, so you shouldn't be running them very often.

I won't type asdf local elixir path:/path/to/elixir and setting up an alias means that I would have to set that up for local/global/shell as well. I think aliases support in asdf is the way to go as well.

@whatyouhide I must be misunderstanding you. You won't type asdf local elixir path:/path/to/elixir but you will type ln -s /path/to/elixir ~/.asdf/installs/elixir/master && asdf reshim elixir master? How is that easier? Either way you have to specify the full path.

@nathanl thanks for the PR. I'm going to merge all of your changes except for the part about ln -s /path/to/elixir ~/.asdf/installs/elixir/master

@Stratus3D Stratus3D merged commit a785082 into asdf-vm:master May 17, 2019
@bitwalker
Copy link

@bitwalker the goal of asdf is to make version management simple, that usually results in it being fairly easy to use too, but being easy to use is a side affect of being simple and well designed.

I'm definitely aware of the correspondence between simple/easy, my point was that as a user, those qualities mean different things than they do as a maintainer. Specifically, with my user hat on the "ease" in which I can avoid using multiple tools to do one thing (version management), and the "simplicity" of something that doesn't use any magic, just simple OS primtives, are the reasons why I chose it.

It is fundamental.

Part of being simple is only doing one thing, and for asdf that one thing is extendable version management. Adding support for an --alias flag would add a lot of complexity to the code for a feature isn't central to the purpose of asdf.

I'm not convinced that it is as complex as you expect. Supporting options with getopt would be a simple solution, and would vibe with using OS primitives as done so far, and certainly supports the basic functionality needed for the --alias flag.

There are plenty of other tools for creating and managing aliases, these can be used in combination with asdf if users have the desire. asdf provides a good API, there is nothing preventing you from writing a shell script to make it do what you want.

I will of course have to investigate to see if there are limitations here, but if that's the case, then if I need to maintain my own shell script to add this capability, I'm not opposed to that idea, but it does seem rather fundamental to asdf itself. I'm a firm supporter of providing necessary primitives and letting the community go from there though, so as long as everything is present that would be required to support my proposal, then I'm good.

Do you have suggestions for tools for alias management? The shell is plainly inadequate for this out of the box, as creating arbitrarily-long lived aliases and destroying them on the fly is not something you get for free.

Adding an --alias flag would fundamental change what a version in asdf actual is. Currently a version is exactly what it says it is. If you specify elixir 1.7.1, you can be sure you'll get the 1.7.1 release of Elixir, if you use elixir ref:abcdef1, you can be assured you will get that ref of Elixir. Using aliases would mean .tool-versions files would not contain versions, they'd contain identifiers which may be literal versions or may be aliases.

I think there are two usage patterns, distinct from one another: First is the use you are talking about, where users are installing versions and saving .tool-versions for use in a team environment, where the predictability/stability of the version identifiers is important. Secondly, you have the use of ad-hoc installs for short periods of time, where the .tool-versions is not shared outside of the local machine (i.e. it is not committed to a project). These latter uses are very ephemeral, and are often switched to and from frequently, which is why the aliases would be so pleasant.

It would be absolutely possible for the .tool-versions to have the full path:<path> representation stored in it, rather than the alias, and it would be trivial to resolve whether something is a local alias or a "proper" version. This would be able to catch potentially unsupported/undesired use cases that you are concerned about. In practice though, I doubt this is an issue that warrants much concern; I certainly never use MAJ.MIN.BUILD versions for ad-hoc installs from a local build directory, or even git refs, they get names for their purpose, like otp-init-experiment and such. I suspect that is true of anyone who would be using the aliases functionality.

There is also the issue with aliases conflicting with actual versions. So I could create an alias named 1.7.1 and point it at my local 1.7.1 build directory. If I later changed the version of Elixir in that directory all projects that specified 1.7.1 would not be using 1.7.1.

Again, I think it is absolutely possible to deal with this edge case in a sane way, probably by warning when the .tool-versions is loading a version from a an aliased path, not an asdf-managed build, thus making it crystal clear when things have been changed out from under you.

Without knowing what all the future versions will be there is no way to prevent conflicts from aliases and literal versions.

This is really the responsibility of the users managing aliases though, just like it would be if they implemented this functionality manually. The benefit of having it in asdf is that these edge cases can be dealth with sanely and given friendly UX so that even those who think they know what they are doing, can avoid accidentally making a mistake like you've outlined. In practice I don't think this is likely to occur, but others that want aliases may have different usage patterns than me.

The asdf global and asdf local commands should only be run when you need to change the version, so you shouldn't be running them very often.

I use them very frequently when switching between builds with different things I'm testing. Granted, I'm a bit of a special case as a open source maintainer with a lot of projects with a large matrix of languages and versions to work across - but that is precisely why I use asdf. Maybe I'm expecting too much trying to solve for my use case, but I know I'm not the only one in this position.

@whatyouhide I must be misunderstanding you. You won't type asdf local elixir path:/path/to/elixir but you will type ln -s /path/to/elixir ~/.asdf/installs/elixir/master && asdf reshim elixir master? How is that easier? Either way you have to specify the full path.

He does that once, and then uses the alias from then onward, which is the point, he only needs to type the verbose command the one time.

We can move this discussion to an issue if you'd like, perhaps it would be better to do that so that you can point other users there one way or the other. I don't want to pressure you on this, if you still aren't convinced, then I will find a solution one way or the other, but I had hoped we might find consensus of some kind.

@nathanl nathanl deleted the readme-show-custom-elixir branch May 17, 2019 16:34
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.

7 participants