JuliaLang / Pkg.jl

Pkg - Package manager for the Julia programming language
https://pkgdocs.julialang.org
Other
621 stars 269 forks source link

Macro to add "using" packages automatically #2027

Closed mossr closed 3 years ago

mossr commented 4 years ago

Not sure if this is where you'd like the Pkg manager to go, but I threw together an @add macro to automatically install missing packages when calling using. Example:

@add using Clustering

This will run using Clustering if we already have it, otherwise it will add it, then run using Clustering.

Here's the macro:

macro add(expr)
    packages::Vector{Symbol} = [arg.args[end] for arg in expr.args]
    quote
        for package in $(esc(packages))
            using_package = Meta.parse("using $package")
            try
                eval(using_package)
            catch err
                if err isa ArgumentError
                    using Pkg
                    Pkg.add(string(package))
                    eval(using_package)
                else
                    throw(err)
                end
            end
        end
    end
end

This also works for multiple comma separated packages:

@add using Random, Clustering, LinearAlgebra

I tried searching for related issues to no avail. My use-case is for one-off lecture-style Pluto notebooks given to students so I can just call a one-line @add using Package instead of wrapping everything in a try/catch or creating a light-weight package with a Project.toml just for one file. Thoughts and feedback welcome!

fredrikekre commented 4 years ago

See https://github.com/JuliaLang/julia/pull/26469, https://github.com/JuliaLang/julia/issues/35062

mossr commented 4 years ago

Thank you for linking those (I knew this wasn't a unique issue but failed to find those).

I created a separate package—AddPackage.jl—with this macro so I can use it within Pluto notebooks sent to students. Also, the threads you linked seem to focus on the interactive REPL responses when calling using Package, where @add using Package is helpful for notebooks or single one-off scripts without a Project.toml.

fredrikekre commented 4 years ago

Everything has a Project.toml file, but perhaps Pluto can't handle the interactivity?

mossr commented 4 years ago

Pluto can handle adding packages within a cell, but the use-case is mainly for convenience so cells don't look like:

try
    using Package
catch
    using Pkg
    Pkg.add("Package")
    using Package
end

and instead look like:

@add using Package

(again, for lecture-style notebooks/Julia files that may be sent as single files and not part of a package, thus without a Project.toml)

fredrikekre commented 4 years ago

I mean that if something like https://github.com/JuliaLang/julia/pull/26469 were implemented.

mossr commented 4 years ago

Good point, then I agree that Pluto may not be able to handle that level of interactivity.

StefanKarpinski commented 4 years ago

I originally wanted to prompt to add packages when someone does using and the package isn't already added. I still think that would be a nice feature to have.

oxinabox commented 3 years ago

Effectively closed by https://github.com/JuliaLang/julia/pull/39026 and probably by Pluto changes?