Is it possible to whitelist Pkg.dir
on JuliaBox? I use it include
certain files which are not modules, from the source dir and/or to check the existence of other packages. Or is there another, recommended way of doing this without Pkg.dir
? Thanks
You can use dirname(@__FILE__)
within a package, which gives the directory of the currently running file.
Or @__DIR__
Thanks!
What about finding Julia’s root Pkg.dir?
i.e. the result of:
Pkg.dir()
You could do
joinpath(homedir(),".julia","v$(VERSION.major).$(VERSION.minor)")
to get ~/.julia/v*.*
So it is a bit of an annoyance that you cannot do Pkg.dir()
on Juliabox, no doubt.
I will point out however that Pkg.dir()
is incorrect in many other situations. For example, if people build custom sysimages, or compile to binary. Pkg.dir()
will also fail in those situations. Hence, using Pkg.dir()
(or Pkg.installed()
) in your packages is really not a good idea.
Thanks - so then @__DIR__
is the way to go?
Pkg.dir()
is also going away in Pkg3 since it allows multiple different versions of a given package to be installed at the same time (and in different depots) so there is no longer a coherent answer to the question this function asks.
Has there been any discussion about how to migrate existing Pkgs?
// running into this problem with getting WebIO
to v0.7
edit: similar discussion: How to get Julia home in Julia 0.7? (maybe that answers the question)
You can use @__DIR__
which is actually the recommended approach previously as well. Pkg3 just happens to break the non-recommended approach of using Pkg.dir
. Otherwise there’s not really much you have to do at this point.
How can @__DIR__
be used to replicate the behavior of Pkg.dir("PkgName")
?
Or, rather, how to check if a package is installed?
What is your use case? In 0.7 it is hard to give a definite answer to this question. You can use Requires.jl to load code when another package is loaded.
There’s also Pkg.API.installed()
which will show you all the packages that are installed in your current environment, but as @kristoffer.carlsson said, it’s not so clear what it means for a package to be installed or not in Pkg3. It can be installed in one environment at one version, installed at a different version in a different environment, and not installed in yet another environment.
I just want to say that don’t get too attached to the exact output of Pkg.API.installed()
because the output it gives with names as the keys is fundamentally a bit flawed.
Right, that will have to go at some point as names are no longer unique within the dependency graph of a project. It’s really just a legacy API shim.
Mostly for “user-friendly dependency management”.
Take SearchLight, the ORM: it works with a multitude of database backends and relies on the corresponding lower level access libraries. It didn’t make sense to add all the libraries (SQLite.jl, MySQL.jl, ODBC.jl, etc) as dependencies, given that a project will use just one backend. So I’ve added none. At runtime, when the package loads the database configuration file, it checks if the configured backend library is installed - if not, it installs it.
I guess it’s not a big deal, this can be offloaded onto the user. But as it is now, it makes for a pretty good user experience.
I think in these situations, the idea in Pkg3
is to offload this to the user. Pkg3
essentially allows you to create a custom environment for each project. Hence in this case, the user would create a Pkg3 environment for their web application, and specify Genie, Searchlight and say ODBC.jl as dependencies for that environment. Searchlight would, on load, read the app configuration, and load ODBC.jl, assuming it to be available.
This is the only way to ensure that the environment in dev and prod are the same. The issue with the existing system (where Searchlight installs the package if not found, or even a user installs it manually) is that there is no guarantee that you will get the same version on two installs.
OK, thank you - yes, I see your point. Similar to ruby’s Gemfile, managed by Bundler. Indeed, in such a scenario, the user would have to fully configure and manage the dependency requirements. Makes sense, thanks.