Golang(存在しない)のパッケージ管理

4504 ワード

Golang(存在しない)のパッケージ管理
  • Golang開発とGOPATH
  • Govendor
  • Go Modules after 1.11
  • go get被壁問題
  • まとめ
  • 最近Golangが上手になって、意外にも最初からパッケージ管理の上で多くの問題にぶつかって、大きな輪を探して、そのため1篇の博文を開いてGolang package managingの中で登った穴を記録します.
    Golangのパッケージ管理はPythonのように健全ではなく、condaでもpipでも簡単にバージョンを指定でき、tunaでミラーソースを交換することでGFWを克服することができます.Golangのgo getコマンドは、repoコードをダウンロードしてインストールするプロセスにすぎず、golang.orgサイトは壁に囲まれているのでgolang.org/x/以下のすべてのパッケージは基本的にダウンロードできませんがgithubをダウンロードしています.comのバッグもgolangに依存することが多い.orgのパッケージはダウンロードできません.
    Golang開発とGOPATH
    最初は知らなかったが、後で明らかになって驚いたのは、デフォルトのGolang開発モデルでは、すべての工事(自分で書いたものを含む)を$GOPATH/srcに置くことで、作業ディレクトリをGOPATHに入れて逆方向にこの条件を満たすことができるが、Pythonプロジェクトを書くたびにPYTHONPATHに入れるような奇妙な感じがしたことだ.GOPATHに入れないと、プロジェクト内の他のパッケージを参照することはできません(GolandはプロジェクトGOPATHを構成して避けることができます).しかし、Golang自体が言語の直接的な死の基準です.
    importの1つのパケットは、実際にはいくつかのPATHの中で対応するフォルダを探しています.例えば、import "github.com/tidwall/evio"$GOPATH/src/github.com/tidwall/evio/ディレクトリの下のすべてのファイルを探してロードします(ファイルに注意して、フォルダを再帰的にロードしません)、evioのソースコードにはinternalパケットを参照するときにもimport "github.com/tidwall/evio/internal"、つまり$GOPATH/src/github.com/tidwall/evio/internal/フォルダが使用されていることがわかります.つまりGolangはrelative importの概念がないということです.Golangでは同じフォルダのファイルに複数のpackageを定義することはできませんが、package nameはdirectory nameとは異なり、同じpackageのファイルは互いに感知されます.すなわち、1つのファイルは、他のファイルで定義された関数を直接呼び出すことができます(例えば、goコンパイラは、同じレベルのディレクトリの下のすべてのファイルの関数定義構成シンボルテーブルをスキャンしてから関数コードをコンパイルすることができます).
    Govendor
    Go 1.5以降では、プロジェクトディレクトリの下にあるvendorディレクトリもコンパイル時の検索PATHとして機能するvendorメカニズムが追加されたが、これは本質的にパケット依存バージョン制御の問題を解決するものではなく、vendorの下にあるディレクトリを管理するメカニズムも内蔵されていないため、vendorディレクトリの下にvendorを追加するツールがある.jsonファイルはバージョン管理として使用され、govendorは実行可能なファイルとしてcommand lineの管理方法を提供し、具体的にはdocを参照することができる.しかしgovendorを使用する場合、プロジェクトは$GOPATH/srcの下にあるはずです.
    Go Modules after 1.11
    Go 1.11以降にgo modulesが「百花斉放」のパッケージ管理市場を整備するために追加され、対応命令はgo modである.go modulesを使用した後、goを追加します.modとgo.sumファイル(バージョンロック用)は、プロジェクトをGOPATHに置く必要がなくなり、go buildコマンドが呼び出されるとgoが検出する.modファイルはmoduleモードを開きgoをダウンロードします.modで宣言されていますが、ローカルにキャッシュされていないパケットは、$GOPATH/pkg/modの保存場所です.さらにgo modulesは$GOPROXY環境変数の使用をサポートし、export GOPROXY=https://goproxy.ioを使用することができ、パッケージをダウンロードする際にgoproxyを使用することができる.ioのエージェントはGFWを迂回している(この点は非常に重要であり、go modulesを使用することにした理由でもある).btw goproxy.io自体もオープンソースで、社内ネットワークのミラーリングなどに使用できます.
    リンクUsing Go Modulesと別れGOPATHを参照し、go modをすばやく使用します.
    go get被壁問題go get命令でパケットをダウンロードするのが一番頭が痛い問題はアドレスが壁にかかっていることです.github.comサイトのパッケージはダウンロードできる場合もありますgolang.orgサイトの人は考えないでください.普通のブログではgolangと言いますが.orgのパッケージはgithubに対応するrepoがあり、git cloneでダウンロードしてソフトリンクを作ることができますが、原始的な感じがします.七牛雲のgopmツールを使うことをお勧めするブログもありますが、私の実測によると、コードには確かに七牛雲のgopmが入っています.ioサイトはパッケージをダウンロードしますが、実測ではこのサイトも壁になっていて使用できません.
    一般的にLinuxのコマンドラインではproxychainsを使用してssサービスにネットワークリクエストをエージェントすることができるので、proxychains go get ...を使用してパッケージをダウンロードしようとしましたが、ダウンロードプロセスがproxychainsの出力をトリガーしていないこと、つまりsocks 5を実行していないことがわかります.export http_proxy=socks5://127.0.0.1:1080ではだめです.issueを参照すると、golangは/x/net/proxyパッケージにsocks 5のサポートがありますが、標準ライブラリにはありませんので、socks 5に基づいてhttpのproxyを作ることはできません.proxychainsでだめなのはissueで、proxychainsの動作原理はダイナミックリンクでhookです.How do those hackers'tools workを参照してください.Proxychains、LD_を使用することでPRELAAD環境変数は、既存のダイナミックライブラリのconnect関数を上書きしてproxy経由のリンクを確立しますが、issueではgolangが独自のシステム呼び出しパッケージを使用して静的リンクを使用していると述べているため、hookできません(lddでgoがダイナミックリンクlibcを持っていることを確認していますが...).
    $ ldd /usr/loca/go/bin/go
    	linux-vdso.so.1 (0x00007ffe58db8000)
    	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f38a85c1000)
    	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f38a8207000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007f38a87df000)
    

    しかしhttp_proxy変数は依然として利用可能であり、http proxyのエージェントが必要であるため、socks 5エージェントをhttpエージェントに変換する方法があり、天朝ローカルエリアネットワーク内のgo getの正しい姿勢を参照してください.本文ではpolipoを使用しています.著者はメンテナンスしていないと言っています.もちろん、http-proxy-to-socksなどのソフトウェアはたくさんあります.httpプロトコルをsocksプロトコルに変換して、自分で書くならサードパーティ製のパッケージで解析すればいいだけです.
    ちなみにsshのdynamicport forwarding(すなわち-Dオプション)もsocks 4とsocks 5プロトコルを使用しており、あるリソースへのローカルアクセスは、ssh serverによって開始アクセスの代わりに動的ポート転送することができ、socksサーバに相当する(何をしても分かる).そしてproxychainsの真の目的はproxy chains,すなわちチェーンエージェントであり,HTTPプロトコルを利用したCONNECTリクエストである.
    まとめ
    どちらかというとGOPROXYを使うのがお勧めですが、1.12からgo modulesが正式に導入され、goproxyを直接使うようになりました.ioも便利です.もしいつかgoproxy.ioも壁に囲まれており、そのオープンソースプロジェクトを使用してvpsに1つ組み合わせることもできます.