GitBucket 4.37.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.37.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.37.0

カスタムSSH URLのサポート

GitBucketの前段にSSHアクセス用のプロキシサーバを別途設置する構成に対応できるよう、管理画面からカスタムSSH URLを設定できるようになりました。

f:id:takezoe:20211211161057p:plain

署名付きコミット検証でEDDSAキーをサポート

Apache SSHDとbouncycastle-javaのバージョンアップにより署名付きコミットの検証でEDDSAをサポートするようになりました。

文字列長制限の緩和

以下の文字列長制限を緩和しました。

  • パスワード(20文字→40文字)
  • WebフックURL(200文字→400文字)

Web APIの改善

Web APIに関して以下の改善を行いました、特にGit Reference APIの改善はJenkins連携の改善に役立つはずです。

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

自宅の作業用デスクを買い換えた

f:id:takezoe:20211204130940j:plain

完全リモートワーク突入してから早2年弱、10年以上前に購入した小さなデスクで作業していたのですが、狭すぎて作業がしづらいだけでなく窮屈な姿勢でのタイピングが肩凝りの原因にもなっていると思われたので、転居で部屋が広くなったこともあり大きなデスクに買い換えてみました。

購入したのはかなでもののラバーウッドテーブルの140cm x 70cmのサイズのもので、配線孔オプションも付けてみました。社でホームオフィス環境整備のための補助があり、全額ではありませんが一部はそれでカバーすることができました。Flexispotなどの電動スタンディングデスクも検討したのですが、最初面白がって上下する以外は使わなそうだなーと思ったのとw めちゃくちゃ重そうで組み立てや移動が大変そうだったのでやめておきました。

実際に数日使ってみたところ、奥行きがあるのでキーボードをタイプする際に肘をデスク上に置けるようになりかなり疲労が軽減されました。姿勢も良くなり長時間作業しても疲れにくくなりましたし、ノートにメモを取ったりなどPC以外の作業も格段にやりやすくなりました。一方で以前のデスクにはついていた引き出しがなくなってしまったので収納については若干困ったのですが、まあ整理をする良い機会かと思い、大掃除には少し早いですがいろいろと断捨離しました。

また、配線が床に這ってしまうと掃除がしづらいので、マグネット付きの電源タップを買ってきてデスクの脚にくっつけてみたのですが、MacBookのACアダプタが重すぎて磁力で支えきれず結局MacBookのACアダプタは以前と同じく壁面のコンセントに直接挿しています。ただ、ディスプレイの電源ケーブルやその他の電子機器についてはデスク脚の電源タップから電源を取れるようになったので以前と比べるとスッキリしたかなと思います。

広いデスクによる問題点としてはディスプレイの位置が遠くなったので若干小さな文字が見えにくくなってしまったということですw 今は5年くらい前に購入した以下の24インチの4Kモニターを使っているのですが、もう少し大きめのものでもいいかも。

買い換えるのであればUSB-C対応のものでMacBookとケーブル一本で接続できるものにしたいです。これとか。

いずれにしても2021年買ってよかったものダントツNo.1です。とても費用対効果の高い買い物でした。椅子も10年以上前に購入したバロンチェアが経年で崩壊してきてしまったので買い換えたいところですが、こちらはさらにお値段が張るのでサンタさんにお願いするしかない…。

Scalaでオレオレdocker-registryを実装してみた

だいぶ前からちょこちょこと作っていたんですが、ようやくイメージのpush、pullができるようになりました。

github.com

モノ自体はScalatraで作ったシンプルなWebアプリケーションで、以下のドキュメントに記載されているDockerのRegistry API V2を実装しています。

docs.docker.com

全てのAPIを実装しているわけではありませんし、色々と手を抜いている部分も多く、コード量は大したことありませんが、このドキュメントだけだとわからない点も多く、結局既存のdocker-registryのコードを調べて実装した部分もありました。docker-registryはAPIの構成自体は比較的シンプルなのですが、真面目に実装するとなると複数のバージョンのマニフェストをサポートしないといけなかったりと細かい部分が色々面倒そうです。

ちなみになんでわざわざこんなものを作っているのかというと、 現在GitBucketにはMavenリポジトリの機能を追加するプラグインが存在するのですが、同様にdocker-registryの機能を追加するプラグインを作りたいなと思っているためです(Scalatraで作っているのもそのため…)。

