что такое `@ .` в параметре командной строки Julia` --project`? - PullRequest
0 голосов
/ 04 декабря 2018

При запуске Julia в командной строке можно указать каталог проекта.Один из вариантов - @., возобновляемый текущий каталог.Что такое @. в этом контексте?

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

Из документов :

Если для переменной задано значение @., Джулия пытается найти каталог проекта, содержащий Project.toml илиФайл JuliaProject.toml из текущего каталога и его родителей.

Я понимаю, что синтаксический анализ аргумента cli --project происходит в этом C-коде и, очевидно, используется этим кодом инициализации , хотя я не уверенпоследовательности событий между ними.

В частности, в 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)

Мое прочтение этого кода таково, что @. это простопроизвольный токен, это могло бы быть просто . для кли?Как Джулия ищет "текущий каталог и его родителей. "

В LOAD_PATH (["@", "@v#.#", "@stdlib"]) используются аналогичные обозначения, как обсуждено здесь и здесь .@. принадлежит к тому же семейству расширений, что и символы LOAD_PATH?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

На основе ответа @fredrikekre написал скрипт для изучения поведения Base.load_path(), Base.active_project(), Base.current_project().

init_me.jl:

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

Результаты следующие:

  • basecase: julia --project=@. init_me.jl в папке с файлом Project.toml дает наиболее ожидаемый результат
  • julia --project=. init_me.jl не работает в папках, путь которых содержит символы, отличные от ASCII
  • папка без Project.toml может стать активным проектом при --project=<some dir without Project.toml>
  • иногда Base.active_project()не Base.current_project()
0 голосов
/ 05 декабря 2018

Домашний проект и --project

Флаг --project определяет «домашний проект» или «домашнюю среду».Среда определяется как Project.toml / Manifest.toml и определяет, какой пакет доступен для using / import.

. Вы можете установить --project в (i) каталог (с или безa Project.toml) (ii) путь к Project.toml или (iii) к @..(i) и (ii) довольно понятны - Юлия будет рассматривать проект, расположенный на пути, как домашний проект.Теперь для (iii), если вы установите --project=@. Джулия попытается найти существующий 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 для манипулирования пакетами).

Теперь сравните это с поведением @., которое будет искать существующий проектfile:

# 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 файл.С опцией @. Джулия сначала ищет в текущем каталоге файл 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[]
...