Into the Sunset on May 1st: Bintray, JCenter, GoCenter, and ChartCenter
jCenterが閉鎖するってことでもう大変ですね。自分が使っているOSSの作者さんは期日までに移行してくれるのかとか戦々恐々としているところでしょう。
一方、ライブラリを公開している人間としては、早く移行先探さなきゃ!そもそも今まで公開してたのどうするよ!という状態じゃないでしょうか。というか私だ。
旧バージョンは移行できない可能性があるし、そもそも新バージョンも期日までに全部対応しきれるのか?状態なので、一旦bintrayに全くアクセスできなくなっても大丈夫なようにお手軽にできるバックアッププランを実行しておくことにしました。
今までアップロードしたファイル群を全部落とす
bitrayにアップロードした過去のファイル群を一旦手元に落とします。
といっても一括でダウンロードできるようなリンクが用意されているわけではなさそうです
https://dl.bintray.com/<user name>/<repository name>/
でファイルツリーっぽいものにアクセスできるのですが
ソースを見ると以下のようになっています
<html>
<head>
<script>
function navi(e){
location.href = e.target.href.replace('/:','/'); e.preventDefault();
}
</script>
</head>
<body>
<pre><a onclick="navi(event)" href=":net/" rel="nofollow">net/</a></pre>
</body>
</html>
:net/
ってなんだ?と思ったら、JSでリンクの処理してますね。これがシンプルなリンクになってくれていれば、サイトまるごとダウンロードとかのツールでダウンロードできるのでしょうが、ちょっと無理くさい。
しかしまあ、ページの構造は非常にシンプルなので、ちょっとしたツール書けば良さそうですね。
ってことで以下のようなツールを実行
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.File
object Main {
private const val baseUrl = "https://dl.bintray.com"
private const val basePath = "/<user name>/<repository name>/"
private val dirs = mutableListOf<String>()
private val files = mutableListOf<String>()
private val client: OkHttpClient = OkHttpClient.Builder().build()
private fun download(url: String): Response =
client.newCall(Request.Builder().get().url(url).build()).execute()
@JvmStatic
fun main(args: Array<String>) {
downloadDir("")
while (dirs.isNotEmpty()) {
downloadDir(dirs.removeAt(0))
while (files.isNotEmpty()) {
downloadFile(files.removeAt(0))
}
}
}
private fun downloadDir(dir: String) {
val url = baseUrl + basePath + dir
println("download dir: $url")
val content = download(url).body?.string() ?: run {
println("error")
return
}
var base = 0
while (true) {
val start = content.indexOf("href=", base)
if (start < 0) break
val end = content.indexOf("\"", start + 7)
if (end < 0) break
val name = content.substring(start + 7, end)
if (name.endsWith(".pom") ||
name.endsWith(".xml") ||
name.endsWith(".zip") ||
name.endsWith(".jar") ||
name.endsWith(".aar") ||
name.endsWith(".md5") ||
name.endsWith(".asc") ||
name.endsWith(".sha1")
) {
files += dir + name
} else {
dirs += dir + name
}
base = end + 1
}
}
private fun downloadFile(filename: String) {
val url = baseUrl + basePath + filename
println("download file: $url")
val content = download(url).body?.byteStream() ?: run {
println("error")
return
}
File(filename).let { file ->
file.parentFile.mkdirs()
val bytes = content.readAllBytes()
content.close()
println("write file: $file size: ${bytes.size}")
file.outputStream().use { it.write(bytes) }
}
}
}
全く洗練されていないクソコードですが、一発動けばいいやなのでご愛敬
これでディレクトリ構造を保持してまとめてダウンロードできます。
HTTPサーバーにホスティング
前項でダウンロードしたファイルをHTTPでアクセス可能なところにアップロードしてしまえば、即席の野良mavenリポジトリの完成です。Webサーバーを持っている人なら、ディレクトリ切ってそこにアップロードしておくとかでもいいかもしれません。
Webサーバーなんてもっとるかい、とか、持ってるけどそういう用途では使いたくないとかの場合は、Github Pagesがお手軽ですね。プロジェクトごとに分けるならそれぞれのプロジェクトのページに置いても良いでしょう。私の場合は、ユーザーページにまとめておきました。
<username>.github.io
というリポジトリをつくって、ここにmavenリポジトリのファイルツリーをコミット。SettingsからGithub Pagesの設定をして終わりです。
私の場合は以下のように、mavenディレクトリを切ってその中に全部突っ込みました。
これで、利用する場合は
repositories {
mavenCentral()
maven { url = URI("https://ohmae.github.com/maven") }
}
みたいに指定すれば、上記Github Pagesで作ったリポジトリも検索対象となり、そこのライブラリを利用できるようになります。
以上です。