Go: cmd / go:Goツールチェーンにパッケージバージョンのサポートを追加

作成日 2018年03月07日  ·  242コメント  ·  ソース: golang/go

提案:Goツールチェーンにパッケージバージョンのサポートを追加する

Go開発者と私たちのツールの両方の実用的な語彙にバージョンを追加するのはかなり昔のことです。
リンクされた提案はそれを行う方法を説明しています。 代替案の説明については、特に理論的根拠のセクションを参照してください。

このGitHubの問題は、提案の内容について話し合うためのものです。

その他の参考資料:

Proposal Proposal-Accepted modules

最も参考になるコメント

この提案は2か月以上にわたって活発な議論が行われており、@ rsc@ spf13はフィードバックセッションを実施し、コミュニティから貴重な意見を集めて提案を改訂しました。 @rscは、さらにフィードバックを得るために、 @ sdboyerと毎週ミーティングを開催しています。 追加の改訂をもたらした提案について、貴重なフィードバックが提供されました。 ますます、このフィードバックは、提案ではなく、付随する実装に関するものです。 かなりのレビューを経て、この提案を受け入れ、Goのツール実装者の幅広いエコシステムが重要な調整を開始して、ユーザーベースが可能な限り最高のエクスペリエンスを享受できるようにする時が来たと感じています。

この提案には2つの反対意見があり、私たちは話し合うべきだと感じています。

  1. この提案では、ライブラリの使用とリリースに関する慣行の一部を変更する必要があります。
  2. この提案では、非互換性に関連して発生する可能性のあるすべてのシナリオに対する技術的な解決策を提供できません。

これらは観察において正確ですが、意図したとおりに機能します。 コードの作成者とユーザーは、開発者がgofmtの実行など、Goの他の詳細に適応したように、ライブラリの使用とリリースに関する慣行の一部を変更する必要があります。 ベストプラクティスを変えることが正しい解決策になる場合があります。 同様に、vgoは非互換性を含むすべての可能な状況を処理する必要はありません。 RussがGopherconSingaporeでの最近の講演で指摘したように、非互換性に対する唯一の永続的な解決策は、非互換性を修正し、Goパッケージエコシステムを維持するために協力することです。 vgoやdepのようなツールでの一時的な回避策は、開発者が実際の問題を解決する時間を与えるのに十分な時間だけ機能する必要があり、vgoはこの仕事を十分に行います。

この重大な問題に寄せられたすべてのフィードバックと情熱に感謝します。 提案は受け入れられました。

—Go提案レビュー委員会

全てのコメント242件

よくある質問

この問題のコメントは、以下のディスカッションからであれ、他のディスカッションからであれ、最もよくある質問に答えます。 ディスカッションからの他の質問は、次の号のコメントにあります。

なぜ提案は「 Depを使用」しないのですか?

この提案につながった旅の開始時、ほぼ2年前、私たちは皆、RubyのBundler、次にRustのCargo:タグ付きセマンティックバージョン、手動で編集された依存関係制約ファイルによって例示されるパッケージバージョン管理アプローチに従うことだと信じていましたマニフェストと呼ばれる、別のマシンで生成されたロックファイルと呼ばれる一時的な依存関係の記述、マニフェストを満たすロックファイルを計算するバージョンソルバー、およびバージョン管理の単位としてのリポジトリ。 Depはこの大まかな計画にほぼ正確に従っており、元々はgoコマンド統合のモデルとして機能することを目的としていました。 ただし、Bundler / Cargo / Depアプローチの詳細と、特にgoコマンドに組み込まれているGoにとっての意味を理解すればするほど、それらの詳細についてGoチームの他のメンバーと話し合うほど、いくつかの詳細がわかります。 Goに適しているとは思えませんでした。 この提案は、開発者が理解して使用しやすいシステムを出荷することを期待して、これらの詳細を調整します。 変更したい具体的な詳細については、提案の理論的根拠のセクションを参照してください。また、提案を発表するブログ投稿も参照してください。

メジャーバージョン番号をインポートパスに表示する必要があるのはなぜですか?

インポート互換性ルールに従うこと。これにより、システムの残りの部分が劇的に簡素化されます。 提案を発表するブログ投稿も参照してください。このブログ投稿では、インポート互換性ルールの動機と正当性について詳しく説明しています。

メジャーバージョンv0、v1がインポートパスから省略されているのはなぜですか?

v1は、2つの理由でインポートパスから省略されています。 まず、多くの開発者は、v1に到達した後は決して重大な変更を加えないパッケージを作成します。これは、最初から推奨されていることです。 これらの開発者全員が、v2をリリースする意図がない場合でも、明示的なv1を強制する必要があるとは考えていません。 v1は単なるノイズになります。 それらの開発者が最終的にv2を作成する場合、デフォルトのv1と区別するために、追加の精度が開始されます。 v1をどこにでも配置するための目に見える安定性については良い議論があります。システムを最初から設計している場合は、それが緊密な呼びかけになるかもしれません。 しかし、既存のコードの重みは、v1を省略することを支持してバランスを強く傾けます。

semverによると、これらのバージョンには互換性の保証がまったくないため、v0はインポートパスから省略されています。 明示的なv0要素を要求しても、互換性を確保することはほとんどありません。 ライブラリを更新するたびにすべてのインポートパスを更新して、完全に正確にv0.1.2と言う必要があります。 それはやり過ぎのようです。 代わりに、開発者が依存しているモジュールのリストを確認し、見つけたv0.xyバージョンに適切に注意することを望んでいます。

