独自のプロジェクトでプライベートGoモジュールを使用する方法

提供:Dev Guides
移動先:案内検索

著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Goのエコシステムの有益な側面の1つは、多数のモジュールがオープンソースであることです。 それらはオープンソースであるため、自由にアクセス、調査、使用、および学習することができます。 ただし、独自のビジネスロジックを社内に保持するなど、さまざまな理由でプライベートGoモジュールを作成する必要がある場合があります。

このチュートリアルでは、プライベートGoモジュールを公開し、プライベートモジュールにアクセスするための認証を設定し、プロジェクトでプライベートGoモジュールを使用します。

前提条件

プライベートモジュールの配布

多くのプログラミング言語とは異なり、Goは中央パッケージサーバーではなくリポジトリからモジュールを配布します。 このアプローチの利点の1つは、プライベートモジュールの公開がパブリックモジュールの公開と非常に似ていることです。 完全に独立したプライベートパッケージサーバーを必要とする代わりに、Goプライベートモジュールはプライベートソースコードリポジトリを介して配布されます。 ほとんどのソースコードホスティングオプションはこれをすぐにサポートするため、追加のプライベートサーバーを設定する必要はありません。

プライベートモジュールを使用するには、プライベートGoモジュールにアクセスできる必要があります。 このセクションでは、チュートリアルの後半で別のGoプログラムからプライベートモジュールにアクセスするために使用できるプライベートモジュールを作成して公開します。

新しいプライベートGoモジュールを作成するには、まず、それが存在するプライベートGitHubリポジトリのクローンを作成します。 前提条件の一部として、GitHubアカウントにmysecretという名前のプライベートな空のリポジトリを作成しました。これは、プライベートモジュールに使用するリポジトリです。 このリポジトリは、コンピュータのどこにでも複製できますが、多くの開発者はプロジェクト用のディレクトリを持っている傾向があります。 このチュートリアルでは、projectsという名前のディレクトリを使用します。

projectsディレクトリを作成し、次の場所に移動します。

mkdir projects
cd projects

projectsディレクトリから、git cloneを実行して、プライベートmysecretリポジトリをコンピュータに複製します。

git clone [email protected]:your_github_username/mysecret.git

Gitはモジュールのクローンを作成したことを確認し、空のリポジトリのクローンを作成したことを警告する場合があります。 もしそうなら、これはあなたが心配する必要があるものではありません:

OutputCloning into 'mysecret'...
warning: You appear to have cloned an empty repository.

次に、cdを使用して、複製した新しいmysecretディレクトリに移動し、go mod initをプライベートリポジトリの名前とともに使用して、新しいGoモジュールを作成します。

cd mysecret
go mod init github.com/your_github_username/mysecret

モジュールが作成されたので、別のプロジェクトから使用できる関数を追加します。 nanoまたはお気に入りのテキストエディタを使用して、mysecret.goなどのリポジトリと同じ名前のファイルを開きます。 名前は重要ではなく、何でもかまいませんが、リポジトリと同じ名前を使用すると、新しいモジュールで作業するときに最初に調べるファイルを簡単に決定できます。

nano mysecret.go

mysecret.goファイルで、リポジトリと同じ名前のパッケージに名前を付け、SecretProcess関数を追加して、呼び出されたときにRunning the secret process!行を出力します。

projects / mysecret / mysecret.go

package mysecret

import "fmt"

func SecretProcess() {
    fmt.Println("Running the secret process!")
}

プライベートモジュールが作成されたので、他の人が使用できるようにプライベートリポジトリに公開します。 プライベートリポジトリでは最初にしかアクセスできないため、プライベートモジュールにアクセスできるユーザーを制御できます。 自分へのアクセスを制限することもできますが、友人や同僚へのアクセスを許可することもできます。

プライベートGoモジュールとパブリックGoモジュールはどちらもソースリポジトリであるため、プライベートGoモジュールの公開は、パブリックGoモジュールの公開と同じプロセスに従います。 新しいモジュールを公開するには、git addコマンドを使用して現在のディレクトリで変更をステージングし、git commitコマンドを使用してそれらの変更をローカルリポジトリにコミットします。

git add .
git commit -m "Initial private module implementation"

最初のコミットが成功したというGitからの確認と、コミットに含まれるファイルの概要が表示されます。

Output[main (root-commit) bda059d] Initial private module implementation
 2 files changed, 10 insertions(+)
 create mode 100644 go.mod
 create mode 100644 mysecret.go

残っているのは、変更をGitHubリポジトリに移動することだけです。 パブリックモジュールと同様に、git pushコマンドを使用してコードを公開します。

git push

次に、Gitは変更をプッシュし、プライベートリポジトリにアクセスできるすべての人が変更できるようにします。

