Документация Engee

4. Работа со средами

В этом разделе описывается взаимодействие Pkg со средами. Подробнее о роли сред в загрузке кода, в том числе о стеке сред, из которых может быть загружен код, читайте в этом разделе руководства по Julia.

Создание собственных сред

До сих пор мы добавляли пакеты в среду по умолчанию по пути ~/.julia/environments/v1.8. Однако можно легко создавать и другие независимые проекты. Преимущество такого подхода заключается в том, что при желании вы можете зарегистрировать Project.toml и даже Manifest.toml в системе управления версиями (например, git) вместе с вашим кодом. Следует отметить, что когда два проекта используют один и тот же пакет в одной и той же версии, содержимое этого пакета не дублируется. Чтобы создать новый проект, создайте для него каталог, а затем активируйте этот каталог, чтобы сделать его «активным проектом», для которого будут выполняться операции с пакетами:

(@v1.8) pkg> activate MyProject
Activating new environment at `~/MyProject/Project.toml`

(MyProject) pkg> st
    Status `~/MyProject/Project.toml` (empty project)

Обратите внимание, что при активации нового проекта приглашение REPL меняется. Пока пакет не добавлен, в этой среде нет никаких файлов, а каталог среды может даже не быть создан:

julia> isdir("MyProject")
false

(MyProject) pkg> add Example
   Resolving package versions...
   Installed Example ─ v0.5.3
    Updating `~/MyProject/Project.toml`
  [7876af07] + Example v0.5.3
    Updating `~~/MyProject/Manifest.toml`
  [7876af07] + Example v0.5.3
Precompiling environment...
  1 dependency successfully precompiled in 2 seconds

julia> readdir("MyProject")
2-element Vector{String}:
 "Manifest.toml"
 "Project.toml"

julia> print(read(joinpath("MyProject", "Project.toml"), String))
[deps]
Example = "7876af07-990d-54b4-ab0e-23690620f79a"

julia> print(read(joinpath("MyProject", "Manifest.toml"), String))
# Этот файл сгенерирован компьютером, поэтому редактировать его напрямую не рекомендуется.

julia_version = "1.8.2"
manifest_format = "2.0"
project_hash = "2ca1c6c58cb30e79e021fb54e5626c96d05d5fdc"

[[deps.Example]]
git-tree-sha1 = "46e44e869b4d90b96bd8ed1fdcf32244fddfb6cc"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "0.5.3"

Эта новая среда полностью отличается от той, которую мы использовали ранее. Более подробное объяснение см. в описании Project.toml и Manifest.toml.

Использование проекта другого пользователя

Просто клонируйте его проект, например с помощью git clone, cd в каталог проекта и вызовите

shell> git clone https://github.com/JuliaLang/Example.jl.git
Cloning into 'Example.jl'...
...

(@v1.8) pkg> activate Example.jl
Activating project at `~/Example.jl`

(Example) pkg> instantiate
  No Changes to `~/Example.jl/Project.toml`
  No Changes to `~/Example.jl/Manifest.toml`

Если проект содержит манифест, пакеты будут установлены в том состоянии, которое задано этим манифестом. В противном случае будут разрешены последние версии зависимостей, совместимые с проектом.

Обратите внимание, что activate не устанавливает отсутствующие зависимости. Если у вас есть только файл Project.toml, то файл Manifest.toml должен быть сгенерирован путем «разрешения» среды, а затем должны быть установлены и предварительно скомпилированы все отсутствующие пакеты. instantiate делает все это за вас.

Если у вас уже есть разрешенный файл Manifest.toml, все равно нужно удостовериться, что пакеты установлены и имеют правильные версии. И снова instantiate делает все это за вас.

Короче говоря, instantiate помогает убедиться, что среда готова к использованию. Если делать ничего не требуется, instantiate ничего не делает.

Вместо того чтобы использовать activate в Julia, вы можете указать проект при запуске с помощью флага --project=<path>. Например, чтобы запустить скрипт из командной строки, используя среду в текущем каталоге, можно выполнить следующее.

