タイトルで察した方は帰って結構です。
git submoduleというのがある。これは、別レポジトリをレポジトリの一部として管理できる機能で、要するに依存しているレポジトリのURLと対応するコミットをコードの一部として管理するものだ(大雑把すぎる)。すると依存レポジトリのバージョンをgitで一括で管理できるようになる。
$ git submodule add <repo URL> # その後 $ git submodule init $ git submodule update # または、上記を一括で $ git submodule update --init # submodule の submodule まで再帰的に $ git submodule update --init --recursive
submoduleも一つの独立したgitディレクトリとして振る舞うので、そこでpullしてから上でaddすることによって「依存関係にあるレポジトリのバージョンを上げる」という変更をgitで記録できる。
さて、このようなことを実践したレポジトリをpushしたところ、Travisが落ちた。Permission denied (publickey)と言われている。gitのsshプロトコルでアクセスした場合、sshの鍵がないとダウンロードできない(sshでログイン出来ないので)。もちろん、自分の秘密鍵を公開レポジトリに置くような馬鹿はいない。よって、submoduleをダウンロードできず、CIは失敗する。
さてどうしたものか。
とりあえずググると、Gistに解決策が転がっていた。まず、Travisが自動で行うgit clone --recursive
をやめさせる(git: submodules: false
)。続いて、sed
でgit@github.com
をhttps://github.com
に変換する。力技だ。
確かにこれはLinuxでなら動くが、OS Xだと動かない。OS XはUnixでありLinuxではないので、コマンドの挙動がほんの少しずつ異なる。以下に同じ問題に苦しめられた人間の怨嗟の声がある。
Sed: 'sed: 1: invalid command code R' on Mac OS X
何が起きているかというと、sed -i
はファイルをその場で(in-place)書き換える。これは怖いので、sedはバックアップファイルを作りたいと思っている。そのバックアップファイルの拡張子を-i
オプションの引数として要求されているのだが、我々はそれを渡さず、代わりにsedスクリプトと変更して欲しいファイルを渡した。するとsedはスクリプトをバックアップファイルの拡張子と思い込み、続くファイル名をsedスクリプトだと思って実行しようとして、「そんなコマンドはない」と返しているというわけだ。
回避するには、適当な拡張子をくれてやればいい。あるいは、空の文字列を渡せばそもそもバックアップファイルは作られない。
# この""が必要 $ sed -i "" 's/hoge/foo/g' foobar.dat
あとはこれで、Travisで環境を見て分岐してから実行して終わりだ。