git push origin main
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 404 bytes | 404.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:your_github_username/mysecret.git
 * [new branch]      main -> main

パブリックGoモジュールと同様に、プライベートGoモジュールにバージョンを追加することもできます。 Goモジュールの配布方法チュートリアルの新しいモジュールバージョンの公開セクションには、これを行う方法に関する情報が含まれています。

このセクションでは、SecretProcess関数を使用して新しいモジュールを作成し、それをプライベートmysecret GitHubリポジトリに公開して、プライベートGoモジュールにしました。 ただし、別のGoプログラムからこのモジュールにアクセスするには、モジュールにアクセスする方法を認識できるようにGoを構成する必要があります。

GotoAccessプライベートモジュールの構成

Goモジュールは通常、ソースコードリポジトリから配布されますが、Goチームはいくつかの中央Goモジュールサービスも実行して、元のリポジトリに何かが起こった場合にモジュールが存在し続けるようにします。 デフォルトでは、Goはこれらのサービスを使用するように構成されていますが、プライベートモジュールをダウンロードしようとすると、これらのモジュールにアクセスできないため、問題が発生する可能性があります。 一部のインポートパスがプライベートであり、中央のGoサービスを使用してはならないことをGoに通知するには、GOPRIVATE環境変数を使用できます。 GOPRIVATE環境変数は、インポートパスプレフィックスのコンマ区切りのリストであり、検出されると、Goツールは中央サービスを経由せずに直接アクセスしようとします。 そのような例の1つは、作成したばかりのプライベートモジュールです。

プライベートモジュールを使用するには、GOPRIVATE変数に設定して、プライベートと見なすパスをGoに指示します。 GOPRIVATE変数値を設定するときに選択できることがいくつかあります。 1つのオプションは、GOPRIVATEgithub.comに設定することです。 ただし、これは、github.comでホストされているモジュール(自分のものではないものも含む)の中央サービスを使用しないようにGoに指示するため、探しているものではない可能性があります。

次のオプションは、GOPRIVATEgithub.com/your_github_usernameなどの独自のユーザーパスのみに設定することです。 これにより、すべてのGitHubをプライベートと見なすという問題は解決しますが、ある時点で、作成したパブリックモジュールがあり、Goモジュールミラーを介してダウンロードしたい場合があります。 これを行うことは問題を引き起こさず、完全に合理的なオプションですが、さらに具体的にするオプションもあります。

最も具体的なオプションは、GOPRIVATEをモジュールのパスに正確に一致するように設定することです(例:github.com/your_github_username/mysecret)。 これにより、前のオプションの両方の問題が解決されますが、次に示すように、各プライベートリポジトリをGOPRIVATEに個別に追加する必要があるという問題も発生します。

GOPRIVATE=github.com/your_github_username/mysecret,github.com/your_github_username/othersecret

あなた自身のための最良の選択肢を選ぶことはあなたの状況で賛否両論を比較検討することの問題です。

現在、プライベートモジュールは1つしかないため、値には完全なリポジトリ名を使用します。 現在の端末でGOPRIVATE=github.com/your_github_username/mysecret環境変数を設定するには、次のエクスポートコマンドを使用します。

export GOPRIVATE=github.com/your_github_username/mysecret

設定されていることを再確認したい場合は、envコマンドとgrepを使用して、GOPRIVATEの名前を確認できます。

env | grep GOPRIVATE
OutputGOPRIVATE=github.com/your_github_username/mysecret

Goはモジュールがプライベートであることを認識していますが、モジュールを使用するにはまだ十分ではありません。 プライベートモジュールを別のモジュールにgo getしようとすると、次のようなエラーが表示される可能性があります。

go get github.com/your_github_username/mysecret
Outputgo get: module github.com/your_github_username/mysecret: git ls-remote -q origin in /Users/your_github_username/go/pkg/mod/cache/vcs/2f8c...b9ea: exit status 128:
    fatal: could not read Username for 'https://github.com': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.

このエラーメッセージは、Goがモジュールをダウンロードしようとしましたが、まだアクセスできない何かが発生したことを示しています。 モジュールのダウンロードにはGitが使用されているため、通常は資格情報の入力を求められます。 ただし、この場合、GoはGitを呼び出しており、プロンプトを表示することはできません。 この時点で、モジュールにアクセスするには、Gitがすぐに入力せずにクレデンシャルを取得する方法を提供する必要があります。

HTTPS用のプライベートモジュールクレデンシャルの提供

あなたに代わってログインする方法をGitに伝える1つの方法は、.netrcファイルです。 ユーザーのホームディレクトリにある.netrcファイルには、さまざまなホスト名と、それらのホストのログイン資格情報が含まれています。 Gitを含む多くのツールで広く使用されています。