The Four: The Hidden DNA of Amazon, Apple, Facebook, and Google

2017年の出版で日本語訳も出ているので今更感ありますが、近隣の書店で売っていたので英語の読書ネタにちょうどいいかと思い読んでいました。途中で別の積読を崩したりしていたので、読み切るのになんだかんだ2ヶ月くらいかかってしまいました。

ベストセラーなだけあって面白く、最後まで飽きずに読み切ることができました。Big Techに対して批判的なスタンスで書かれており、印象に残ったのは以下のような点です。

  • AmazonAppleのビジネスに関する分析
  • Googleの分析ではGoogleの話そっちのけで自分がボードを務めていたNewYork Timesでの失敗談w
  • とにかくFacebookが嫌いらしい
  • 将来の予測という点では外してたりいまだに現実になっていない部分もあるけど、パンデミックなど予測不能なこともあるので仕方ない
  • 今後のキャリアアドバイスについては現実的で普通のことしか書かれていない
  • Big Techの社会・経済への悪影響についてかなり強く懸念を表明している

出版から4年経っているので半分答え合わせのような部分もあり、リアルタイムで読むのとはまた違った面白さがあったかなと思います。難点としてはペーパーバックで読んだのですが、字が小さすぎて読むのが辛かったですw

AWSコンテナ設計・構築[本格]入門

Amazonのレビューでもやけに評判がいいし、AWS & ECS弱者なので読んでみました。感想としては例によってAWS使うの大変だなーという感じ…。ハンズオン形式ですが、一通り目を通すだけでもECSと周辺サービスを組み合わせてどんなことができるか掴めるのではないかと思います。

scala-cliでScalaによるスクリプティングとパッケージングを試してみる

最近VirtusLab社が突如として公開したScala用の汎用CLIツールscala-cliを試してみました。

scala-cli.virtuslab.org

基本的にはScalaスクリプティングするためのツールのようで、便利ツールや教育用途での使用が想定されているようですが、スクリプトを実行可能jarやDockerイメージとしてパッケージングしたり、Scala.jsやScala Nativeでのコンパイルにも対応しているようです。MacであればHomebrewでインストールが可能なのですが、手元の環境ではHomebrewのバージョンが古いせいかインストールできなかったのでGitHubから最新のソースを取得して自分でビルドしたものを使っています。

スクリプトの実行

まずは簡単なScalaプログラム(HelloWorld.scala)を実行してみます。

@main def hello() = println("Hello, world")

以下のようにして実行します。runはデフォルトのサブコマンドなので省略することもできるようです。デフォルトでScala 3が使われるようですね。

$ scala-cli run HelloWorld.scala
Compiling project (Scala 3.0.2, JVM)
Compiled project (Scala 3.0.2, JVM)
Hello, world

使用するScalaのバージョン、ライブラリなどはscala-cliコマンドのオプションのほか、ソースコード中にコメントで特殊なディレクティブを記述することでも指定できます。Scala 2.12は大丈夫だったのですが、Scala 2.13を指定してみたところコンパイルが失敗してしまいました(Compilation failedとだけ表示される)。これは最新のソースからビルドしたものを使っているせいかもしれません。

// using scala 3
// using lib org.wvlet.airframe::airframe-json:21.10.0
import wvlet.airframe.json.JSON

@main def hello = {
  val jsonValue = JSON.parse("""{"id":1, "name":"leo"}""")
  println(jsonValue)
}

Ammoniteでサポートされている拡張子が*.scスクリプトにも対応しています。こちらではmainメソッドを記述する必要がないほか、Ammonite形式の記述でライブラリのインポートなどが可能です。AmmoniteスクリプトはMetalsやIntelliJでもサポートされているのでスクリプトの記述時にIDEの支援機能を利用できるのは嬉しいですね。

import $ivy.`org.wvlet.airframe::airframe-json:21.10.0`
import wvlet.airframe.json.JSON

val jsonValue = JSON.parse("""{"id":1, "name":"leo"}""")
println(jsonValue)

mainメソッド付きの*.scalaファイルと同じように実行できます。

$ scala-cli run hello.sc

パッケージング

スクリプトをパッケージングしてみます。

$ scala-cli package hello.sc
Wrote hello, run it with
  ./hello

$ ./hello
Hello, world!

