Project with scripts (bin/)

At some point in the bag old (pre-Pkg3) days, when discussing what Pkg3 might be able to, I asked if it would be possible to create a package in a way that would automatically “install” scripts (eg point the system $PATH to a MyPackage/bin/ folder or something).

With python pip, this can be done pretty easily, but it happens sort of automatically if the package author specifies. I think for Julia is would make more sense to have a separate Pkg command for installable scripts (] install?).

I recall Stefan saying at one point that this could be done, but I don’t recall if he actually thought it was a good idea. I did some searching through Pkg.jl issues and the forums but didn’t find the discussion (maybe it was on slack?). Is this something that others would find desirable?

Some potential issues that occur to me:

  • How to deal with the fact that this would be kind of global? In other words, what happens if multiple packages have a script of the same name, or I have multiple versions of the package in different projects?
  • what Julia environment would the script be run in? Presumably the one in MyPackag's Manifest.toml?
  • how to deal with uninstalling such packages?

The issues that you raised with the approach seem to overcome its potential advantages.

On linux systems, one can just create a symlink in /usr/local/bin to the desired package script and that would suffuce.

Perhaps Im missing something however providing installation support for packages should really not be julia’s concern.

I believe python’s pip really predates modern *nix distribution python package python support and hence its intrusiveness.

One can, yes. But not everyone can. That is to say, for some users mucking around with stuff like symlinks and $PATH are difficult asks.

Maybe not - I suppose it could always be a separate package (InstallableScrpts.jl?).

I didn’t realize that - to me this has always been the state of things :laughing:

Then again, conda is much more modern than pip and can do the same thing. These days, bioinformatics software are almost always conda-installable, and then available from the command line. A lot of users have superficial knowledge of Unix at best, and even command line interfaces are tough.

1 Like

As the possibilities for compiling Julia programs into binaries and libraries improves and becomes common practice, I find myself in favor of providing some rudimentary support for “installing” scripts, binaries, and libraries (generated via PackageCompiler et. al, henceforth called “artifacts”), under a few conditions:

  • You never attempt to (by default) install into a system-wide directory. The user running Julia probably doesn’t even have the permissions to do that anyway, and may not be able to get sure permissions (such as on a system they don’t own). Instead, provide one or more default directories such as ~/.julia/bin/ and ~/.julia/lib/ for binaries/scripts and libraries, respectively. If a user wants these to be available system-wide, they or their admin can use symlinks or change the default directories to make artifacts available in an acceptable manner.
  • Standards for the shebang at the top of Julia scripts (such as #!/usr/bin/env julia) are enforced by the community and/or ] install, so that scripts don’t wire-in poor assumptions about how to invoke Julia on a user’s machine. This standard should also be documented.
  • Automatic ] install is disabled for packages by default, but can be enabled for automatic or one-shot installation for one or more packages, such as via ] install --auto-install MyPackage. It also does not mess with PATH or LD_LIBRARY_PATH unless specifically invoked by the user, such as via ] install --init-paths. This should be an interactive command which offers to make the necessary modifications if possible, or can be a no-op but provides the user a few lines of shell script (or instructions on Windows) that can be placed in the appropriate location (such as ~/.profile) to invoke the appropriate changes.
  • The path that an artifact is being installed into, the package version, and optionally the Pkg slug that an artifact comes from, is echo’d to the REPL every time that artifact is installed or updated.
  • Possibly controversial: Packages which try to automatically install their artifacts without the user’s express consent via the above mechanisms are shunned by the community, and not accepted into the General registry. This provides a layer of social protection against packages shadowing other binaries/libraries on a user’s system for malicious intent, such as sudo or passwd.

In my opinion, pip is a poor example to look at: on my Linux distro (Gentoo) which makes heavy usage of Python packages for all sorts of important OS stuff, pip is patched to not overwrite system libraries, and is not installed by default. It is actively advised against in the official documentation. Everything that pip does is already handled by the distribution package manager. Thus, I surmise that any language-specific package manager which thinks it’s okay to litter stuff across a user’s system is going to itself become controversial and be patched or disabled by any sensible distribution or system admin.

3 Likes

I agree with all of that, and it’s expressed clearly. Is this the sort of thing that warrants a Julep?

True - my intent was not to suggest that it’s a good example of implementations, it’s just the only other thing I’ve used to make a package other than julia :grimacing: :flushed:

1 Like

@kevbonham and @jpsamaroo, reaching out because I think the jlenv org might be of interest to you? One of the tools is jlenv - a port of the rbnev/pyenv tools. That said the use of binstubs in Julia seems relatively limited, so there maybe sharp edges when using these tools.

The jlenv org contains a collection projects addressing the various use cases that give rise to needing to switch between different versions of Julia.

The announcement in the Tools forum has more details.