デフォルトでは、go getがモジュールをダウンロードしようとすると、最初にHTTPSを使用しようとします。 ただし、前の例で示したように、ユーザー名とパスワードの入力を求めるプロンプトを表示することはできません。 Gitに資格情報を与えるには、ホームディレクトリにgithub.comを含む.netrcが必要です。

Linux、MacOS、またはWindows Subsystem for Linux(WSL)で.netrcファイルを作成するには、ホームディレクトリ(~/)で.netrcファイルを開いて、編集できるようにします。 :

nano ~/.netrc

次に、ファイルに新しいエントリを作成します。 machineの値は、資格情報を設定するホスト名である必要があります。この場合はgithub.comです。 loginの値は、GitHubのユーザー名になります。 最後に、passwordの値は、作成したGitHubパーソナルアクセストークンである必要があります。

〜/ .netrc

machine github.com
login your_github_username
password your_github_access_token

必要に応じて、エントリ全体をファイルの1行に配置することもできます。

〜/ .netrc

machine github.com login your_github_username password your_github_access_token

注:ソースコードホスティングに Bitbucket を使用している場合は、bitbucket.orgに加えてapi.bitbucket.orgの2番目のエントリも追加する必要があります。 以前は、Bitbucketは複数のタイプのバージョン管理のホスティングを提供していたため、GoはAPIを使用して、ダウンロードを試みる前にリポジトリのタイプを確認していました。 これはもはや当てはまりませんが、APIチェックはまだ存在しています。 この問題が発生した場合、エラーメッセージの例は次のようになります。

go get bitbucket.org/your_github_username/mysecret: reading https://api.bitbucket.org/2.0/repositories/your_bitbucket_username/protocol?fields=scm: 403 Forbidden
    server response: Access denied. You must have write or admin access.

プライベートモジュールをダウンロードしようとしたときに403 Forbiddenエラーが表示された場合は、Goが接続しようとしているホスト名を再確認してください。 api.bitbucket.orgなどの別のホスト名を示している可能性があります。


これで、プライベートモジュールのダウンロードにHTTPS認証を使用するように環境が設定されました。 GoとGitがモジュールをダウンロードしようとするデフォルトの方法はHTTPSですが、代わりにSSHを使用するようにGitに指示することもできます。 HTTPSの代わりにSSHを使用すると便利な場合があるため、プライベートモジュールのプッシュに使用したのと同じSSHキーを使用できます。 また、個人用アクセストークンを作成したくない場合は、 CI /CD環境をセットアップするときにデプロイキーを使用できます。

SSH用のプライベートモジュールクレデンシャルの提供

HTTPSの代わりにプライベートGoモジュールの認証方法としてSSHキーを使用するために、GitはinsteadOfと呼ばれる構成オプションを提供します。 insteadOfオプションを使用すると、すべてのGitリクエストのリクエストURLとしてhttps://github.com/を使用する代わりに、ssh://[email protected]/を使用することをお勧めします。

Linux、MacOS、およびWSLでは、この構成は.gitconfigファイルにあります。 このファイルは、コミットの電子メールアドレスと名前も構成されているため、既にご存知かもしれません。 ファイルを編集するには、nanoまたはお気に入りのテキストエディタを使用して、ホームディレクトリにある~/.gitconfigファイルを開きます。

nano ~/.gitconfig

ファイルを開いたら、次の例のように、ssh://[email protected]/urlセクションを含めるようにファイルを編集します。

〜/ .gitconfig

[user]
    email = [email protected]
    name = Sammy the Shark
    
[url "ssh://[email protected]/"]
    insteadOf = https://github.com/

userセクションに対するurlセクションの順序は重要ではありません。また、url以外にファイルに何もない場合でも心配する必要はありません。 ]追加したセクション。 userセクション内のemailフィールドとnameフィールドの順序も重要ではありません。

この新しいセクションは、https://github.com/で始まる使用するURLの前に、代わりにssh://[email protected]/を置き換える必要があることをGitに通知します。 GoはデフォルトでHTTPSを使用するため、これはgo getコマンドにも影響します。 プライベートモジュールを例として使用すると、これはGoがgithub.com/your_github_username/mysecretインポートパスをURLhttps://github.com/your_github_username/mysecretに変換することを意味します。 GitがこのURLに遭遇すると、URLがinsteadOfによって参照されるhttps://github.com/プレフィックスと一致することがわかり、結果のURLがssh://[email protected]/your_github_username/mysecretに変わります。

ssh://git@ URLがそのホストでも機能する限り、これと同じパターンをGitHub以外のドメインに使用できます。

