Julia`--project`命令行选项中的@。是什么?

时间:2018-12-04 13:05:18

标签: command-line-interface julia

在命令行中启动Julia时,可以指定项目目录。选项之一是@.,可能是当前目录。在这种情况下,@.是什么?

# from `julia --help`
--project[={<dir>|@.}]    Set <dir> as the home project/environment

来自docs

  

如果变量设置为@,则Julia尝试从当前目录及其父目录中找到一个包含Project.toml或JuliaProject.toml文件的项目目录。

我意识到cli --project参数解析是在此C code中进行的,并且显然由该init code使用,尽管我不确定两者之间的事件顺序。

具体在initdefs.jl中,我们有:

project = (JLOptions().project != C_NULL ?
    unsafe_string(Base.JLOptions().project) :
    get(ENV, "JULIA_PROJECT", nothing))
HOME_PROJECT[] =
    project == nothing ? nothing :
    project == "" ? nothing :
    project == "@." ? current_project() : abspath(project)

我对这段代码的理解是,@.只是一个任意的令牌,对于cli来说它可能是一个简单的.吗? Julia如何搜索“当前目录及其父目录。

LOAD_PATH["@", "@v#.#", "@stdlib"])中使用了类似的符号, 如herehere所述。 @.LOAD_PATH符号属于同一扩展家族吗?

2 个答案:

答案 0 :(得分:4)

家庭项目和--project

--project标志定义“家庭项目”或“家庭环境”。环境由Project.toml / Manifest.toml定义,并定义using / import可用的软件包。

您可以将--project设置为(i)目录(有或没有Project.toml)(ii)Project.toml的路径或(iii)到@. 。 (i)和(ii)很不言自明-Julia将把位于路径上的项目视为家庭项目。现在,对于(iii),如果您设置--project=@.,Julia将尝试找到一个现有的 Project.toml文件并将其用作主项目。考虑以下示例:

~$ tree .
.
├── A
└── Project.toml

1 directory, 1 file

其中A是一个空目录。我们可以轻松尝试(i)和(ii):

# existing file
[~]$ julia --project=Project.toml -E 'Base.active_project()'
"~/Project.toml"

# existing directory
[~]$ julia --project=A -E 'Base.active_project()'
"~/A/Project.toml"

# non-existing directory
[~]$ julia --project=B -E 'Base.active_project()'
"~/B/Project.toml"

# non-existing file
[~]$ julia --project=B/Project.toml -E 'Base.active_project()'
"~/B/Project.toml"

请注意,在Project.toml文件不存在的最后三个示例中,但是会在需要时创建它(例如,在使用Pkg来操作程序包时)。

现在,将其与@.的行为进行比较,该行为将查找现有项目文件:

# from our root directory
[~]$ julia --project=@. -E 'Base.active_project()'
"~/Project.toml"

# from inside the A directory
[~/A]$ julia --project=@. -E 'Base.active_project()'
"~/Project.toml"

在两种情况下,我们都找到了相同的Project.toml文件。使用@.选项,Julia首先在当前目录中查找Project.toml文件,如果找不到,则将其上移到父文件夹并在其中查找,依此类推。这就是第二个示例中发生的情况。朱莉娅没有在空的Project.toml目录中找到A文件,因此我们移至父目录,并找到了那里的Project.toml

是的,我们可以为此选择其他一些令牌,但是.则没有,因为它已经具有含义。它是当前目录的路径,并且是与--project一起使用的完全有效的路径。

加载路径和"@"

要加载包Example,仅在其Example部分中用[deps]定义一个主项目是不够的;主页项目还需要显示在Julias加载路径(Base.load_path())中。默认情况下,加载路径从["@", "@v#.#", "@stdlib"]展开,其中"@v#.#"扩展到~/.julia/environments/v#.#,其中#替换为Julias主版本号和次要版本号,而"@stdlib"扩展到Julias标准库的目录。 "@"扩展为1.活动项目(通过Pkg.activate / pkg> activate激活)或2.主页项目。我们可以使用Base.load_path()检查扩展的加载路径:

# without home project; @ expands to nothing
[~]$ julia -E 'Base.load_path()'
["~/.julia/environments/v1.0/Project.toml", "~/julia10/usr/share/julia/stdlib/v1.0"]

# with home project; @ expands to our specified home project
[~]$ julia --project=@. -E 'Base.load_path()'
["~/Project.toml", "~/.julia/environments/v1.0/Project.toml", "~/julia10/usr/share/julia/stdlib/v1.0"]

最后,如果我们从加载路径中删除"@",那么定义一个主项目也没关系:

[~]$ export JULIA_LOAD_PATH="" && julia --project=@. -E 'Base.load_path()'
String[]

答案 1 :(得分:0)

基于@fredrikekre答案,编写了一个脚本来探索get_fieldBase.load_path()Base.active_project()的行为。

init_me.jl:

Base.current_project()

结果如下:

  • 基本情况:带有Project.toml文件的文件夹中的""" Explore Base.load_path() behaviour in diffferent situations. Run this file as: julia init_me.jl julia --project=@. init_me.jl julia --project=. init_me.jl Try running in a folder that has or does not have Project.toml file. """ MESSAGE = Dict(true => " (exists)", false => " (does not exist)") exist(path)::Bool = isfile(path) || isdir(path) printexist(path::String) = println(" ", path, MESSAGE[exist(path)]) printexist(nothing) = println("nothing") printf2(s,n=8) = print(" " * s * ' '^(n-length(s))) p_ = Base.JLOptions().project project_option = (p_ != C_NULL) ? unsafe_string(p_) : "option not provided" println("--project:\n ", project_option) println("load_path():") for path in Base.load_path() printexist(path) end println("Base.active_project():") printexist(Base.active_project()) println("Base.current_project():") printexist(Base.current_project()) println("alias expansion with Base.load_path_expand():") for alias in ["@.", "@", "@stdlib", "@v1.0"] printf2(alias) printexist(Base.load_path_expand(alias)) end 会产生最理想的结果
  • julia --project=@. init_me.jl在路径包含非ASCII字符的文件夹上失败
  • 没有julia --project=. init_me.jl的文件夹可以在Project.toml上成为活动项目
  • 有时--project=<some dir without Project.toml>不是Base.active_project()