私をGUIXに魅了した理由の1つは、お互いに邪魔することなく、さまざまなバージョンのパッケージを同時に「インストール」できることでした。しかし、実際にこれらのさまざまなバージョンを使用する方法がわかりません。
たとえば、最近このpyyaml
パッケージは5.4.1から6.0にアップグレードされました。。いくつかの理由で5.4.1を使い続けたいと思います。 (ここでは、例えばpyyamlを使っています。)私のストアには古いバージョンがあります。
$ ls -d1 /gnu/store/*pyyaml*
/gnu/store/22v8l25b33vs65wjd9ap28n772bvlih3-python-pyyaml-5.4.1/
/gnu/store/2j2s1jd6y8x7mlqjp968955misx1qw1c-python-pyyaml-6.0/
/gnu/store/54imz4x65s3xbjrgrfswgk815gfkhk4b-python-pyyaml-5.4.1/
/gnu/store/6537a8na1rbilffqqi642q0lipqfi2zg-python-pyyaml-5.4.1.drv
/gnu/store/6flrrmhq203vg6awdw7r2lsmzix4g2rh-python-pyyaml-6.0-guile-builder
/gnu/store/73k3qdz9rdh64pl7a0f0951zm2pbx5s2-python-pyyaml-5.4.1.drv
/gnu/store/7bcbwi93ihz8v2sdzmj6l9vhjqaxr14l-python-pyyaml-5.4.1-builder
...
以前のバージョンをどのように使用しますか?
このような古いバージョンを使用するだけでも大丈夫です。たとえば、私は次のように動作したいと思います。
$ guix shell "[email protected]" python
guix shell: error: python-pyyaml: package not found for version 5.4.1
このエラーは、私のチャンネルで以前のバージョンが利用できないために発生します。したがって、使用する古いバージョンのチャンネルを何らかの方法で指定することが可能かもしれませんが、方法はわかりません。
XY問題のサイドノードに関してこの問題の直接的な原因は、docker-composeがもう機能しないことです。
$ guix shell docker-compose
guix shell: error: build of `/gnu/store/8qhvnw5mwra9i6ji24xlywcpdl0rdznn-docker-compose-1.29.2.drv' failed
$ zcat /var/log/guix/drvs/8q/hvnw5mwra9i6ji24xlywcpdl0rdznn-docker-compose-1.29.2.drv.gz
...checking requirements: ERROR: docker-compose==1.29.2 ContextualVersionConflict(PyYAML 6.0 (/gnu/store/igfl4023dzvl8vi6xs1m96lcsr4fdw07-python-pyyaml-6.0/lib/python3.9/site-packages), Requirement.parse('PyYAML<6,>=3.10'), {'docker-compose'})
しかし、私はdocker-composeについて特に気にしません。むしろ、この質問は、これをGUIXの基本ツールに置き換えようとする旅の一部です。
(また、pyyaml 6はユーザーにいくつかのセキュリティ機能を強制するため、pyyaml 5はもう使用しないでください。pyyamlは例としてのみ使用されます。)
答え1
3番目は魅力です。下層民のリストを使うのが一番効果的だそうです。
info guix Inferiors
詳細より。情報ページのスナップショット。 (興味深いことに、彼らのユースケースは私のユースケースと非常によく似ています。つまり、以前のバージョンのyamlライブラリをPythonインタプリタとして使用するのではなく、古いバージョンのjsonライブラリをトリックインタプリタとして使用することです)。
Note: The functionality described here is a “technology preview” as
of version 0.0-git. As such, the interface is subject to change.
Sometimes you might need to mix packages from the revision of Guix
you’re currently running with packages available in a different revision
of Guix. Guix “inferiors” allow you to achieve that by composing
different Guix revisions in arbitrary ways.
...
When combined with channels (*note Channels::), inferiors provide a
simple way to interact with a separate revision of Guix. For example,
let’s assume you want to install in your profile the current ‘guile’
package, along with the ‘guile-json’ as it existed in an older revision
of Guix—perhaps because the newer ‘guile-json’ has an incompatible API
and you want to run your code against the old API. To do that, you
could write a manifest for use by ‘guix package --manifest’ (*note
Invoking guix package::); in that manifest, you would create an inferior
for that old Guix revision you care about, and you would look up the
‘guile-json’ package in the inferior.
引き続き例を挙げましょう。以下は、この特定のユースケースの同じ例です。
$ cat mypyyamlmanifest.scm
(use-modules (guix inferior) (guix channels)
(srfi srfi-1))
(define channels
(list (channel
(name 'guix)
(url "https://git.savannah.gnu.org/git/guix.git")
(commit
;; The commit with the python-pyyaml 5.4.1
"d3e1a94391a838332b0565d56762a58cf87ac6b1"))))
(define inferior
(inferior-for-channels channels))
(packages->manifest
(list (first (lookup-inferior-packages inferior "python-pyyaml"))
(specification->package "python")))
$ guix shell -m mypyyamlmanifest.scm
...
$ python3 -c "import yaml; print(yaml.__version__)"
5.4.1
この情報を見つけるのになぜそれほど長い時間がかかったのか考えてみましょう。 (たぶんGUIX開発者はこの記事を読んで、私はそれを使ってドキュメントにパッチを提供するかもしれません。)
guix info guix package
これがチェックリスト使用の出発点です。説明には--manifest
リストの作成方法の簡単な例がありますが、ディスカッションチャネルはありません。--export-manifest
私が作成した環境を再現する方法を学んだ説明リンクがあります。私の最初の答え。このセクションでは、このエクスポートにチャンネル情報が含まれていないと説明しているため、マニフェストにチャンネル情報がまったく含まれていないため、2番目のファイル(私の2番目の答え)。説明はすぐ下に--export-manifest
リンクされていますが--export-channels
、既存の内容を修正していたので、最初は読みませんでしたchannels.scm
。しかし、字幕の必要性の説明でセクションが終わります。
--manifest
説明の一部がguix package
マニフェストから直接チャンネルを定義することである場合は、理解しやすくなります。
私が正しく理解していると、劣等は技術的にチャンネルとは異なるため、上記の最後の文は間違っており、マニフェストでチャンネルを定義することはできません。しかし、実際には、マニフェストのすべてのパッケージにサブパッケージを使用して、マニフェストのチャネルを効果的にハードコーディングすることが可能になります。これにより、マニフェストで直接チャンネル仕様を許可する方が簡単なのかと思います。
質問への答えでは、このソリューションは問題を引き起こした元の問題であるrunningを解決するのに十分ではありません。元のチャンネルのソリューションがまだ使用されているdocker-compose
からです。可能docker-compose
python-pyyaml
パッケージに劣った入力を使用させるmodify-inputs
。これにより、古い古いプロファイルがdocker-compose
使用され、残りのプロファイルでは元のチャンネルの最新プロファイルを使用できます。python-pyyaml
python-pyyaml
答え2
素晴らしいinfo guix
ページをご提供いただきありがとうございます。これが可能だと思います。
guix shell \
--with-git-url=python-pyyaml="https://github.com/yaml/pyyaml.git" \
--with-branch=python-pyyaml="release/5.4.1" \
python-pyyaml python
しかし、すでに完璧なパッケージ定義がある場合は、少し奇妙な感じがします。https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/python-xyz.scm?h=d3e1a94391a838332b0565d56762a58cf87ac6b1#n3907。
pyyaml
非常にシンプルなパッケージでgithubで素晴らしいホストされ、標準のgit分岐とPythonのインストール手順に従います。ただし、一部のパッケージはより複雑になる可能性があり、これらの単純な交換が機能しない可能性があります。
パッケージに使用するチャネルgit urlに特定のコミットを指定する方法はありますか? (または完全なguix shell
コマンド?)
編集:この解決策が悪いもう1つの理由は、次のように動作しないことです--export-manifest
。
$ guix shell \
--with-git-url=python-pyyaml="https://github.com/yaml/pyyaml.git" \
--with-branch=python-pyyaml="release/5.4.1" \
--export-manifest \
python-pyyaml python > mymanifest.scm
$ guix shell -m mymanifest.scm
guix shell: error: the source of [email protected] is not a Git
そしてmymanifest.scm
:
$ cat mymanifest.scm
;; What follows is a "manifest" equivalent to the command line you gave.
;; You can store it in a file that you may then pass to any 'guix' command
;; that accepts a '--manifest' (or '-m') option.
(use-modules (guix transformations))
(define transform1
(options->transformation
'((with-git-url
.
"python-pyyaml=https://github.com/yaml/pyyaml.git")
(with-branch . "python-pyyaml=release/5.4.1"))))
(packages->manifest
(list (transform1
(specification->package "python-pyyaml"))
(transform1 (specification->package "python"))))
答え3
これはおそらくGUIXyに近いです。
- それでもpyyaml 5.4.1を持つコミットでチャンネルファイルを作成します。
- このチャンネルファイルから設定ファイルを作成します。
- このプロフィールを有効にしてください。
- 必要なパッケージを含むマニフェストを作成します。
- このマニフェストを使用してシェルを作成します。
$ cat mypyyamlchannels.scm
(list (channel
(name 'guix)
(url "https://git.savannah.gnu.org/git/guix.git")
(branch "master")
(commit
"d3e1a94391a838332b0565d56762a58cf87ac6b1")
(introduction
(make-channel-introduction
"9edb3f66fd807b096b48283debdcddccfea34bad"
(openpgp-fingerprint
"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))
$ guix pull -C mypyyamlchannels.scm -p mypyyamlprofile
$ GUIX_PROFILE="$(realpath mypyyamlprofile)"
$ . "$GUIX_PROFILE/etc/profile"
$ guix shell python-pyyaml python --export-manifest > mypyyamlmanifest.scm
$ cat mypyyamlmanifest.scm
;; What follows is a "manifest" equivalent to the command line you gave.
;; You can store it in a file that you may then pass to any 'guix' command
;; that accepts a '--manifest' (or '-m') option.
(specifications->manifest
(list "python-pyyaml" "python"))
$ guix shell -m mypyyamlmanifest.scm
しかし、ここには2つの欠点があります。
- 内容が少し長くなります。同じ環境を再生成するには、2つのファイル(チャンネルとマニフェスト)と4つのコマンド(guix pull、set GUIX_PROFILE、ソース設定ファイル、guix Shell)、および2つのシンボリックリンク(
mypyyamlprofile
、、)が必要です。mypyyamlprofile-1-link
機能しない変換ソリューションには1つのマニフェストファイルと1つのguixシェルコマンドが必要です。チャンネルとマニフェストファイルを1つにまとめてから、単一のコマンドでシェルをインスタンス化するために使用できる方法はありますか? - メインチャンネルでのミキシングとマッチングはできません。ミキシングのためには、基本チャンネルを結合するチャンネルファイルを作成し、python-pyyamlパッケージで特定のコミットを含むチャンネルを何とか選択する必要があると思います。これは矛盾を引き起こす可能性がありますが、解決することができます。
編集:明らかに粗雑なものは、ミキシングとマッチングをより簡単にします。
Sometimes you might need to mix packages from the revision of Guix
you’re currently running with packages available in a different revision
of Guix. Guix “inferiors” allow you to achieve that by composing
different Guix revisions in arbitrary ways.