これには、インポートパスでv0とv1を区別しない効果がありますが、通常、v0はv1につながる一連の中断変更であるため、v1をその中断シーケンスの最終ステップとして扱うことは理にかなっています。v0と区別する必要はありません。 。 @Meroviusが述べているように(https://github.com/golang/go/issues/24301#issuecomment-376213693):

v0.xを使用することにより、v0。(x + 1)によってコードの修正が強制される可能性があることに同意したことになります。 代わりにv0。(x + 1)がv1.0と呼ばれる場合、なぜ問題になるのですか?

最後に、メジャーバージョンv0とv1を省略することは必須であり、オプションではないため、パッケージごとに1つの正規のインポートパスがあります。

マスターで作業を続けるのではなく、v2用に新しいブランチを作成する必要があるのはなぜですか?

新しいブランチを作成する必要はありません。 残念ながら、 vgoモジュールの投稿は、「主要なブランチ」リポジトリのレイアウトに関する議論でその印象を与えています。 しかし、vgoはブランチを気にしません。 タグを検索し、タグが指す特定のコミットを解決するだけです。 マスターでv1を開発する場合、v1で完全に完了したと判断し、マスターでv2コミットの作成を開始したい場合は、問題ありません。マスターにv2.xyタグのタグ付けを開始します。 ただし、一部のユーザーはv1を使い続けるため、v1のマイナーなバグ修正を発行したい場合があることに注意してください。 少なくとも、v2のマスターの使用を開始した時点で、その作業用に新しいv1ブランチをフォークすることをお勧めします。

最小限のバージョン選択により、開発者は重要な更新を取得できなくなりませんか?

これはよくある恐怖ですが、もし何か逆のことが起こると私は本当に思います。 https://research.swtch.com/vgo-mvsの「アップグレード速度」セクションの引用:

最小限のバージョン選択では各依存関係の最小許容バージョンが使用されることを考えると、これによりパッケージの非常に古いコピーが使用され、不要なバグやセキュリティの問題が発生する可能性があると考えられがちです。 ただし、実際には、逆のことが起こると思います。最小許容バージョンはすべての制約の最大値であるため、ビルド内のすべてのモジュールで使用できる制御の1つのレバーは、新しいバージョンの使用を強制する機能です。他の方法で使用されるよりも依存関係の。 最小限のバージョン選択のユーザーは、Cargoのようなより積極的なシステムを使用している友人とほぼ同じくらい最新のプログラムになってしまうと思います。

たとえば、他のいくつかのモジュールに依存するプログラムを作成しているとします。これらのモジュールはすべて、gopkg.in /yaml.v2などの非常に一般的なモジュールに依存しています。 プログラムのビルドでは、モジュールによって要求されたものとその少数の依存関係のうち、最新のYAMLバージョンが使用されます。 たった1つの良心的な依存関係でさえ、ビルドに他の多くの依存関係を更新させる可能性があります。 これは、前述のKubernetesGoクライアントの問題の反対です。

どちらかといえば、最小バージョンの選択は、代わりに反対の問題を抱えることになります。この「最小の最大」の答えは、依存関係を早すぎる方向に強制するラチェットとして機能します。 しかし、実際には、依存関係は適切な速度で前進し、最終的にはCargoや友人よりも適切な量だけ遅くなると思います。

「適切な量の速度低下」とは、アップグレードが要求された場合にのみ発生し、そうでない場合には発生しないという重要な特性を指していました。 つまり、コードが変更されるのは、それが発生することを期待していて、テストやデバッグなどの準備ができている場合にのみ(予期しない方法や破壊的な方法で)変更されるということです。

@Meroviusによる応答https://github.com/golang/go/issues/24301#issuecomment-375992900も参照してください。

$ GOPATHが非推奨になった場合、ダウンロードしたコードはどこにありますか?

チェックアウトして作業および変更するコードは、基本的に他のすべての開発者ツールと同様に、ファイルシステムのどこにでも保存できます。

Vgoには、ダウンロードしたソースコードを保持し、バイナリをインストールするためのスペースが必要です。そのため、Vgoは$ GOPATHを使用します。これは、Go1.9の時点でデフォルトで$ HOME / goになっています。 したがって、開発者は、これらのファイルを別のディレクトリに配置する必要がない限り、$ GOPATHを設定する必要はありません。 バイナリのインストール場所だけを変更するには、(いつものように)$ GOBINを設定できます。

なぜ// importコメントを紹介するのですか?

そうではなかった。 それは既存の慣習でした。 ツアーでのその例のポイントは、 go.modがインポートコメントから正しいモジュールパスが存在する場合、それらをどのように推測できるかを示すことでした。 すべてのプロジェクトがgo.modファイルを使用すると、インポートコメントは完全に冗長になり、おそらく非推奨になります。

ディスカッションの概要(最終更新日2017-04-25)

この問題のコメントには、以下の議論の要約が含まれています。

移行をどのように処理できますか?

[ https://github.com/golang/go/issues/24301#issuecomment -374739116 by @ ChrisHines。]

@rscによる応答https://github.com/golang/go/issues/24301#issuecomment-377529520 。 元の提案では、互換性が重要な場合にサブディレクトリに移動する作成者が移行を処理することを前提としていますが、もちろんその動機は間違っています。 互換性は、作成者の移動にほとんど影響を与えないユーザーにとって最も重要です。 そして、それは古いバージョンには役立ちません。 リンクされたコメント(現在は#25069)は、モジュール対応コードを使用およびビルドできるように、古い「gobuild」への最小限の変更を提案しています。

シングルトン登録をどのように処理できますか?

[ https://github.com/golang/go/issues/24301#issuecomment -374791885 by @ jimmyfrasche。]

@rscによる応答https://github.com/golang/go/issues/24301#issuecomment-377527249 。 完全に異なるモジュール間のシングルトン登録の衝突(同じパスのhttp.Handleなど)は、提案の影響を受けません。 単一モジュールの異なるメジャーバージョン間の衝突の場合、作成者は、通常はv1をv2に呼び出すことによって、調整を期待する異なるメジャーバージョンを記述し、要件サイクルを使用して、v2が古いv1で使用されないようにすることができます。調整について知っています。

バージョン管理されたコマンドをどのようにインストールする必要がありますか?

[ https://github.com/golang/go/issues/24301#issuecomment -375106068 by @ leonklingele。]

@rscによる応答https://github.com/golang/go/issues/24301#issuecomment-377417565 。 つまり、gogetを使用します。 インストール場所には引き続き$ GOPATH / binを使用します。 $ GOPATHのデフォルトは$ HOME / goになっているため、コマンドは$ HOME / go / binになり、$ GOBINはそれをオーバーライドできることに注意してください。

インポートパスでv0、v1が省略されているのはなぜですか? なぜ他の人が現れなければならないのですか? なぜv0、v1が表示されないのですか?

[ https://github.com/golang/go/issues/24301#issuecomment -374818326 by @ justinian。]
[ https://github.com/golang/go/issues/24301#issuecomment -374831822 by @ jayschwa。]
[ https://github.com/golang/go/issues/24301#issuecomment -375437150 by @ mrkanister。]
[ https://github.com/golang/go/issues/24301#issuecomment -376093912 by @ mrkanister。]
[ https://github.com/golang/go/issues/24301#issuecomment -376135447 by @ kaikuehne。]
[ https://github.com/golang/go/issues/24301#issuecomment -376141888 by @ kaikuehne。]
[ https://github.com/golang/go/issues/24301#issuecomment -376213693 by @ Merovius。]
[ https://github.com/golang/go/issues/24301#issuecomment -376247926 by @ kaikuehne。]

上記のFAQに追加されました。

提案にzipファイルが記載されているのはなぜですか?

[ https://github.com/golang/go/issues/24301#issuecomment -374839409 by @ nightlyone。]

エコシステムは、具体的な交換フォーマットを定義することで恩恵を受けます。 これにより、プロキシやその他のツールが有効になります。 同時に、バージョン管理の直接使用を放棄しています(この投稿の上部にある理論的根拠を参照してください)。 これは両方とも、特定の形式を説明する動機です。 ほとんどの開発者は、zipファイルについてまったく考える必要はありません。 godoc.orgのようなものを構築しているのでない限り、開発者はそれらの内部を調べる必要はありません。

zipとtarについては#24057も参照してください。

メジャーバージョンをインポートパスに入れることはDRYに違反しませんか?

[ https://github.com/golang/go/issues/24301#issuecomment -374831822 by @ jayschwa。]

いいえ、インポートのセマンティクスはgo.modファイルを参照しなくても理解できる必要があるためです。 go.modファイルは、より詳細な情報のみを指定しています。 ブロック引用から始まる、提案のセマンティックインポートバージョンセクションの後半を参照してください。

また、乾燥しすぎると、システムが壊れやすくなります。 冗長性は良いことです。 したがって、「DRYに違反する」、つまり、自分自身を制限して繰り返すことは、必ずしも悪いことではありません。 たとえば、1つだけでなくディレクトリ内のすべての.goファイルにpackage句を配置します。 それは早い段階で正直な間違いを見つけ、後で外部テストパッケージ(パッケージxとパッケージx_test)を区別する簡単な方法になりました。 打たれるバランスがあります。

疑似バージョンのタイムスタンプに使用されるタイムゾーンはどれですか?

[ https://github.com/golang/go/issues/24301#issuecomment -374882685 by @ tpng。]

UTC。 疑似バージョンを自分で入力する必要がないことにも注意してください。 git commit hash(またはハッシュプレフィックス)を入力すると、vgoが適切な疑似バージョンを計算して置換します。

vgoは、CやプロトコルバッファなどのGo以外の依存関係に対応しますか? 生成されたコード?

[ https://github.com/golang/go/issues/24301#issuecomment -374907338 by @ AlexRouSg。]
[ https://github.com/golang/go/issues/24301#issuecomment -376606788 by @ stevvooe。]
[ https://github.com/golang/go/issues/24301#issuecomment -377186949 by @ nim-nim。]

非Go開発は、引き続きgoコマンドの非目標であるため、Cライブラリなどの管理はサポートされず、プロトコルバッファも明示的にサポートされません。

そうは言っても、Goでプロトコルバッファを使用するのは難しすぎることは確かに理解しているので、個別に対処してもらいたいと思います。

より一般的に生成されるコードに関しては、実際のクロスランゲージビルドシステムが答えです。特に、すべてのユーザーが適切なジェネレーターをインストールする必要がないためです。 作成者がジェネレーターを実行して結果をチェックインする方がよいでしょう。

最小限のバージョン選択により、開発者は重要な更新を取得できなくなりませんか?

[ https://github.com/golang/go/issues/24301#issuecomment -375090551 by @ TocarIP。]
[ https://github.com/golang/go/issues/24301#issuecomment -375985244 by @ nim-nim。]
[ https://github.com/golang/go/issues/24301#issuecomment -375992900 by @ Merovius。]

FAQに追加されました。

###マスターを使用してv1を開発し、それを再利用してv2を開発できますか?

[ https://github.com/golang/go/issues/24301#issuecomment -375248753 by @ mrkanister。]
[ https://github.com/golang/go/issues/24301#issuecomment -375989173 by @ aarondl。]

はい。 FAQに追加されました。

これのタイムラインは何ですか?

[ https://github.com/golang/go/issues/24301#issuecomment -375415904 by @ flibustenet。]

@rscによるhttps://github.com/golang/go/issues/24301#issuecomment-377413777での応答。 つまり、目標はGo1.11に「テクノロジープレビュー」を導入することです。 作業は凍結まで数週間続く場合がありますが、それ以上は続きません。 おそらく、提案が承認済みとしてマークされ、cmd / goの開発コピーが更新されるまで、見つけることができるすべてのライブラリにgo.modを追加するPRを送信しないでください。

後方互換性のないセキュリティ変更を行うにはどうすればよいですか?

[ https://github.com/golang/go/issues/24301#issuecomment -376236546 by @ buro9。]

@rscによるhttps://github.com/golang/go/issues/24301#issuecomment-377415652での応答。 要するに、 Go 1互換性ガイドラインでは、メジャーバージョンのバンプを回避するためにセキュリティ上の理由で重大な変更を許可していますが、既存のコードを可能な限り機能させる方法で行うのが常に最善です。 たとえば、関数を削除しないでください。 代わりに、関数をパニックまたはログにします。不適切に呼び出された場合にのみ致命的です。

1つのリポジトリがサブディレクトリ(たとえば、v2、v3、v4)に異なるモジュールを保持している場合、vgoは異なるコミットから混合して一致させることができますか?

[ https://github.com/golang/go/issues/24301#issuecomment -376266648 by @ jimmyfrasche。]
[ https://github.com/golang/go/issues/24301#issuecomment -376270750 by @ AlexRouSg。]

はい。 各バージョンタグは、リポジトリ全体の1つのサブツリーにのみ対応するものとして扱われ、決定ごとに異なるタグ(したがって異なるコミット)を使用できます。

プロジェクトがsemverを誤用した場合はどうなりますか? インポートパスでマイナーバージョンを許可する必要がありますか?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 by @ pbx0。]
[ https://github.com/golang/go/issues/24301#issuecomment -376645212 by @ powerman。]
[ https://github.com/golang/go/issues/24301#issuecomment -376650153 by @ pbx0。]
[ https://github.com/golang/go/issues/24301#issuecomment -376660236 by @ powerman。]

@powermanが指摘しているように、明らかに重大な変更をリリースしようとしているときに少なくともプロジェクトに通知できるように、API整合性チェッカーを提供する必要があります。

ビルドに複数のパッケージがあるかどうかを判断できますか?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 by @ pbx0。]

最も簡単な方法は、結果のバイナリでgoversion-mを使用することです。 バイナリをビルドせずに同じことを表示するgoオプションを作成する必要があります。

プロキシとベンダー、特にオープンソースとエンタープライズへのvgoの依存に関する懸念。

[ https://github.com/golang/go/issues/24301#issuecomment -376925845 by @ joeshaw。]
[ https://github.com/golang/go/issues/24301#issuecomment -376936614 by @ kardianos。]
[ https://github.com/golang/go/issues/24301#issuecomment -376947621 by @ Merovius。]
[ https://github.com/golang/go/issues/24301#issuecomment -376979054 by @ joeshaw。]
[ https://github.com/golang/go/issues/24301#issuecomment -376988873 by @ jamiethermo。]
[ https://github.com/golang/go/issues/24301#issuecomment -377134575 by @ Merovius。]

応答:[ https://github.com/golang/go/issues/24301#issuecomment -377411175 by @ rsc。]プロキシとベンダーの両方がサポートされます。 プロキシは企業にとって非常に重要であり、ベンダーはオープンソースにとって非常に重要です。 また、信頼性の高いミラーネットワークを構築したいのですが、vgoが稼働するのは一度だけです。

GOPATHセマンティクスに依存するprotobuildに関する懸念。

[ https://github.com/golang/go/issues/24301#issuecomment -377601170 by @ stevvooe。]

応答[ https://github.com/golang/go/issues/24301#issuecomment-377602765 by @rsc]は新しい問題で詳細を尋ねましたが、その問題は提出されていないようです。

特別なvgo-v1-lockタグを追加することを提案します。

[ https://github.com/golang/go/issues/24301#issuecomment -377662150 by @ kybin。]

最初は魅力的なように見えますが、おそらく引き受ける価値のない特別なケースにつながります。 https://github.com/golang/go/issues/24301#issuecomment-384344659での完全な応答。

ベンダーなしで深い依存関係にパッチを当てるにはどうすればよいですか?

[ https://github.com/golang/go/issues/24301#issuecomment -378255833 by @ chirino。]

応答[ https://github.com/golang/go/issues/24301#issuecomment-378261916 by @ kardianos。]置換ディレクティブを使用する。

モジュール名の変更についてはどうしますか?

[ https://github.com/golang/go/issues/24301#issuecomment -379020339 by @ jimmyfrasche。]

応答[ https://github.com/golang/go/issues/24301#issuecomment-379307176 by @ rsc。]
これらは、vgo提案が直接対処しようとしない実際の既存の問題ですが、最終的には明らかに対処する必要があります。 コードが消える答えは、キャッシュプロキシ(ミラー)とそれらを信頼する理由を用意することです。 それは将来の仕事です。 (または、必要に応じてトップレベルプロジェクトでベンダーを使用します。)コード移動の答えは、タイプエイリアスがタイプリダイレクトであるのと同じように、モジュールまたはパッケージリダイレクトの明示的な概念を追加することです。 それも将来の仕事です。

ローカルGitサーバーへの接続はどうですか?

[ https://github.com/golang/go/issues/24301#issuecomment -383168012 by @ korya。]

直接gitアクセスが計画に追加されました。 #24915を参照してください。

バイナリのみのパッケージはどうですか?

[ https://github.com/golang/go/issues/24301#issuecomment -382793364 by @ sdwarwick。]

バイナリのみのパッケージは、GOPATH / pkgへのある種の帯域外インストールの限られた状況でのみサポートされてきました。 Go getは、バイナリのみのパッケージのフェッチとインストールをサポートしたことがなく、引き続きサポートしません。 バイナリのみのパッケージは、1つの特定のコンパイラと依存関係の1つの特定のコピーでのみ機能します。これにより、サポートできる範囲が大幅に制限されます。 正しい答えは、ほとんどの場合、代わりにソースコードを使用することです。

go.modファイルでpath @ version構文を使用する必要がありますか?

[ https://github.com/golang/go/issues/24301#issuecomment -382791513 by @ sdwarwick。]

これは#24119です。 最初は良い考えのように思えましたが、慎重に検討した結果、違います。

変更https://golang.org/cl/101678はこの問題に言及しています: design: add 24301-versioned-go

この提案は印象的で、私はそれについてのほとんどすべてが好きです。 しかし、メーリングリストに以下の懸念事項を掲載しましたが、返事はありませんでした。 その間、私はvgoのGophers slackチャネルで他の人によって提起されたこの問題を見て、そこでも満足のいく答えを見ていません。

差出人: https ://groups.google.com/d/msg/golang-dev/Plc42fslQEk/rlfeNlazAgAJ

私は、vgo以前の世界とvgoの世界の間の移行パスがうまくいかないことを最も心配しています。 スムーズな移行パスがないと、Goコミュニティに大きな苦痛を与えるリスクがあると思います。 明らかに、移行はコミュニティ全体でアトミックにすることはできませんが、これまでにvgoについて書いたことをすべて理解していれば、広く使用されている既存のパッケージがvgo以前のツールと投稿の両方で使用できない場合があります。 -vgoツール。

具体的には、メジャーバージョンが2以上のリリースにすでにタグを付けている既存のパッケージは、go.modファイルがあり、/ vN拡張インポートパスでインポートされるまでvgoでは機能しないと思います。 ただし、これらの変更がリポジトリに行われると、vgo以前のパッケージの使用が中断されます。

これにより、ダイヤモンドの中央にある2つの兄弟パッケージが共通のv2 +パッケージをインポートするという、別の種類のダイヤモンドインポートの問題が発生するようです。 兄弟パッケージは、vgoまたはpre-vgoツールを使用しているかどうかに関係なく、ダイアモンドの上部にあるパッケージがビルド不可能な状態になるのを防ぐために、アトミックにvgoインポートパスを採用する必要があるのではないかと心配しています。

このシナリオでの移行パスを説明するものはまだ見ていません。

提案は次のように述べています。

モジュール対応ビルドは、v0またはv1セマンティックバージョンでタグ付けされている場合、非モジュール対応パッケージ(go.modファイルを含むツリーの外部にあるパッケージ)をインポートできます。 また、v0.0.0-yyyymmddhhmmss-commitの形式の「疑似バージョン」を使用して特定のコミットを参照することもできます。 疑似バージョン形式では、タグなしのコミットと、v2以降のセマンティックバージョンでタグ付けされているが、セマンティックインポートのバージョン管理規則に準拠していないコミットを参照できます。

しかし、モジュールに対応していないパッケージが、推移的な依存関係> = v2のモジュールに対応したパッケージをインポートする方法がわかりません。 それはまだ対処されていない方法で生態系の断片化を引き起こすようです。 推移的な依存関係のどこかにパッケージ> = v2を持つモジュール対応の依存関係があると、ビルドを機能させ続けるために、すべての依存関係もvgoを採用するように強制されるようです。

更新: https ://github.com/golang/go/issues/24454も参照してください

Goプロジェクトは、プロジェクトの開始からこの規則を奨励していますが、この提案はより多くの歯を与えます。パッケージユーザーによるアップグレードは、パッケージ作成者がインポート互換性ルールに従う場合にのみ成功または失敗します。

これが何を意味するのか、そしてそれが現在の状況からどのように変化するのかは私にはわかりません。 これは現在の状況も説明しているように思われます。このルールに違反すると、アップグレードとgo-getが失敗します。 AIUIは実際には何も変わらないので、少なくとも「より多くの歯」についての言及を削除することをお勧めします。 もちろん、この段落が、破損にペナルティを科す/防止するための追加のメカニズムがあることを意味することを意図していない限り、

これは、初期化中に別のパッケージに登録されるデータベースドライバーや画像形式などにも影響します。これは、同じパッケージの複数のメジャーバージョンがこれを実行する可能性があるためです。 そのすべての影響がどうなるかは私にはわかりません。

メジャーバージョンがv0またはv1の場合、バージョン番号要素を省略する必要があります。 それ以外の場合は含める必要があります。

どうしてこれなの? リンクされた投稿では、これが開発者が重大な変更を行ったときに代替パスを作成するために現在行っていることであるという理論的根拠のみがわかりますが、これは、開発者がバージョンを処理しないツールを最初に計画していないという事実の回避策です。 新しいプラクティスに切り替える場合は、新しいvgo対応パッケージにv0またはv1が含まれることを許可し、奨励(または義務化)してみませんか? バージョンのないパスは混乱の機会にすぎないようです。 (これはvgoスタイルのパッケージですか?モジュールの境界はどこにありますか?など)

私は一般的にこの提案が好きですが、インポートパスにメジャーバージョンを要求することに固執しています。

  1. go.modからメジャーバージョンがすでにわかっている場合は、DRYの原則に違反します。 2つの間に不一致がある場合に何が起こるかを理解することも直感的に理解するのは難しいです。
  2. v0v1の不在を許可するという不規則性も、直感的ではありません。
  3. 依存関係をアップグレードするときにすべてのインポートパスを変更するのは、面倒な可能性があります。

moauthの例のようなシナリオは実行可能である必要があることを理解していますが、より一般的なシナリオで物事を単純に保つことを犠牲にしていないことを願っています。

まず第一に:印象的な仕事!

私にはまったく不明確で、少し過小評価されているように思われることが1つあります。

この提案にzipファイルがあるのはなぜですか?

レイアウト、制約、および作成時やライフサイクルの管理方法、サポートが必要なツール、リンターなどのツールがどのように相互作用するかなどの複数のユースケースも、提案でカバーされていないため、不明です。

したがって、この提案の範囲内でまったく議論しない場合は、ここでまだ書かれていない後の提案を参照してzipという単語を削除するか、提案テキストから全体を削除することをお勧めします。

これについて後で議論することで、さまざまな対象者がここでより良い貢献をすることもできます。

疑似バージョン(v0.0.0-yyyymmddhhmmss-commit)のタイムスタンプに使用されるタイムゾーンはどれですか?

編集:
https://research.swtch.com/vgo-moduleに記載されているように、UTCで表示されます。

@rsc Cの依存関係に対処しますか?

最小限のバージョン選択により、破損しない変更の伝播が非常に遅くなるようです。 プロジェクトA、B、Cで使用される人気のあるライブラリFooがあるとします。誰かがAPIを変更せずにFooのパフォーマンスを向上させます。 現在、アップデートの受信はオプトアウトプロセスです。 プロジェクトAがFooをベンダー化したが、BとCがそうではなかった場合、作成者はAへのベンダー依存関係を更新してprを送信するだけで済みます。シチュエーション。 これは、セキュリティ更新の場合はさらに問題があります。 一部の放棄された/小さい/あまりアクティブでないプロジェクト(ライブラリではない)が古いバージョンのx / cryptoに直接依存していると宣言した場合、そのプロジェクトのすべてのユーザーは、プロジェクトが更新されるまで、場合によっては永久にx / cryptoの欠陥に対して脆弱になります。 現在、このようなプロジェクトのユーザーは最新の修正バージョンを受け取るため、セキュリティ状況が悪化します。 IIRCは、メーリングリストの議論でこれを修正する方法についていくつかの提案がありましたが、私が知る限り、この提案はそれについて言及していません。

IIRCは、メーリングリストの議論で[セキュリティパッチの入手]を修正する方法についていくつかの提案がありましたが、私が知る限り、この提案はそれについて言及していません。

go get -pの説明を参照してください。

go get-pの説明を参照してください。

私はそれを見ましたが、これはまだオプトインメカニズムです。
私は、ライブラリが以前のすべてのリリースを安全でないものとしてマークし、ユーザーにgo get -pを実行させるか、安全でないライブラリに明示的にオプトインする方法を考えていました。

今日私たちが知っているgo getのサポートが非推奨になり、最終的に削除される場合、(タグなしの)Goバイナリをフェッチしてインストールするための推奨される方法は何ですか? 最初にプロジェクトをgit clone 'してから、バイナリをインストールするために手動go installを実行する必要がありますか?
$GOPATHが非推奨になった場合、これらのバイナリはどこにインストールされますか?

@leonklingele :私の理解では、逆にgo getは非推奨にはなりません。
自動で透過的なバージョン管理機能で強化されます。 プロジェクトがタグなしプロジェクトに依存している場合は、マスターを取得して、この正確なバージョンで「ベンダー」にします。
繰り返しになりますが、vgoについて少し読んだことによる私自身の理解です。 私はまだそれを完全に理解する過程にあります。

これが一般的なGitリポジトリでの作業の流れにどのように影響するのか、また提案からのこの文に基づいて作成するのだろうか。

メジャーバージョンがv0またはv1の場合、バージョン番号要素を省略する必要があります。 それ以外の場合は含める必要があります。

現時点では、マスター(私にとってこれには短命の機能ブランチが含まれます)で作業し、時々新しいバージョンでコミットにタグを付けるのが一般的であるようです。 ライブラリのv2をリリースするとすぐに、このワークフローがGoモジュールでより混乱するように感じます。これは、 masterv2のブランチがあるためです。 masterが現在のブランチであり、 v2がメンテナンスブランチであると期待しますが、それはまったく逆です。

デフォルトのブランチをmasterからv2に変更できることは知っていますが、新しいメジャーバージョンをリリースするたびにそれを更新するタスクが残っています。 個人的には、 masterv1のブランチが欲しいのですが、これが提案にどの程度正確に適合するかはわかりません。

新しいメジャーリリースはチャーンを引き起こします。 新しいリリースを作成するたびにGitリポジトリ(デフォルトのブランチ)の1つの設定を変更する必要がある場合、ライブラリのユーザーが新しいバージョンに切り替える場合に比べて、コストはごくわずかです。

提案のこの側面は、適切なインセンティブを設定すると思います。それは、上流の作成者に、下位互換性のある方法で変更を行い、全体的なエコシステムの解約を減らす方法について考えるように促します。

今、私はマスターとv2ブランチを持っています

代わりに、masterにv2/サブディレクトリを作成できます。

@mrkanister

マスターとv1ブランチが欲しいのですが、これが提案にどの程度正確に適合するかはわかりません。

https://research.swtch.com/vgo-moduleの私の理解によると、vgoはバージョンを識別するためにブランチではなくタグを使用します。 したがって、タグが正しいブランチとコミットを指している限り、マスターで開発を続け、v1からブランチすることができます。

新しいメジャーリリースはチャーンを引き起こします。 新しいリリースを作成するたびにGitリポジトリ(デフォルトのブランチ)の1つの設定を変更する必要がある場合、ライブラリのユーザーが新しいバージョンに切り替える場合に比べて、コストはごくわずかです。

これは私が過去に一生懸命に噛んだと思う問題のある考え方です。 1つのプロジェクトの1人の場合、デフォルトのブランチを切り替えるのは今のところ簡単です。 しかし、ワークフローの慣習に反することは、特に複数の言語で作業する場合、人々が忘れることを意味します。 そして、これは、Goが、新参者が学ばなければならないことをまったく異なる方法で行う方法のもう1つの奇妙な例になります。 一般的なプログラマーのワークフローの慣習に反することは、_まったく_マイナーなコストではありません。

一般的なプログラマーのワークフローの慣習に反することは、決して小さなコストではありません。

従来の道をたどらないことが、イノベーションに必要な条件となる場合があります。

提案の一部を正しく理解していれば、サブディレクトリや新しいブランチを作成する必要はありません。 go.moduleをライブラリの正しいインポートパスに更新することを確認する限り、潜在的にマスターブランチとgitタグのみをリポジトリに0.0、1.0、2.0などに設定できます。

@mrkanister devの場合、マスター(または任意のdevブランチ)のクローンを作成し、「replace」ディレクティブ(vgo-tourを参照)を使用してそれを指すと思います。 (私があなたの意味を理解しているなら、確かではありません)。

@rscロードマップと今何をすべきかについてもっと正確にお願いしたいと思います。
Goポリシーに従い、3か月(現在は2か月)にvgo​​をフリーズする機能を備えていますか?
巡礼者のバトンですべてのlibsメンテナにgo.modファイルを追加するように依頼する必要がありますか、それとも提案が正式に受け入れられるのを待つ必要がありますか(名前と構文が変更されないようにするため)?

@flibustenetツールは1.0ポリシーの対象外であるため、何でも変更できます。

https://golang.org/doc/go1compat

最後に、Goツールチェーン(コンパイラ、リンカ、ビルドツールなど)は活発に開発されており、動作が変わる可能性があります。 これは、たとえば、ツールの場所とプロパティに依存するスクリプトがポイントリリースによって破損する可能性があることを意味します。

提案からも

計画は、提案の承認を条件として、Go 1.11のモジュールサポートを、まだ変更される可能性のあるオプション機能としてリリースすることです。 Go 1.11リリースでは、ユーザーがモジュールを「実際に」使用して重要なフィードバックを提供する機会が与えられます。 詳細は変更される可能性がありますが、将来のリリースではGo1.11互換のソースツリーを使用できるようになります。 たとえば、Go 1.12は、それまでにファイル構文やファイル名が変更された場合でも、Go 1.11go.modファイル構文を使用する方法を理解します。 今後のリリース(Go 1.12など)では、モジュールのサポートが完了したことを宣言します。 今後のリリース(Go 1.13など)では、非モジュールのgogetのサポートを終了します。 GOPATHでの作業のサポートは無期限に継続されます。

フィードバックをお寄せいただきありがとうございます。

@AlexRouSg

https://research.swtch.com/vgo-moduleの私の理解によると、vgoはバージョンを識別するためにブランチではなくタグを使用します。 したがって、タグが正しいブランチとコミットを指している限り、マスターで開発を続け、v1からブランチすることができます。

あなたは正しいです、これは以前と同じように機能し続けます(確かに再確認するだけです)、良いキャッチです!

それが邪魔にならないので、私(そして明らかに他の人)が理解していないのは、 v1パッケージの存在を禁止する理由です。 インポートの最後に/v1を使用してインポートしようとしましたが、インポートするパッケージのgo.modに追加しましたが、 vgov1という名前のフォルダーを検索します。代わりに

@mrkanister
インポートパスでv1またはv0を許可しない主な理由は、互換性のあるパッケージのバージョンごとにインポートパスが1つだけであることを確認するためだと思います。
/ v1の代わりにプレーンインポートパスを使用すると、移行が容易になるため、最後に/ v1を追加するためにすべてのインポートパスを更新する必要はありません。

こんにちは、

提案の多くのポイントは歓迎されており、時間の経過とともに出現した大規模なGoコードベースを使いこなすのに役立ちますが、「最小限のバージョンを使用する」ルールは非常に有害です。

  • コードエコシステムを進歩させたい。 つまり、新しいバージョンをテストして使用し、問題が発生する前に問題を早期に検出する必要があります。
  • セキュリティの問題を修正する新しいモジュールリリースをできるだけ早く適用したい
  • セキュリティの問題を修正する新しいモジュールリリースをできるだけ早く適用できるようにする必要があります。 それらは、セキュリティ修正で常にタグ付けされているわけではありません。 新しいリリースを回避する場合は、それらの修正も回避します
  • 新しいリリースにセキュリティ修正が含まれていない場合でも、変更を早期に適用することは、セキュリティ修正を含む次のリリースが公開されたときにvetへの変更が少なくなることを意味します(そして、そのようなリリースが公開されたときに最後に必要なことは、迅速に行うことは、これまで見たことのない中間的な変更に行き詰まることです)。
  • 中間リリースを適用することは、互換性を破る場合にのみ有害であり、互換性を破るべきではありません。また、互換性を破る場合は、次のリリースの習慣にする前に、それを検出してモジュールの作成者に伝えることをお勧めします。必要。
  • 古い依存関係のバージョンがまだ指定されており、マニフェストを更新する時間がないため、古いコードがあなたを引きずり下ろすのは望ましくありません。 メジャーリリースの最新バージョンを使用すると、他のコードエコシステムでこの社会的ニーズに対応できます。開発者に最新バージョンのテストを強制し、「より重要な」(つまり、より楽しい)ことを行うために手遅れになるまで延期しないでください。

    • 理論的には、無制限の数のモジュールバージョンを出荷できるため、すべてのコードで必要なバージョンを使用できます。実際には、同じdepを使用する2つのモジュールを作成したらすぐに、バージョンを選択する必要があるため、より複雑になります。ソフトウェアは、複数のバージョンを許容することが少なくなります。 それで、あなたはすぐに、護送船団全体を遅くするストラグラーをどうするかという古い問題にぶつかりました。 私は、ストラグラーに「あなたは正しい、好きなだけゆっくり行く、誰もがあなたを待つだろう」と言ってこの問題を管理する人間の文化に出会ったことはありません。 それは素晴らしく利他的かもしれませんが、生産的ではありません。

人間の慣性と戦うことは困難で苦痛であり、それが楽しいからではなく、進歩する必要があるため、私たちはそれと戦っています。 問題を回避し、人間にもう少し先延ばしにするように促す快適なツールを作成することは、プロジェクトの沈降と技術的負債の蓄積を加速するだけで、まったく役に立ちません。 githubにはすでに数十のGoプロジェクトがあり、そのほとんどのreadmeは、重要な修正を行ったためにユーザーにアップグレードを懇願する作者に捧げられています。デフォルトで最も古いリリースに設定すると、問題が一般化されます。

適切なルールは、「すべての中間コミットではなく、メジャーリリースと一致する最新リリースを使用する」ことです。 それは今後の妥協と安定性になります。 コードベースを最もよく知っている元のプロジェクトをコマンドに入れ、ユーザーを新しいコード状態に切り替えるタイミングを適切に決定できます。

メーリングリストからコピーされた私の未回答の質問:

ほとんどの開発者は、さまざまなメジャーバージョンがさまざまなブランチに存在する通常の「メジャーブランチ」規則に従うことを好むと予想されます。 この場合、v2ブランチのルートディレクトリには、次のようにv2を示すgo.modがあります。

どちらもvgoでサポートされているサブディレクトリとこの主要なブランチ規則があるようです。 私の逸話的な経験では、Goや他の言語でこの規則に従うリポジトリはありません(最近は比較的使用されていないように見えるgopkg.inによって強制されたもの以外のリポジトリを実際に考えることはできません)。 マスターブランチは最新のものであり、その履歴にはv2.3.4タグがあります。 タグは、(マイナーバージョンだけでなく)すべてを分離するために存在します。 古いバージョンにパッチを適用する必要がある場合は、最後のv1タグからブランチが一時的に作成され、コミットがプッシュされ、新しいタグがプッシュされ、ブランチがまとめて削除されます。 バージョンのブランチはありません。現在のmaster / dev / featureブランチとバージョンタグだけです。 Gitでは「すべてが参照」であることは知っていますが、他のVCSの場合、区別はそれほど曖昧ではない可能性があります。

そうは言っても、私は上記のワークフローをvgo(v2.0.0、v2.0.1と言うタグがあり、ブランチがない)でテストしましたが、機能しているようです。 だから私の質問は:これは今は機能しますが、それは意図されていますか? ブログの他の2つのワークフローほど完全には説明されていないようで、v2 / v3 ...ブランチなしで作業することは、上で説明したように私が一度も行ったことがないので、誤って機能が失われないようにしたいのです。これ(または他の)が投稿でワークフローを説明しているのを見て、誰でも(特にGoコミュニティの外で)大規模に採用されました。

もちろん、私の議論は好みと逸話に帰着しているので、必要に応じてすべての言語でこれを証明するために、いくつかのレポスクレイピングを喜んで行います。 これまでのところ、私は提案の投稿が本当に好きで、一般的に変更に参加しており、引き続きvgoをフォローして遊んでいきます。

すべての努力に感謝します。

誰かがMVSの提案された代替モデルがアップグレードケイデンスを改善するためにどのように機能するかを明確にすることができますか? はっきりしないから。 代替(広く使用されている)モデルについての私の理解は

  • 開発者は手作りのマニフェストを作成し、使用されているすべての依存関係のバージョン制約を一覧表示します
  • 開発者は$ solverを実行します。これにより、ロックファイルが作成され、指定された制約を満たす推移的な依存関係バージョンの選択されたサブセットが一覧表示されます。
  • このロックファイルはコミットされ、ビルドおよびインストール時に再現可能なビルドを保証するために使用されます
  • 依存関係の新しいバージョンがリリースされて使用されると、開発者はマニフェストを更新し、ソルバーを再実行して、新しいロックファイルを再コミットする可能性があります。

私が理解しているように、提案されたMVSモデルは

  • 開発者は、モジュール内のインポートパスのセットに基づいて、 go.modを自動生成し、推移的な依存関係の現在最新バージョンを選択します
  • go.modはコミットされ、ビルド時とインストール時にバージョンの下限を取得するために使用されます。 MVSは再現性のあるビルドを保証します
  • 依存関係の新しいバージョンがリリースされて使用されると、開発者はvgo get -uを実行します。これにより、推移的な依存関係の最新バージョンがフェッチされ、 go.modが新しい下限で上書きされます。 その後、送信されます。

何かを見落とさなければならないようで、誰かが何を指摘してくれると助かります。 この理解は、正確なバージョンと実際のビルドで使用されているロックファイルを指定していることを意味しているように思われるため、MVSは、一般にバージョンを抑えることができないため、アップグレードのリズムを上げるのに適しています。

明らかに私は何かが欠けています(そして約5mで愚かになるでしょう)、それは何ですか?

@tpng

/ v1の代わりにプレーンインポートパスを使用すると、移行が容易になるため、最後に/ v1を追加するためにすべてのインポートパスを更新する必要はありません。

これ実際には必要ないはずです。 例を挙げましょう:

ユーザーは現在、依存関係マネージャーとアップストリームリポジトリのタグによって固定されたライブラリのv1.0.0などを使用しています。 ここで、アップストリームはgo.modを作成することを決定し、モジュール/v1も呼び出します。 これにより、新しいコミットと新しいタグが作成されます(例: v1.0.1 )。 vgoはそれ自体で依存関係を更新しようとはしないので、これはユーザーにとって何も壊さないはずですが、ユーザーはインポートパスを変更することで意識的に更新できます(pr vgoはそれを行うことができます)彼/彼女のために)。

インポートパスでv1またはv0を許可しない主な理由は、互換性のあるパッケージのバージョンごとにインポートパスが1つだけであることを確認するためだと思います。

はい、私は確かに、図書館の新しいユーザーを混乱させないという点を理解できると思います。

メジャーバージョンがv0またはv1の場合、バージョン番号要素を省略する必要があります。 それ以外の場合は含める必要があります。

誰かがこの背後にある理由を説明できますか? ライブラリのユーザーとして、v1をまだ使用したくない場合はどうすればよいですか。これは、セマンティックバージョニング(新しいメジャーバージョン)ではまったく問題ない重大な変更が導入されたためです。

不安定な/未完成のパッケージを示すバージョン1より前のバージョンのみを省略したいと思います。 バージョン1から、安定したリリースを入手できるという事実に頼ることができるようにしたいと思います。 インポートパスでv1を省略すると、絶えず変化するライブラリを追跡しているのか、安定したバージョンを追跡しているのかわからないため、混乱を招きます。 これは、v1が最初の安定したリリースを特定するセマンティックバージョン管理スキームでもうまく機能しないと思います。これは、そのバージョンをバージョン0.xと明確に区​​別するために使用されます。

@kaikuehne

ライブラリのユーザーとして、v1をまだ使用したくない場合はどうすればよいですか。これは、セマンティックバージョニング(新しいメジャーバージョン)ではまったく問題ない重大な変更が導入されたためです。

私が理解している限り、 vgoは、パッチバージョンであっても、それ自体で依存関係を更新することはありませんが、代わりに、これを意識的な決定として残します。 したがって、ライブラリのv0.4.5(タグが付いている)に依存している場合は、理論的にはそれを永久に使用し続けることができます。 go.modファイルにバージョンを手動で固定することもできます。

私が使用する別の依存関係が同じパッケージに依存しているが、バージョンv1に依存している場合はどうなりますか? 両方のパッケージは、同じインポートパスを使用してインポートされます。 それらを同じバイナリにコンパイルするときに競合はありませんか?

v1もインポートパスの一部にする必要がある場合は、両方が異なるパッケージとして扱われます。

@kaikuehneすると、動作する最小限の共通バージョンに更新されます。 (私の理解では)

@kaikuehne私はあなたの推論を理解していません。 あなたはv0を使用しているので、おそらくあなたは重大な変更で大丈夫です。 安定性が保証されていないバージョンをすでに使用しているのに、v1が壊れた場合に問題になるのはなぜですか? さらに、ブレークを変更してv0.1-> v1.0に移行する代わりに、アップストリームはブレークをv0.2に追加してから、(ブレークしない)v1.0リリースするとします。 これは、セマンティックバージョンに関する期待の範囲内であるように見えますが、(使用するパッケージマネージャーに関係なく)まったく同じ量の労力になります。 つまり、「作成者がAPIの中断を突然停止した」ことが、1.0より前のリリースの使用によって引き起こされたのではない問題を構成する方法を本当に理解していません。

言い換えると、v0.xを使用することで、v0。(x + 1)によってコードの修正が強制される可能性があることに同意したことになります。 代わりにv0。(x + 1)がv1.0と呼ばれる場合、なぜ問題になるのですか?

議論のポイント4:インポート互換性ルールを明示的に採用し、「新しいパッケージは古いパッケージと下位互換性がなければなりません」...

私の場合、セキュリティパッケージhttps://github.com/microcosm-cc/bluemondayを持っていて、最近(昨年末)、公共の機能が基本的に目的に適していないことを知ったシナリオがありました。 だから私はそれを削除しました。

この提案では、関数を削除するとバージョンがバンプされ、安全でない/安全でないコードが削除されることはありません。

それを避けるために、おそらく代わりに、削除したいfunc内のlog.Fatal()を使用します。これは、既存のコードが安全でないエンドポイントを使用しないようにするためですが、互換性を維持するためです。

これらのどちらも理想的ではないことを考えると...パブリック関数を非推奨にする必要のあるセキュリティ修正が処理されることをどのように予測しますか? (ランタイムlog.Fatal()で開発者を驚かせない場合は?)

このためのコミットを見たい人のために: https ://github.com/microcosm-cc/bluemonday/commit/a5d7ef6b249a7c01e66856b585a359970f03502c

@Meroviusバージョン0.xを使用する際の説明に感謝します。 あなたが言ったように、1.0より前のバージョンを使用するときに依存する保証はなく、バージョン0.xはsemverの特殊なケースです。 私が正しく理解していれば、概説されたルールは実際にはバージョン0.xにはまったく適用されません。 私の質問は、この違いをコードにも反映することが理にかなっているのかどうかです。特にパッケージに名前を付ける場合はそうです。 たとえば、パッケージがバージョンのないパッケージのみをインポートした場合、不安定なコードに基づいて構築されていることが一目でわかります。 すべてのインポートにバージョンv1が含まれている場合は、安定したバージョンを使用していることがわかります。

@ buro9この提案は、セキュリティ関連のAPI破損の免除を含むgo1互換性保証に大まかに従うことを提案しています。

@kaikuehneありがとう、それはあなたの懸念を明らかにします。

私が懸念している機能の相互作用があります(私が物事を正しく理解していると仮定して)。

修正されたバージョン(タグから派生した合成インポートパス要素ではなく、ソース内のリテラルvNディレクトリ)を使用するモジュールMがあり、Mの複数のメジャーバージョンに推移的に依存するプログラムPを構築している場合は、一部のシナリオでは、最小限のバージョン選択に違反する必要がありますか?

つまり、PがMのメジャーバージョン2、3、および4に依存しているとします。Mのメジャーバージョンごとに、最小限の完全なバージョンが指定されています。 Mのバージョンは、タイプエイリアスで同じタイプ定義を透過的に使用するなどの明確な目的でソースを共有するため、メジャーバージョンごとに1つのコピーではなく、3つのメジャーバージョンすべてにMのコピーを1つだけ含めることができます。 1つのメジャーバージョンの完全バージョンを選択すると、他の2つのメジャーバージョンの完全バージョンの選択が修正され、他のメジャーバージョンの一方または両方に非最小バージョンが選択される可能性があります。

vgoはこれをどのように処理しますか? これは、時々最小よりわずかに少ないこと以外の問題を引き起こす可能性がありますか? (ソリューションを生成しない、またはソルバーをループさせるモジュールのセットを誤って構築する可能性があるように?)

@jimmyfrasche

メジャーバージョンディレクトリを使用している場合、vgoは引き続きタグを使用し、そのタグの一致するバージョンフォルダのみを取得します。 たとえば、バージョン2、3、4に依存しています。vgoはタグv2.nm、v3.nm、v4.nmをチェックアウトします
そして、タグv2.nmからv2フォルダーのみを取得します。 したがって、最終的にはすべてがまだタグをフォローしています。

このメーリングリストの投稿で質問しましたが、具体的な答えは見当たりません。 ここで繰り返します:

protobufsやcファイルなどのGo以外のリソースはどうなりますか? これがあなたの投稿ですでに回答されている場合はお詫びしますが、protobufファイルのインポートパスを配布および設定するためにベンダーパスを使用します。 事前にコンパイルされたprotobuf出力に対してGoパッケージをコンパイルしますが、ベンダーの依存関係に依存するprotobufファイルから新しいGoパッケージをコンパイルする場合も考慮する必要があります(つまり、別のprotobufファイルからrpc.Statusを参照します)。 その説明が密すぎる場合は、より具体的な例をいくつか提供できます。

具体的には、 protobuildというプロジェクトがあります。これを使用すると、protobufファイルのインポートをGOPATHの場所にマップできます。 この提案がGOPATH内のリソースの解決をどのように処理し、それを他のコンパイラーインポートスペースにどのようにマップできるかがわかりません。

これは私たちにとってプロトバフを扱う上での大きな問題であり、このプロジェクトはそれらの問題の多くを軽減しました。 これが提案と完全に相容れないのであれば、それは残念なことです。

繰り返しになりますが、私が見逃したことがある場合はお詫び申し上げます。

私はその提案が大好きです。 あまりにも多くのプロジェクトがマイナーバージョン間に小さな重大な変更を頻繁に導入し、非常に大きな重大な変更のためにのみメジャーバージョンのバンプを予約することを心配しているだけです。 マイナーなバージョン破壊の変更が頻繁に行われる場合、SIVの仮定に違反するため、ダイヤモンドの依存関係の問題が発生します。 インポートステートメントにマイナーバージョンを含めると、より多くのプロジェクトがノーブレーク変更契約に準拠するのに役立つのではないかと思います。 欠点は余分なインポートチャーンであり、マイナーバージョンの更新はより困難になります(そしてより明確になります)。

これは私が持っている別の質問を提起します:ビルドに1つ以上のバージョンのパッケージがあるかどうかを判断するのは(今日)vgoで簡単ですか? 同じパッケージの2つのバージョンを許可することは、前進するために重要ですが、ほとんどのプロジェクトは、initの予期しない副作用の可能性があるため、一時的でない限り、これを避けたいと思うようです。 これをチェックする簡単な方法があると便利な場合があり、一部のプロジェクトではコードチェックイン時に強制する必要があります。

あまりにも多くのプロジェクトがマイナーバージョン間に小さな重大な変更を頻繁に導入し、非常に大きな重大な変更のためにのみメジャーバージョンのバンプを予約することを心配しているだけです。

重大な変化は重大な変化です。 小さくしたり大きくしたりすることはできません。 そのようなパッケージは、信頼性が低く、semverに従わないため、最終的にコミュニティによって拒否されると思います。 彼らがsemverに従い、42.xxのような大きなメジャー数にすぐに到達したとしても、とにかく使用するのは非常に不便です。 したがって、多くの重大な変更を加えたい場合は、メジャー番号0を使用し続けます。これにより、現在のgo getと同じように機能し続け、同じ問題が発生します。 0以外のメジャーバージョンをリリースした後にAPIを試してみたい場合は、これらの実験を移動して、永久メジャー0の「実験的」パッケージを分離し、「小さな重大な変更」を終えたらメインパッケージのメジャーをインクリメントして、最終的に次の安定したAPIを取得します。

インポートパスにマイナーを含めると、semverのイデオロギーに違反し、メジャーを含める以上の新機能は提供されません。

semverのセマンティクスを考えると、それが作成者が行うべきことであることは理解していますが、マイナーバージョン間のマイナーな重大な変更は、バージョン1をすでに過ぎた人にとって一般的で魅力的なケースであるというのが私の恐れです。私の逸話的な経験では、パッケージの作成者はそうではありません。 semverの正確なセマンティクスに従い、多くの場合、企業はマーケティング目的でメジャーバージョンのバンプを予約します。 ですから、私の魅力は、何が理想的であるかではなく、semverである厄介な人間の現実にうまく対処するために特定の変更を加えることが実用的であるかどうかについてです。

おそらく、semverに従わないパッケージのマイナーバージョンをオプションで含めることさえ可能であり、おそらくそれは提案全体を台無しにするでしょう、私はそれをもっと考える必要があるでしょう。 私はこれがより良い方法であるとは提案していませんが、輸入にマイナーバージョンを含めるか、含めることを義務付けるかのトレードオフをさらに調査することに興味があるだけです。

ここで、goコーパス(および明らかな重大な変更を探すツール)からより良いデータを生成して、semverタグを使用する既存の人気のあるプロジェクトの中でsemverがほとんどフォローされていると言われる頻度を判断することが可能です。

vgoプロポーザルを使用すると、メジャーバージョンでAPIの変更を適切に解除できます。 それ自体は、それらを防ぐために何もしません。

vgoプロポーザルでは、あるメジャーバージョンが別のメジャーバージョンを参照できるため、コードを適切に再利用できます。 それを強制することは何もしません。

vgo MVSプロポーザルでは、新しいパッケージに更新できます。 更新を強制することはありません。


vgoの世界ではるかに簡単に構築できるものは次のとおりです。

  1. モジュールホストにプッシュする前に、APIブレーキの変更をキャッチするツール。 各バージョンはzip形式であり、多くの異なるvcsツールやコマンドなしで比較できます。
  2. セキュリティ問題レジストリ。 付加価値のためのモジュールホスティングと一緒にホストします。 ツールは、手動または自動でgo listと同様にそれらをクエリし、クエリによってフィルタリングされた問題の通知を受け取ることができます。

vgoは、次の方法でこれらを簡単にします。

  • 問題スペースの制約(zipファイルでのみ機能し、API比較を行うために任意のgit / hg / svn履歴を保存する必要はありません)。

    • 問題空間の定義(MVS、バージョン定義)

  • ビルド部分のツーリング。

vgoは1つの主要な原則に基づいて動作します。つまり、単一の入力セットは常に同じものを構築する必要があります。 セキュリティ更新をキャッチするためにランダムな再構築に依存している場合、それは間違っています。 プロジェクトのメンテナーとして、一部のGoプロジェクトは、再構築せずに何年も実行されます。 タイムリーなセキュリティ更新が重要であることに同意します。vgoはこのニーズのビルド部分を満たします。

vgoが許可するものとvgoが何であるかを混同しないでください。

@ pbx0これがそのような議論に適した場所かどうかはわかりませんが、おそらくメーリングリストの方が適しています。 いずれにせよ、メジャー番号を変更せずに変更を壊すことが起こります。 たまにでも。 Semverは、このケースについてFAQで回答しています。

セマンティックバージョニングの仕様に違反していることに気づいたらすぐに、問題を修正し、問題を修正して下位互換性を復元する新しいマイナーバージョンをリリースします。

しかし、ここには改善の余地があると思います。 自動APIチェッカー(おそらくすでに存在しているものもあります)を実装するのは簡単なはずです。これは、godoc.orgにリストされているすべてのパッケージを取得し、定期的に新しいバージョンをチェックします。新しいバージョンが検出された場合、チェックは以前のバージョンと互換性があります。 semverタグを使用し、メジャーが変更されていない場合のバージョンのAPI。 次に、互換性のない変更が検出された場合は、作成者に連絡してみてください。おそらく、githubで問題を自動開くか、githubアカウントからのメールを使用してください。 これは考えられるすべてのケースを網羅しているわけではありませんが、コミュニティにとって非常に役立つ場合があります。

私はパスを使用してメジャーバージョンをスコープすることを固く信じており、私のサポートであるFWIWを表明したいと思いました。

1年前、このようなインポートパスにバージョンを配置することは、醜く、望ましくなく、おそらく回避可能であると信じていました。 しかし、この1年間で、私はそれらがシステムにどれほどの明快さと単純さをもたらすかを理解するようになりました。

ほぼ20年前、私はスタートアップにVCSが必要で、約10種類のVCSを試しました。 ディレクトリを使用してブランチを公開したため、Perforceをすぐに除外しました。 したがって、v2ブランチはすべて同じコードになりますが、v2フォルダーの下にあります。 私はこの考えが嫌いでした。 しかし、他の9つでパイロットを実行した後、ローカルファイルシステムに両方のバージョンのブランチを作成したいと思うことがよくありました。Perforceではそれが簡単になり、他のバージョンでは驚くほど複雑になりました。 ファイルシステムは私たちの封じ込めの比喩です。 使ってみよう。

提案から:

プロキシからGoモジュールをフェッチするためのURLスキーマを定義します。これは、カスタムドメイン名を使用してモジュールをインストールする場合と、$ GOPROXY環境変数が設定されている場合の両方に使用されます。 後者を使用すると、企業や個人は、セキュリティ、可用性、またはその他の理由で、プロキシを介してすべてのモジュールダウンロード要求を送信できます。

これについては他の場所で説明しましたが、この提案に関する私の最大の懸念は、今日のベンダーの最大の強みの1つである常に利用可能なコードと完全に再現可能なビルドを破棄する(または少なくとも対処しない)ように見えることです。 提案されたプロキシシステムがこれらの長所に適切に対応したり、それに取って代わったりすることはないと思います。

今日ベンダーを使用するプロジェクトには、GoツールチェーンとGit(または別のバージョン管理システム)のみが必要です。 単一障害点は1つだけです。それはgitリポジトリです。 コードをチェックアウトすると、ネットワークに再度アクセスすることなく、コードを完全に構築および再構築できます。これは、セキュリティ上の重要な考慮事項です。 私たちのほとんどにとって、ベンダープロジェクトには追加のインフラストラクチャは必要ありません。ローカルコンピューターと無料のGitHubアカウントだけです。

vgoのプロキシへの依存は、重要なインフラストラクチャのオーバーヘッドをもたらしますが、これは十分に強調されていないと思います。 新しいインフラストラクチャをプロビジョニング、実装、保守、および監視する必要があります。 これはソフトウェア組織にとっては合理的かもしれませんが、個人や分散型オープンソースプロジェクトにとっては負担になります。 さらに、CIのようなものは、多くの場合、会社の開発環境と同じインフラストラクチャで実行されないTravisCIのようなサードパーティにアウトソーシングされます。 これにより、プロキシインフラストラクチャの再利用が困難になります。

他の言語では、キャッシュプロキシを使用できます。 Pythonは私が最も経験を積んだものであり、私の経験では、Pythonを設定するオーバーヘッドのために使用されることはめったにありません。 Goプロジェクトでこれを簡単にできるかもしれませんが、デフォルトでない場合は、使用頻度が低くなり、実際のGoビルドの可用性が大幅に低下します。 左パッドのNPMイベントの影響は、この点で優れたケーススタディです。

モジュールとプロキシシステムで、独自のプロジェクトのコードと一緒に依存関係をチェックインでき(現在のベンダーと同様ですが、必ずしも同じ実装である必要はありません)、 vgoプロキシ実装で使用できる場合は、私の懸念に対処できます。 しかし、それが意図されているのであれば、提案ではもっと完全に対処する必要があると思います。

@joeshawベンダーディレクトリを引き続き使用して、自己完結型のビルドを作成できます。

提案から:

1つの限定的な使用を除いて、ベンダーディレクトリの使用を禁止します。ビルド中のトップレベルモジュールのファイルツリーの最上部にあるベンダーディレクトリは、引き続きビルドに適用され、自己完結型のアプリケーションリポジトリを引き続き許可します。 (他のベンダーディレクトリを無視すると、Goはビルド全体で各インポートパスが同じ意味を持つビルドに戻り、特定のインポートパスを持つパッケージの1つのコピーのみが特定のビルドで使用されるようになります。)

今日ベンダーを使用するプロジェクトには、GoツールチェーンとGit(または別のバージョン管理システム)のみが必要です。 単一障害点は1つだけです。それはgitリポジトリです。

現在、独自のドメインでパッケージをホストしている場合は、a)git-repositoryをホストし、b)go-getがそれを見つけるために必要な<meta>タグを提供する必要があります。 将来的には、a)vgoがコードをフェッチするために必要な$# .zip $#$ファイルと.jsonファイルを提供する必要があります。 純粋なホスティングに必要な障害のポイントとインフラストラクチャが少ないようです。 もちろん、開発のためにリポジトリをホストする必要がありますが、最悪の場合、以前と同じレベルになるだけでなく、実際に開発している人だけが使用するため、リポジトリ自体のスケーラビリティと信頼性ははるかに低くなります。

したがって、バニティインポートの場合、オーバーヘッドの点で大きな違いはないようです。

OTOHで、バニティインポートを使用していない場合は、 githubが実行しているすべてのインフラストラクチャを無視しています。 ですから、これはリンゴ同士の比較ではないようです。あなたが一番上に出る唯一の方法は、他の人に難しい問題を解決させることです。 しかし、将来それを行うことを妨げるものは何もありません。 AIUI Microsoftやその他の企業は、このタスクにエンジニアリング時間とサービス能力を投資することをすでに志願しています。 将来的には、Goパッケージをホストする作業は、npmパッケージ、gem、またはクレートをホストする作業によってほぼ下限になると思います。githubリポジトリがあり、中央の[これを利用可能にする]ボタンをクリックします。 zipをホストするマネージドサービス。

vgoのプロキシへの依存

個人的には、必要なインフラストラクチャの機能を表す「プロキシ」という言葉は嫌いです。 「ミラー」の方が適切なようです。 ミラープロキシとして実装できますが、選択したWebサーバーによって提供されるファイルの集まりであり、ほぼ無限のスケーラビリティと稼働時間のためにcloudflareの背後に隠されている場合もあります。

他の言語では、キャッシュプロキシを使用できます。

他の言語は、これが実際には問題にならない理由について、完全に優れたモデルとして機能すると私は主張します。 彼らはパッケージをホストするためにパッケージを集中型ホスティングに依存する傾向があります- vgoはこのモデルを非常によくサポートするだけでなく、オプション(したがって、すべての利点を欠点なしで得ることができます)と非常にシンプルになります実装、スケーリング、運用する。


IMO、Goの前後と他の言語で何が起こっているかを直接比較すると、1:1の同等性がたくさんあることは明らかです。 そして、将来的にはもっと努力が必要だと感じる唯一の理由は、既存のインフラストラクチャを当然のことと見なし、新しいインフラストラクチャがまだ存在していないことを確認しているためです。 しかし、そうなることを疑う正当な理由はないと思います。

したがって、バニティインポートの場合、オーバーヘッドの点で大きな違いはないようです。

本当ですが、パッケージの_vast_少数はバニティドメインを使用しているので、これは強力な対位法ではないと思います。 (バニティドメインには他にも実際的な問題があります。それは、GitHubを使用するよりも可用性が_はるかに悪い_傾向があるということです。)

OTOHで、バニティインポートを使用していない場合は、githubが実行しているすべてのインフラストラクチャを無視しています。

はい、正確に! これが私の主張だと思います。 インフラストラクチャと稼働時間を無料またはリーズナブルなコストで維持するためのすばらしい作業をすべて手に入れることができます。 さらに重要なことに、それはあなた自身の時間を含まない。

GitHubがvgo互換のミラーを実行することになった場合、おそらくこれはそれほど問題ではありませんが、すべてのコードを含む単一のGitフェッチ(ユーザーの観点からはアトミックアクション)の優雅さが好きですプロジェクトをビルドする必要があります。

他の言語は、これが実際には問題にならない理由について、完全に優れたモデルとして機能すると私は主張します。 彼らはパッケージをホストするためにパッケージの集中ホスティングに依存する傾向があります-vgoはこのモデルを非常によくサポートするだけでなく、オプションになり(したがって、すべての利点を欠点なしで得ることができます)、実装、スケーリング、および動作します。

問題は、これによりプロジェクトの構築に単一障害点(SPOF)が追加されることです。 コードは、何があっても(そしておそらくGitHubでも)VCSに存在するため、1つのSPOFになります。 他の言語では、集中型リポジトリは2番目のSPOFです。 Goの場合、すべてのインポートパスは追加のSPOF(github.com、golang.org、honnef.co、rsc.ioなど)であり、SPOFを増やすと全体的な可用性が低下します。

ミラーを実行すると、確かに2つに戻る可能性がありますが、私が主張するのはインフラストラクチャであり、存在する必要はありません。 担当者をベンドリングする(またはローカルのオンディスクミラーを使用する)と、これは1つ(VCS)に戻ります。

いずれにせよ、これは論点かもしれません。 私は元々、私の主な懸念を解決するように見えるトップレベルのvendorディレクトリに関する提案の一部を理解していませんでした-それを指摘してくれてありがとう、 @ kardianos-古いものからのきれいな休憩ですがベンダーシステムの方が良いかもしれません。

git grepが大好きなので、「トップレベルのvendor 」が引き続きサポートされる構成であることがうれしいです。

ミラーを実行すると、確かに2つに戻る可能性がありますが、私が主張するのはインフラストラクチャであり、存在する必要はありません。

エンタープライズ開発者はこちら。 おそらく私たちはターゲット人口統計ではありませんが、Goを使用したいと思います。 javaやjavascriptの場合のように、企業内にミラーがなければ、それが起こっていることはわかりません。これにより、今日構築するものはすべて明日構築できるようになります。

エンタープライズ開発者はこちら。 おそらく私たちはターゲット人口統計ではありませんが、Goを使用したいと思います。 javaやjavascriptの場合のように、企業内にミラーがなければ、それが起こっていることはわかりません。これにより、今日構築するものはすべて明日構築できるようになります。

@jamiethermoベンダーは今日あなたのためにそれに対処していませんか?

プロキシまたはミラーのサポートは問題ありません。それがGoの採用に役立つのであれば、私はそれですべてです。 私の懸念は、ローカルの自己完結型ソースツリー(今日はベンダーと呼んでいます)の代わりとしてのミラーでした。

@joeshaw

ベンダーは今日あなたのためにそれに対処しませんか?

さて、私は無知と「コードをどのように整理すればよいか」に対するある程度のフラストレーションを告白しなければなりません。 「自己完結型のソースツリー」とは、すべてのコードとベンダーツリーのすべてのコードを含む巨大なgitリポジトリがあることを意味しますか? 他のすべてのコードを自分のリポジトリにチェックインしたので、ミラーは必要ありませんか?

「コードをどのように整理すればよいか」については、このページ「 Goコードの書き方」でディレクトリ構造について説明していますが、ベンダーについては触れていません。

セマンティックインポートバージョン管理を採用します。このバージョン管理では、メジャーバージョンごとに個別のインポートパスがあります。 具体的には、インポートパスには、モジュールパス、バージョン番号、およびモジュール内の特定のパッケージへのパスが含まれます。 メジャーバージョンがv0またはv1の場合、バージョン番号要素を省略する必要があります。 それ以外の場合は含める必要があります。

my / things / sub / pkg 、my / things / v2 / sub / pkg、およびmy / things / v3 / sub / pkgとしてインポートされたパッケージは、モジュールmy / thingのメジャーバージョンv1 、v2、およびv3からのものですが、ビルドはそれらを単に3つの異なるパッケージとして扱います。

my / things / sub / pkgもv0にすることができます。

ツアーをフォローしました。 この例はGOPATHツリーの外部で作成されており、機能しますが、その状況ではdep initがバーフします。 私は今80チームと協力していると思いますが、巨大な木が1本必要ないのは本当に素晴らしいことです。 (私がこれを入力しているときに、誰かがラップトップと眉をひそめた顔を持って立ち上がって、「私はこの本当に奇妙なバグを持っています...」)

@joeshaw

インフラストラクチャと稼働時間を無料またはリーズナブルなコストで維持するためのすばらしい作業をすべて手に入れることができます。

私はそれをうまく言いませんでした。 「バニティインポートを使用していない場合に必要なインフラストラクチャが少ないと主張する場合は、githubが実行するすべてのインフラストラクチャを無視している」という意味です。 私は、インフラストラクチャがまだそこにあり、実行する必要があることを指摘するつもりでした。 そして、それは将来もあなたのために実行され続けることができます。

したがって、あなたの懸念は、私が最も可能性の高いシナリオであると考えるもので対処されます。資金提供団体(現在Microsoftはそのように形作られています)がzipファイルのホスティングを行っているということです。

私は単一のGitフェッチの優雅さが好きですが-ユーザーの観点からのアトミックアクション

vgo getは、アトミックアクションと同じくらい多く、作業が少なく、同じ性質(HTTPリクエスト)で理解しやすいものです。

問題は、これによりプロジェクトの構築に単一障害点(SPOF)が追加されることです。

では、私の最後のコメントはどこに間違っていますか? 失敗のポイントの数がどちらかといえば少ないことは私にはかなり明白に思えるので、それらはより単純で、スケーリングがより簡単で、実行がより安価です。

他の言語では、集中型リポジトリは2番目のSPOFです。 Goの場合、すべてのインポートパスは追加のSPOF(github.com、golang.org、honnef.co、rsc.ioなど)であり、SPOFを増やすと全体的な可用性が低下します。

これは単純化しすぎだと思います。 ダウンしたミラーでコードをホストしている場合でも、開発は可能であり(githubはアップのまま)、ユーザーは(別のミラーを使用して)インストールできる可能性があります。 依存関係をミラーリングするため、ダウンする依存関係の1つのホストは重要ではありません。 「一元化された」コミュニティ運営のミラーが稼働し続けることを信頼できない場合は、ユーザーに違いはなく、自分で運営するか、誰かにお金を払って実行することができます。これにより、ダウンタイムの影響を完全に制御できます。一元化されたリポジトリ。

少なくとも動作が低下しているため、実際に言及していることはいずれもSPOFではありません。 それに加えて、実際のミラーの操作は比較的簡単であり(ステートレスHTTPサーバーであるため)、信頼性と可用性が大幅に低下するとは確信していません。

そしてFTR、今のところあなたのgit-hostingSPOFです:あなたのgit-hostがダウンしていると、ユーザーはインストールできず、あなたは開発できません。

ミラーを実行すると、確かに2つに戻る可能性がありますが、私が主張するのはインフラストラクチャであり、存在する必要はありません。

そして、上記の私の(言い回しの悪い)ポイントは、それはすでに行われているということでした:)あなたは単にa)現在起こっていることを無視し、b)将来は起こらないと仮定しています:)

別の視点を与えるには:

  • システム全体のクロスランゲージソフトウェアコンポーネントマネージャー(Fedora、Centos、RHELのrpm / dnf)を使用して、多くのGoプロジェクトを構築しています。
  • これにより、rpmレイヤーコンポーネントの名前空間で再生することにより、vgo提案と同じトリックの多くを使用できます(通常、rpm名前空間レベルでプロジェクトの名前をプロジェクトからcompat-project-xに変更して、互換性のないバージョンのvgoとまったく同じインポートパス)。
  • これらのトリックは、複雑なGoプロジェクトの構築を支援するのに間違いなく役立ちます
  • 言語レベルで行うほど完全で堅牢ではありませんが
  • 元のコードに制約のrpm / dnfオーバーレイを追加するよりも、言語制約をrpm / dnfに中継する方がよいでしょう。
  • GoツールにGoプロジェクトのソースを調べるように説得するために現在必要なすべてのファイルシステムの回避策にかなりうんざりしています。 物理的なGOPATHはまったく見逃されません。

したがって、私たちはvgoにわくわくしており、すぐに展開されることを望んでいます(何年も前に必要でした)。

そうは言っても、vgoのようなワークフローを使用すると、次のような問題が発生しました。

vgoの提案は、makefileを不要にしたことを祝福します。 これは完全に真実ではありません。

  • 多くのGoプロジェクトは、自動生成されたgoファイルに夢中になり、それらを再生成したり、生成を成功させるために必要なものを表現したりするための標準的な方法はありません。
  • 多くのプロジェクトが事前生成されたファイルとともに出荷する必要があるのは非常に悪いことです(完全に別個の事前生成されたファイルリポジトリを構成する場合もあります)
  • これらのファイルは、バージョンの非互換性の大きな原因です。 人間は、新しい依存関係のバージョンにさらされたときに毎日変更する必要のないコードを書くように注意します。 自動生成されたファイルOTOHは、正確な生成環境に密接にリンクしていることがよくあります。これは、ジェネレータツールの作成者が必要に応じてファイルを再生成すると想定しているためです。
  • vgoを成功させるには、それらのファイルを識別し、.zipモジュールからそれらを取り除き、.zipモジュールのユーザーにそれらを再生成する方法を表現する方法が必要です。

これは、現在の「すべてがGOPATHにある必要がある」ルールによって悪化します

  • 多言語プロジェクトによってGOPATHの外部で公開されたプロトファイルに生成が依存している場合、すべてをGOPATHに含めることはできません。
  • Goツールチェーンは、GOPATH外のリソースを読み取ることを学習する必要があります
  • Goツールチェーンは、必ずしもGoで記述されていないプロジェクトにさらされている場合、GOPATHの外部にリソースを公開することを学習する必要があります。
  • GOPATHを使用してコピーでリソースを複製する現在の回避策は、バージョンの非互換性のもう1つの原因です。
  • 全員が同じファイルを同時にコピーすることはありません
  • プロジェクトが複数のソースからコピーし、独自のミックスを作成する場合があります。
  • すべてのプロジェクトは独自のコピーでQAを行うため、Goプロジェクトの構成は危険です。
  • vgoバージョンソルバーは、コードリリース間の関係を計算するが、リソースリリース間の関係を無視する場合、意図したとおりに機能しません。
  • vgoは、互換性のないモジュールバージョンの急増を避けるために、GOPATHの外部に公開するもののプライベートコピーを不要にする必要があります。

多くのプロジェクトは、「すべてのGoディレクトリは個別のパッケージです」というルールを利用して、互換性のない、または完全に壊れたコードを含むプロジェクトを個別のサブディレクトリに公開しています。

  • 他の多くのGoプロジェクトは、同じルールを使用して特定のサブディレクトリを選択し、元のプロジェクトの単体テストおよびQAと互換性のないコンテキストでそれらを使用しています。
  • 元のプロジェクトまたはプロジェクトのコンシューマーで変更が元のプロジェクトの他の部分を利用しない限り、それは「機能」し、「再現可能なビルド」を生成します。 それが起こると、砂の城全体が蓄積された技術的負債の下で崩壊します、
  • 他のプロジェクトの以前の誤用をクリーンアップする必要があるため、プロジェクトが新しいプロジェクトバージョンへの更新を拒否していることがわかります。
  • Goプロジェクトが再利用するコードベースのバグの責任を負わないと見なし、同時にそれらのまったく同じコードベースによって公開された修正を適用することを拒否する奇妙な統合失調症があります(私たちはすべて人間であり、不快な現実の否定は配線されています人間の脳内)
  • 修正は伝播せず、最初に修正を必要とするバグ、またはチェリーピッキングによって無効にされた単体テストに遭遇するまで、すべてが「正常」です。
  • プロジェクトのセキュリティ状態をベンダーディレクトリ内の同じプロジェクトのセキュリティ状態と比較した自動セキュリティチェッカーには、フィールドデーがあります
  • プロジェクトが大きくなればなるほど、そのようなカチカチと音を立てる爆弾がベンダーの中に隠されている可能性が高くなります
  • zipモジュール内のプロジェクト境界を明確に定義することにより、vgoはそのような慣行に終止符を打ちます
  • ただし、多くのGoコードベースの大規模なクリーンアップも必要になります
  • vgoを成功させるには、既存のGoプロジェクトがリファクタリングし、ソフトウェアの互換性の観点から意味のあるモジュールにコードベースを分割するのに役立つツールを提供する必要があります。 そうしないと、vgoを使用するプロジェクトは、調整不可能な制約を生成するか、現状をロックダウンします(これは既存のコードでは機能しますが、コードの進化の観点からはひどいものです)。

プロジェクト間の制限がほとんどない単一のGOPATHツリーでGoコードベース全体を公開するという現在の慣行は、ソフトウェアエンジニアリングPOWからの有害な副作用を生み出しました。

  • コードは、技術的に意味のあるプロジェクトではなく、コード作成者にとって最も便利なリポジトリ(彼がアクセスできるリポジトリ)でコミットされます。
  • Goプロジェクトは互いにブリードアウトし、あるプロジェクトの一部は別のプロジェクトの一部に依存し、この他のプロジェクトの一部は元のプロジェクトに依存します
  • これにより、ロックダウンされたバージョン制約グラフが効果的に生成され、他のすべてを移動せずに1つの部分を移動することはできません。
  • 1回の操作で他のすべてを変更するためのリソースは誰にもありません
  • プロジェクトがデッドロックし、進行が停止する
  • 明確な境界を持つモジュールを使用し、モジュール間のバージョン制約を明示的にしようとすると、これらの状況が明らかになります
  • それは非常に人気がないでしょう(問題は今日存在しますが、ベンダーのベールの下に隠されています)
  • 多くの場合、サブディレクトリを分離するだけではありません。問題のあるプロジェクトの依存関係は、AおよびDレベルのA / B / C / Dディレクトリツリーで発生する可能性がありますが、BおよびCでは発生しません。
  • vgoを成功させるには、既存のGoプロジェクトがリファクタリングし、依存関係グラフの線に沿った個別のモジュールにコードベースを分割するのに役立つツールを提供する必要があります。

Testfing /フィクスチャ、example、testdataは、他のすべてのワームの缶であり、独自の依存関係と依存関係バージョンが必要です。

  • それらは別々のモジュールに何らかの方法で分離する必要があります。そうしないと、ソルバーのバージョン解決に悪影響を及ぼします。
  • 彼らのニーズを無視すると、元のプロジェクト以外はユニットテストを実行しないと効果的に判断できます
  • バージョンのアップグレードを許可する場合、これは非常に危険です。 問題が発生します。 あなたはそれらを検出する必要があります
  • 他のコードだけでなく、元のプロジェクト以外の誰も複製できない特定の環境(たとえば、通信する特定のサーバーやWebサイト)に依存する統合テストでは、おそらく特定の分離が必要です。

私はおそらくもっと多くのことを忘れていますが、それらは最も重要です。

最後に:

  • Goプロジェクトは孤立して生きていない
  • 一部のGoプロジェクトは、コネクタを他の言語に公開します
  • 他の言語の一部のプロジェクトはGoコネクタを公開しています
  • そのため、semverを他の言語とは異なる方法で扱うことが問題になります。
  • 多言語プロジェクトがリリースされたときに、Go部分以外のすべてを最新のマイナーバージョンに更新することはできません。
  • それは運用管理POWからは地獄でしょう。
  • 最新のサブリリースへの自動アップグレードは、すべての人に古いバージョンをバキュームさせることにより、ソフトウェア制約グラフを簡素化する上で大きな役割を果たします(利点は技術的であり、メカニズムは社会的です)。
  • 忠実度の高い再構築は、ピクセルパーフェクトなWebサイトに似ています。 それらは明らかに良いアイデアのように見え、元の作者のエゴに報酬を与えますが、進化可能ではなく、ローカル(元の)コンテキストに適応できないため、実際に結果を使用しようとする人にとってはPITAです。

プロキシサーバーの場合:

デバッグを容易にするために、$ GOPROXYはローカルツリーを指すfile:/// URLにすることもできます。

サードパーティのモジュールをzip形式で含むディレクトリを指すhttps:/// URLのfile:///で機能するようにしてください(他のすべてを除外します)

これは、エンティティが同じサードパーティプロジェクトリストのサブセットに依存する複数の開発チームの作業を調整するための最も簡単な方法です。「優れた」サードパーティリリースの検証と展開を担当するQA /法務/セキュリティ担当者がいます。共通のディレクトリにあり、他のすべての人に、この共通のディレクトリで使用可能なモジュールに依存して作業を行わせる。

そうすれば、他の人の作業と互換性のないリビジョンで作業を開始することはなく、別のチームによってすでに識別されているバグのあるまたは危険なリビジョンにとどまることがなく、開発ステーションが同じコピーのダウンロードを継続的に待機することはありません。すでにローカルで利用可能なソフトウェアの。

@Merovius同意しませんが、私たちは話題から外れており、問題の議論を滞らせたくないと思います。 ただし、別の媒体でフォローアップできてうれしいです。 (私の電子メールは私のgithubプロファイルにあり、私はGophers slackのjoeshawです。)

https://github.com/golang/go/issues/24301#issuecomment -374882685、 @ tpng

疑似バージョン(v0.0.0-yyyymmddhhmmss-commit)のタイムスタンプに使用されるタイムゾーンはどれですか?

編集で述べたように、UTC。 ただし、これらを入力する必要はないことにも注意してください。 git commit hash(プレフィックス)を入力するだけで、vgoが正しい疑似バージョンを計算して置換します。

https://github.com/golang/go/issues/24301#issuecomment -374907338、 @ AlexRouSg

Cの依存関係に対処しますか?

https://github.com/golang/go/issues/24301#issuecomment -376606788、 @ stevvooe

protobufsやcファイルなどのGo以外のリソースはどうなりますか?

https://github.com/golang/go/issues/24301#issuecomment -377186949、@ nim-nim:

vgoの提案は、makefileを不要にしたことを祝福します。 これは完全に真実ではありません。 [生成されたコードの議論。]

非Go開発は、引き続きgoコマンドの非目標であるため、Cライブラリなどの管理はサポートされず、プロトコルバッファも明示的にサポートされません。

そうは言っても、Goでプロトコルバッファを使用するのは難しすぎることは確かに理解しているので、個別に対処してもらいたいと思います。

より一般的に生成されるコードに関しては、実際のクロスランゲージビルドシステムが答えです。特に、すべてのユーザーが適切なジェネレーターをインストールする必要がないためです。 作成者がジェネレーターを実行して結果をチェックインする方がよいでしょう。

https://github.com/golang/go/issues/24301#issuecomment -375248753、 @ mrkanister

デフォルトのブランチをマスターからv2に変更できることは知っていますが、それでも、新しいメジャーバージョンをリリースするたびにそれを更新するタスクが残っています。 個人的には、マスターとv1ブランチが必要ですが、これが提案にどの程度正確に適合するかはわかりません。

@AlexRouSgや他の人が指摘したように、これを行うことができます。 私は彼らの答えを確認したかっただけです。 これもFAQに追加します。

https://github.com/golang/go/issues/24301#issuecomment -375989173、 @ aarondl

これは現在機能していますが、意図されていますか?

もちろん。

@ jamiethermo 、Perforceとさまざまなディレクトリのブランチについてコメントしてくれてありがとう。 私はその機能を忘れていましたが、おそらくそれがvgoで許可することが重要であると私に確信させたものです。

https://github.com/golang/go/issues/24301#issuecomment -376925845から、ベンダーとプロキシについて素晴らしい議論がありました。 ここには明らかに2つの異なる懸念事項があります。

オープンソース開発者はインフラストラクチャに依存することを避けたい傾向があるので、 @ joeshawが書いたように彼らはベンダーを望んでいます。 確認のため、限定された形式で機能し続けます(goコマンドを実行しているターゲットモジュール全体の最上位にあるベンダーディレクトリのみ)。

エンタープライズ開発者は、インフラストラクチャに依存することに問題はありません。これは単なる別のコストです。特に、すべてのリポジトリですべてのベンダーコードを複製せず、すべての同期を維持するために時間を費やす必要があるなど、大幅なコスト削減がもたらされる場合はなおさらです。 @jamiethermoが求めたように、基本的に、私たちが話をしたすべての企業は、ベンダーではなく、プロキシ/ミラーを望んでいます。 それも機能することを確認します。

また、開発者が信頼し、信頼する理由がある共有ミラーネットワークを構築して、すべてのオープンソース開発者がベンダーである必要があると感じないようにすることも非常に望んでいます。 しかし、それは後でです。 最初のvgoはgoになる必要があります。

https://github.com/golang/go/issues/24301#issuecomment -377220411、@ nim-nim:

サードパーティのモジュールをzip形式で含むディレクトリを指すhttps:/// URLのfile:///で機能するようにしてください(他のすべてを除外します)

「他のすべてを除外する」と言って、あなたが何を求めているのか正確にはわかりません。 $ GOPROXYが設定されている場合、vgoはそのプロキシに問い合わせます。 他の場所にフォールバックすることはありません。 そのプロキシは、静的ファイルツリーによって提供できます。静的ファイルツリーは、ほとんどがzip形式のサードパーティモジュールです。 ただし、ナビゲーションとルックアップのために、ファイルツリーには他のメタデータファイルも含まれている必要があります。 HTTPはディレクトリリストのようなことをするための標準的な方法を私たちに与えないので、それらの余分なファイルは避けられません。

https://github.com/golang/go/issues/24301#issuecomment -377186949、@ nim-nim:

うわー、それは長いコメントです。 私はあなたが書いたもののほとんどに同意すると思います。 あなたの投稿の最後の箇条書きに返信したいと思います。

  • 忠実度の高い再構築は、ピクセルパーフェクトなWebサイトに似ています。 それらは明らかに良いアイデアのように見え、元の作者のエゴに報酬を与えますが、進化可能ではなく、ローカル(元の)コンテキストに適応できないため、実際に結果を使用しようとする人にとってはPITAです。

ロックファイルはピクセルパーフェクトなウェブサイトのようなものだと私は主張すると思います。 対照的に、忠実度の高いビルドは、コンテキストの変化に応じて適切に低下します。 デフォルトでは、ビルドはたとえばB1.2とC1.4を使用します。 しかし、それがB 1.3を必要とするより大きなビルドの一部である場合、問題なく、B 1.3とうまくいきますが、アップグレードの具体的な要件がない限り、C 1.4を維持します(新しいものが存在する場合でも)。 したがって、本当に忠実度の高いビルドは、両方の長所です。可能な限りオリジナルに忠実ですが、それが不可能な場合はピクセルパーフェクトを主張しません。

https://github.com/golang/go/issues/24301#issuecomment -375415904、 @ flibustenet

@rscロードマップと今何をすべきかについてもっと正確にお願いしたいと思います。
Goポリシーに従い、3か月(現在は2か月)にvgo​​をフリーズする機能を備えていますか?

Vgoはプロトタイプであり、単独でリリースされることはありません。 フリーズなどの影響を受けません。 しかし、この提案は、アイデアとほとんどのコードをメインのcmd / goに移動することです。 リリースの一部として、cmd / goは確かにフリーズの対象となります。 オプトインであり、vgo固有のコードがgoコマンドの残りの操作からかなり分離されているため、vgo固有の部分での作業のリスクはかなり低く、その一部が数週間続くことがわかりました。フリーズに。 現在、私は提案の議論と調整に焦点を合わせています。 提案が重大な問題なく良好な状態になったら、コードをcmd / goに移動します。

巡礼者のバトンですべてのlibsメンテナにgo.modファイルを追加するように依頼する必要がありますか、それとも提案が正式に受け入れられるのを待つ必要がありますか(名前と構文が変更されないようにするため)?

go.mod構文は変更される可能性が高いと思います(この問題をご覧ください)。 しかし、提案で述べたように、私たちは古い構文を永久に受け入れ続け、vgoは既存のファイルを更新するだけなので、大したことではありません。 そうは言っても、コードがcmd / goの開発コピーに到達するまで、見つけることができるすべてのライブラリにPRを送信しようとはしません。

https://github.com/golang/go/issues/24301#issuecomment -376640804、 @ pbx0

vgoを使用すると、ビルドに1つ以上のバージョンのパッケージがあるかどうかを簡単に判断できますか?

今日行う最も簡単なことは、バイナリをビルドしてから、その上でgoversion -mを実行することです(https://research.swtch.com/vgo-reproを参照)。 より一般的なモジュール対応のgoリストがある場合、最初にバイナリをビルドしなくても同じことができるはずです。

https://github.com/golang/go/issues/24301#issuecomment -376236546、 @ buro9

[microcosm-cc / bluemonday @ a5d7ef6のように、下位互換性のないセキュリティ変更を行うことはできますか? ]

@Meroviusが言ったように、 Go 1互換性ガイドラインを採用する場合は、メジャーバージョンにぶつかることなくセキュリティの変更が明示的に許可されます。

とはいえ、セキュリティのために何かをしなければならない場合でも、混乱を最小限に抑えるように努力する必要があります。 あなたがリンクしたコミットは、間違いなく必要以上に破壊的です。将来の状況では、「セキュリティの問題を排除しながら、できるだけ少ないクライアントを壊すにはどうすればよいか」という観点から、このような変更に取り組むことをお勧めします。 「」

たとえば、関数を削除しないでください。 代わりに、関数をパニックまたはログにします。不適切に呼び出された場合にのみ致命的です。

この場合、AllowDocTypeを削除する代わりに、それを保持し、AllowDocType(false)を受け入れ続けました。これは、安全な設定だからです。 誰かがライブラリのラッパーを、おそらく-allowdoctypeフラグのあるコマンドラインプログラムとして作成した場合、少なくともそのフラグのないプログラムの使用は引き続き機能します。

そしてそれを超えて、Doctypeが完全にチェックされていないことが懸念されたようですが、最も一般的な使用法を機能させ続けるために最小限のチェックを入れて、他の使用法を保守的に拒否したと思います。 たとえば、少なくとも、私は許可を続けていましたが、&#<> \文字を含まない引用符で囲まれた文字列を使用して..>を許可することもできました。

https://github.com/golang/go/issues/24301#issuecomment -375090551、 @ TocarIP

[アップデートがすぐに得られないことについての懸念。]

最小限のバージョン選択では、ビルド全体が新しいバージョンに更新されないようにすることは1つの依存関係では不可能であるため、プログラムはより最新のものになる可能性があるという逆のことが起こると思います。

@Meroviushttps://github.com/golang/go/issues/24301#issuecomment-375992900に書いたことは、私には正確に聞こえます。 重要な点は、更新を要求したときにのみ更新を取得することです。そのため、更新を期待し、テストやデバッグなどの準備ができた場合にのみ、(潜在的に)問題が発生します。 あなたはそれらを要求する必要がありますが、ロックファイルを備えた他のシステムよりもそれほど頻繁ではありません。 また、「非推奨/安全でないバージョンでビルドしています」などの警告を簡単に表示できるようにしたいと考えています。 ただし、更新されない操作の副作用として、単にサイレントに更新しないことが重要です。

FAQにも追加されました。

これまでの素晴らしい議論とお互いの質問に答えてくれた皆さんに感謝します。 多くの人から本当に素晴らしい答えがありましたが、 @ Meroviusと@kardianosに特に感謝します。 FAQhttps ://github.com/golang/go/issues/24301#issuecomment-371228664とディスカッションサマリーhttps://github.com/golang/go/issues/24301#issuecomment-371228742更新しました。 まだ答えられていない3つの重要な質問があります(それらは要約でTODOと言います)、それは私が次に取り組むでしょう。 :-)

@ rsc 、#24057には、zipの代わりにtarを使用する方法についての説明があります。

https://github.com/golang/go/issues/24301#issuecomment -375106068、 @ leonklingele

今日私たちが知っているgogetのサポートが非推奨になり、最終的に削除される場合、(タグなしの)Goバイナリをフェッチしてインストールするための推奨される方法は何ですか?

それはまだ取得に行きます。 バイナリのリポジトリにタグが付いていない場合、gogetは最新のコミットを使用します。 しかし、実際には、バイナリを公開している人は、ライブラリを含むリポジトリ(またはミックス)と同じように、含むリポジトリにタグを付けることをお勧めします。

$ GOPATHが非推奨になった場合、これらのバイナリはどこにインストールされますか?

$ GOPATHで作業する必要はありませんが、コードは$ GOPATHにリストされている最初のディレクトリに書き込まれます。これはソースキャッシュです。vgoを使用した後は$ GOPATH / src / vを参照してください。 バイナリは$ GOPATH / binにインストールされます。 数リリース前の時点では、$ GOPATHを設定する必要はありません。デフォルトの$ HOME / goがあります。 したがって、開発者は$ GOPATHの設定について心配するのをやめ、それが何であるかさえ知る必要がなくなり、バイナリが$ HOME / go / binにあることを知るだけです。 $ GOBINを使用して、その場所を上書きできます。

@dsnet 、ありがとうディスカッションサマリーにリンクを追加しました。 あちらでその議論を続けましょう。

$ GOPROXYが設定されている場合、vgoはそのプロキシに問い合わせます。 他の場所にフォールバックすることはありません。 そのプロキシは、静的ファイルツリーによって提供できます。静的ファイルツリーは、ほとんどがzip形式のサードパーティモジュールです。 ただし、ナビゲーションとルックアップのために、ファイルツリーには他のメタデータファイルも含まれている必要があります。 HTTPはディレクトリリストのようなことをするための標準的な方法を私たちに与えないので、それらの余分なファイルは避けられません。

元のモジュールがzip形式で保持されている限り、それらを改ざんする誘惑を取り除き、インデクサーは堅牢で軽量で問題ありません。

リストの制約はファイルには適用されませんが、lftpのようなユーティリティは何年もの間httpディレクトリをリストすることができました(主要なhttpサーバーで動作する場合は非標準であるかどうかは関係ありません)。 したがって、インデックスなしの運用はおそらく可能であり、インフラへの投資を望まない小規模な事業体にとっては望ましいことです。 yum / dnf / zipperもカスタムインデックスに依存しており、共有ディレクトリのインデックスを作成することは、一部の組織で考えられているほど簡単ではありません。

オープンソース開発者はインフラストラクチャに依存することを避けたい傾向があるので、 @ joeshawが書いたように彼らはベンダーを望んでいます

実際には、オープンソース開発者はほとんどの場合、プロセス全体がオープンで透過的であり、他の誰かの良い願いに頼る必要がないことを望んでいます。 したがって、インフラストラクチャ自体がオープンソースであり、ローカルに簡単かつ安価にデプロイできる限り、インフラストラクチャは完全に問題ありません。 githubのような巨大なブラックボックスのプロプライエタリサイトに依存することは明らかにこのカテゴリに分類されませんが、それはインフラと同じではありません。 オープンソースの人々は、他の誰よりも何十年も前にミラーリングを行いました。 彼らが受け入れないものは閉じられており、ミラーを設定するのに費用がかかります(オープンソースの用語では、費用は人間の時間で測定されます)

オープンで簡単で安価なベンダーの性質、ベンダーのプロセス自体、およびサードパーティのコードの廃止されたバージョンでのコードベースの漸進的な化石化を促進する方法は、それほど高くはありません。

エンタープライズ開発者はインフラストラクチャに依存することに問題はありません-それは単なる別のコストです

グーグルで働くのはとても素晴らしいことだろう:(。Goインフラへの投資が簡単である既存の大規模なGoオペレーションを持つ少数の企業を除いて、他の誰もが長くて退屈な承認プロセスを経なければならないだろう、問題を調べるために誰かにお金を払うことを正当化するためだけなら。したがって、インフラコストはGoの到達範囲を減らし、新しい構造による採用を妨げるでしょう。

事業者はオープンソースのようなもので、安くて簡単なことを気にします。 彼らはオープンをまったく気にしませんでしたが、それが安価と相関していることに気付いた今、それはゆっくりと変化しています(展開を支援するための高価なコンサルティングで高価なブラックボックスソリューションを専門としていた従来のエンタープライズサプライヤーの失望に)。

内部ITを最低入札者に委託する企業は、安価な開発者がインターネットから理解できない壊れたコードや危険なコードをダウンロードすることを絶対に望まないため、ミラーを強く主張します。 彼らは、問題がないかローカルミラーコンテンツをスキャンするために人とツールにお金を払い、内部ITにそれを排他的に使用するように強制します。

また、開発者が信頼し、信頼する理由がある共有ミラーネットワークを構築して、すべてのオープンソース開発者がベンダーである必要があると感じないようにすることも非常に望んでいます。

モジュールを含むインデックス付きディレクトリの参照コピーをどこかに公開するだけです。 特定のWebサーバー構成を必要とするプロキシのような設定は忘れてください。 それはオープンソースが行うことであり、彼らは自分自身をミラーリングするのに問題はありません。 ミラーリングがディレクトリのコンテンツをコピーするだけで、特定のWebサーバー構成を必要としない限り、ミラーリングを希望する組織はたくさんあります。

より一般的に生成されたコードに関しては、実際のクロスランゲージビルドシステムが答えです。

あなたは私と同様に決して起こらないことを知っています、誰かが常にそれ自身のことをする新しい言語を発明したいと思うでしょう。 それはストローマンの議論です。

これは、プロジェクト固有のプロセスがコードを生成するものを起動する標準コマンドをGoが正規化することを妨げるものではなく、実行できることと実行できないことに関する厳密なガイドラインがあります(通常、標準のGoコマンドでカバーされていることは何も実行しないでください。これらのコマンドはすでにそのままで大丈夫です)。

特に、すべてのユーザーが適切なジェネレーターをインストールする必要がないためです。 作成者がジェネレーターを実行して結果をチェックインする方がよいでしょう。

現在、バージョンの移植性についてはまったく気にしておらず、生成前にソフトウェア環境がフリーズすることを期待しているため、既存のジェネレーターの実装方法を大幅に再考する必要があります。 生成すると、再生せずにそれ以降のバージョン変更が危険になるという直接的な影響があります。 人間は元のバージョンセットに対してのみチェックするため、結果が人間によってチェックされるかどうかは関係ありません。 vgoは、それ以降のバージョン変更を実行できることに依存しています。

したがって、vgoは遅かれ早かれ再生に取り組む必要があります。 後でとは、生成されたコードが存在する場合にvgoの更新が危険であることをプロジェクトが検出するのを待つことを意味します。

https://github.com/golang/go/issues/24301#issuecomment -374791885、 @ jimmyfrasche

これは、初期化中に別のパッケージに登録されるデータベースドライバーや画像形式などにも影響します。これは、同じパッケージの複数のメジャーバージョンがこれを実行する可能性があるためです。 そのすべての影響がどうなるかは私にはわかりません。

はい、「プログラムにはこれらの1つだけが含まれる」と想定するコードの問題は現実のものであり、新しい(より良い)ベストプラクティスと規則を確立するために私たち全員が取り組む必要がある問題です。 この問題がvgoによって引き起こされているとは思わないので、vgoは間違いなく以前よりも状況を改善します。

vgoは1.xと2.xを一緒にすることさえできないというDepのルールを採用すべきだと主張する人もいることを理解していますが、それはGoでターゲットにしている大規模なコードベースに非常に明確に対応していません。 vgo-importの投稿に示されているように、大規模なプログラム全体が1つのAPIから別のAPIに一度にアップグレードされることを期待するのは現実的ではありません。 基本的に、他のすべてのパッケージマネージャーは同じ理由で1.xと2.xを一緒に許可すると思います。 確かに貨物はそうします。

一般に、vgoはベンダーと比較して重複を減らします。 ベンダーを使用すると、特定のパッケージの1.2、1.3、および1.4を、気付かずに1つのバイナリにまとめたり、1.2のコピーを3つ作成したりするのは簡単です。 少なくともvgoは、重複の可能性を1つの1.x、1つの2.xなどに削減します。

異なるパッケージの作成者が同じものを登録しようとしないようにする必要があるのはすでに事実です。 たとえば、expvarはhttp.Handle( "/ debug / vars")を実行し、基本的にそのパスへのクレームを賭けています。 awesome.io/supervarsのようなサードパーティのパッケージが同じパスを登録しようとしてはならないことに私たち全員が同意することを願っています。 そのため、1つのパッケージの複数のバージョン間で競合が発生します。

expvar / v2を導入すると、それはawesome.io/supervarsと同じように、2番目の異なるパッケージになり、大規模なビルドではexpvarと競合する可能性があります。 ただし、supervarsとは異なり、expvar / v2はexpvarと同じ個人またはチームによって所有されているため、2つのパッケージを調整して登録を共有できます。 それは次のように機能します。 expvar v1.5.0がv2の記述を決定する前の最後であるとすると、v1.5.0にはhttp.Handleが含まれています。 v2をv1の代わりに使用したいので、http.Handleをv2.0.0に移動し、v1がv2に呼び出しを転送できるようにするAPIをv2に追加します。 次に、この転送で実装されるv1.6.0を作成します。 v1.6.0はhttp.Handleを呼び出しません。 それをv2.0.0に委任します。 これで、expvarv1.6.0とexpvar / v2を共存させることができます。これは、そのように計画したためです。 残っている唯一の問題は、ビルドがexpvarv1.5.0とexpvar / v2を使用した場合にどうなるかということです。 それが起こらないようにする必要があります。 その方向へのインポートがない場合でも、expvar / v2にv1.6.0(またはそれ以降)のexpvarを要求させることでこれを行います。もちろん、expvar v1.6.0では、APIを呼び出すためにv2.0.0以降のexpvar / v2も必要です。 。 この要件サイクルにより、v1.5.0とv2が混在しないようにすることができます。 この種のメジャーバージョン間の調整を計画することが、最小限のバージョン選択で要件グラフのサイクルを許可する理由です。

要件グラフでサイクルを許可することと組み合わせた「唯一のメジャーバージョン」ルールにより、作成者は、モジュールの異なるメジャーバージョン間のシングルトンの適切な調整(およびシングルトン所有権の移行)を管理するために必要なツールを利用できます。 問題を解決することはできませんが、作成者に問題を解決するために必要なツールを提供することはできます。

特にプロトコルバッファには登録の問題があることを私は知っています、そしてそれらの問題はプロトコル.pb.goファイルが渡されてプロジェクトにコピーされる非常にアドホックな方法によって悪化します。 これもまた、vgoからほとんど独立しているものです。 これを修正する必要がありますが、おそらくvgoではなくGoプロトコルバッファの使用方法を変更することによって修正する必要があります。

https://github.com/golang/go/issues/24301#issuecomment -374739116、 @ ChrisHines

私は、vgo以前の世界とvgoの世界の間の移行パスがうまくいかないことを最も心配しています。 [もっと詳しく]

これが提案に対する最初のコメントであったことを本当にうれしく思います。 それは明らかに正しくするための最も重要なことです。

古いgogetと無数のベンダーツールから新しいモジュールシステムへの移行は、信じられないほどスムーズに実行する必要があります。 私は最近、それがどのように機能するかについてよく考えています。

元の提案では、開発者はモジュールのバージョン2をv2 /という名前のリポジトリサブディレクトリに配置するオプションが許可されています。 このオプションを実行すると、開発者はセマンティックインポートのバージョン管理を使用し、モジュールと互換性があり、古い「goget」との下位互換性もあるリポジトリを作成できます。 このオプションを説明する投稿は、プロジェクトの大多数がこのオプションを実行したくないことを認めています。これは問題ありません。 プロジェクトがすでにv2以降である場合にのみ、互換性のために必要です。 同時に、v2以降で広く使用されている大規模なプロジェクトの数を過小評価していました。 例えば:

  • github.com/godbus/dbusはv4.1.0にあります(462個のパッケージによってインポートされます)。
  • github.com/coreos/etcd/clientv3はv3.3.3にあります(799パッケージによってインポートされます)。
  • k8s.io/client-go/kubernetesはv6.0.0にあります(1928パッケージによってインポートされました)。

クライアントの破損を防ぐために、これらのプロジェクトは、すべてのクライアントがモジュールを使用していると見なされるまでサブディレクトリに移動してから、ルートに戻る必要があります。 それは質問することがたくさんあります。

gitサブモジュールでトリックをプレイする別のオプション。 古いgogetコマンドは、リポジトリのデフォルトブランチよりも「go1」という名前のタグまたはブランチを優先するため、スムーズな移行を有効にしたいプロジェクトは、「v2」サブディレクトリのみが設定された「go1」ブランチにコミットを作成できます。実際のリポジトリルートを指すgitサブモジュールとして。 「goget」がそのgo1ブランチをチェックアウトし、サブモジュールにデータを入力すると、正しいファイルツリーレイアウトが取得されます。 ただし、これはちょっとひどいことであり、新しいリリースが作成されるたびにサブモジュールポインタを更新する必要があります。

これらは両方とも、作成者がユーザーを壊さないように、そしてそれでも新しいリリースに対してのみ措置を講じなければならないという不幸な影響を及ぼします。 代わりに、作成者による追加の作業がなくても、理想的には古いリリースでも、ユーザーのコードが機能し続けることを望んでいます。

しかし、これらは、モジュールの世界に移行するときに、変更されていない古いものを機能させるために私が考えることができる唯一の方法です。 そうでない場合、代替手段はold go getを変更することです。これは、実際にはold gobuildを変更することを意味します。

基本的に、2つの異なるインポートパス規則があります。メジャーバージョンがない古いものと、v2以降のメジャーバージョンがある新しいものです。 古いツリーのコードはおそらく古い規則を使用しますが、新しいツリーのコード(go.modファイルを含むディレクトリの下)はおそらく新しい規則を使用します。 移行中に2つの規則をオーバーラップさせる方法が必要です。 old goにセマンティックインポートのバージョン管理について少し教えれば、オーバーラップの量を大幅に増やすことができます。


提案された変更: 「新しい」コードを、同じディレクトリまたは親ディレクトリにあるgo.modファイルを含むコードとして定義します。 古いgogetは、いつものようにコードをダウンロードし続ける必要があります。 「ビルドする」ステップで、「新しい」コードでのインポートの処理を調整することを提案します。 具体的には、新しいコードのインポートでx / y / v2 / zと表示されているが、x / y / v2 / zが存在せず、x / y /go.modで「modulex / y / v2」と表示されている場合、gobuildは次のように読み取ります。代わりにx / y / zとしてインポートします。 このアップデートは、Go1.9およびGo1.10のポイントリリースとしてプッシュされます。

更新:#25069にコピーされました。


この変更により、モジュール対応パッケージがリポジトリの構造化に「メジャーブランチ」または「メジャーサブディレクトリ」アプローチを選択するかどうかに関係なく、モジュール対応パッケージが新しいバージョンのモジュール対応パッケージを使用できるようになります。 それらはもはやサブディレクトリアプローチに強制されることはありませんが、それでも機能するオプションです。 また、古いGoリリースを使用している開発者は、(少なくともポイントリリースに更新した後でも)コードをビルドできます。

@rsc私はvgoへの移行をどのように機能させることができるかを理解しようとしてきましたが、あなたが回答で示したのと同じ結論に達し、あなたの提案は私が思いついた最良のアプローチと一致します私自身で。 私はあなたの提案された変更が好きです。

https://github.com/golang/go/issues/24301#issuecomment -377527249、 @ rsc

次に、この転送で実装されるv1.6.0を作成します。 v1.6.0はhttp.Handleを呼び出しません。 それをv2.0.0に委任します。 これで、expvarv1.6.0とexpvar / v2を共存させることができます。これは、そのように計画したためです。

これはそれよりも簡単に聞こえます。 実際には、ほとんどの場合、これはv1.6.0がv2ラッパーの形式でv1を完全に書き換える必要があることを意味します_(http.Handleへの転送呼び出しは、別のハンドラー(v2からの1つ)を登録することになります。登録されたハンドラーと正しく対話するには、コードもv2からのものである必要があります)_。

これにより、v2が進化するにつれて、特に時間とともに、v1の動作に関する微妙な詳細が変わる可能性が非常に高くなります。 これらの微妙な詳細の変更を補正し、v1.6.xでv1を十分にエミュレートできるとしても、それでも多くの余分な作業が必要であり、v1ブランチ(つまり、v1.5.0の後継)の将来のサポートになる可能性が非常に高くなります。ここ)無意味。

@powerman 、これが些細なことだと言っているわけではありません。 また、v1とv2がhttp登録などの共有リソースをめぐって争う範囲でのみ調整する必要があります。 ただし、このパッケージングエコシステムに参加する開発者は、パッケージのv1とv2が大規模なプログラムで共存する必要があることを絶対に理解する必要があります。 多くのパッケージは作業を必要としません。たとえば、yamlとblackfridayはどちらもv1とは完全に異なるv2にありますが、競合する共有状態がないため、明示的な調整は必要ありませんが、他のパッケージは必要です。

@powerman @rsc
私はGUIパッケージを開発しています。つまり、「メイン」スレッドを使用しているため、2つ以上のインスタンスを持つことさえできません。 最悪の場合のシングルトンシナリオから来て、これが私がやることに決めたものです。

  • v0 / v1リリースしかないため、2つ以上のバージョンをインポートすることはできません

  • パブリックコードを独自のapiバージョンフォルダーに配置します。たとえば、vgoで許可されていると仮定した場合はv1 / v2、またはapi1 / api2を使用します。

  • これらのパブリックAPIパッケージは内部パッケージに依存するため、v2で書き直す代わりに、パッケージが大きくなるにつれてローリングリライトされ、処理がはるかに簡単になります。

https://github.com/golang/go/issues/24301#issuecomment -377529520では、提案された変更により、「新しい」コードが同じディレクトリまたは親ディレクトリにあるgo.modファイルを持つコードとして定義されています。 これには、たとえばGopkg.tomlから依存関係を読み込んで作成された「合成された」go.modファイルが含まれますか?

@zeebo 、はい。 ツリーにgo.modファイルがある場合、コードは実際にはvgoでビルドされると想定されます。 そうでない場合は、rm go.mod(または、少なくとも他の人が見つける可能性のあるリポジトリにチェックインしないでください)。

@ AlexRouSg 、GUIパッケージの計画は私には理にかなっています。

@rscうーん..わかりません。不明な点がある場合は申し訳ありません。 ファイルツリーにGopkg.tomlのみが含まれるパッケージは、定義の「新規」としてカウントされますか?

@rsc

より一般的に生成されるコードに関しては、実際のクロスランゲージビルドシステムが答えです。特に、すべてのユーザーが適切なジェネレーターをインストールする必要がないためです。 作成者がジェネレーターを実行して結果をチェックインする方がよいでしょう。

protobufをGOPATHにマッピングすることで、これを解決することができました。 はい、カジュアルユーザーは更新するためのツールを必要としないようになっていますが、protobufを変更および再生成する場合、protobuildのソリューションは非常にうまく機能します。

ここでの答えはかなり残念です。 存在しない新しいビルドシステムを見つけることは、単なる答えではありません。 ここでの現実は、これらのビルドシステムを再構築せず、新しいvgoシステムの採用を避けて、機能するものを引き続き使用することです。

vgoは、GOPATHを気に入って採用し、その問題を回避した人たちの破産を宣言するだけですか?

@zeebo 、いいえ、Gopkg.tomlを持っていることは新しいものとしてカウントされません。 ここで「新規」とは、vgoスタイル(セマンティックインポートバージョン管理)のインポートを使用することが期待されることを意味します。

@stevvooe

protobufをGOPATHにマッピングすることで、これを解決することができました。 ..。
vgoは、GOPATHを気に入って採用し、その問題を回避した人たちの破産を宣言するだけですか?

私はあなたのプロトビルドを見ていませんが、一般的に、はい、私たちは非GOPATHモデルに移行しており、GOPATHが有効にしたかもしれないトリックのいくつかは取り残されます。 たとえば、GOPATHを使用すると、元のgodepは、ベンダーのサポートがなくてもベンダーをシミュレートできます。 それはもう不可能です。 一見すると、protobuildは、所有していない他のパッケージにファイル(pb.go)をドロップできるという前提に基づいているように見えます。 そのようなグローバルな操作はもうサポートされません。 私は完全に真剣で、vgoとは別に、protobufsが十分にサポートされていることを確認したいと思っています。 @neildはおそらく提案を聞くことに興味があるでしょうが、おそらくこの問題についてはそうではありません。

@stevvooehttps://github.com/golang/go/issues/24301#issuecomment-377602765@rscのコメントを提供しましたその問題は、 vgoの角度をカバーすることになります。 物事が他の場所で処理されることになった場合、 @ dsnet etalが私たちに道標を示すと確信しています。

注:以前のコメントはよくわかりませんでした。別のアプローチで問題が解決したようです。 以下は私の考えでした。

ただのアイデア。

vgo getにvgo-v1-lockのような特定のタグを認識させるのはどうですか?
リポジトリにタグがある場合、他のバージョンタグを無視し、タグに固定される場合があります。

したがって、リポジトリがv2.1.3を最後のバージョンとしてタグ付けした場合、
ただし、所有者はvgo-v1-lockタグをv2.1.3とタグ付けされた同じコミットにプッシュします
go.modと書くことができます

require (
    "github.com/owner/repo" vgo-v1-lock
)

vgo get -uであっても、リポジトリの所有者がタグを変更または削除するまで、更新されないはずです。
これにより、大きなリポジトリの移動の準備が容易になる可能性があります。

図書館の著者が準備されると、著者はユーザーに発表することができます
インポートパスに「/ v2」を追加することで手動で更新できること。

深い依存関係にパッチを適用する必要がある場合(たとえば、元の作成者がまだタグでリリースしていないCVE修正を適用する場合)をどのように処理しますか。 元の作成者のリリースにパッチを適用できるため、ベンダー戦略でこれを処理できるようです。 vgoがこれをどのように処理できるかわかりません。

@chirinoは、go.modファイルのreplaceディレクティブを使用して、パッチが適用されたパッケージを指すことができます。

@rsc

一見すると、protobuildは、所有していない他のパッケージにファイル(pb.go)をドロップできるという前提に基づいているように見えます。

これは、プロジェクトが行うことではありません。 GOPATHとベンダーディレクトリからインポートパスを構築します。 プロジェクト内のすべてのprotobufファイルは、そのインポートパスで生成されます。 また、特定のGoパッケージへのマップのインポートなども行います。

これの利点は、すべてを再生成することなく、依存関係で定義された他のプロトブフに依存するリーフプロジェクトでプロトブフを生成できることです。 GOPATHは、事実上、protobufファイルのインポートパスになります。

この提案の大きな問題は、ファイルシステム上のGoパッケージに関連するプロジェクト内のファイルを解決する機能が完全に失われることです。 ほとんどのパッケージングシステムには、これを行う機能がありますが、困難になります。 GOPATHは、これを非常に簡単に実行できるという点で独特です。

@stevvooe申し訳ありませんが、protobuildの機能についてはまだ混乱していると思います。 新しい問題「x / vgo:protobuildと互換性がありません」を提出し、現在存在するファイルツリーの簡単な実例、ツリーに追加されるprotobuildと、それがvgoで機能しない理由を教えてください。 ありがとう。

モジュール名を変更する必要がある場合(ドメインの喪失、所有権の変更、商標紛争など)はどうなりますか?

@jimmyfrasche

ユーザーとして:
次に、一時的な修正として、go.modファイルを編集して、同じインポートパスを維持しながら、古いモジュールを新しいモジュールに置き換えることができます。 https://research.swtch.com/vgo-tour

ただし、長期的には、すべてのインポートパスを変更し、go.modファイルを編集して新しいモジュールを使用する必要があります。 基本的に、vgoの有無にかかわらず行う必要があるのと同じことです。

パッケージメンテナとして:
go.modファイルを更新して、モジュールのインポートパスを変更し、ユーザーに変更を通知するだけです。

@jimmyfrasche

モジュール名を変更する必要がある場合(ドメインの喪失、所有権の変更、商標紛争など)はどうなりますか?

これらは、vgo提案が直接対処しようとしない実際の既存の問題ですが、最終的には明らかに対処する必要があります。 コードが消える答えは、キャッシュプロキシ(ミラー)とそれらを信頼する理由を用意することです。 それは将来の仕事です。 コード移動の答えは、タイプエイリアスがタイプリダイレクトであるのと同じように、モジュールまたはパッケージリダイレクトの明示的な概念を追加することです。 それも将来の仕事です。

コードが消える答えは、キャッシュプロキシ(ミラー)を使用することです。

本当に企業向けのIMO。 ほとんどの小規模企業やその他の企業は、すべての依存関係を同じリポジトリにベンダー化してコミットすることで完全に問題ありません。

上記のコメントで述べた互換性のために#24916を提出しました。
また、HTTPSアクセスを主張する代わりに、gitなどを直接使用することに戻ることを提案する#24915を提出しました。 コードホスティングのセットアップがまだAPI専用の準備ができていないことは明らかなようです。

計画されたvgogetコマンドを使用してmodファイルに一貫性を作成するためのマイナーな提案

「vgo-tour」ドキュメントでは、 vgo getコマンドは次のように表示されます。

vgo get rsc.io/[email protected]

このフォーマットをmodファイルにミラーリングするのはどうですか? 例えば:

module "github.com/you/hello"
require (
    "golang.org/x/text" v0.0.0-20180208041248-4e4a3210bb54
    "rsc.io/quote" v1.5.2
)

単純に:

module "github.com/you/hello"
require (
    "golang.org/x/[email protected]"
    "rsc.io/[email protected]"
)
  • コマンドラインとの一貫性を向上させる
  • 単一の識別子はアイテムを完全に定義します
  • 複数のバージョン管理されたパッケージ識別子を必要とするmodファイルで定義された操作をサポートするためのより良い構造

この提案が「バイナリのみ」のパッケージ配布をどのように扱うかについて、より明確にすることを求めています。

バイナリライブラリのバージョン管理/配布は、vgoに関する説明ドキュメントのいずれにも表示されていないようです。 これをもっと注意深く見る必要がありますか?

今日の動作方法では、プレーンなgitツールを使用できれば、 go getは問題なく動作します。 それがプライベートGithubリポジトリであるか、私自身のGitサーバーであるかは関係ありません。 私はそれを本当に愛しています。

私の理解では、そのように働き続けることは不可能になるでしょう。 本当? はいの場合、コードをチェックアウトするために、ローカルにインストールされgitバイナリを使用するオプションを維持することは可能ですか? (明示的なCLIフラグを使用しているイベント)

@korya最近提出された問題https://github.com/golang/go/issues/24915をご覧ください

@ sdwarwick 、re https://github.com/golang/go/issues/24301#issuecomment -382791513(go.mod構文)、#24119を参照してください。

https://github.com/golang/go/issues/24301#issuecomment -382793364に関して、私はあなたが何を意味するのか理解していない可能性がありますが、go getはバイナリのみのパッケージをサポートしたことがなく、計画していませんサポートを追加します。 必要になる可能性のあるさまざまなバイナリをすべて列挙するのは非常に困難です。 ソースを要求し、依存関係またはコンパイラが変更されたときに再コンパイルできるようにすることをお勧めします。

@AlexRouSgはい。 これらは「goget」ではサポートされていません(ただし、「gobuild」はビルドタイプとしてサポートされています)。これは@rscが参照しているものです。 これらのタイプのパッケージの配布は、「go get」ツールの外部で行う必要があるため、この新しい提案でも同じである可能性があります。

バイナリのみのパッケージの現在のサポートは、これまでと同じようにうまく機能しないと思います。 私はそれを取り除くために自分の邪魔をするつもりはありません。

ディスカッションの概要を再度更新しました。 また、古いcmd / goの最小限のモジュール認識についての提案については、#25069を提出しました。

@ kybin 、re https://github.com/golang/go/issues/24301#issuecomment-377662150vgo-v1-lockタグ、アピールはわかりますが、そのための特別なケースを追加することは、全体に特別なケースを追加することを意味します残りのモジュールサポート。 この場合、利益はコストに比例するとは思いません。 人々はすでに疑似バージョンを使用して同様の効果を得ることができます。 また、タグが移動したり、下位互換性が適切に尊重されなかったりすることも心配です(たとえば、セマンティックインポートのバージョン管理を回避するためにvgo1-v1-lockをv2.3.4からv3.0.0に移動します)。 ですから、バランスをとると、おそらくこれを行うべきではないと思います。

この提案が受け入れられたことを示す時が来たと思います。

それが何らかの形で受け入れられるかどうかについては、何の疑いもありませんでした。 代わりに、ここでの議論の目標は、正確な形式を考え出し、何を調整すべきかを特定することでした。 私がブログ投稿に書いたように:

Goの開発者は、私たちが知らない多くの巧妙な方法でGoを使用しているため、Goチームと私には見えない問題があることを私は知っています。 提案フィードバックプロセスの目標は、現在の提案の問題を特定して対処するために私たち全員が協力し、将来のGoリリースで出荷される最終的な実装ができるだけ多くの開発者にとってうまく機能することを確認することです。 提案討論問題の問題点を指摘してください。 フィードバックが届き次第、ディスカッションの概要とFAQを更新します。

ディスカッションの概要とFAQは、現時点で最新のものです。 ここでの議論とオフイシューは、次の重要な変更を促しました。

  • 古いcmd / go、#25069の最小限のモジュール認識。
  • 最小限のベンダーサポートの復元、#25073。
  • 直接Gitアクセスのサポートを復元する#24915。
  • go.mod、#24641に引用符をドロップします。
  • gopkg.in、#24099、その他のサポートが向上しました。
  • ブランチ識別子によるコミットの命名のサポート、#24045。

また、go.modファイル名と構文を変更する可能性についての議論も促されましたが、結果として生じる変更は引用符を削除することだけでした。

議論は終わりを告げ、GitHubにロードするのにかなり苦痛になるほど長くなりました(明らかに100のコメントが多すぎます!)。 提案に承認済みのマークを付けることで、vgoの使用と、Go 1.11に「プレビュー」として含める準備をすることに集中でき、GitHubがより迅速に読み込むことができる問題に移行できます。

もちろん、さらに多くのバグを見つけて修正し、さらに多くの設計調整を行う必要があります。 これらの詳細についての議論は、それらの詳細に固有の新しい問題について行うことができます。 「x / vgo:」プレフィックスとvgoマイルストーンを使用してください。

みんな、ありがとう。

@rsc今vgoを試す方法は何ですか? github.com/golang/vgoまたはgithub.com/golang/goをフェッチしてビルドする必要がありますか?

@ngrillygo get -u golang.org/x/vgoを使い続けます。

@rscは、この提案に多大な労力と時間を費やしていただき、ありがとうございます。 最終的に、Goの依存関係管理について良い話ができるようになることを願っています。

この提案が受け入れられたことを示す時が来たと思います。

提案を提出する個人が、それが受け入れられる準備ができたときに宣言することは適切ではないと思います。 提案を提出する人、特にこれほど大きくて意見のある人は、それが受け入れられることについて発言するべきではないと思います。 彼らの提案の提出は彼らの偏見を伝えています。 一方で、提起した後の心変わりがあったら、断言するのは間違いないと思います。

現時点では、 vgo内の技術的決定に関して、深刻な意見の不一致があるように感じます。私が恐れているのは、エコシステムとコミュニティを断片化することです。 そのことを念頭に置いて、競合する提案が完成し、スポットライトを当てるにはもう少し時間がかかると思います。 それが起こったら、議論と最終的な決定を容易にするために、複数の企業とコミュニティからの代表で構成される_中立的な_パーティーを開く必要があります。

Goのリーダーシップのかなりの部分が、Goの背後にあるコミュニティ(それを使用する他の企業を含む)から孤立しすぎており、その結果、言語とエコシステムが傷つき始めていることへの懸念が高まっています。 そのため、Goプログラミング言語のユーザーを反映した表現を備えた中立的なグループが必要であり、このような提案を承認するのに役立ちます。

最終的に、Google内でソフトウェアエンジニアとして働くことは、業界の大部分とは異なる視点をもたらします。 コア開発者のクリティカルマスがGoogle内にいることは、前進するときに必要な多様性に貢献しません。

@theckmanあなたの考え方は次のようです。

  1. Goに関する決定は、主にGoogleのエンジニアで構成される小さなチームによって行われます。
  2. Googleのニーズは非常に具体的であるため、Googleのエンジニアは他のコミュニティから隔離されています。
  3. これは、Googleの視点を支持し、他のGoユーザーには適応されない決定につながります。
  4. これは、Goコミュニティを傷つけ、断片化する可能性があります。
  5. この問題を解決するために、Goは、Goコミュニティの多様性(「民主的」なもの)を反映したグループによって共同で決定が下される正式な決定プロセスを採用する必要があります。

理論的には、私は「民主的」なものが好きになる傾向がありますが、実際には次のようになります。

  • 「小さな」Goユーザーを犠牲にして、Goチームが下した決定がGoogleのニーズに偏っているとは思わない。 非常に小さなショップ(Googleとは正反対)の開発者として、Goは私たちのニーズに非常によく適合しているように感じます。また、私の周りの他の小さなチームがGoを喜んで使用していることを知っています。 個人的には、Go言語に対する私が持っている唯一の不満は、Goチームによって認められており(依存関係の管理、ジェネリックスの欠如、冗長なエラー処理)、彼らはそれに取り組んでいると確信しています。 「民主的な」プロセスがあれば、Goチームが下した決定の例を挙げていただけますか?

  • 「民主的な」意思決定プロセスを採用することで、あなたが言及した問題が自動的に解決され、コミュニティを「断片化」するリスクがなくなるとは思いません。 これはBDFLモデルを改善する可能性がありますが、それ自体が安定性を保証するものではありません。 オープンソースの歴史、そして一般的な人類の歴史は、意見の不一致や対立によって台無しにされた民主主義社会の例をたくさん提供しています。

@ theckman@ ngrillyが礼儀正しくしようとしていた間、私は具体的に説明します。vgoの提案が受け入れられない理由について技術的な問題があれば、できるだけ早くここに教えてください。 いくつかの既知の問題が適切に対処されていないと思われる場合は、お知らせください。 そのような場合がない場合、「提案を受け入れる時が来た」と言う人の違いは何ですか? 技術的な理由で十分ではないと思われる場合は、2か月間話し合いました。教えてください。

理由もなくここに政治を追加したいようですが、それはすべてを遅くするだけです。それは、私たちが十分に幸運であり、他の害を及ぼさない場合です。 そして、これには理由があると信じている場合でも(これはこれを議論するのに適切な場所ではありません)、代わりにメーリングリストでこの議論を開始してください。

皆さん、もう1つのオフトピックコメントでごめんなさい!

@powerman足が不自由で、私の以前のコメントを引用して申し訳ありません:

現時点では、vgo内の技術的な決定に関して、深刻な意見の不一致があるように感じます。私が恐れているのは、エコシステムとコミュニティを断片化することです。 そのことを念頭に置いて、競合する提案が完成し、スポットライトを当てるにはもう少し時間がかかると思います。

代替案が出てくることは承知しており、時間があるまでキボッシュに受け入れてもらうようお願いしました。 依存関係の管理はしばらくしていないので、他の提案の仕上げをしながら短期滞在を求めるのは無理はないと思います。

フォーマットが少し制約されているという理由だけで、この問題でそれをうまく表現するのが簡単かどうかはわかりません。 それでも、基本的にWIP提案の一部を複製するので、躊躇します。 アイデアを断片化したり、作者から雷を盗んだりしたくありません。

しかし、それらの提案が進行中であり、誰がそれらに取り組んでいるのかを知ることで、これが準備ができているという宣言は、それらの競合する意見を抑圧する積極的な試みであるように感じました。 Gopherとしての長年の間に観察したパターンのために、これらの懸念を提起せざるを得ないと感じました。 私は本当に言語、エコシステム、そしてコミュニティが成功することを望んでいます、そしてこれらはその目標だけを念頭に置いて育てられています。

編集:明確にするために、短期滞在とは、2か月などを意味するものではありません。 私は数週間を意味します。

@ngrilly申し訳ありませんが、あなたのコメントを無視するつもりはありませんでした。 私はそれを以前のものに対処することを計画しましたが、私が望んでいたよりも冗長になってしまいました。

2つの問題があると思います。 これらの決定がどのように行われるかについて別のフォーラムで議論することがあると感じているので、その周りにいくつかのコンテキストを追加しましたが、他の提案が完了するまで、この提案の受け入れを一時的に停止することに焦点を当てたいと思います公開する機会がありました。

代替案が出てくることは承知しており、時間があるまでキボッシュに受け入れてもらうようお願いしました。 ... [K]それらの提案が進行中であり、誰がそれらに取り組んでいるのかを知ると、これが準備ができているという宣言は、それらの競合する意見を抑圧する積極的な試みであるように感じました。

そうではなかったことを保証します。 私はここでタイムラインについてかなり明確にしています。 2月中旬からの私の最初の投稿では、目標はvgo提案をGo1.11に統合することであると述べています。 開発フリーズが近づいています。 進行中の他の提案や、誰がそれらに取り組んでいるのかについては何も知りません。 それは私にとってのニュースです。 人々がこの提案に関与したり、反対の提案をしたい場合、この提案は1か月半開いているので、少し遅れています。

明確にするために、Golang Weeklyや他の人が報告したことにもかかわらず、私は提案が受け入れられたことをマークしませんでした。 私はそうする時が来たと思うとだけ言った。 つまり、最初にそうすることについて一般的なコンセンサスがあったことを確認したかったという理由だけで、私は提案承認ラベルを適用しませんでした。 そして、少なくともここでの全体的な議論とhttps://github.com/golang/go/issues/24301#issuecomment -384349642の絵文字カウンターから判断すると、一般的なコンセンサスは受け入れに賛成しているようです。

私は代替案が来ていることを知っています

@theckman 、あなたがこのようなことを知っているなら、おそらくあなたはそれを知っている唯一の人です。 今日まで、この問題を提起している人は今まで見たことがありません。 Go 1.11でこれを試してみたいというラスの発言は最初から非常に明確だったと思います。したがって、誰かが代替案に取り組んでいる場合、ヘッズアップとしても、提案するのに約2か月かかりました。

また、Goチームが気まぐれで決定を下さなかったという良い実績があるという事実を受け入れることができると思います。そして、Go 1.8から最後の瞬間にエイリアスをどのように引っ張ったかを見ると、それは正しくありませんでした。その時にやるべきことは、少なくとも彼らが彼ら自身の実験/解決策を構築することを許可するという礼儀を彼らに与えるべきです。

結局のところ、この提案は、使用する依存関係のバージョンを選択する方法に関する単なるアルゴリズム以上のものをもたらします。 誰かがそれを改善する方法を見つけた場合、2つのオプションがあります。通常のCLプロセスを介して送信するか、独自のツールを作成してコミュニティに使用させることです。 Goチームは、独自のバージョンのツールimhoを引き続き提供できるため、これに解決済みの問題があるとは思われません。

ただし、これまでのところ、Goチームではなく、コミュニティによって行われた分割アクションのほとんどに注意してください。 Goチームにツールを作成する機会を与え、それが実行可能であるときにそれを評価し、それがどれほど悪いかについて書くのではなく、それを改善して前進する方法について議論をテーブルに持ち込みましょう。

これを別の種類のエクスペリエンスレポートの一部と見なしてください。私がAlias提案の_非常に_声の反対者であったものを理解し、現在、提案が実際に動作していることを確認します。

編集:元のメッセージには非常に残念な省略がありましたrecord of *not* making decisions on a whimはテキストであるはずでしたが、残念ながら「not」の部分が欠落していました。 お詫び申し上げます。

私は提案に関する基本的な懸念の詳細な記事を持っています。 一度に紹介できるように、この記事を完成させようとしています。これは複雑で微妙な領域であるため、これらの問題は完全に対処する必要がありますが、生活と仕事がそれを困難にしています。

私はSlackでこの記事をほのめかし、その一部を@rscと直接話し合ったが、これまでここではこれらについて言及しないことを選択した。 私が完全にリリースする準備ができる前にこの記事を宣伝することは、ひどく建設的ではないように私には思えました。 でも、すでにお伝えしているように、2ヶ月が経ちましたので、来週からシリーズをスタートさせるために大いに力を入れていきます。

(編集:これは@theckmanが参照していた「代替」です)

@sdboyerあなたは複数の懸念があると述べました。 少なくとも今すぐ彼らのリストを公開していただけませんか?
私は依存関係地獄を別のレベル(chef、go、npm、composer)に持っていくいくつかのシステムで作業しています。経験から、この提案は行くことに関してそれらすべての解決策です。

@ theckman@ sdboyerのフィードバックのみを参照していることを確認できますか? それは秘密ではありません。 サムは、vgoがリリースされた最初の日に文字通りそれについて言及しました(「私は私の懸念についてより詳細な文書を書いています」-https://sdboyer.io/blog/vgo-and-dep/)。 しかし、それは提案ではなくフィードバックであり、複数形の「他の提案」を何度も参照しました。 あなたが知っていることはもっとありますか?

go / types APIユーザーにとってのvgoの意味は何ですか? go / typesサポートの現在の状況はどうなっていますか?

vgo対応のgo / types.Importer実装を追加するためのPRmdempsky / gocode#26を受け取りましたが、これが必要かどうか/なぜ必要かはわかりません。

必要であると仮定して、正規のvgo対応のgo / types.Importerを別の場所(たとえば、x / vgoまたはx / tools repo)に追加して、go / typesベースのツールがこのサポートを再実装する必要がないようにすることはできますか? ?

私はvgoの詳細を実際にはフォローしていないので、これは単に「影響なし」である可能性がありますが、上記のgo / typesについての言及はありません。 「vgogo / types golang」のグーグル検索も、同様に有益ではありません。

ありがとう。

@mdempsky 、計画はvgo対応(さらに言えば、キャッシュ対応のビルド)パッケージローダー(おそらくgolang.org/x/tools/go/packages)を用意することですが、まだ存在していません。 捨てる必要のあるコードを書くのではなく、そのパッケージを待つ必要があります。 PRをマージしないでください。 コメントしました。

@mdempskyhttps://github.com/mdempsky/gocode/pull/26で返信する予定でしたが、ここで返信します。

https://github.com/mdempsky/gocode/pull/26は完全に使い捨てです。 vgoに対して現在放棄されているCLを使用する概念実証にすぎません。

@rscの返信を見たばかりなので、 https: //github.com/golang/go/issues/14120#issuecomment-383994980でも議論が行われていることを簡単に指摘しておきます。

概要:バージョンに関する数年の経験の後、最後の最善の試みは、非常に複雑なアルゴリズムであるsatソルバーでした。 しかし、入力データにいくつかの簡単な変更を加えると、NP完全決定問題は管理しやすいだけでなく、非常に高速になります。

NPMの使用経験が豊富なGoの小規模チームユーザーとして、私はvgoの提案が非常に気に入っています。 FWIW、私はvgoがgo適切に実装されることを楽しみにしています。そして、それが私のチームと私にとってより早く導入されることを楽しみにしています。

私が特別な人というわけではありません。小さなチームの問題についての議論を見たので、チャイムを鳴らそうと思ったのです。

これが私のレビューです。

表面的には、プロポーザルドキュメントの最後のリビジョンの_Proposal_セクションは、あまり具体的ではないにしても、問題ないように見えます(たとえば、 Subversionがどの程度サポートされるかは不明です)。 1つの例外は、「1つの限定された使用を除いて、ベンダーディレクトリの使用を禁止する」ということは、ベンダーディレクトリが非モジュールパッケージでまったくサポートされないことを示しているように見えることです。 そうですか?

一方、この提案は、現在のgo getのさまざまな利点を損なう特定の設計および実装の決定を暗示しています。 損失は​​許容できる場合もあれば、回避される場合もありますが、 vgo getgo getに置き換わる場合は、設計上の考慮事項として対処し、議論する必要があります。そうしないと、ツールが完成する可能性があります。適切な代替品ではなく、 vgogoにマージされないか、 go getがサードパーティのツールとして復活する必要があります。

_Implementation_セクションには、次のように書かれています。「今後のリリース(Go 1.13など)では、非モジュールのgogetのサポートを終了します。 GOPATHでの作業のサポートは無期限に継続されます。」 これは面倒です。 まず、何年も更新されていない優れたプロジェクトがたくさんあります。 Go 1の互換性の約束のおかげでまだ機能しますが、多くの人はgo.modファイルを追加しません。 次に、依存関係のないプロジェクトの開発者、またはバージョンを気にしない開発者に、モジュールファイルを追加するか、新しいgo getエコシステムを控えるように強制します。 これが欲しいのは当然かもしれませんが、その理由を説明してください。 (私にとっては、不必要に面倒に思えます。古いgo getのフォークを使用したいと思います。他の言語のパッケージマネージャーはさらに面倒であることに同意します。 vgoそれらよりも優れていますが、現在のgo getよりも優れたユースケースを処理することはできません。

vgo vs goに関する私の主な関心事は、それらがサポートするワークフローにあります。 私はvgo-introの投稿でそれを表現しました。 これは、提案の_Compatibility_セクションに広く属している場合もあれば、その範囲外である場合もありますが、ここで提起された他の質問や問題に対応しています。

参考までに、これが私のvgo-introコメントのコピーです。

今後のリリースでは、バージョン管理されていない古いgogetのサポートを削除する予定です。

提案の他の側面は問題ないように聞こえますが、これは残念なことです。 (バージョン管理ツールチェーンにバージョン管理を組み込むか、バージョン管理ツールを使用し続けるかを選択する必要がある場合は、後者を選択します。)vgoの利点は、再現性のあるビルドを容易にし、プロジェクトの中断を遅らせることです。プロジェクトの作成者(go.modファイルを使用)がそれに直面するまで、互換性のない更新が原因です。 しかし、go getの利点は、モノリポジトリの利点をマルチリポジトリの世界にもたらすことです。依存関係の完全なクローンにより、独自のプロジェクトと同じように簡単にそれらを操作できます(履歴の検査、編集、差分の変更。何かの定義に行き、それを非難します)、それはコラボレーションを促進し(あなたは単にあなたの変更をプッシュして提案します)、そして一般的にいつでも世界のただ1つの現在の状態-各プロジェクトの先端-そしてすべてが存在するという見解を課します他は歴史です。 このユニークなアプローチ(実際のモノレポ以外)は、Goエコシステムの特徴的な恩恵であり、悪いことよりも良いことをしたので、放棄すべきではないと思います。

提案のより微妙なマイナスの結果は、バージョン管理が不治で継承可能になることです。プロジェクトがバージョンにタグを付けると、新しいバージョンにタグを付けることなく、将来の変更がユーザーに届くことを期待できません。 元の作成者がタグ付けを継続することを決意している場合でも、フォークの作成者はタグ付けを強制されるか(ソースプロジェクトがまだアクティブな場合は特に厄介です)、古いタグを削除する必要があります。

全体として、依存関係管理に対する現在のGoアプローチは、バージョン管理よりも全体的に優れていることを強調したいと思います。 これは、すべてのコミットが表示されることを期待する最新の動的で協調的なオープンソースとの整合性が高く、リリースのソースのみを公開する(または「内部変更を巨大な非記述的コミット」に統合する)だけでは不十分です(可視性とコラボレーションが大幅に低下するため)とダイナミズム)。 モノリポジトリと現在のGoエコシステムの両方で、ほとんどのプロジェクトにバージョンが必要ないことがわかります。 もちろん、このアプローチは究極ではなく、欠点もあり、バージョン管理されたプロジェクトをサポートすることも重要ですが、バージョンなしのプロジェクトを犠牲にしてこれを行うべきではありません。

要約すると、現在のgo getgodefなどの補助ツールを使用)は、次の機能を備えたワークフローをサポートしています。

  • 依存関係の編集可能なソースコード
  • VCSでの依存関係のソースコード
  • 依存関係の最新リビジョン

依存関係のソースコードは編集可能なままであると推測できます。つまり、 godefは、_書き込み保護されていない_ファイル_にリンクし、ビルド中に使用されます。 ただし、 vgoは、他の2つのポイントを更新します。 2番目の点に関しては、#24915はVCSツールのサポートを延長しましたが、それでもそれを削除するという目標を宣言しています。 ワークフローでは、依存関係がVCSからチェックアウトされるだけでなく、チェックアウトが開発者にとって有用であり(たとえば、浅いgitチェックアウトではなく、 .gitが削除されたgitチェックアウトではない)、ビルド中に使用される必要があります。 、ただし、 vgoはこの要件を満たさない場合があります。 3番目の点に関しては、vgo-introコメントでその価値を正当化しましたが、 vgoはそれを完全に放棄しているようです。

Goバージョニングツールは、現在のワークフローのサポートを削除する必要はありません。また、Goエコシステムで作業するという独自の利点を維持し、 go getの適切な代替となるために、サポートを削除してはなりません。 vgoの設計はこれを困難にしますが、明らかに実行不可能ではありません。 一方、プロポーザルの_Proposal_セクションは、現在のワークフローとほぼ互換性があるようです。 3番目のポイント(最新のリビジョンをチェックアウトする)をサポートするために導入する唯一の課題は、大きな問題ですが、v2.0.0以上のモジュールについて、 masterでチェックアウトできるかどうかを判断するのが難しいことです。 masterが別のメジャーバージョンであるため、指定どおりにチェックアウトする必要があるかどうか。 これは、 gopkg.inを使用する現在のgo getにとっては難しいことではありません。これは、すべてがデフォルトでmasterでチェックアウトされ、gopkg.inの内容が一致するタグまたはブランチでチェックアウトされるためです。 しかし、 vgoはこの区別を曖昧にし、gopkg.inモデルをすべてのパッケージに広げます。 (さらに、ブランチの一致を停止します。)実際には、指定されたメジャーバージョンの最新リビジョンを取得する方法を確実に推測する必要があります。

私はそれを見逃したかもしれませんが、このシナリオでvgoはどのように機能しますか?

  • 私はlibXに応じてサービスAとサービスBの両方に取り組んでいます(私も取り組んでいます)
  • libXに大きな変更が必要です

現在の方法では、変更を行い、サービスAとサービスBをコンパイルし、libXの$ GOPATHにあるものをすべて取得し、修正してから、主要なsemverバンプでlib Xをプッシュしてから、両方のサービスをプッシュします。 AとBは、 Gopkg.tomlでlibXの新しいメジャーを使用するように指示します。

vgoが引き継ぐと、私のサービスのgo buildはgithubから存在しない新しいバージョンのlib Xを見つけようとしますが、あらゆる種類の問題を予測できます。

それで、私は明白な何かを逃していますか?

このタイプのものにはreplaceディレクティブを使用できます。

2018年4月30日月曜日、12:15 [email protected]は次のように書いています。

私はそれを見逃したかもしれませんが、このシナリオでvgoはどのように機能しますか?

  • 私はlibXに応じてサービスAとサービスBの両方に取り組んでいます(私は
    にも取り組む)
  • libXに大きな変更が必要です

現在のやり方では、変更を加え、サービスAをコンパイルして
サービスB、彼らはlibXの$ GOPATHにあるものをすべて取得します、私はものを修正します、
次に、主要なsemverバンプを使用してlib Xをプッシュし、次にサービスAとBの両方をプッシュします。
Gopkg.tomlでlibXの新しいメジャーを使用するように指示します。

これで、vgoが引き継ぐときに、サービスを構築して、
githubからのlibXの既存の新しいバージョン、そして私はあらゆる種類のことを予見することができます
トラブル。

それで、私は明白な何かを逃していますか?


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/golang/go/issues/24301#issuecomment-385499702 、またはミュート
スレッド
https://github.com/notifications/unsubscribe-auth/AAuFsfnD8_kbUj8fSXvGgeN77ki6KYM6ks5tt2LLgaJpZM4Sg3bp

@kardianosええ、でもそれでも試してみるにはlibの変更をプッシュする必要があるということですか?

編集:置換にパスを使用できるようです(https://github.com/golang/go/issues/24110)。これは良いことです。 しかし、これが何度もコミットされることになることも予測できます。

go.mod.replaceなどの追加ファイルを作成して、開発環境でオーバーライドを定義し、それらをgitignoreできるようにする計画はありますか?

@primalmotion不正なコミットを防ぐには、おそらくgitフックを使用する必要があります。

しかし、正しい答えは、これをあまり頻繁に行わない(ローカルパスに置き換える)ことだと思います。 ライブラリが非常に緊密に結合されている場合は、別のリポジトリに配置しないでください(したがって、緩く結合されているふりをします)。 一般的に、これらのサービスの現在の実装を考慮せずに、そのlibを修正、テスト、およびリリースできるはずです。 特にvgoの場合、両方のサービスが古いバージョンのlib(以前に使用していたもの)を手動で更新してそのlibの新しいバージョンに更新するまで、両方のサービスが引き続き使用されることを保証します。 1年に1回、ローカルパスへの置換をときどきコミットする場合、それは大したことではありません。CIは、これに気づき、数分で修正するのに役立ちます。

go.mod.replaceがバージョン管理されていない@primalmotionを使用すると、再現できないプロジェクトをコミットできます。 代わりに、 go.modでreplaceを使用すると、現在使用してテストしているものを正確にコミットできます。
置換でコミットするのは間違いかもしれませんが、それに気づいて修正するでしょう。
または、任意である場合もあります。サブモジュールを使用して実行します。プロジェクトとライブラリを一緒に作業する場合は問題ありません。サブモジュールをコミットすると再現可能です。 私はPythonで頻繁にそれを行い、Goではそれを見逃しました。 vgoを使えば、またそのように作業できることを嬉しく思います。 _(私の悪い英語で明確になることを願っています、ごめんなさい)._

問題は、気にすることを決定するまで(つまり、リリースを準備するとき)、再現可能なビルドを気にしないことです。 libの更新がチェックアウト、再構築、テストの実行だけである非常に機敏な開発環境があります。 サービスのマスターブランチでGopkg.lockをコミットするのではなく、外部ライブラリの固定バージョンと主要な制約を含むtomlだけをコミットします。 リリースブランチを作成したら、Gopkg.lockをコミットしてから、再現可能なビルドを作成します(これは、ciによって実行されます)。

Vgoは基本的に、私たちが長年にわたって構築してきたすべてのワークフローを壊します。 ここで、libでの小さな印刷デバッグ(私たち全員がこれを行うので、嘘をつかないでください:))、または少しの最適化のような愚かなことを試すには、数十のサービスを調べて、 replaceを追加する必要があります

何が私たちのためにvgoを機能させることができますか:

  • 私が述べたようにオーバーライドシステム
  • それをまったく使用せず、開発のために古き良きGOPATHにフォールバックする方法。

そして、それが素晴らしいので、私たちは本当にそれが私たちのために働くことを望んでいます。

go 1.11(現在フリーズ中)でテストするものがありますか、それとも1.12に行くことができますか?
すでに実験的なものとしてマークされています。 そして、実際の開発でテストする人が多ければ多いほど、フィードバックの価値は高くなると思います。

バージョン管理されたパッケージに関する問題について読みました。 簡単なシナリオの1つとして、 foo-plistという名前のplistを解析するためにdepを使用するというライブラリを作成する場合。 解析の結果として、そのplistライブラリはそれ自体の特定のタイプを公開します。 これで、ライブラリがv2にアップグレードされ、これらのplistタイプのオブジェクトが返された場合、ライブラリはv2にアップグレードする必要があります。

たとえば、この提案の印象の下で、前述のplistライブラリのv1とv2の両方をサポートするライブラリが必要な場合、これを解決するのは非常に難しいようです。

たとえば、npmでは、ライブラリはピアの依存関係を指定して>=1.0.0|>=2.0.0と言うことができ、使用するplistのバージョンを決定するのはライブラリのユーザー次第です。 したがって、私のライブラリfoo-plistのユーザーがplistに依存する別のライブラリも使用している場合、両方のライブラリがplistのv1とv2に満足している場合、ユーザーはどちらを選択するかを選択できます。実際にインポートします。 さらに重要なことに、両方のライブラリがplistタイプをエクスポートする場合、それらのタイプは実際には互換性があります。

それらが異なるインポートパスになる場合、それをサポートする方法はないと思います。

@ itsnotvalid foo-plist.2は、foo-plistをインポートし、タイプエイリアスを使用してそのタイプを再エクスポートできます。 この手法の適切な説明は、 https://github.com/dtolnay/semver-trickにあります。

Aramはここで、以前のリリースのブランチ(またはディレクトリ)への変更をバックポートすることの難しさについて指摘しました。 同じモジュール内のソースへの「自己」参照にはインポートパスのバージョンも含まれるため、パッチが正常にインポートされないか、誤ってバージョン間のインポートが導入される可能性があります。

考え?

明確にするために、私はインポートパスのバージョンを使用したモジュール間のインポートに完全に慣れています。 ラスの議論は非常に説得力があると思います。 モジュール内のインポートについては、あまり明確ではありません。 ビルド内の特定のパッケージに単一のインポートパスを設定するという目標は理解していますが(モジュール間でインポートされているか、独自のモジュール内でインポートされているかに関係なく)、選択する必要がある場合は、次のソリューションが必要です。このプロパティを維持することよりもアラムの問題。 (また、ビルドシステムは、最上位モジュールをビルドするときにmodファイルからバージョンを挿入し、モジュールの依存関係をダウンロードした後、文字通りソースに挿入できると思います)

@rscこれを前進させる可能性はありますか? これを妨げる大きなものは何も見当たりません。

これについて焦っているように思われる場合は申し訳ありませんが、vgoのサポートに取り組んでいるツールが増えており、これを遅らせるほど、ツールのメンテナである私たちがこれを行ったり来たりするのが混乱します。 。

@sdboyerは今週彼の記事を公開する予定です。 彼らを待つのは公平だと思います。

どの依存関係バージョンを選択するための解決アルゴリズムが、モジュール、プロキシサポート、バージョン管理なども含む提案全体をブロックする原因になるべきではないと思います。

そして、後でこれらの依存関係をダウンロードするためのアルゴリズムを改善/変更することを決定した場合、他に影響を与えることなくそれを行うことができます。

私は@dlsniperに同意します-私たちはすでに凍結状態にあり、vgoデザインが導入されてからほぼ3か月が経ちました。 1.11での作業がさらに遅れると、1.12に戻されるのではないかと心配しています。

シリーズの最初の投稿はついにライブになります。 公開に時間がかかり、シリーズが終了するまでにさらに時間がかかることをお詫び申し上げます。 しかし、最初の投稿は、私がシリーズ全体でカバーしようとしているトピックの大まかな概要を提供しているので、人々は少なくとも範囲の感覚を得ることができるはずです。

簡単に言うと、vgoには素晴らしいことがたくさんあり、その多くはコミュニティとして長い間望んでいました。 ただし、MVSは目的に適さないため、本番環境に移行するべきではないと思います。 私たちが望んでいるこれらのものの多くがMVSに巻き込まれているのは残念です。特に、MVSに固有のものが非常に少ない場合はなおさらです。 私は別のアプローチに取り組んでいます。これはブログシリーズ全体で比較のために参照されており、最終的な投稿で明確に示されます。

私が取り組んでいる代替コアアルゴリズムは、 go.modをに移行するのが非常に簡単である可能性が高いため、問題が発生することはないと思います。依存関係の推移閉包を含み、ビルドリストアルゴリズムではなく、コンパイラが読み取るものである別のロックファイルが追加されました。 (ロックファイルには他にも理由がありますが、それはポスト5にあります。)少なくとも、それは私たちにエスケープバルブを与えます。

ただし、MVSは一時的なものであっても問題ないと言えば、慣性の利点が得られます。 その時点で、 @ rscには不十分であることを証明する必要があります(実際には、マージされる前からすでに標準として設定されています)。彼は、これがgo getについての真のステートメントであると信じています。

今日、多くのプログラマーはほとんどバージョン管理に注意を払わず、ほとんどすべてが正常に機能します。

上記のすべてを考えると、これを先に進めると「ジェネリック、ラウンド2」が作成されるのではないかと心配しています。ただし、今回は、マシンではなく、相互作用を制御するルールに関するものです。

ただし、MVSは一時的なものであっても問題ないと言えば、慣性の利点が得られます。

現在、depには慣性の利点があることに注意してください(他の言語のバージョンマネージャーと同じ敷地内に構築されていることと、幅広いコミュニティのサポートを受けてより長く存在することの両方によって)。 少なくとも私にとっては、vgoの提案は、優れた議論に支えられた優れた設計であるため、この慣性を克服することができました。

個人的には、Goでのバージョン管理が遅れてもかまいません。私はすべて、迅速ではなく正しいことを行うことに賛成です。 しかし、少なくとも現時点では、vgoはまだ私にとって正しい解決策のように見えます(そして、コミュニティのAIUIの多くの人々は、これを緊急の問題として認識してます)。

@mvdanこの変更には、その影響がないわけではありません。 私たちは皆これを望んでいますが、特に疑問を提起する人が明らかに問題に多くのことを考えている場合は、疑問を鎮めるために余分な時間をかけることも賢明だと思います。

フリーズと、 1.11 vgoのプレビューを取得することへの影響についての言及を聞き続けています。 これが1.11で統合されるかどうかについてのこの時点での公式ラインは何ですか? この問題は、潜在的な影響を考えると驚くほど静かに思えます。

@sdboyerこれが1.11にマージされるべきかどうかについてのあなたの立場は、あなたがMVSでのあなたの立場を公式に_ちょうど_だけ公に述べていることを考慮してどうですか?

これが1.11にならない場合は、2019年2月の1.12まで正式にプレビューできず、8月の少なくとも1.13まで正式にリリースされます。 2019.これにより、 @ rscが最初に議論を開始してから18か月後に最も早いリリースが可能になります。 もちろん、これを不必要に急ぐべきではありませんが、 @ Meroviusが前述したように、私を含め、多くの人々は依存関係管理への公式の対応を「緊急の」問題と考えています。 18ヶ月待つのは行き過ぎのようです。

確かにdepが公式の回答になると思われ、リポジトリをそれに変換しました(そしてその結果に満足しています)。 この提案により、長期使用のためにdepが事実上非推奨になりますが、 vgoの統合を開始する公式の方法はありません(少なくとも#25069がマージされるまで)。保管寿命が非常に限られていることがわかっているツール( depを使用)を使用します。

FWIW、 vgo1.11の提案として統合し、#25069を1.11に含める(そして1.9へのパッチリリースとして)ことで、これを前進させるべきだと絶対に思います。 1.11のリリース時に$#$と1.10 #$)。

私は正直に言って、MVSの完全な意味とそれに関する@sdboyerの懸念を理解していません。 しかし、この分野での彼の経験を考えると、これらの懸念は真剣に検討する価値があると思います。 とは言うものの、彼がvgo1.11のMVSと統合することに参加している場合(彼の[まだ進化している]提案が[ 1.12 ]で受け入れられた場合、モジュールを壊してはならないことを理解しながらもともとMVS用に設計されたものです)、それなら先に進まない理由はありません。

また、この提案について@rscに感謝します。 Goが別のツールのアプローチをコピーしただけでなく、慣用的な方法でこの問題に対処しようとしていることを感謝します。 依存関係の管理は決して楽しいものではありませんが、この提案により、Goは業界を前進させ、現在は最高のシステムと見なされているシステムを飛躍させる可能性があるようです。

私の$ .02を追加するだけで、私の意見では、MVSは依存関係管理の「あはは」の瞬間です。 人々がそれに向けて考えてきた量に感謝しますが、MVSはこれが進むべき場所であると確信しています。

私は特に、他の人が提起した点に同意します。「自動セキュリティ修正」は、せいぜい夢のようなものであり、最悪の場合、ワームの巨大な缶です。

さらに、私は@joshuarubinと一緒です:依存関係管理への公式の対応は緊急の問題です。 他の人は、MVSを今すぐ進め、後で必要に応じて他のソリューションに変更できるとコメントしています。 それが本当に可能なら、それがより良い方法だと思います。

次の方法で、メジャーバージョンをインポートパスから切り離すことを提案します。 (私はvgo-importの理由を説明し、そこに記載されているvgoの成果を低下させないと信じています。)これは、Go 1.9および1.10のgo buildが学習する必要があるという#25069のアイデアに触発されています。インポートパスを創造的に解釈します(バージョン部分を削除することにより)。 私の提案では、古いgo buildは変更されませんが、 vgoは同様のトリックを学習します。


構文的には、唯一の変更点は次のとおりです。

  1. .goファイルでは、$ v2がディレクトリの場合はimport "repo/v2/pkg"import "repo/v2/pkg"のままですが、それ以外の場合import "repo/pkg"になります。 これにより、現在のgo getとの互換性が維持されます。
  2. go.modファイルでは、 module "repo/v2"v2サブディレクトリにある場合は同じままですが、トップレベルにある場合はmodule "repo"になります。 (これは正規のインポートプレフィックスです。)
  3. go.modファイルには、 require repo v2.3.4 as repo2と書くこともできます。 次に、 .goファイルでimport "repo2/pkg"を使用します( v2がディレクトリの場合はimport "repo2/v2/pkg" )。 これは現在のgo getではインポートできません( require github.com/owner/project v2.3.4 as gopkg.in/owner/project.v2のようなものを使用しない限り)が、これは同じモジュールで複数のメジャーバージョンを使用する場合にのみ必要であり、依存関係はそうではありませんメジャーバージョンをサブディレクトリに保存します。これは、現在のgo getではサポートできません。

技術的には、これによりgo.modを次のように書くことができます。

require repo v1.0.0
require repo v1.1.1 as repo1
require repo v2.2.2 as repo2
require repo v2.3.3 as repo3

ただし、最小バージョンの選択により、 reporepo1の両方が$ v1.1.1のリポジトリを参照し、 repo2repo3が参照されるようにこれが解決されます。 v2.3.3 。 このエイリアシングを許可するか禁止するかはわかりません。


利点:

  • モジュール対応コードは、v2.0.0を過ぎても、現在のgo getと互換性があります。 その結果:

    • go get最小限のモジュール対応にする必要はありません(#25069)

    • v2.0.0以降のプロジェクトは、モジュールとの互換性を損なう必要はありません-認識しないgo get

  • プロジェクトは、依存関係がモジュールになるのを待ってから、モジュール自体になる必要はありません[1]
  • モジュールを認識しないプロジェクトを非推奨にしたり、作成者が新しいモジュールを認識しないプロジェクトを開始するのを思いとどまらせたりする必要はありません。
  • 現在のgo getのバージョンレスワークフローのサポートを維持しやすくなります(ここ上記で説明)

短所:

  • すでに書き込まれたgo.modファイルが引き続き機能するという約束を守るのは不便かもしれません(新しいモジュールファイルの名前がgo.modと異なる場合を除く)

アンビバレンス:

  • 異なるモジュールの同じインポートパスが異なるメジャーバージョンを参照する場合があります

    • 良い:v2.0.0以降およびメジャーバージョンの変更時の保守が容易

    • 悪い例: go.modを見ないと、どのメジャーバージョンを使用しているかわからない

  • モジュールは、コード内で使用するために任意のインポートプレフィックスを定義できます

    • 一部のユーザーは、すべてを短い名前でインポートすることを選択します(たとえば、 import "yaml"require gopkg.in/yaml.v2 v2.2.1 as yaml

[1]現在、 vgoは、モジュールの非モジュラー推移依存関係がv2.0.0を超えていない場合にのみ、非モジュラー依存関係を適切にサポートできます。 それ以外の場合、プロジェクトは、v2.0.0以降のプロジェクトに間接的に依存するすべての依存関係がモジュールになるのを待つ必要があります。

https://github.com/rsc/corpusのパッケージから見つけたGopkg.tomlファイルの分析を行い、https://github.com/zeebo/dep-analysisに要約を書きました そこにあるデータに基づくと、vgoが特定されたほとんどすべてのユースケースを処理できないという証拠はあまりないようです。

これがコミュニティの恐怖を軽減し、ツールを実際に体験して作成するためにさらに6か月かかることを忘れずに、提案をそのまま進めるという合意に達するのに役立つことを心から願っています。発生する可能性のある問題を修正するために必要な変更。

私があなたを引用するならば:

すべての制約のほぼ半分は、実際にはまったく制約ではありません。マスターブランチを指しています。

これはおそらく、マスターだけがタグなしまたは「v2、v3のような名前付きブランチ」が存在するためです。その場合、選択肢がないため、比較は公平ではありません。

@mvrhov 「不公平」とはどういう意味かわかりません。 私には、vgoとdepがそのケースをうまく処理するように思えます。 むしろ、現実的な代替案、そのケースをうまく処理する必要があります。 特に:リリースされたバージョンがまだない場合、vgoの世界では、v1.0 / v0.xのタグを付けるだけで、インポートパス(vgoの主な特異性)を変更する必要はありません。

分析のポイントは、私が知る限り、さまざまなアプローチによって引き起こされる現実の痛みを推定することです。 この事件がどのように実際の苦痛をもたらすのか私にはわかりません。

この提案は2か月以上にわたって活発な議論が行われており、@ rsc@ spf13はフィードバックセッションを実施し、コミュニティから貴重な意見を集めて提案を改訂しました。 @rscは、さらにフィードバックを得るために、 @ sdboyerと毎週ミーティングを開催しています。 追加の改訂をもたらした提案について、貴重なフィードバックが提供されました。 ますます、このフィードバックは、提案ではなく、付随する実装に関するものです。 かなりのレビューを経て、この提案を受け入れ、Goのツール実装者の幅広いエコシステムが重要な調整を開始して、ユーザーベースが可能な限り最高のエクスペリエンスを享受できるようにする時が来たと感じています。

この提案には2つの反対意見があり、私たちは話し合うべきだと感じています。

  1. この提案では、ライブラリの使用とリリースに関する慣行の一部を変更する必要があります。
  2. この提案では、非互換性に関連して発生する可能性のあるすべてのシナリオに対する技術的な解決策を提供できません。

これらは観察において正確ですが、意図したとおりに機能します。 コードの作成者とユーザーは、開発者がgofmtの実行など、Goの他の詳細に適応したように、ライブラリの使用とリリースに関する慣行の一部を変更する必要があります。 ベストプラクティスを変えることが正しい解決策になる場合があります。 同様に、vgoは非互換性を含むすべての可能な状況を処理する必要はありません。 RussがGopherconSingaporeでの最近の講演で指摘したように、非互換性に対する唯一の永続的な解決策は、非互換性を修正し、Goパッケージエコシステムを維持するために協力することです。 vgoやdepのようなツールでの一時的な回避策は、開発者が実際の問題を解決する時間を与えるのに十分な時間だけ機能する必要があり、vgoはこの仕事を十分に行います。

この重大な問題に寄せられたすべてのフィードバックと情熱に感謝します。 提案は受け入れられました。

—Go提案レビュー委員会

レコードに色を加えるために、 @ sdboyerとの毎週の会議は承認と見なされるべきではありません。 サムは最近、MVSの問題と、vgoについて好きなことについて書き始めました。 私はこれを追加して、一緒に来る他の人との誤解がないようにします。 彼の意見が必要な場合は、彼の言葉を読んでください。 私の見解は、それらには現在意図されているアプローチとのかなりの不一致が含まれているということです。

@mattfarina FWIW、私はその文章を「私たちは彼の批判を認識しており(彼が個人的にそれを表現したので)、それは私たちの意見を変えなかった」ともっと読みました。 しかし、彼の意見や議論がこの時点で公表されていないのは残念です。

アプローチに関して未解決の根本的な懸念がまだある間、提案を受け入れることは無責任であると感じます。 著者とコミュニティドメインの専門家@sdboyerの間のコンセンサスは、提案が受け入れられたと見なされる前に到達するための合理的な最低基準のようです。

@merovius私たちの何人かは、公的および私的に意見を共有しています。 多くの人々は、提起された問題は、十分な解決策を与えられたのではなく、(時には無礼に)スチームロールされたと感じています。 私は実際的な問題を公に共有し始めて、それらを解決しようと試みることができます。 たとえば、今日、私はここで実際の問題に関するいくつかの詳細をシャーディングします。 面白いことに、これはハッカーニュースのトップページにあり、同時にこれは承認済みとしてマークされていました。

@peterbourgon Go Dependency Management調査を実施し、Glideに取り組んで、人々のニーズに耳を傾け、それを実現しようとした人として、私は(単なる意見ではなく)実際的な問題を示すことができます。 つまり、ユーザーからの要望、ニーズ、期待をそれらの問題の解決策に合わせることができます。 私の懸念は、vgoの現在のパスの不一致です。 依存関係の管理方法の違いにより、満たされていないニーズと実用的な問題があります。

私の懸念を軽減し始める簡単な方法は、KubernetesでvgoをTimHockinsが満足できるように機能させることです。

私の懸念を軽減し始める簡単な方法は、KubernetesでvgoをTimHockinsが満足できるように機能させることです。

今日Kubernetesでvgoを機能させるのか、それとも今後数年間でKubernetesでvgoを機能させるのか。 私が理解しているように、vgoとdepの間の基本的な設計上の不一致の1つは、現在存在するエコシステムと連携する必要があるかどうか(depの仮定)、またはコミュニティをタグ付きリリースの実行と互換性の維持にシフトできるかどうか(vgoの仮定)です。 。

そのため、Goコミュニティの規範が変わるまで、しばらくの間、vgoが多くの依存関係でKubernetesを使用して機能しない可能性があります。

@mattfarinaもちろんです。 個人的には、これを「スチームロール」として描くのは非常にイライラします。 @sdboyerは何ヶ月もの間、公開討論をほとんど控えており、彼からの実際の具体的な議論はまだありません。 彼には理由があり、それは公平です。 しかし、コンセンサスにはまだ議論が必要であり、少なくとも公共記録に関する限り、私は個人的に、提起されて明らかに無視された問題を認識していません(ただし、あなたの投稿をまだ読んでいません)。

私に関する限り、どんな議論も密室で行われました。 そして、どちらの方法でも情報がないことを考えると、適切な考慮が払われた場合、双方が適切であると仮定することは公正であると思います。

@bradfitz SemVerは、今日のGo pacakgesによって、一般的にPHP、node.js、Rust、およびその他の多くの言語で使用されています。 それはかなり一般的なことです。 これらの言語間で問題が発生し、SemVerの互換性の問題からパッケージが壊れた場合もあります。 意図的に、時には偶然に。 人々は堕落しやすいので、これらの他のすべての言語に存在する問題を回避するために、Goは何を変えるのでしょうか?

互換性が常に維持されるというのは悪い仮定であり、開発者はそれを調整して依存関係ツリーにその情報を渡すためにノブにアクセスできないようにする必要があります。

誰もが同意すると思います。依存関係管理の現在の状況は、どの言語/プラットフォームでもひどいものです。 @bradfitzが対立の主なポイントを正しく説明したと思います。 vgoは成功しないかもしれませんが、私には何かを変更する必要があることは明らかです(つまり、Goだけでなく、一般的に)。vgoは試してみるのに非常に有望に見えます。

@mattfarina互換性が実際に維持されているかどうかを自動的に制御するサービスの実装を試みる予定です。 これをgodoc.orgと統合し、READMEのバッジを提供し、go getのプロキシとして使用します。これを十分に機能させるには、さまざまな方法があります。 確かに、 @ sdboyerはAPIの互換性について正しいですが、実際の互換性を保証するものではありませんが、それは良いスタートであり、ほとんどの場合十分に機能するはずです。

そのため、Goコミュニティの規範が変わるまで、しばらくの間、vgoが多くの依存関係でKubernetesを使用して機能しない可能性があります。

特に既存の行動や期待がすでに十分に確立されている場合、希望は戦略ではありません。 5年前にこの議論を行っていたとしたら、Goはここで費やすイノベーショントークンを持っていた可能性があり、物事はより影響を受けやすくなりました。 しかし、この問題を長い間無視した結果として、現在提案されているツールは、ユーザーがいる場所でユーザーに会わなければならないことは明らかです。

人々は堕落しやすいので、これらの他のすべての言語に存在する問題を回避するために、Goは何を変えるのでしょうか?

リリース/タグ付けを簡単にするだけでなく、APIの互換性もチェックするある種のgo releaseコマンドについて説明してきました(Goリリース用に作成したGo内部のgo tool apiチェッカーなど)。 また、 godoc.orgを照会してパッケージの呼び出し元を検索し、タグがプッシュされる前に、リリース前の時間に新しいバージョンに対してテストを実行できる場合もあります。 等

パッケージの呼び出し元を見つけて、タグがプッシュされる前に、プレリリース時に新しいバージョンに対してもテストを実行します。 等

これは、Google以外の人にとっては実際には実用的ではありません。

これは、Google以外の人にとっては実際には実用的ではありません。

すべてのクラウドプロバイダーがサービスとしての秒単位の支払いを提供し始めているので、誰もが実行して必要な$ 0.57または$ 1.34を支払うことができるオープンソースツールとしてこれを提供できなかった理由はわかりません。多数のホストに対して数分間、何億ものテストを実行します。

テストの実行に関しては、Googleの秘密のソースはあまりありません。

すべてのクラウドプロバイダーがサービスとしての秒単位の支払いを提供し始めているので、誰もが実行して必要な$ 0.57または$ 1.34を支払うことができるオープンソースツールとしてこれを提供できなかった理由はわかりません。多数のホストに対して数分間、何億ものテストを実行します。

これには、特定のクラウドプロバイダーのアカウントが必要であり、特定のクラウドプロバイダーの利用規約に同意する必要があります(これは、世界のほとんどがそうでないかのように扱っている場合でも、法的な理由でできる場合とできない場合があります)。問題)、クラウドプロバイダーがサービスを提供する地域に住んでいる必要があり(たとえば、イランにいて、クラウドプロバイダーが米国にある場合は、輸出法により使用できない場合があります)、クラウドプロバイダーに支払うために費やすお金があります(おそらくリリースを行うたびに)。 それほどお金はかからないかもしれませんが、それは誰もがそれを支払うことができるという意味ではありません。 Goを包括的で多様なオーディエンスが使用できるようにしたい場合、これは良い解決策とは思えません。

/ 2セント

@SamWhited MeteorJSは、クラウドプロバイダーでプロジェクトを実行するための組み込みのmeteor publishコマンドであるgalaxyでこれを機能させました。 たぶん私は提起された問題を誤解しているかもしれませんが、それでの彼らのスイングはうまく見えました。

@bradfitz APIは変更されないが、その背後の動作は変更される場合はどうなりますか? これは、SemVerから脱却し、SemVerをインポートするユーザーに影響を与えるケースです。 この状況をどのように検出しますか? 何度も経験したことがあるのでお願いします。

誰でも実行できるオープンソースツールで、多数のホストに対して数分間にわたって何億ものテストを実行するために必要な0.57ドルまたは1.34ドルを支払うことができます。

これは今、コストに触れています。 これは、米国のハイテク都市の人々にとっては問題ないかもしれません。 アフリカ、中央アメリカ、または世界的に分散している他の場所の人々はどうですか。 このようなツールは、「ハイテクエリート」サークルの外で一般的にどのようにアクセスできますか?

そして、パブリッククラウドの仕事をしていないすべてのケースはどうですか? オンプレミス(多くの人がそれを行う)またはプロプライエタリで信頼の問題がある。 このようなものは彼らのためにどのように機能しますか? 社内ツールを使用している場合は、使用しているインポートを公共サービスに漏らしたくない場合があります。 GitHubからインポートを取得したが、このサービスはGoogleで実行されているとします。 依存関係ツリーをGoogleに渡しても大丈夫だと思いますか? 束はしません。

また、godoc.orgにクエリを実行してパッケージの呼び出し元を検索し、タグがプッシュされる前のプレリリース時に新しいバージョンに対してテストを実行できる場合もあります。 等

この例としてKubernetesを取り上げましょう。 誰かがKubernetesにインポートされたパッケージを作成します。 したがって、ツールはそれを取得してすべてのテストを実行する必要があります。 その一部は、WindowsおよびPOSIXで実行するように設計されています。 マルチOS /マルチアーチをテストできますか(Goがそれを処理するため)。 それは実際にどのように見えるか(そしてコスト)?

-

このようなツールが役立つと思います。 私は人々が他のことを考えるという意味ではありません。 多くの人にとって、彼らがどのように問題を解決しているかはわかりません。 それらは十分に実用的ではないか、すべてのセットアップに適合しません。

既知の制御可能な制約を使用して数学の問題を解決しようとしているように感じます。 しかし、人々は散らかっているので、フォールトトレラントなソリューションが必要です。

今日の初めに@technosophosを引用するには:

「バージョンマネージャーは、実際にはコンパイラーやリンカーなどのツールではありません...バージョンマネージャーは、共同作業を行う人々のためのものです。」

その価値については、彼は複数の依存関係マネージャーを作成し、他の人を研究し、さらに多くのことを書いた人々と話をしました。

アプローチに関して未解決の根本的な懸念がまだある間、提案を受け入れることは無責任であると感じます。 著者とコミュニティドメインの専門家@sdboyerの間のコンセンサスは、提案が受け入れられたと見なされる前に到達するための合理的な最低基準のようです。

ここで少し積み重ねてみましょう。非標準であり、最適ではないパッケージングに関する歴史があります( go getエコシステム)。 「標準」ツールとの互換性という名目で人々を悪い習慣に追いやる別のgo getをリリースするよりも、標準のパッケージマネージャーをあきらめるほうがよいでしょう。 公開リリース以来Goを使用している人として、Goチームのリーダーシップは、 go get (nee goinstall )で犯した間違いの教訓を学んでいないように思われるため、この会話は苛立たしくてがっかりします。

この提案について表明した合理的かつ実際的な問題があります。 単に「意図したとおりに機能している」と言うのではなく、提案を変更してそれらに対処する必要があります。 1.11、1.12、または1.13で正しく実行できない場合は、正しく実行できるようになるまで待つ必要があります。 この提案は、他のほとんどのシステムとは大幅に異なる動作をし、良い方法ではないシステムを提案します。

MVSの背後にある動機付けの理由は、従来のアプローチがNP完全であるということのようです。 やる気が非常に悪いと思います。 NP完全問題を扱う場合、主な質問は「ハードインスタンスが発生する頻度」です。 パッケージ管理では、答えは「めったにない」ように見えます。 問題のNP-HARDラベルを回避するためだけに、不完全で役に立たない問題の定式化に甘んじるべきではありません。

具体的なポイントのほとんどは、問題に近い他の人々( @sdboyer @peterbourgon @mattfarinaなど)によって表明されています。 私の主な不満は、これらの具体的なポイントが適切に対処されていない場合に、この提案を受け入れることです。

@SamWhited 、あなたは架空のデザインのオプション機能について問題を抱えています。 クラウドプロバイダーを信頼していない、自国のファイアウォール内でクラウドプロバイダーを使用できない、または支払いを望まない架空のユーザーは、いつでも自分のマシンで一晩テスト(またはその一部)を実行できます。 または、 go release署名チェックを使用すると、95%無料でアクセスできます。

@ mattfarina@ SamWhited 、ディスカッションをhttps://github.com/golang/go/issues/25483に移動しましょう。

@mattfarina

これらの言語間で問題が発生し、SemVerの互換性の問題からパッケージが壊れた場合もあります。 意図的に、時には偶然に。 人々は堕落しやすいので、これらの他のすべての言語に存在する問題を回避するために、Goは何を変えるのでしょうか?

これらのケースでvgoのパフォーマンスがdepよりも悪いと想定される理由はまだわかりません。 それどころか、vgoのパフォーマンスは厳密に優れているように思われます。 あなたのブログ投稿では、vgoモデルの失敗の証拠として、ヘルムに関する特定の問題について言及しています。 ただし、vgoの世界では、vgoがgrpcにv1.4.0を使用することを選択した理由は2つあります。

  1. helmの開発者は、要件としてgo.modgrpc >= v1.4.0を指定することを選択しました。 その場合、この要件を元に戻すだけで、以前のバージョンのgrpcにロールバックできます。
  2. helmの依存関係の開発者は、 grpc >= v1.4.0を指定することを選択しました。 その場合、 depもそれをインストールし、helmがgrpc < v1.4.0を制限してロールバックしようとすると、要件が競合するため、depが鳴く必要があります。

したがって、vgoは少なくともdepと同様に、この問題を解決するように思われます。 一方、depの世界では、別のオプションがあります。

  1. ヘルムの推移的な依存関係にはgrpc >= v1.x.0が必要で、いくつかのx < 4が必要でした。その後、 grpcv1.4.0 $をリリースし、depはインストール時に新しいバージョンを使用することにしました。 。 この場合、ヘルムが壊れて、バグ修正リリースを行うために群がる必要があり(投稿で説明されているように)、労力が発生します。 その間、vgoは新しいバージョンを無視しただけで、問題なく動作し続けます。

どうやら基本的なことを見落としているようです。 しかし、前回、Slackについてこれについて説明を求めたとき、私は架空の将来のブログ投稿に延期されました。 したがって、私の欲求不満は、アイデアがそのvgoからどこから来ているのかを本当に理解していないため、depよりもバージョンのセマンティクスを壊す人々に何らかの問題があります。

明確にするために、これは約depではありません。 これは、他のSATソルバーベースのパッケージ管理ソリューション(depを含む)と比較したMVS(vgo)の動作の分析です。

Mattによる別の例では、次のように述べています。

あなたはモジュールappの開発者であり、2つの依存関係があります。

  • grpc [> = 1.8 ]
  • helm 、これには次の依存関係があります。

    • grpc [> = 1.0、<1.4]( grpcが1.4で重大な変更を導入したため)。

ほとんどの人は推移的な依存関係の要件( helm -> grpc [> = 1.0、<1.4])について知りません。これは、 helmが次の場合に壊れることに注意する必要があるためです。 grpc > = 1.4を使用します。 大多数の人がそれを気にしたり、調査に時間と労力を費やしたりすることはないと思います。

vgoを使用している場合(特にMVSに依存している場合)、次のようになります。

  • helm
  • grpc [> = 1.8 ]

これは無効な組み合わせである必要があり( helmの要件が満たされていないため)、ほとんどのdepマネージャーは、競合があることを通知するエラーメッセージを表示します( helmが一部の要件を示している場合)フォーマット)。

これは、MVSとvgoに対する批判の重要なポイントです。 完全なSATの解決が必要になるのを避けるために、特定のバージョンに問題がある場合に依存関係が状態になることを許可したくありません。 詳細については、 MVSの記事TheoryおよびExcluding Modulesのセクションを参照してください。

MVSは、SemVerが常に尊重され、したがってこれが必要ではないという仮定の下で、この可能性を認めたくありません(または、少なくとも現在のモジュールにそれを指示する機能を制限したいと考えています)。 下位互換性についてのあなたの記事を参照して、下位互換性を順守することが難しく、vgoの方法を強制されたときに非現実的である理由を示します。

MVSソリューションは、これらの非互換性について依存関係の作成者が共有できる知識を無視して、除外するバージョンを指定するようにモジュール開発者に依頼することです。 したがって、ほとんどのdepマネージャーがどのバージョンの依存関係が相互に互換性があるかを把握するために実行する複雑なロジックを理解して実行する責任を開発者に移します(つまり、SATが解決します)。

人々が魔法のようにSemVerに準拠し始めない限り、vgoを使用してエキセントリックな演習に変換するときに依存関係をインストールすることを想像します。モジュールをインポートした後、READMEファイルをチェックして、互換性のないバージョンのリストをコピーする必要があります。それらはgo.modファイルにあります。 excludeステートメントは現在1つのバージョンのみを使用することに注意してください。

@メロヴィクス

@mattfarinaのブログ投稿では、Helmが意図的にgrpc v1.4.0にアップグレードすること、つまりgo.modを更新することと同等であると説明しています。 問題は、depまたはvgoがこの問題をどのように回避するかではなく、ライブラリの作成者がこの問題から回復できるようにする方法です。 depの場合、 grpc<v1.4.0制約をアドバタイズするパッチをリリースできます。 grpcに他の依存関係を持たないユーザーの場合、これは問題なく機能します。 ユーザーがすでに最新バージョンのhelmに更新していて、 grpc>=v1.4.0に別の依存関係を持っている場合、この制約によりビルドが失敗します。 理想的ではありませんが、微妙に壊れたランタイム動作よりも優れています。

vgoの場合、Helmメンテナは同等のオプションを利用できますか? ユーザーが何らかの理由でgrpcをv1.4.0にアップグレードした場合、MVSは常に[email protected]を選択し、Helmは壊れ、Helmメンテナはそれについて何もできません(変更された動作を調整する必要はありません。時間がかかる)。 @mattfarinaについて話すことはできませんが、それが私が提起された懸念を読む方法であり、それは私が共有するものです。 depおよび同様のシステムを使用すると、中間ライブラリは、上限の制約を伴う互換性違反から防御できます(または、より頻繁に回復できます)。

@ibrasho @mattfarina

GopherconSGトークでのRussの例の1つは、非常によく似た(おそらく同一ですか?)シナリオをカバーしているようです。

上記の投稿では、helmは「grpc [> = 1.0、<1.4]」に依存していると言います。 しかし、それは厳密には正確ではありません。 ヘルムの特定のバージョンは「grpc [> = 1.0、<1.4]」に依存しているということだと思います。 ヘルムのバージョンが2.1.3であるとしましょう。 おそらく、このバージョンのhelmはgrpc 1.4の後にリリースされました(そうでなければ、grpc 1.4と互換性がないことをマークすることは知られていませんでした)。 その話でのRussのポイントは、以前のバージョンのhelm(たとえば、2.1.2)は、おそらく(まだ)grpc1.4と互換性がないとマークしていないということです。

言い換えれば、満足のいく割り当て(depによる)はhelm = 2.1.2、grpc = 1.8でした。 Depは、指定されたバージョンのすべての制約を満たすため、エラーなしでこのバージョン割り当てを正しく選択できます。

@balasanjay

Helmのバージョンは、例を根本的に変更しません。 [email protected][email protected]への依存関係を宣言する可能性があり、helmのユーザーは直接または他のパッケージを介して[email protected]への依存関係を持つ可能性があります。 このシナリオでは、MVSは失敗し、Helm @ 2.1.2と[email protected]をインストールします さらに、この例では、問題が明らかになる前に、ユーザーが意図的に[email protected] (したがって、grpc @ 1.4.0)に更新し、場合によってはHelm @ 2.1.4Helm @ 2.2.0などに更新することを前提としています。

MVSは、理論上の目標を達成するために、中間依存関係からの除外を意図的に禁止しています。

否定的な意味(X→¬Y、同等に¬X∨¬Y:Xがインストールされている場合、Yはインストールされてはなりません)を追加することはできません。

この例では、X = helm>= 2.1.3がインストールされている場合、Y = grpc>=1.4.0をインストールしてはならないことを表現する必要があります。これは、設計上行うことはできません。

事実上、互換性ルールが破られた場合、最上位のパッケージ(破損を修正することによる)と最下位のユーザー(手動で除外を追加することによる)のみが頼りになります。 Helmのような中間体は、依存関係の将来のすべてのバージョンで機能する必要があります。これにより、私にとって、そのようなライブラリの価値提案が大幅に減少します。

おそらくこれは、grpcやaws-sdk-goのような頻繁に使用されるライブラリでのより良い動作を促進するでしょう。なぜなら、破損の完全な矢面に立つことはすべての関係者によって感じられ、回避するのがより困難になるからです。 ただし、それは必ずしも簡単ではありません。 「破損」が実際には破損ではなく、一部のユーザーには意図しない結果をもたらすが、他のユーザーには役立つ動作の正当な変更である場合はどうなりますか? この種のことは珍しいことではなく、上流の作者はそのシナリオの変更を元に戻すことを当然のことながら躊躇します。

私はラスほどはっきりしていなかったと思います。 もう一度やり直します。

最初は、depsの状態は次のようになります。
ヘルム2.1.2:grpc> = 1.0

その後、grpc1.4がリリースされます。 Helmの開発者は、互換性がないことを認識しているため、Helmの新しいバージョンをプッシュします。
ヘルム2.1.3:grpc> = 1.0、<1.4

Helmとgrpcのいくつかの新機能に依存する新しいアプリを起動します(議論のために)。 私は次のdepsをリストします:
ヘルム> = 2.0.0
grpc> = 1.4

上記の主張は、depが固有の競合に気づき、エラーを報告するというものでした。

しかし、競合のないバージョン割り当てがあるため、Russはそれは真実ではないと指摘しました。 具体的には、depはhelm2.1.2とgrpc1.4の使用を選択できます。 depによると、helm 2.1であるため、これは有効な割り当てです。 3はgrpc1.4と互換性がないものですが、2.1は互換性がありません。 2はすべてのgrpc> = 1.0と互換性があります。

言い換えると、depは、競合をまだ記録していないバージョンにダウングレードすることで、競合を「修正」することを_有効に_選択できます。 不変のバージョンがある場合、これは避けられないようです。 したがって、depもhttps://codeengineered.com/blog/2018/golang-vgo-broken-dep-tree/を誤って処理するようです。

@balasanjayもちろんですが、最終的にHelmは必要な新しい機能を備えた2.2.0をリリースし、アップグレードしようとすると問題が発生します。

(私は、vgoがMVSの結果にこの形式の「競合」があることを人々に認識させるための適切に設計されたUXを備えている場合、これがうまくいくことを慎重に楽観視しています。「適切に設計された」とは、人々が対処することを奨励することを意味しますいつもたくさんの警告で大丈夫ではなく、問題です。)

depが競合を検出する状況があることには確かに同意しますが、それがそのブログ投稿で提示されたものではないことを明確にしたかっただけです(または、少なくとも、現在提示されているバージョン要件ではありません)。

そしてFWIW、私は、それが紛争の比較的単純な例を破った場合、セーフガードの有効性を疑うことは合理的だと思います。

記録のために、私はラスの例を追跡しました(これは印象的な程度でこれとほとんど同じです): https ://youtu.be/F8nrpe0XWRg?t = 31m28s

再:最小限のバージョンの選択、私は次の状況を解決する方法を理解するのに問題があります:

メンテナンスモードの人気のあるライブラリを想像してみてください。たとえば、v1.2.3は、変更なしで1年以上リリースされています。 他の多くのライブラリはそれに依存しています。
開発者がやって来て、v1.2.3で行う速度の最適化を実現します。 APIを変更することなく、ライブラリのコア機能を10倍高速化します。 これはv1.3.0としてリリースされています。 翌年、このパッケージにはこれ以上のバグは見つかりません。

扶養家族はどのようにしてこのアップデートを入手するのですか? これらv1.2.3で動作しますが、v1.3.0の方が明らかに優れています。

@daurnimator

扶養家族はどのようにしてこのアップデートを入手するのですか?

各アプリケーションは、使用する最小バージョンとして1.3.0を設定する必要があります。

さて、今日はなんてばかげた日でしょう。 😄

この提案は、2か月以上にわたって活発な議論が行われています。

この問題は何年にもわたって未解決であり、これらすべてに設定されたタイムラインrscは、すべてを考慮して、非常に人為的に短いものでした。

この提案には2つの反対意見があり、私たちは話し合うべきだと感じています。

  1. この提案では、非互換性に関連して発生する可能性のあるすべてのシナリオに対する技術的な解決策を提供できません。

これが私がラスに概説した立場への言及であるならば、それは誤解を招く似顔絵です。 このトピックに関する私の考えをまとめるのに非常に長い時間がかかった理由の1つは、誤解を招くような議論やステートメントを繰り返し使用すると、率直に言って不安定になるためです。

文字通り、考えられるすべてのシナリオをカバーできるとは誰も考えていません。 問題は、MVSが_illusory_問題(SATを回避する)のみを解決し、代わりに実際にははるかに重要な_new_問題を作成し、合理的に操作できる中間層として効果的に機能できないことです。

これらは観察において正確ですが、意図したとおりに機能します。 コードの作成者とユーザーは、開発者がgofmtの実行など、Goの他の詳細に適応したように、ライブラリの使用とリリースに関する慣行の一部を変更する必要があります。

ここで提案されている変更の程度を、gofmtの実行と比較することで簡単にすることはできません。これは、Go開発者として実行する最も無意味なアクティビティの1つです。

RussがGopherconSingaporeでの最近の講演で指摘したように、非互換性に対する唯一の永続的な解決策は、非互換性を修正し、Goパッケージエコシステムを維持するために協力することです。 vgoやdepのようなツールでの一時的な回避策は、開発者が実際の問題を解決する時間を与えるのに十分な時間だけ機能する必要があり、vgoはこの仕事を十分に行います。

明確にしましょう-重要なのは_コミュニティ_です。 我ら。 ソフトウェアエコシステムを生み出す人々。 限られたトークンを有用なコラボレーションに費やすのに役立つツールを作成することで、より良いエコシステムに到達します。そもそも参加することで私たちを罰する脆弱なツールを作成することではありません。

@メロヴィクス

私は架空の将来のブログ投稿に延期されました。 したがって、私の欲求不満は、アイデアがそのvgoからどこから来ているのかを本当に理解していないため、depよりもバージョンのセマンティクスを壊す人々に何らかの問題があります。

これらすべての議論をまとめるには時間がかかり、それは私の日課ではありません。 今夜のフィニッシュを目指していましたが、まだ最終編集パスです。 😢明日の朝...? 何も決まっていない!

問題は、MVSが幻想的な問題(SATを回避する)のみを解決することです...

敬意を表して、私見SATソリューションは非ソリューションであるため、私にとって、MVSは非常に現実的な問題を解決します。

IMHO SATソリューションは非ソリューションであるため、私にとってMVSは非常に現実的な問題を解決します。

可能であれば、その背後にある理由を理解したいと思いますか?

この問題は何年にもわたって未解決であり、これらすべてに設定されたタイムラインrscは、すべてを考慮して、非常に人為的に短いものでした。

ここには、明らかに矛盾する2つのアイデアがあります。 調査では、依存関係の管理には遅かれ早かれ解決策が必要であることが繰り返し示されています。 しかし、6か月のスケジュールでは、提案を確認して承認するのに十分ではありません。

実装する最初のソリューションを選ぶべきではないことを理解しています。 しかし、時間は要因の1つです。 vgoへの反対提案はまだ明確に定義されておらず、実現するまでに何年もかかる可能性が非常に高いでしょう。 私はいつでもGo1.14の非常に素晴らしいSATベースのソリューションよりもGo1.11のvgoを選びます。

これはまた、vgoが実装するものが石に設定されていることを前提としています。 私たちが知っている限りでは、vgoは1.12および1.13ウィンドウの間に大幅に変更される可能性があります。

可能であれば、その背後にある理由を理解したいと思いますか?

これは、PCREよりもGoの正規表現を優先する理由と同じです。 二次/指数最悪の場合の複雑さを持つアルゴリズムに依存するようにプログラムを許可しない。

vgogo getに置き換わるだけで、他には何もありません。 vgogo getと比較し、 vgoを存在しないものと比較する必要があります。 「悪い方がいい」! ここで、実装の詳細に焦点を当てましょう。

FWIW、完全なSATソルバーがなくても、IMOで上限を導入することは完全に可能です。生成されたソリューションを最適にしたり、既存のソリューションが見つかることを保証したりすることは不可能です。 必要に応じて、

  1. 上限を指定できるようにする
  2. MVSを介して解決する場合は無視してください
  3. 見つかったソリューションをすべての境界に対してチェックし、適合しない場合は鳴きます(これが重要な違いです。従来のアプローチでは、代わりに別のソリューションを見つけようとします)

これは、非互換性をマークして静的に検出する可能性を維持しながら、MVS(病理学的ランタイムのない単純なアルゴリズム)の利点を得るということを意味しますが、解決策が存在する場合は常に解決策を見つけるという保証を放棄します。 議論することはできますが、あなた見つける解決策は実際には解決策ではありません。なぜなら、非互換性がまだそこにあり、アルゴリズムには知られていないからです。

したがって、少なくとも私には、MVSの上限を取得するために何らかの方法で改造することは完全に可能であるように思われます。 それが実際に必要であるとはまだ確信していませんが、それが事実であることが判明した場合は、いつでも後で追加することができます。 「MVSは根本的に不適当」という主張を問題にします。 しかし、私はまだ問題を誤解しているかもしれません。 そして、それをよりよく説明する失敗シナリオがあるかもしれませんか?

@sdboyer心配ありません。 先ほど申し上げましたように、これはあなたの日課ではないことを完全に理解しており、ご参加いただきありがとうございます。 それは「議論がわからなければ話せない」という現実的な問題です。 あなたは私と同じように全体の状況に不満を感じていると想像できます:)

これは、PCREよりもGoの正規表現を優先する理由と同じです。 二次/指数最悪の場合の複雑さを持つアルゴリズムに依存するようにプログラムを許可しない。

@cznic依存関係の管理は技術的な問題であるだけでなく、社会的な制約や考慮事項と絡み合っていると私は考えています。 したがって、正規表現(純粋に技術的な実装の問題)と比較するかどうかはわかりません。基本的に時間計算量に基づくアルゴリズムを優先することは、公正なアプローチです。

MVSを好む人もいます。それは、MVSの方が簡単で推論が簡単であり、目前の問題の他の側面を解決するのであれば、それは理解できる考慮事項だからです。

SATベースのアルゴリズムよりもそれを好む理由が他にあるのではないかと思っていました。

SATベースのアルゴリズムよりもそれを好む理由が他にあるのではないかと思いました。

@ibrashoMVSはロックファイルを必要としません。

SATベースのアルゴリズムよりもそれを好む理由が他にあるのではないかと思っていました。

個人的に、私の理由は

  1. ロックファイルとマニフェストを1つのファイルに統合します。このファイルは、主にコンピューターで編集できます。 一般的なケースでは、再現性(または「高忠実度」)を維持しながらノイズを低減することを意味します。 AFAICTこれはMVSに固有のものです。 他のパッケージマネージャーに対する私の主な不満の1つは、マニフェストファイルを編集しなければならないという苦労であるため、これは私にとって大きな意味があります。
  2. 段階的な修理がより簡単に/可能になります。 私は分散開発の問題を解決するためのこのアプローチを強く信じているので、これも私にとって重要です。
  3. ほとんどの図書館で、エコシステムが集合的にHEADの近くにとどまるのに役立つ可能性があります。 これは主に推測であり、使用可能なツールに多少依存します。 ただし、「すべてを最新バージョンにプルする」のが十分に単純である場合は、新しいバージョンのライブラリを本番環境で相互にテストする頻度を高めることができます。
  4. 他のアプローチであるAFAICTの望ましい品質を維持または上回りながら、これらすべてを実現します。 アップグレードは、必要な場合にのみ行われます。 また、バイナリパッケージは、依存関係の一部のビルドが新しいバージョンで壊れた場合でもビルドを継続し、作成者が修正に取り組む時間を与えます。

特にこの最後の部分は皮肉なものです。 この正確な品質は@sdboyerの前回の投稿で非常に重要であると描かれているためですが、現時点では、vgoはこの点で従来のアプローチよりも厳密に優れていると私は信じています。

@メロヴィクス
「ロックファイルとマニフェストを1つのファイルに統合します」

  • マニフェストはファイル全体に効果的に分散しているため、これは完全には当てはまりません。 インポートステートメントは、マニフェストとして効果的に機能します。

@docmerlin 「マニフェスト」とは、依存しているすべてのモジュールと適切なバージョンをリストしたファイルを意味します(特に、インポートステートメントよりも厳密に多くの情報が含まれています。そうでない場合は必要ありません)。 vgoの場合はgo.modになり、depの場合はGopkg.tomlなります。 依存関係ソルバーの構成ファイルを呼び出すこともできます。 別の用語がより適切であると考える場合は、私のコメントを読んでいるときに、マニフェストの代わりにそれを自由に使用してください。

すべての依存関係をリストするファイルと、ファイルごとに明示的なインポート(依存関係の潜在的に厳密なサブセット)のリストの両方が存在することは、ごく普通のことであることに注意してください。 特に、私が知っているすべてのGo依存関係マネージャーはそうしています。 他のアプローチでも、再現性のあるビルドを保証するために使用する特定の正確なバージョンを記述したロックファイルを使用します。 そして、私が言及したMVSの際立った特徴は、このファイルがマニフェスト/ dependency-solver-config / go.modファイルから一意に派生できるため、このファイルが必要ないことです。

(個人アカウントから削除+再投稿)

@cznic MVCの複雑さのクラスとSATベースのアプローチを分離して焦点を当てることは意味がありません( @sdboyerがどこかに書いていると思いますが、それは私たちができる数少ないことの1つであるため、私たちはそれについて話すことに巻き込まれます名前/識別)。

#25483での@bradfitzの提案は、vgoに関するいくつかの懸念に対処するためのものであり(最初はクレイジーですが、おそらく優れた実用的なソリューションだと思います)、リリース前にAPIの任意のユーザーからテストを実行する必要があります。 これは一般にNP完全問題ですが、実際には(gps2のように)優れた解決策になる可能性があります。

したがって、一方ではSATベースのパッケージ管理アルゴリズムがあり、他方ではNLにアルゴリズムがあり、後でNP完全な作業を強制します(またはタイムアウトします。これは、実用的なSATソルバーが行うことです。敵対的なロックファイルの場合)。

MVCの複雑さのクラスとSATベースのアプローチを単独で重視することは意味がありません...

「フォーカス」という用語がどこから来ているのかわかりません。 利用可能なアルゴリズムが2つある場合、一方の最悪のケースは2次またはそれより悪く、もう一方は線形またはより良い場合、私は後者を選択し、前者を避けます。 私はそれを焦点ではなく原則と呼ぶでしょう。

... vgoに関するいくつかの懸念に対処するための#25483の提案...

問題#25483はvgoに関連していないようです。 打ち間違え?

利用可能なアルゴリズムが2つある場合、一方の最悪のケースは2次以下で、もう一方は線形以上である場合、私は後者を選択し、前者を避けます。

@cznic確かに、通常、2つのアルゴリズムで同じ結果が得られる場合は、複雑さの低いアルゴリズムが必要です(ただし、これは必ずしもそれほど単純ではありませんが、Pythonは、複雑さの限界が悪いにもかかわらず、小さな入力に挿入ソートを使用します。定数+ある時点までの実行時間)。

この場合(MVSとSATベースのアルゴリズム)、結果は意図的に異なり、幅広い結果をもたらします。 このため、アルゴリズムの複雑さを比較するだけでなく、それらのより広い影響を考慮する必要があることをお勧めします。

問題#25483はvgoに関連していないようです

その号の最初の行は、この号のBradのコメントへのリンクです: https ://github.com/golang/go/issues/24301#issuecomment-390788506。 このツールはvgo以外でも役立ちますが、MVSのいくつかの欠点を軽減するために主に検討されているようです(私の意見/理解では)。

うん、たくさんのコメント。 役立つ詳細と履歴を追加してみます。

数年前には、さまざまな依存関係管理ソリューション(godep、glideなど)がありました。 前進する道を見つけるために、いくつかのことが起こりました。

  1. 投資された知識豊富な人々のグループが委員会に集まりました。 Googleのgoチームメンバーがこのグループの一部であったことに注意してください。
  2. 依存関係マネージャーを作成した、または依存関係マネージャーに関する情報を持っていた2番目のグループは、この最初のグループをサポートしていました。
  3. 既存のツール(Go内およびGo外)のニーズと考えに関するコミュニティの調査が実施されました。 一部の結果は、委員会の目だけに限定されていることに注意してください。
  4. Goを本番環境に使用している企業にインタビューを行い、ニーズの詳細を調べました。 詳細は公開されていないので、自由に話すことができます。

調査とインタビューのデータはすべて委員会にフィードバックされました。 データを調べて議論した後、彼らは特定の機能を備えたソリューションが必要であると判断し、仕様を作成しました。 その後、depでの開発はそれらのニーズを満たし始めました。

昨年のGopherconで、依存関係管理に投資した人々がそれについて話し合う貢献者サミットがありました。 それらの会話の終わり近くに、ラスはテーブルにやって来て、次のようなことを言いました。 彼はそれをしてvgoを思いついた。 それはコミュニティとは別に行われました。

vgoは、調査やインタビューで人々が表明したニーズを満たしていますか? 私がラスから集めたものから、彼は結果を読んでいませんが、彼はプロセスを批判しました。 誰かがマッピングを行う価値があるかもしれません。

ああ、サミットでラスは理由の1つを共有しました、その時、彼はSATソルバーが好きではありませんでした。 彼は、GoogleのGoチームがそれほど多くのコードを維持するためのフックを望んでいなかったため、コード行が少ないソリューションを望んでいました。 特に、違いをよりよく理解するために、dep、glide、およびその他のツール間でLOC比較を行ったためです。

GoはGoogleが所有し、実行しているプロジェクトです。 問題がリソースの1つである場合、Goは基盤の下にあり、他の組織の人々がその所有権に関与する必要がありますか? これは、ツールチェーンを維持するためのリソースを追加するもう1つの方法です。

いいえ、#25483はvgoとは関係ありません。 架空のgo releaseヘルパーコマンドで実行できる別の種類のものとして、それを手元にリストしました。 しかし、それはいつでも役に立ちます。

私のより大きなポイントは、GoがGoパッケージのリリースを非常に簡単に行えるようにしたことは一度もないということです。 以前、私はPerl CPANパッケージのリリースを自動化するためにhttp://search.cpan.org/dist/ShipIt/を作成しましたが、そのようなツールを手動で実行する場合と比べて、ツールを使用する場合に大きな違いがありました。

人間が間違いを犯さないようにするためにGoがどう違うのかと尋ねられたので、私は架空のgo releaseについてのみ言及しました。

vgoで見られる実際の問題の1つは、修正するのが簡単なようです。最大バージョンの問題です。 1つのライブラリがdepのv1.7で壊れた場合、除外以外にそれを指定する方法はありません...これはv1.8が出るまでしか役に立ちませんが、まったく同じ方法で壊れている可能性があります。

2つのライブラリに互換性がない場合にvgoが判断できるようにする方法として、vgoに最大バージョンを追加するのは簡単なようです。 1つのライブラリが少なくともv1.7が必要であると述べ、1つのライブラリが必要であると述べている場合

これがないと、vgoは1.7を使用するだけで、ライブラリの1つが壊れます。 運が良ければ、コンパイラエラーが発生します。おそらく、微妙な動作のバグがあり、それが先に進むまで気付かない可能性があります。 そして、陰湿なのは、それがおそらく直接呼び出していない推移的な依存関係であるということです。

@natefinchの最大バージョン制限により、MVSは非常に巧妙な回避-SMT-ソルバー領域から外れます。

@natefinchは、最終チェック/フィルターとしての最大バージョンを意味すると思います。 MVSがその仕事を終えると、これらの最大バージョン制限のいずれかが満たされない場合、vgoはエラーになります。 それでもSATソルバーの領域に入ることができません。

その通り。 解決策はありません。 「vgoは1.7を使用するのが正しいと言っていますが、モジュールXはそのバージョンでは動作しないと述べています」というだけです。 これは、 require foo 1.7と表示されているものがあり、より高いfooバージョンがない場合にexclude foo 1.7と表示されている場合、vgoで今日発生する可能性があります。

そして、あなたは何をすることになっていますか?

機械的な解決策がないため、人間の脳を使って解決策を見つけます。 互換性のないバージョンのライブラリが必要であると明確に述べている2つのライブラリを使用しようとしています。 Aは1.6で壊れ、Bは1.7で壊れます。 終わり。

依存関係の作成者にバグを修正するように説得するか(バグの場合)、ライブラリの作成者の1人に新しい依存関係のバージョンと互換性のある新しいバージョンをリリースするように説得するか、たくさんのものをフォークして自分で修正する必要があります。 。

良い答えはありません。 しかし、これを修正できるツールは世界中にありません。

@sdboyer

問題は、MVSが幻想的な問題を解決する(SATを回避する)だけであるということです。

ラスとの個人的な会話について話すことはできませんが、「SATを回避する」というのは私にとってストローマンの議論のようです。 「SATを回避する」ことは「SATを使用する」こと以上の目標ではありません。どちらもユーザーに具体的な影響を与えません。

私が見ているように、MVSが解決する具体的な問題は次のとおりです。

  • デフォルトでビルドを再現可能にする、
  • テストされたバージョンに可能な限り近いものを構築し、
  • 偽の拒否を回避します。

限られたトークンを有用なコラボレーションに費やすのに役立つツールを作成することで、より良いエコシステムに到達します。そもそも参加することで私たちを罰する脆弱なツールを作成することではありません。

同意します。 しかし、私はあなたの仮定を詳しく見てみたいと思います。どのツールが参加を「罰する」のか、そしてその理由は何ですか?

投稿で挙げた例の1つは、「現在、私たちのプロジェクトは[email protected]に依存していますが、 [email protected]以降では機能しません。 私たちは良き市民になり、適応したいと思っていますが、現在、帯域幅がありません。」


あなたが行っている最初の(暗黙の)仮定は、あなた(またはあなたのユーザー)がその依存関係のすべてのリリースに対してプロジェクトを徹底的にテストする時間と帯域幅を持っているということです。¹一部のプロジェクトでは、その仮定自体が成り立たない場合があります:非互換性を発見したときに全員が上限にタグを付けるという期待を設定することで、リグレッションをテストし、潜在的にすべてのリリースの境界を更新する帯域幅を持たないメンテナを「罰する」ことになります。

対照的に、MVSの下では、メンテナは1つのことを宣言する義務があります。「 [email protected]に対して徹底的にテストし、機能しました。」 ユーザーがそれを妨害するために何もしなかった場合、ユーザーは[email protected]に対して構築し、すべてが以前と同じように機能し続けます。

MVSでは、_breakageは明示的なアップグレード時にのみ発生します。_これは重要な利点です。ユーザーが他の依存関係をアップグレードして[email protected]を取得し、パッケージの使用を中断した場合、ユーザーは単純にアップグレードを修正する時間があるまで、またはXのメンテナが非互換性を修正する時間があるまで、アップグレードを取り消します。適切な期待があれば、後者の方が前者よりもはるかに可能性が高くなります。 $# [email protected]互換性が回復した場合、 [email protected]は不必要な忙しい作業になる可能性があります。


あなたがしている2番目の仮定は、モジュールの_任意の部分_に影響を与えるすべての非互換性がモジュールの_すべてのユーザー_に影響を与えるということです。 パッケージの[email protected]に該当しない部分があまり使用されていない関数である場合、ユーザーがそれを呼び出さないプログラムでXをアップグレードしないようにするのはなぜですか?

モジュールの一部が他の部分に依存していない場合、それらは別々のモジュールである必要があると主張することができますが、それでもパッケージメンテナに余分な作業が必要になります。定期的にテストおよびアップグレードするための帯域幅しかない場合は、細粒度の依存関係を持つ細粒度モジュールの複合体全体ではなく、1つのモジュールを維持するための帯域幅。


¹一般に、依存関係との非互換性を検出するには、それらの依存関係の_すべてのリリースの外積_に対してテストする必要があります。 [email protected]の特定の使用は問題ない可能性がありますが、依存している他のパッケージと組み合わせると壊れます。の上。 たとえば、おそらくあなたとあなたの依存関係は、グローバル構成で互換性のないオプションを必要とします。

彼らは単にそのアップグレードを取り消すことができます

これは、これがコンパイラエラーまたは同様に非常に目立つものであると想定しています。 すぐには明らかにならない微妙な動作のバグである可能性がはるかに高くなります。 更新してテストを実行すると、すべて問題ないように見えます。 たぶん、10秒だったタイムアウトが30になり、負荷がかかっているときにスタックの残りのタイムアウトがスローされます。 それが本番環境で実行されるまで気付かないでしょう(数年前にmgoを変更したことで、私たちにも同様のことが起こりました)。

[email protected]で機能しなくなったパッケージの部分があまり使用されていない関数である場合、ユーザーがXを呼び出さないプログラムでXをアップグレードしないようにするのはなぜですか。

推移的な依存関係である場合、おそらくその関数を使用しているかどうかがわからないため、コードを変更したときに未使用のコードパスが突然アクティブ化されないというのは誰ですか? そのため、壊れた関数が呼び出されています。 自分のライブラリを理解する専門家であるライブラリメンテナを信頼する方がはるかに優れています。1.7では機能しないと言われた場合は、1.7でビルドしないでください。

これは、これがコンパイラエラーまたは同様に非常に目立つものであると想定しています。 すぐには明らかにならない微妙な動作のバグである可能性がはるかに高くなります。

ほぼすべてのソフトウェアパッケージのほぼすべてのバージョンに潜んでいる微妙なバグがあります。 そのようなバグが1つ見つかったという理由だけで、リリースを完全に使用不可としてマークすることは通常ありません。 代わりに、後のポイントリリースで修正します。

この特定のクラスのバグが特別な理由は何ですか?

コードを変更しても、未使用のコードパスが突然アクティブ化されないというのは誰ですか?

これはまさにMVSの議論です。コードを変更すると、_そのリビジョンで_破損が検出され、そのリビジョンでもバージョン制約を更新できます。

これは、ユーザーとして、依存関係を一括ではなく一度に1つずつアップグレードすると、障害を二分する方が簡単であることを意味しますが、これは一般的な変更にも当てはまります。変更が小さいほど、より正確に実行できます。それらがコードへの変更であるかその依存関係であるかに関係なく、それらを二等分します。

この特定のクラスのバグが特別な理由は何ですか?

単なるバグではありません。 それよりも大きいです。 彼らのコードの第一人者であるライブラリの作者は、「よ、バージョン1.7のXは、私のものを非常に悪い方法で壊してしまい、それを使って構築することすらしない」と世界に語った。

明らかに、それがコンパイラエラーでない限り、それは判断の呼びかけです。 99個の関数がパニックになったが、1つはパニックにならない場合、それは単なるバグですか? それとも完全な非互換性ですか? パニックになるのが1つの関数だけだとしたらどうでしょうか。

ある時点で、人間はその決定をしなければなりません。 宣言されていない大きな問題が本番環境に移行することを心配するよりも、ビルド時に発生する先制的な宣言された非互換性に対処したいと思います。

単なるバグではありません。 それよりも大きいです。 彼らのコードの第一人者であるライブラリの作者は、「よ、バージョン1.7のXは、私のものを非常に悪い方法で壊してしまい、それを使って構築することすらしない」と世界に語った。

ライブラリの作成者がこれを表現する別の方法があります。互換性のないバージョンのXで使用すると失敗するテストを記述します。これには、Xが修正バージョンをリリースした場合にライブラリを変更する必要がなく、将来の回帰。

互換性のないバージョンのXで使用すると失敗するテストを記述します。

ええ、私はそれを考えました。 しかし、次に、すべてのトップレベルバイナリに、すべての推移的な依存関係に対してすべてのテストを実行するように要求します。テストには、持っていないインフラストラクチャが必要になる場合があります。 すべてのテストスイートが100%分離されているわけではありません。

go test ./...がベンダーディレクトリでテストを実行しないのには理由があります。

要約すると(おそらく不十分ですが)、vgoに対する主な技術的議論は、ライブラリが自身の依存関係に対してグローバルに尊重される制約を宣言する方法が必要であるということのようです。

GPS2がvgoの両サイドのようにどのように適合するかを探る、競合する提案を制裁することに双方が同意してみませんか。 次に、vgoがメインラインをマージする前に、vgoの実験をマージし、GPS2の提案を再検討しますか?

過去に多くの依存関係ツールに苦労した人として、私はvgoに興奮しています。 FWIWは、「コミュニティ」のメンバーとして、これまでのところvgoソリューションによく代表されていると感じています。 しかし、私はグローバルバージョンの制約を追加することを支持して議論を検討することにオープンであり続け、その議論がさらに発展することを楽しみにしています。

これを捨てるだけです:

これは、これがコンパイラエラーまたは同様に非常に目立つものであると想定しています。 すぐには明らかにならない微妙な動作のバグである可能性がはるかに高くなります。 更新してテストを実行すると、すべて問題ないように見えます。 たぶん、10秒だったタイムアウトが30になり、負荷がかかっているときにスタックの残りのタイムアウトがスローされます。

これは一般的なソフトウェアの問題です。 NPM(私が個人的に最もよく知っている他のバージョン管理ツール)は、semverを強く受け入れているコミュニティと組み合わせたSATソルバーを使用しますが、この問題は依然として存在します。

推移的な依存関係の議論に関する限り、現実には魔法の杖はありません。ある時点で、開発者は使用する依存関係を認識し、最終的に責任を負うコードを適切にテストするために時間をかける必要があります。 法的な理由やその他の理由で、推移的なライブラリを含め、使用するすべてのライブラリを正当化する必要があるのは、私の雇用主だけではありません。

正直なところ、私の目には、vgoに対する苦情の多くは「完璧ではないため、機能しない」ように思われます。 完璧なソリューションが必要な場合は、必ず適切なソリューションを実装してください。

私には、コアチームがほとんどの状況で優れたツールを提供し、より高度なツールや特定のツールを提供することをコミュニティに任せるという、全体的なGoの哲学と非常に一致しているように見えます。

@malexdev次のような議論で、アクターに問題がある可能性があります。

完璧なソリューションを求めて、良いソリューションを実装することを忘れないでください。

depは今日の良い解決策です。 コミュニティが協力して作成したもの。 vgoは、以前に開始したように、いくつかの仮定を行います。

  1. 偶然であっても、誰もsemverから抜け出さないこと
  2. 既存のエコシステムの既存のコードベースを作り直す必要があること

vgoは、「完璧な世界」の「完璧なソリューション」に基づいていますが、depは、フォールトトレラントでありながら、他のプログラミング言語エコシステムですでに機能しているものに従って今日機能します。

これは、先ほど書いたパッケージ管理の問題スペースの履歴で確認できます。

要約すると(おそらく不十分ですが)、vgoに対する主な技術的議論は、ライブラリが自身の依存関係に対してグローバルに尊重される制約を宣言する方法が必要であるということのようです。

私はこの要約に同意します。

GPS2がvgoの両サイドのようにどのように適合するかを探る、競合する提案を制裁することに双方が同意してみませんか。

この時点で、私はGPS2が必要であるか、あるいは良い考えでさえあると確信していません。 上で並べた機能は、MVSの上にvgoに組み込むことができます(これまたはthisのように)。 個人的には、 @ sdboyerの次のブログ投稿にMVS自体に対する適切な議論が含まれることを望んでいますが、現時点では、別のアルゴリズム、特にvgoのUXの大きな利点を犠牲にする理由はわかりません。

とはいえ、公平を期すために、私もそれを実験することに反対する理由は見当たらない。

depは今日の良い解決策です。

同意するかどうかはわかりません。 私自身は使用していませんが、SATを解決するアプローチに直接追跡できると思われる問題について、何人かの人々が不満を言っているところです。 そして、私はdepsの全体的な設計に非常に不満を持っていることを知っています(依存関係ソルバー自体の問題は別として、一般的なワークフローとUXです)。

  1. 偶然であっても、誰もsemverから抜け出さないこと

申し訳ありませんが、この声明の正当性を繰り返し求めてきましたが、何も得られませんでした。 なぜvgoはこれを何らかの形で、dep以上の形や形で想定するのでしょうか? 私はこの声明に根本的に同意しません。 これは、アルゴリズムを説明するために行われた仮定です。 depのアルゴリズムを説明するのと同じように、セマンティックバージョンに組み込まれている仮定を説明します。 最悪の場合、これらのセマンティクスに準拠しなかった場合、同じ破損が発生します。


一般的に、私たちが話していることのさまざまな部分を区別することは理にかなっていると思います。 苦情のいくつかは、SIV、いくつかのMVS、およびいくつかの一般的なvgo-shellに関するものです。 たとえば、MVSがバージョンの上限を処理できないことは事実ですが、vgoがバージョンの上限を処理できなかったことを意味するわけではありません。 SIVでは(importステートメントを書き直すことによって)多くのコードを変更する必要がありますが、これも必ずしもvgoで必要になるとは限りません。 はっきりしているとはいえ、移行できる限り、それほど大きな問題ではないと思います。 どのAFAICTができるか。

@rscGopherConSGがバージョン管理に関する基調講演を開くのを見たところです。 彼は、依存関係が重大な変更をもたらすシナリオに取り組み、vgoとdepがそれをどのように処理するかを比較しました。これがここでの主な関心事のようです。 (それは素晴らしい時計です。)

私が彼の主張を正しく理解していれば、悪いバージョンを避けるために最大バージョン制限が使用されている場合、depもビルドを壊す可能性があります。 この点でvgoがdepに達していないことを懸念しているここの人々がこの点に対処するのを見るのは非常に興味があります。

@willfaught悪いバージョンを回避するために最大バージョン制限が使用されている場合、ビルドを中断することは成功と見なされます。 これが私たちが望んでいることです。 Russは、この問題が自動的に解決されないことを正しく指摘しています。 Helm>2.0.0の制約は、ユーザーを自動的に「 [email protected] 」にアップグレードしませんが、ユーザーが明示的に「Helm」に依存している場合は、正常に機能します(grpcをダウングレードするか、ビルドの失敗をトリガーします)。 == 2.1.4 "。 個人的には、ライブラリで問題が発生したときに最初に試みることは、最新バージョンへの更新を強制することです。 Depを使用すると、GRPC1.4.0によって発生した障害が通知されます。 vgoの場合、Helmがこれを私に伝える唯一の方法は、ドキュメントを使用することです。

理解されていないために要点を繰り返すと、 depvgoも、この問題の発生を防ぐことも、確実な解決策を提供することもできません。 むしろ、 depを使用すると、Helmは問題が存在することを通知できますが、 vgoはそうではありません。

要約すると(おそらく不十分ですが)、vgoに対する主な技術的議論は、ライブラリが自身の依存関係に対してグローバルに尊重される制約を宣言する方法が必要であるということのようです。

互換性ルールに違反した場合の不幸な経路に対処するには、これらの制約が必要であるという点で、この要約に色を追加します。 vgoは、インポート互換性ルールを確立してから、ルールが常に守られていると想定してソリューションの開発に進みます。 この理想化された世界では、上限の必要性は限られているか、存在しないことさえあります。 現実の世界では、これは起こりません。開発者は、意図的またはその他の方法で、互換性を損なう更新をリリースします。

@Meroviusは実行可能な解決策に取り組んでいると思います。 MVSは指定どおりに続行し、解決が完了した後、vgoは解決された各パッケージの除外をチェックします。 見つかった場合、これらはエンドユーザーに報告されます。エンドユーザーは、これらの制約を満たすように依存関係を変更するか、制約を上書きして無視するかを選択できます。 私もこれの裏側にいて、時々あなたはメンテナよりよく知っています。 それはあなたのアプリケーションのために働きます、そしてそれはあなたが気にするすべてです。

これにより、中間ライブラリが非互換性をエンドユーザーに伝達するためのパスが復元されます。 ヘルムの例をもう一度繰り返すには:

[email protected] :ヘルム@ 2.1.2
[email protected] :GRPC @ 1.3.5

==>ユーザーは意図的に[email protected]にアップグレードします。

ユーザー:Helm @ 2.1.3、 GRPC @ 1.4.0( "Helmが更新されたので、ついにgrpc 1.4を使用できるようになりました!")
ヘルム:GRPC @ 1.4.0

==>バグが検出されました! ユーザーにHelmの問題が発生しているため、新しいバージョンを確認してください。

ユーザー:Helm @ 2.1.4、 GRPC @ 1.4.0
ヘルム:GRPC @ 1.3.5、弱いGRPC <1.4.0

ユーザーには、Helm @ 2.1.4のインストールによってGRPC1.4.0が拒否されるという警告が表示されます。 Helmが壊れていて、それを修正しようとしているので、GRPC 1.4.0への依存関係を削除し(残念ながらいくつかの便利な機能が失われます)、MVSを再実行します。 今回、MVSはGRPCを1.3.5に、Helmを2.1.4に解決し、すべての弱い制約を再チェックし、それらが保持されていることを確認しました。これで完了です。

これらの問題を魔法のように解決するツールは期待していませんが、ミドルウェアライブラリとしての手段は期待しいます。 私が知る限り、 vgoの唯一のオプションは、すべてのアップストリーム依存関係をフォークして名前を変更することです(または同等に、それらをプロジェクトにコピーします)。これらの依存関係との互換性の問題からユーザーを保護したい場合。 誰もそれを望んでいないと思います。

@willfaught悪いバージョンを回避するために最大バージョン制限が使用されている場合、ビルドを中断することは成功と見なされます。 これが私たちが望んでいることです。

講演で指摘されたのは、このシナリオではvgoはdepよりも悪くないということです。 彼の例では、depが解決策を見つけることができないという意味で、ビルドは壊れていません。 dep解決策を見つけ、その解決策に悪いバージョンが含まれているという意味で壊れているため、回避したかったのと同じ悪い状況が発生します。

優れた例を紹介するビデオを実際に見る必要がありますが、私が理解/覚えている要点は次のとおりです。

  • パッケージバージョン(依存関係の要件を含む)は不変です
  • パッケージの既存の依存関係に最大バージョン制限を追加するには、パッケージの新しいバージョンを公開する必要があります。
  • すべての要件を満たすために、depが以前のバージョンのパッケージを選択する可能性があります。その場合、新しい最大バージョンの制限は存在しません。 これにより、結局、悪いバージョンを使用することができます。

最大バージョンの除外を追加するという提案にほぼ同意しますが、この心配があります。ライブラリに「gRPC> 1.4、<1.8を使用」と入力し、gRPC 1.9で、作成者が「何を知っているか、Helmはそうです、1.8で重大な変更を加え、1.9.0で以前の動作に戻しています。」 現在、Helm + gRPCをインポートしようとしている人は、Helmが「1.8.0、1.8.1、1.8.2を除いて、gRPC> 1.4を使用しますが、1.9 +はかっこいい」というバージョンをリリースするまで、1.9を使用できません。

言い換えれば、gRPC 1.9が互換性がないかどうかは公開されるまでわからないため、おそらくexclude grpc 1.8で十分です。公開されると、Helmはそれを除外リストに追加できるかどうかを判断できます。

私はこの空間について本質的に何も知りません。 しかし、ここでの議論を読むと、最大の不一致は、誤ったケースを検出する方法に要約されているように思えます。 つまり、MVS(vgo)とSAT(dep)はどちらも、通常の状況を多かれ少なかれうまく処理します。おそらく同じではありませんが、十分に処理します。

SATは、MVSにはない機能を提供します。SATを使用すると、ライブラリパッケージP1の作成者は「P1にはP2が必要であり、P2Version> 1.1およびP2Version <1.4で動作します」と宣言できます。 MVSは、「P1にはP2が必要であり、P2Version> 1.1で動作する」と宣言することしかできず、「P2Version <1.4」という制限を表現することはできません。 通常の場合、これは問題ではありません。 一部の操作がP2をバージョン1.4にアップグレードしようとする場合にのみ問題になります。 その場合、SATはエラーを報告しますが、MVSは報告しません。 MVSを使用する場合、非互換性がコンパイルエラーでない場合は、事後ずっと失敗する可能性があります。

SATサポーターがMVSに関する他の大きな問題を認識していることは間違いありませんが、これまでのところ、これは私が理解している問題です。

制限式自体がバージョン管理されている場合(P1の特定のリリースの一部である場合)、通常のイベントの過程で、P2バージョン1.4がリリースされる前に、P1バージョン2.2は喜んで「P2Version > 1.1 "。 P1の作成者が非互換性に気付くのは、P2バージョン1.4がリリースされたときのみであり、「P2Version> 1.1およびP2Version <1.4」でP1バージョン2.3をリリースします。 したがって、P1バージョン2.2を使用している場合、SATもMVSも、P2をバージョン1.4にアップグレードする際の問題を報告しませんが、微妙な方法で失敗する可能性があります。

つまり、P1のリリースで互換性のある最小バージョンのP2をリストすることは完全に理にかなっていますが、リリースが最新バージョンのP2で正しく機能する場合、リリースで互換性のある最大バージョンをリストすることは意味がありません。 。 互換性のある最大バージョンは控えめであるため、P2の新しいバージョンやより良いバージョンが登場するにつれてますます間違っているか、P2が将来互換性のない方法で変更された場合、リリース時にその要件を指定できなくなります。 tが存在します。

したがって、最小バージョン要件以外のものを定義するシステムが必要な場合、それらの要件は特定のリリースの一部ではなく、パッケージに関連付けられたある種のメタデータの一部である必要があります。パッケージ自体を更新せずにいつでも。 つまり、「このパッケージを更新する」操作は、「現在のパッケージバージョンに互換性があるかどうかを確認する」操作とは別にする必要があります。

私はさらに主張します-そしてこれは上記よりも間違いなく希薄です-「私の現在のパッケージバージョンが互換性があるかどうかを確認する」が失敗した場合、問題を解決するためにツールを信頼することは一般的に賢明ではありません。 「関連するすべてのパッケージを現在のバージョンにアップグレードする」という簡単な操作で互換性の問題を解決できない場合は、検討が必要です。 ツールはその考えを導くことができますが、一般的にそれを置き換えることはできません。 特に、ツールがパッケージのダウングレードを自動的に開始することは非常に賢明ではないようです。

だから私たちが

  1. パッケージの非互換性を説明するパッケージメタデータを定義する方法
  2. これに基づいて、現在のパッケージに互換性があるかどうかを報告するツール

そうすれば、おそらくMVSとSATの主な違いのいくつかはそれほど重要ではなくなります。

とてもよくイアンと言ってくれてありがとう。 フォローアップするために、バージョンとvgoを確立したら、パッケージに関する追加情報(goコマンドが参照できる情報)を記録する新しいgodoc.org(おそらく別の名前)が絶対に必要です。 そして、その情報の一部は、goコマンドが特定のビルドで警告またはエラーとして報告する可能性のあるペアごとの非互換性です(つまり、損傷を報告し、回避して隠そうとはしません)。 ただし、コアツールチェーンにバージョンを含めることが最初のステップであり、最小限のバージョン要件とセマンティックインポートのバージョン管理に加えて、この問題で受け入れられているのはそれです。


私たちはこれを可能な限りスムーズに着陸させることをお約束します。 そのためには、既存のパッケージの問題を修正するために、追加のツール、より教育的なアウトリーチ、およびPRが必要になります。 全体的なアプローチが受け入れられずに前進することは思いがけないように思われたため、この提案を受け入れることですべてが妨げられました。 しかし、提案は受け入れられ、不確実性が終わった今、作業はより積極的に着陸し始めます。

バージョン互換性に関する外部情報についても同じ考えを持っていました...バージョン互換性は全体で一定でなければならないため、ソース管理にある必要はありません(実際、ソース管理にあることは上記のように明らかに不利です)。 これに対する提案された解決策があれば、それは間違いなく提案されたMVSの1つの主要な問題であるように思われるので、それは素晴らしいことです。

議論がこの方向に有機的に進んでいるのを見るのは素晴らしいことです。 それは私の懸念の中心的な推進力の1つであり、人々がすでにほとんどの道を進んでいるときに、根本的な問題を説明するのが非常に簡単になります。

@ianlancetaylor 、すでにリリースされているバージョンの制約情報を変更できるようにする必要があるというこの観察結果に注目していると思います。 @rscが示したように、そのようなサービスは私たちが話し合ったものであり、私は会議で提案しました。 確かに、godoc.orgまたは他の何かでそれを行うことができます。 しかし、実際には別のサービスが必要だとは思いません。サービスがない方がよいでしょう。 私は金曜日に公開した記事でこれを簡単に参照しました(そのアンカーのすぐ上)。 他に何もないとしても、サービスでは、非互換性の宣言を警告に表示する必要がある質問があります。これは、IDの処理を意味し、宣言をdepgraphの特定の状況にスコープする方法です。 宣言をメタデータファイル内に保持することは、そのことについて心配する必要がないことを意味します。 しかし、それについては1秒で詳しく説明します。

ここで本当に重要なのはこの点ですが、意図した方法ではないかもしれません。

おそらく、MVSとSATの主な違いのいくつかはそれほど重要ではなくなります。

人々が特定している問題の解決策として、この検索を行うメタツールの提案(はい、それはSAT検索です)が伝えています。 MVSが説明されているように進んだ場合、それは私たちがdepを変換しなければならないものとほぼ同じです。 そして、最初に注意すべきことは、検索ツールについて話しているほどこれらの非互換性について懸念している場合、実際に言っているのは、MVSがより大きなアルゴリズムの単なる一歩になるということです。 grokkabilityのメリットはすぐに利用できます。

それよりも悪いことを除いて、最小バージョンと現在のバージョンを一緒に圧縮することから生じる情報損失の焼き付けられた問題を回避できるメタツールの量はありません。 その大きな結果はカスケードロールバックです。つまり、このリストの非互換性のいずれかを実際に修正しようとすると、問題に必ずしも関係のない依存関係グラフの他の部分が破棄される可能性が非常に高くなります。 また、開発者は、他の人に害を及ぼさない更新戦略に従うことができなくなります。 。 (ああ、そして幻のルールですが、それは一般的には単なるMVSの副作用です)。

これが、MVSがこのような高次ツールを構築するための不適切な中間層であると主張した理由です-「目的に適していない」。 人々がこれらの非互換性が発生すると信じていることは明らかです、それでMVSはただ難しい問題を取り、それをより難しくしています。

代わりに、「非互換性サービス」の問題をメタデータファイルに統合すると、ペアワイズ宣言の単純なセットのみを使用して、同じ効果を達成できると思います。 (これはコンセプトのドラフトですが、ますます一緒にぶら下がっているようです)

MVSの一部が変更される必要がありますが、MVSはそこでエンコードされた情報の上で実行できます。 これは、非互換性が本当におかしくなり、それらすべてを避けたい場合に最も役立ちます。 ただし、主要なアルゴリズムは、MVSのように見えるベースラインから開始し、その後、不条理に古いバージョンに移行する可能性なしに、より広範な検索に切り替えます(明確にするために、MVS自体は引き続き検索と見なす必要があります)。

(注:今週は休暇になるので、次の週末まで応答しません)

@sdboyer

この検索を行うメタツールの提案-はい、それはSAT検索です

もっと具体的にできますか? あなたが引用した文は、選択したバージョンが互換性があるかどうかを報告するツールをIanが提案した直後です-そして私の知る限り、それがここで提案された主な選択肢です(それは確かに私が上で意図したものです)。 その問題は間違いなく検索ではなく、些細なことであり、SATを解く必要はありません(それは、与えられた値のセットに対してブール式を評価するだけであり、それを満たす値を見つけようとはしません)。

確かに、数式に互換性のない既知の値があることを報告するだけでは、SATを解く必要はありません。 そのような値が含まれていない結果を見つけるプロセスを支援するツールなど、それに基づいてアクションを実行します。

その文を引用したのは、人々が常に必要な検索を受け入れたことを示していると思うからではなく、そのような状況を報告することが重要であると信じるなら、そのようなシナリオに遭遇する可能性が高いと信じているからです。

問題は、これらのケースに対処することの妥当性と重要性が確立されると、人々は「MVS上ですべての検索を実行できれば問題ない」という誤ったジャンプをしているように見えることです。 可能ですが、MVSが設計上遮断する可能性のある有用なパスがあるため、このような試みは処理が非常に難しくなります。

2018年5月28日16:02:13EDT、 AxelWagnernotifications @ github.comは次のように書いています。

@sdboyer

この検索を行うメタツールの提案-はい、それは
SAT検索

もっと具体的にできますか? あなたが引用した文はイアンの直後です
選択したバージョンが互換性があります-そして私の知る限りでは、それがメインです
ここで提案された代替案(それは確かに私が上で意図したものです)。
その問題は間違いなく検索ではなく、些細なことであり、
SATを解く必要はありません(ブール式を評価するだけです)
与えられた値のセットに対して、それを満たす値を見つけようとはしません)。

-
あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示してください。
https://github.com/golang/go/issues/24301#issuecomment -392595150

その文を引用したのは、人々が常に必要な検索を受け入れたことを示していると思うからではなく、そのような状況を報告することが重要であると信じるなら、そのようなシナリオに遭遇する可能性が高いと信じているからです。

明確にするために:このように上限を変更するという提案は、提起された懸念に純粋に反応し、それが可能であることを示します(MVSが基本的に目的に適していないという主張に批判的に疑問を呈するため)。 その譲歩と妥協する意欲を、あなたがずっと正しかったと私たちが考える証拠としてとるのは少し不公平に思えます。

私にとって、その主張(MVSは不適当であり、間違った方向への本質的に不可逆的なステップである)は、私が個人的に挑戦していることであり、私があなたの議論を読んでいるレンズです。 それらの議論の1つは、非互換性を宣言し、それらが発生したときにバージョン選択アルゴリズムを失敗させることができる場合の機能であるというものでした。 もう1つの公正な議論は、それらが発生した場合、アルゴリズムがそれらを解決できるようにするとよいということです(これには、実際にSATソルバーが必要です)。

しかし、それらは有効で公正な懸念であると思いますが、MVSが根本的に不適当であることを私に証明するための基準を通過するとは思いません。 出発点としてのMVSは、優れた重要な機能をテーブルにもたらすと今でも信じています。 そしてそれらの懸念が実際に重大な苦痛を引き起こすことが判明した場合でも、純粋な失敗を伴う上限の追加( go.modの一部として、または個別のサービスとして)から、それを繰り返すことができる方法はまだたくさんありますある時点で完全なSATソルバーとロックファイルを追加するまで。 つまり、これらのことが起こることには同意しますが、a)予想しているほどの痛みを引き起こさないこと、およびb)MVSから始めても解決可能な問題であることに、(おそらく素朴に)楽観的です。

互換性を決定するソース管理の外の何かがMVSシステムの決定論を変えるだろうと私は思います。 あるlibに制約としてfoo> = 1.5.0があり、別のlibにfoo> = 1.6.0がある場合。 次に、これら2つをバイナリに入れて、1.6.0を選択します。 MVSでは、これが繰り返し可能なビルドに必要なすべてです。 常に1.6を選択します

ただし、外部互換性をミックスに追加すると、最初のライブラリを更新して1.6と互換性がないと言うことができます。その後、コードが変更されていなくても、アルゴリズムは1.7を選択します...つまり、再びロックファイル。

参考までに、ロックファイルは悪いことではないと思います。 構築する必要があるものの正確なリストがあると便利です。 そしてそれはそれを速くするはずです。 魔法の論理は必要ありません。

@natefinch外部互換性ツールがv1.6.0に互換性がないことを示したために、アプリケーションのgo.modファイルがv1.7.0を要求するように更新された場合、ロックファイルは必要ありません。 v1.7.0を指定するとgo.modファイルに存在するため、作成者はv1.7.0が使用されている理由と、その情報が読者に役立つというコメントを追加することもできます。

@leighmcculloch 、アプリ内のファイルが更新された場合、それは別のビルドであり、「ロックファイルなしの再現性のあるビルド」の問題の範囲外です。

帯域外の互換性情報は、知識の発展を反映するために提案されています。リリース時には非互換性は知られていませんでしたが、その後明らかになり、すでにリリースされたバージョンに関する追加情報が公開されています。 IMHOの定義によると、このアプローチは依存関係のプル方法に変化をもたらします。そうでない場合、なぜこれが非互換性情報を抽出するのでしょうか。

@redbaron @natefinch

非互換性情報のポイントは、ライブラリの作成者が非互換性情報をユーザーに伝達することです。 その情報がビルド時に使用されるのか、リリース時に使用されるのかは別の問題です。

vgoの場合、現在のアイデアは警告(または潜在的に鳴き声)のみを表示することです。 ただし、特に、使用するバージョンの選択に影響を与えないようにしてください(SATを解決する必要があるため)。 したがって、実際には問題ではありません。どちらかまたは両方で使用でき、再現性の特性を維持しながら、その役割を十分に果たします¹。

詳細には、この情報はリリース時にのみ使用され、ビルド時に使用されるロックファイルに記録されます。 したがって、少なくともvgoとdepの懸念に関しては、とにかくリリース時の使用を「十分に」検討しているようです。

とはいえ、今でも実際にそれらの質問に答える必要はないと思います。


[1]個人的には、リリース時に使用し、ビルド時に-vを使用する場合にのみ使用する方がよいと思います。これは、ユーザーが警告が実行可能かどうかを判断する必要がないためです。

@rscは書いた:

フォローアップするために、バージョンとvgoを確立したら、パッケージに関する追加情報(goコマンドが参照できる情報)を記録する新しいgodoc.org(おそらく別の名前)が絶対に必要です。 そして、その情報の一部は、goコマンドが特定のビルドで警告またはエラーとして報告する可能性のあるペアごとの非互換性です(つまり、損傷を報告し、回避して隠そうとはしません)。

ペアごとの非互換性を記録する必要があるのではないかと思います。 私が現在見ているように、モジュールA @vNとモジュールB @ vMの間の非互換性は、BがL <MであるバージョンvLから互換性のない変更を行ったためです。

モジュールBが互換性のない変更を行わなかった場合、モジュールAにはバグがあります。 もしそうなら、問題はAとBのペアではなく、B自体に関するものです。

そのため、モジュールメタデータのパブリックリポジトリは、以前のバージョンのモジュールとの非互換性のみを記録できるため、問題がより扱いやすくなる可能性があります。 これらの非互換性レポートはバグレポートと非常によく似ていますが、バージョンが公開されると変更できないため、解決できません。

モジュールのバージョンをアップグレードすると、goツールはメタデータを考慮し、現在選択されているバージョンと互換性のないバージョンの考慮を拒否する可能性があります。 これにより、SATを解決する必要がなくなると思います。 また、特定のモジュールに非互換性レポートが多すぎると判断し、依存関係として追加することを拒否する場合もあります。

フォームのタプルのセット( moduleoldVersionnewVersiondescription )で十分な場合があります。

goツールはメタデータを検討し、現在選択されているバージョンと互換性のないバージョンの検討を拒否する可能性があります

もちろん、これは、いくつかの依存関係を追加する場合は機能しません。新しいバージョンは既存のモジュールの一部ではないため、相互に互換性のないバージョンを使用する必要がありますが、合理的なヒューリスティックが利用できる可能性があります。 依存関係追加することは比較的まれであるため、これは重要なAFAICSではありません。

go releaseがこのディスカッションの「十分にスマートなコンパイラ」になりつつあるのではないかと心配しています。 Go 1.11 / 12のgo releaseにユーザーは具体的に何を期待できますか? それが、MVS / SIVに関する合理的な期待に違いをもたらすと思います。

多くの皆さんがGoにもたらしたエネルギー、特にこの提案に感謝します。

提案プロセスの最初の目標は、 「提案が適切で、公正で、タイムリーで、記録された評価と明確な回答を確実に得られるようにすること」です。 この提案は詳細に議論され、議論の要約を公開しました。 6週間と多くの議論の末、提案検討委員会(私が提案を書いたので仲裁人として参加)が提案を受け入れました。

単一のGitHubの問題は、幅広い議論を行うのが難しい場所です。GitHubには会話のさまざまなストランドに対するスレッドがなく、すべてのコメントが表示されないためです。 このようなディスカッションが機能する唯一の方法は、ディスカッションの要約を積極的にキュレーションすることです。 提案が受け入れられるまでに、要約でさえ扱いにくくなっていた。

提案が受け入れられたので、この問題はもはや議論の適切な場所ではなく、要約を更新していません。 代わりに、発生している問題に関する新しい対象を絞った問題や変更の具体的な提案を提出してください。そうすることで、特定のトピックごとに焦点を絞ったディスカッションを行うことができます。 これらの新しい問題の前に「x / vgo:」を付けてください。 新刊の本文で#24301に言及している場合は、他の人が見つけられるようにここで相互参照されます。

最後のポイントは、提案を受け入れることは、プロトタイプの実装のバグなどではなく、アイデアを受け入れることを意味するということです。 解決すべき詳細と修正すべきバグがまだあり、私たちは一緒にそれを続けていきます。

あなたのご親切に感謝します。

やるべきことはまだたくさんありますが(モジュールラベルを参照)、この号で提案されている最初のモジュール実装はメインツリーにコミットされているため、この号を閉じます。

このページは役に立ちましたか?
0 / 5 - 0 評価