10. Project.toml
и Manifest.toml
Основными файлами в Pkg являются Project.toml
и Manifest.toml
. Project.toml
и Manifest.toml
написаны на TOML (отсюда следует расширение .toml
) и содержат информацию о зависимостях, версиях, именах пакетов, UUID и т. д.
Файлы |
Project.toml
Файл проекта описывает проект на высоком уровне. Например, в файле проекта перечисляются зависимости пакета или проекта и ограничения совместимости. Записи файла описаны ниже.
Поле authors
Для пакета необязательное поле authors
представляет собой список строк, описывающих авторов пакета, в виде NAME <EMAIL>
. Например:
authors = ["Some One <someone@email.com>",
"Foo Bar <foo@bar.com>"]
Поле name
Имя пакета или проекта определяется полем name
, например:
name = "Example"
Имя должно быть допустимым идентификатором (последовательностью символов Unicode, которая не начинается с цифры и не имеет значения ни true
, ни false
). При работе с пакетами рекомендуется следовать инструкциям по именованию пакетов. Поле name
является обязательным для пакетов.
Поле uuid
uuid
— это строка с универсальным уникальным идентификатором для пакета или проекта, например:
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
Поле uuid
является обязательным для пакетов.
Для генерации случайных UUID рекомендуется использовать |
Поле version
version
— это строка с номером версии для пакета или проекта. Она должна состоять из трех числовых значений — номера основной версии, номера дополнительной версии и номера исправления, разделенных символом .
, например:
version = "1.2.5"
Julia использует семантическое управление версиями (SemVer), и поле version
должно ему соответствовать. Действуют следующие базовые правила.
-
До версии 1.0.0 можно делать все, что угодно, но когда вы вносите критические изменения, номер дополнительной версии должен увеличиваться.
-
После версии 1.0.0 вносить критические изменения следует только при увеличении номера основной версии.
-
После версии 1.0.0 не следует добавлять новые общедоступные API без увеличения номера дополнительной версии. В частности, это касается новых типов, функций, методов и перегрузок методов из пакетов
Base
или других пакетов. См. раздел Совместимость.
Обратите внимание, что когда речь идет о версиях, предшествующих 1.0.0, Pkg.jl отклоняется от спецификации SemVer. Дополнительные сведения см. в разделе о поведении версий, предшествующих 1.0.
Раздел [deps]
Все зависимости пакета или проекта перечислены в разделе [deps]
. Каждая зависимость указывается в виде пары имя-uuid, например:
[deps]
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Обычно нет необходимости вручную добавлять записи в раздел [deps]
. Для этого используются такие операции Pkg, как add
.
Раздел [compat]
Ограничения совместимости для зависимостей, приведенных в разделе [deps]
, могут быть перечислены в разделе [compat]
. Пример:
[deps]
Example = "7876af07-990d-54b4-ab0e-23690620f79a"
[compat]
Example = "1.2"
Различные возможные ограничения совместимости подробно описываются в разделе Совместимость. Можно также перечислить ограничения для самой julia
, хотя julia
не указана как зависимость в разделе [deps]
:
[compat]
julia = "1.1"
Manifest.toml
Файл манифеста является абсолютной записью о состоянии пакетов в среде. Он содержит точную информацию о (прямых и косвенных) зависимостях проекта. Принимая во внимание пару Project.toml
+ Manifest.toml
, можно создать экземпляр точно такой же среды пакета, что очень полезно для воспроизводимости. Подробнее см. в описании Pkg.instantiate
.
Файл |
Записи Manifest.toml
В манифесте есть три записи верхнего уровня, которые могут выглядеть следующим образом.
julia_version = "1.8.2"
manifest_format = "2.0"
project_hash = "4d9d5b552a1236d3c1171abf88d59da3aaac328a"
Здесь показана версия Julia, для которой был создан манифест, «формат» манифеста и хэш файла проекта, чтобы можно было увидеть, когда манифест будет устаревшим по сравнению с файлом проекта.
Каждая зависимость имеет свой раздел в файле манифеста, и его содержимое зависит от того, каким образом зависимость была добавлена в среду. Каждый раздел зависимостей содержит сочетание следующих записей:
-
uuid
: UUID для зависимости, напримерuuid = "7876af07-990d-54b4-ab0e-23690620f79a"
. -
deps
: вектор с перечислением зависимостей данной зависимости, напримерdeps = ["Example", "JSON"]
. -
version
: номер версии, напримерversion = "1.2.6"
. -
path
: путь к файлу с исходным кодом, напримерpath = /home/user/Example
. -
repo-url
: URL-адрес репозитория, в котором был найден исходный код, напримерrepo-url = "https://github.com/JuliaLang/Example.jl.git"
. -
repo-rev
: редакция git, например ветвьrepo-rev = "master"
или фиксацияrepo-rev = "66607a62a83cb07ab18c0b35c038fcd62987c9b1"
. -
git-tree-sha1
: хэш содержимого дерева исходного кода, напримерgit-tree-sha1 = "ca3820cc4e66f473467d912c4b2b3ae5dc968444"
.
Добавленный пакет
Когда пакет добавляется из реестра пакетов, например путем вызова pkg> add Example
или с определенной версией pkg> add Example@1.2
, результирующая запись Manifest.toml
выглядит так.
[[deps.Example]]
deps = ["DependencyA", "DependencyB"]
git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "1.2.3"
Обратите внимание, в частности, на отсутствие repo-url
, поскольку эта информация включена в реестр, в котором был найден данный пакет.
Добавленный пакет, указанный ветвью
Результирующий раздел зависимостей при добавлении пакета, указанного ветвью, например pkg> add Example#master
или pkg> add https://github.com/JuliaLang/Example.jl.git
, выглядит следующим образом.
[[deps.Example]]
deps = ["DependencyA", "DependencyB"]
git-tree-sha1 = "54c7a512469a38312a058ec9f429e1db1f074474"
repo-rev = "master"
repo-url = "https://github.com/JuliaLang/Example.jl.git"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "1.2.4"
Обратите внимание, что в манифесте хранится как отслеживаемая ветка (master
), так и URL-адрес удаленного репозитория ("https://github.com/JuliaLang/Example.jl.git"
).
Добавленный пакет, указанный фиксацией
Результирующий раздел зависимостей при добавлении пакета, указанного фиксацией, например pkg> add Example#cf6ba6cc0be0bb5f56840188563579d67048be34
, выглядит следующим образом.
[[deps.Example]]
deps = ["DependencyA", "DependencyB"]
git-tree-sha1 = "54c7a512469a38312a058ec9f429e1db1f074474"
repo-rev = "cf6ba6cc0be0bb5f56840188563579d67048be34"
repo-url = "https://github.com/JuliaLang/Example.jl.git"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "1.2.4"
Единственным отличием от отслеживания ветви является содержимое repo-rev
.
Разработанный пакет
Результирующий раздел зависимостей при добавлении пакета с develop
, например pkg> develop Example
или pkg> develop /path/to/local/folder/Example
, выглядит следующим образом.
[[deps.Example]]
deps = ["DependencyA", "DependencyB"]
path = "/home/user/.julia/dev/Example/"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "1.2.4"
Обратите внимание, что включен путь к исходному коду, и изменения, внесенные в это дерево исходного кода, отражаются напрямую.
Закрепленный пакет
Закрепленные пакеты также записываются в файл манифеста. Результирующий раздел зависимостей, например pkg> add Example; pin Example
, выглядит следующим образом.
[[deps.Example]]
deps = ["DependencyA", "DependencyB"]
git-tree-sha1 = "54c7a512469a38312a058ec9f429e1db1f074474"
pinned = true
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "1.2.4"
Единственное отличие — добавление записи pinned = true
.
Несколько пакетов с одинаковым именем
Julia различает пакеты на основе UUID, что означает, что для идентификации пакета недостаточно одного только имени. В одной среде может быть несколько пакетов с одинаковыми именами, но разными UUID. В такой ситуации файл Manifest.toml
выглядит несколько иначе. Рассмотрим, например, ситуацию, когда вы добавили A
и B
в среду, и файл Project.toml
выглядит следующим образом.
[deps]
A = "ead4f63c-334e-11e9-00e6-e7f0a5f21b60"
B = "edca9bc6-334e-11e9-3554-9595dbb4349c"
Если A
теперь зависит от B = "f41f7b98-334e-11e9-1257-49272045fb24"
, то есть от другого пакета с именем B
, то в файле Manifest.toml
будет два разных пакета B
. В данном случае полный файл Manifest.toml
, из которого для наглядности удалены поля git-tree-sha1
и version
, выглядит следующим образом.
[[deps.A]]
uuid = "ead4f63c-334e-11e9-00e6-e7f0a5f21b60"
[deps.A.deps]
B = "f41f7b98-334e-11e9-1257-49272045fb24"
[[deps.B]]
uuid = "f41f7b98-334e-11e9-1257-49272045fb24"
[[deps.B]]
uuid = "edca9bc6-334e-11e9-3554-9595dbb4349c"
Теперь есть массив из двух пакетов B
, а раздел [deps]
для A
был расширен, чтобы явно указать, от какого пакета B
зависит A
.