helloというコマンドが生成されます。このコマンドは軽量なランチャーで、必要な依存関係などは初回実行時に自動的にダウンロードするようです。実行にはJavaがインストールされている必要があります。依存関係も含めてパッケージングしたい場合は--assemblyオプションを指定するとUber JARが生成されます。

$ scala-cli package hello.sc --assembly
Wrote hello.jar, run it with
  ./hello.jar

$ java -jar hello.jar
Hello, world!

--jsオプションでJavaScriptを生成できます。生成されたJavaScriptはNode.jsで実行可能です。

$ scala-cli package hello.sc --js
Wrote hello.js, run it with
  node ./hello.js

$ node hello.js
Hello, world!

--nativeオプションでScala Nativeを使用したバイナリを生成できます。こちらはScala 2.12もしくは2.13を使用する必要があるようです。*.scのサポートはScala 2.13のみのようなのですが、手元で試したところではScala 2.13では依存関係の解決に失敗してビルドが通りませんでした。前述の通り、Scala 2.13では通常の実行でもコンパイルに失敗するので最新のソースではScala 2.13の扱いに問題があるのかもしれません。

$ scala-cli package HelloWorld.scala --native -S 2.12
Linking (1432 ms)
Discovered 971 classes and 8420 methods
Generating intermediate code (2108 ms)
Produced 8 files
Compiling to native code (676 ms)
Linking native code (immix gc, none lto) (148 ms)
Total (4510 ms)
Wrote HelloWorld, run it with
  ./HelloWorld

$ ./HelloWorld
Hello, world!

--dockerオプションでDockerイメージを生成できます。ただし、デフォルトではJava 8ベースのベースイメージが使用されるようなので、手元の環境もJava 8でコンパイルが行われるようにしておくか、パッケージング時に--docker-fromオプションでより新しいバージョンのJavaを使用可能なベースイメージを指定する必要があります。

$ scala-cli package --docker hello.sc --docker-image-repository hello-docker --docker-from openjdk:11-jre-slim
Started building docker image with your application, it would take some time
Built docker image, run it with
  docker run hello-docker:latest

$ docker run hello-docker:latest
Hello, world!

今回は試していないのですが、--dockerオプションを--js--nativeオプションと組み合わせることでJavaScriptやネイティブバイナリで動作するDockerイメージを生成することもできるようです。

この他にもREPLの起動(オプションでAmmoniteを使用することも可能)や、scalafmtを使用したコードのフォーマット、sbtやmillの形式でのプロジェクトとしてエクスポートなど様々な機能がサポートされているようです。スクリプトを実行するだけであればAmmoniteだけで良さそうな気もしますが、作成したスクリプトを配布したり、スクリプトでプロトタイピングをして必要であればsbtプロジェクトとしてエクスポートして本格的に開発する、なんていう使い方も可能かもしれません。

Scalaプロジェクトでのバージョンバッジ

ライブラリ等をGitHubで開発する場合、最新バージョンを表示するためのバッジを表示することが一般的なプラクティスになっています。

バッジを表示するためのサービスは色々ありますが、JVM系のプロジェクトの場合、たとえば以下のような感じでMavenセントラルにデプロイされている最新のバージョンを表示できます(ScalaライブラリはScalaのメジャーバージョン毎に別のアーティファクトとしてデプロイされるのでURLでScalaのバージョンを指定する必要があります)。

![Maven Central](https://img.shields.io/maven-central/v/org.scalatra/scalatra_2.12)

Maven Central

ここで使っているshields.ioは他にも様々なバッジに対応しています。

shields.io

Scalaライブラリの場合、ScaladexというScalaライブラリの検索サービスがバッジを生成する機能を備えており、これを使うとScalaのバージョンを指定しなくてもライブラリが対応しているScalaバージョンも含めたバッジを表示できます。Scala.jsやScala Nativeにも対応しているようです。

github.com

バッジ表示用のMarkdownはScaladex上に表示されているバッジから取得できます。

f:id:takezoe:20211009102159p:plain

実際の表示はこんな感じになります。

[![scalatra Scala version support](https://index.scala-lang.org/scalatra/scalatra/scalatra/latest-by-scala-version.svg)](https://index.scala-lang.org/scalatra/scalatra/scalatra)

scalatra Scala version support

バッジのURLにScalaのバージョンを含める必要もありませんし、Scalaのバージョンごとに対応する最新バージョンも一目でわかるのでなかなか便利です。