代码之家  ›  专栏  ›  技术社区  ›  Evgeny

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

  •  3
  • Evgeny  · 技术社区  · 6 年前

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

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

    docs :

    如果变量设置为@,Julia将尝试从当前目录及其父目录中查找包含project.toml或julia project.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?朱莉娅怎么搜索 “当前目录及其父目录。

    LOAD_PATH ( ["@", "@v#.#", "@stdlib"] ) 如讨论 here here . 做 @ 属于同一扩张家族 加载路径 符号?

    2 回复  |  直到 6 年前
        1
  •  3
  •   fredrikekre    6 年前

    家庭项目和 --project

    这个 ——项目 标志定义“家庭项目”或“家庭环境”。环境由 Project.toml / Manifest.toml 并定义哪些包可用于 using / import .

    你可以设定 ——项目 (i)目录(有或没有 项目文件 )(ii)通往 项目文件 或(iii) @. . (i)和(i i)都是不言而喻的——茱莉亚会考虑将位于路径上的项目作为家庭项目。现在(iii),如果你设置 --project=@. 茱莉亚会找一个 现有的 项目文件 归档并将其用作主项目。请考虑以下示例:

    ~$ tree .
    .
    ├── A
    └── Project.toml
    
    1 directory, 1 file
    

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

    # 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"
    

    请注意,在上面最后三个示例中, 项目文件 文件 不存在 ,但如果需要,它将被创建(例如在使用时 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"
    

    在这两种情况下我们都发现了相同的 项目文件 文件。与 @ 选项Julia首先在当前目录中查找 项目文件 文件,如果找不到,则向上一级转到父文件夹并查找该文件夹,依此类推。这就是第二个例子中发生的事情;Julia没有发现 项目.toml 文件在空 目录,因此我们移到父目录,并找到 项目文件 我们在那儿。

    是的,我们可以为这个选择其他的代币,但不能 . 因为这已经有了意义;它是指向当前目录的路径,是与一起使用的完全有效的路径 ——项目 .

    负载路径和 "@"

    加载包 Example 我们用 例子 在其 [deps] 部分;主项目还需要显示在julias加载路径中( Base.load_path() )默认情况下,加载路径从 ["@", "@v#.#", "@stdlib"] 哪里 "@v#.#" 扩展到 ~/.julia/environments/v#.# 具有 # 替换为Julias主版本号和次版本号,以及 "@stdlib" 使用julias标准库扩展到目录。 “@” 扩展到1。活动项目(用激活 Pkg.activate / pkg> activate 或2。家庭项目。我们可以用 base.load_路径()) 以下内容:

    # 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[]
    
        2
  •  0
  •   Evgeny    6 年前

    基于@fredrikekre answer,编写了一个脚本来探索 Base.load_path() , Base.active_project() , Base.current_project() .

    J.

    """
    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 在带有project.toml文件的文件夹中,文件产生最期望的结果
    • julia --project=. init_me.jl 在路径包含非ASCII字符的文件夹上失败
    • 没有的文件夹 Project.toml 可以成为活动项目 --project=<some dir without Project.toml>
    • 有时 base.active_项目() 不是 base.current_项目()