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.