このセクションでは、SSHを使用して.gitconfigファイルを更新し、urlセクションを追加して、GoモジュールをダウンロードするようにGitを構成しました。 プライベートモジュールの認証が設定されたので、Goプログラムで使用するためにアクセスできます。

プライベートモジュールの使用

前のセクションでは、HTTPS、SSH、またはその両方を介してプライベートGoモジュールにアクセスするようにGoを構成しました。 Goがプライベートモジュールにアクセスできるようになったので、過去に使用した可能性のある他のパブリックモジュールと同様に使用できます。 このセクションでは、プライベートモジュールを使用する新しいGoモジュールを作成します。

projectsなどのプロジェクトに使用するディレクトリで、mkdirコマンドを使用して、新しいプロジェクト用にmyprojectという名前のディレクトリを作成します。

mkdir myproject

ディレクトリが作成されたら、cdを使用してディレクトリに移動し、 [など、プロジェクトが存在するリポジトリURLに基づいて、プロジェクトのgo mod initを使用して新しいGoモジュールを初期化します。 X199X]。 プロジェクトを他のリポジトリにプッシュする予定がない場合、モジュール名はmyprojectまたは他の名前にすることができますが、共有されるほとんどのモジュールで完全なURLが必要になるため、完全なURLを使用することをお勧めします。 。

cd myproject
go mod init github.com/your_github_username/myproject
Outputgo: creating new go.mod: module github.com/your_github_username/myproject

次に、nanoまたはお気に入りのテキストエディタでmain.goを開いて、プロジェクトの最初のコードファイルを作成します。

nano main.go

ファイル内で、プライベートモジュールを呼び出す最初のmain関数を設定します。

projects / myproject / main.go

package main

import "fmt"

func main() {
    fmt.Println("My new project!")
}

今すぐプロジェクトを実行し、すべてが正しく設定されていることを確認するには、go runコマンドを使用して、main.goファイルを提供します。

go run main.go
OutputMy new project!

次に、パブリックモジュールの場合と同様に、go getを使用して、新しいプロジェクトの依存関係としてプライベートモジュールを追加します。

go get github.com/your_github_username/mysecret

goツールは、プライベートモジュールのコードをダウンロードし、最新のコミットハッシュとそのコミットの時刻に一致するバージョン文字列を使用して依存関係として追加します。

Outputgo: downloading github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2
go get: added github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2

最後に、main.goファイルを再度開き、それを更新して、main関数のプライベートモジュールのSecretProcess関数への呼び出しを追加します。 また、importステートメントを更新して、github.com/your_github_username/mysecretプライベートモジュールもインポートとして追加する必要があります。

projects / myproject / main.go

package main

import (
    "fmt"

    "github.com/your_github_username/mysecret"
)

func main() {
    fmt.Println("My new project!")
    mysecret.SecretProcess()
}

プライベートモジュールで実行されている最終的なプロジェクトを確認するには、main.goファイルをパラメーターとして指定しながら、go runコマンドを再度使用します。

go run main.go

元のコードのMy new project!行が表示されますが、インポートしたmysecretモジュールのRunning the secret process!行も表示されます。

OutputMy new project!
Running the secret process!

このセクションでは、go initを使用して、以前に公開したプライベートモジュールにアクセスするための新しいGoモジュールを作成しました。 モジュールを作成したら、go getを使用して、パブリックGoモジュールの場合と同じようにプライベートモジュールをダウンロードします。 最後に、go runを使用して、プライベートモジュールを使用してGoプログラムをコンパイルおよび実行しました。

結論

このチュートリアルでは、プライベートGoモジュールを作成して公開しました。 また、プライベートGoモジュールにアクセスするためにHTTPS認証とSSH認証の両方を設定します。 最後に、新しいプロジェクトでプライベートモジュールを使用しました。

Goモジュールの詳細については、Goプロジェクトに一連のブログ投稿があり、Goツールがモジュールとどのように相互作用して理解するかを詳しく説明しています。 Goプロジェクトには、GoモジュールリファレンスにGoモジュールに関する非常に詳細で技術的なリファレンスもあります。

GOPRIVATE環境変数に加えて、プライベートGoモジュールを操作するときに使用できる変数が増えます。 詳細については、Goモジュールリファレンスプライベートモジュールセクションを参照してください。

.netrcファイルの詳細を調べることに興味がある場合は、.netrcGNU Webサイトに、使用可能なすべてのキーワードのリストが含まれています。 git-configドキュメントには、使用可能な他のオプションに加えて、使用したinsteadOf構成オプションがどのように機能するかについての詳細も含まれています。

このチュートリアルは、 DigitalOcean How to Code inGoシリーズの一部でもあります。 このシリーズでは、Goの初めてのインストールから、言語自体の使用方法まで、Goに関する多くのトピックを取り上げています。