この記事はQiitaで公開されていました
Goのパッケージ名は、リポジトリのURLをそのまま使うことが多いと思いますが、リポジトリはそのままで、別のURLをパッケージ名にすることもできます。
例えば、あるパッケージのリポジトリをGitHubに置いていて、リポジトリのURLは github.com/lufia/ken_all
だとします。
(現在、上記URLは存在しません)
通常は、
import ( "github.com/lufia/ken_all" )
のようにパッケージをimportします。
ですが、
- ホスティング先が変わってもパッケージパスを変えたくない
- 名前に '_' が含まれていて気に入らない
などの場合に、go-import
というmeta要素を含むHTMLを作成して、HTMLが置かれたURLを、パッケージ名として使うことができます。今後、ホスティングをGitHubから他のサービスへ移すことがあったとしても、パッケージをimportしているコードは変更する必要がありませんし、階層で付加情報を表現することもできます。
代わりに、HTMLを置いたURLは変えない努力が必要です。
go-importの書き方
go-import
という名前の付いたmeta要素は、空白で区切った3つのパラメータが、以下の順番で必要です。
簡単なところから、VCS名はバージョン管理ツール名です。hg
, git
, svn
, bzr
からひとつ選びます。
リポジトリルートURLはそのまま、リポジトリのURLです。パッケージ名ではないため、https://等から始まっていなければなりません。パッケージ名プリフィックスは、パッケージ名のうち、リポジトリルートURLまでに該当する部分となります。
ひとつ例を紹介します。
github.com/lufia/ken_all
というパッケージ名をexample.com/japanese/postal
からアクセスできるようにしたい、と仮定します。
VCS名はホスティングがGitHubなので git
ですね。リポジトリルートURLはパッケージ名からわかるように、https://github.com/lufia/ken_all.git
です。
このリポジトリには、
- example.com/japanese/postal/cmd
- →実体はgithub.com/lufia/ken_all/cmd
- example.com/japanese/postal/token
- →実体はgithub.com/lufia/ken_all/token
など、いくつかパッケージが含まれているかもしれませんが、パッケージ名プリフィックスは、リポジトリルートURLまでに該当する部分となります。この例で言えば example.com/japanese/postal
まで、です。
完成したmeta要素は以下の通り。
<meta name="go-import" content="example.com/japanese/postal git https://github.com/lufia/ken_all.git">
これを含むHTMLを、パッケージ名から参照できるURLに置いておけば、example.com/japanese/postalパッケージとして参照ができるようになります。最終的にHTMLへ到達できれば、リダイレクトしても構いません。また、httpsが推奨されていますが、httpでも動作します。
正式なURLのみ許可する
上記のmeta要素を含むHTMLを使うことで、1つのパッケージに対して、複数のパッケージ名でアクセスされる可能性が出てきます。上記の例で言えば、
- example.com/japanese/postal
- github.com/lufia/ken_all
の2つが、パッケージ名として有効です。この動作が困る場合、package
宣言のどこか1か所に// import "canonical import path"
というマジックコメントを入れておくことで、コメントのパッケージ名以外でimportした場合はビルドエラーにできます。
package postal // import "example.com/japanese/postal"
上記の場合、import "github.com/lufia/ken_all"
でimportしているコードはエラーとなるためビルドできません。
go-sourceの書き方
go-import
の他に、go-source
という名前のmeta要素もあります。go-source
は、存在しなくてもビルドに影響はありません。
この要素は、以下の順番にパラメータを要求します。
パッケージ名プリフィックスは go-import
と同じです。リポジトリのホームページも名前の通り、ブラウザで表示可能なリポジトリのTOPをあらわすURLを記述します。
ディレクトリパスのテンプレートは、ディレクトリに含まれるファイルを表示するためのURLを定義します。テンプレートには {dir}
または {/dir}
を含むことができ、これらはパッケージ名プリフィックスから後のパスに置換されます。{dir}
と {/dir}
の違いは、前者は先頭の'/'を含みません。後者は含みます。
プリフィックスが example.com/japanese/postal
の場合
パッケージ名 | {dir} | {/dir} |
---|---|---|
example.com/japanese/postal | (空) | (空) |
example.com/japanese/postal/cmd | cmd | /cmd |
同様に、ファイルパスのテンプレートはソースファイルの内容を表示するためのURLを定義します。このテンプレートには {dir}
, {/dir}
の他に、{file}
, {line}
も含めることができます。それぞれ、{file}
はファイル名に、{line}
はファイル中の行番号に置換されます。
完成したmeta要素は以下の通り。
<meta name="go-source" content="example.com/japanese/postal https://github.com/lufia/ken_all https://github.com/lufia/ken_all/tree/master{/dir} https://github.com/lufia/ken_all/tree/master{/dir}/{file}#L{line}">
ディレクトリURLとファイルURLのテンプレートはホスティングサービスによって異なるため、お使いのサービスを確認してください。
まとめ
すべて含めると、以下のようになります。
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="go-import" content="example.com/japanese/postal git https://github.com/lufia/ken_all.git"> <meta name="go-source" content="example.com/japanese/postal https://github.com/lufia/ken_all https://github.com/lufia/ken_all/tree/master{/dir} https://github.com/lufia/ken_all/tree/master{/dir}/{file}#L{line}"> <meta http-equiv="refresh" content="0; url=https://godoc.org/example.com/japanese/postal"> </head> <body> </body> </html>