```bash
$ julia --project=. myscript.jl
```

Временные среды

Временные среды позволяют легко запускать среду с нуля для тестирования пакета или набора пакетов, а по окончании работы Pkg автоматически удалит среду. Например, при написании отчета об ошибке может потребоваться протестировать минимально воспроизводимый пример в «чистой» среде, чтобы убедиться, что он действительно воспроизводим в том виде, в котором написан. Вам также могут понадобиться вспомогательное пространство для проверки нового пакета или «песочница» для разрешения конфликтов версий между несколькими несовместимыми пакетами.

(@v1.8) pkg> activate --temp # требуется версия не ниже Julia 1.5
  Activating new environment at `/var/folders/34/km3mmt5930gc4pzq1d08jvjw0000gn/T/jl_a31egx/Project.toml`

(jl_a31egx) pkg> add Example
    Updating registry at `~/.julia/registries/General`
   Resolving package versions...
    Updating `/private/var/folders/34/km3mmt5930gc4pzq1d08jvjw0000gn/T/jl_a31egx/Project.toml`
  [7876af07] + Example v0.5.3
    Updating `/private/var/folders/34/km3mmt5930gc4pzq1d08jvjw0000gn/T/jl_a31egx/Manifest.toml`
  [7876af07] + Example v0.5.3

Общие среды

«Общая» среда — это просто среда, которая существует по пути ~/.julia/environments. Поэтому среда по умолчанию v1.8 является общей средой:

(@v1.8) pkg> st
Status `~/.julia/environments/v1.8/Project.toml`

Общие среды можно активировать, установив флаг --shared в положение activate:

(@v1.8) pkg> activate --shared mysharedenv
  Activating project at `~/.julia/environments/mysharedenv`

(@mysharedenv) pkg>

Перед именем общей среды в приглашении REPL Pkg указывается @.

Предварительная компиляция среды

Прежде чем импортировать пакет, Julia «предварительно компилирует» исходный код в промежуточный более эффективный кэш на диске. Эту предварительную компиляцию можно запустить с помощью загрузки кода, если неимпортированный пакет является новым или изменился с момента последнего кэширования.

julia> using Example
[ Info: Precompiling Example [7876af07-990d-54b4-ab0e-23690620f79a]

Или можно использовать параметр предварительной компиляции Pkg, который может предварительно скомпилировать всю среду или определенную зависимость, причем делать это параллельно, что может быть значительно быстрее, чем вышеописанный путь загрузки кода.

(@v1.8) pkg> precompile
Precompiling environment...
  23 dependencies successfully precompiled in 36 seconds

Однако благодаря автоматической предварительной компиляции Pkg ни один из этих способов применять не требуется.

Автоматическая предварительная компиляция

По умолчанию любой пакет, добавляемый в проект или обновляемый в действии Pkg, будет автоматически предварительно скомпилирован вместе с зависимостями.

(@v1.8) pkg> add Images
   Resolving package versions...
    Updating `~/.julia/environments/v1.9/Project.toml`
  [916415d5] + Images v0.25.2
    Updating `~/.julia/environments/v1.9/Manifest.toml`
    ...
Precompiling environment...
  Progress [===================>                     ]  45/97
  ✓ NaNMath
  ✓ IntervalSets
  ◐ CoordinateTransformations
  ◑ ArnoldiMethod
  ◑ IntegralArrays
  ◒ RegionTrees
  ◐ ChangesOfVariables
  ◓ PaddedViews

Исключением является команда develop, которая не собирает и предварительно не компилирует пакет. Когда это произойдет, решать пользователю.

Если при автоматической предварительной компиляции данной версии пакета произошла ошибка, Pkg запомнит этот момент для последующих попыток и пропустит пакет с кратким предупреждением. Для принудительной повторной компиляции этих пакетов можно использовать предварительную компиляцию вручную, так как pkg> precompile всегда будет повторять попытку компиляции всех пакетов.

Чтобы отключить автоматическую предварительную компиляцию, задайте ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0.

Предварительная компиляция новых версий загруженных пакетов

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