mike-neckのブログ

Java or Groovy or Swift or Golang

『モブプログラミング ベストプログラミング』を読み終わった

日本でモブプロが話題になってから約 3 年、日本で出版されてから 1 年半くらい経過したでしょうか、やっと 『モブプログラミング ベストプラクティス』を読み終わった。

続きを読む

java -version の結果

たぶん @yamadamn さんが既にやっているやつ。

調べることにした経緯は、 aws amplify cli のバージョンチェックがおかしいため。

github.com

上記のチェックでは、 java -version の結果が /(\d+\.)(\d+\.)(\d)/g にマッチすることを前提にしているが、どうやら java のバージョンが 14.0.0 のようなケースだとバージョンが 14 のような形になるケースが見られる。実際に確かめてみるべく、ローカルにインストールされているすべての java のバージョンについて java -version を実行してみた

while read version ;
do
  sdk u java "${version}"
  printf "\n%s\n" "${version}"
  java -version
done < <(sdk l java | grep -E '(installed|local only)' | grep -v '6u65' | awk '{print $NF}')

結果

Using java version 11.0.8-amzn in this shell.

11.0.8-amzn
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.8" 2020-07-14 LTS
OpenJDK Runtime Environment Corretto-11.0.8.10.1 (build 11.0.8+10-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.8.10.1 (build 11.0.8+10-LTS, mixed mode)

Using java version 8.0.265-amzn in this shell.

8.0.265-amzn
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_265"
OpenJDK Runtime Environment Corretto-8.265.01.1 (build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM Corretto-8.265.01.1 (build 25.265-b01, mixed mode)

Using java version 13.0.2-zulu in this shell.

13.0.2-zulu
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment Zulu13.29+9-CA (build 13.0.2+6-MTS)
OpenJDK 64-Bit Server VM Zulu13.29+9-CA (build 13.0.2+6-MTS, mixed mode, sharing)

Using java version 11.0.1-zulu in this shell.

11.0.1-zulu
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.1" 2018-10-16 LTS
OpenJDK Runtime Environment Zulu11.2+3 (build 11.0.1+13-LTS)
OpenJDK 64-Bit Server VM Zulu11.2+3 (build 11.0.1+13-LTS, mixed mode)

Using java version 8.0.202-zulu in this shell.

8.0.202-zulu
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_202"
OpenJDK Runtime Environment (Zulu 8.36.0.1-CA-macosx) (build 1.8.0_202-b05)
OpenJDK 64-Bit Server VM (Zulu 8.36.0.1-CA-macosx) (build 25.202-b05, mixed mode)

Using java version 11.0.3-librca in this shell.

11.0.3-librca
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.3-BellSoft" 2019-04-16
LibericaJDK Runtime Environment (build 11.0.3-BellSoft+12)
LibericaJDK 64-Bit Server VM (build 11.0.3-BellSoft+12, mixed mode)

Using java version 20.1.0.r11-grl in this shell.

20.1.0.r11-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)

Using java version 20.1.0.r8-grl in this shell.

20.1.0.r8-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 25.252-b09-jvmci-20.1-b02, mixed mode)

Using java version 20.0.0.r11-grl in this shell.

20.0.0.r11-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment GraalVM CE 20.0.0 (build 11.0.6+9-jvmci-20.0-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.0.0 (build 11.0.6+9-jvmci-20.0-b02, mixed mode, sharing)

Using java version 20.0.0.r8-grl in this shell.

20.0.0.r8-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b06)
OpenJDK 64-Bit Server VM GraalVM CE 20.0.0 (build 25.242-b06-jvmci-20.0-b02, mixed mode)

Using java version 19.3.0.2.r11-grl in this shell.

19.3.0.2.r11-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment GraalVM CE 19.3.0.2 (build 11.0.5+10-jvmci-19.3-b06)
OpenJDK 64-Bit Server VM GraalVM CE 19.3.0.2 (build 11.0.5+10-jvmci-19.3-b06, mixed mode, sharing)

Using java version 19.2.1-grl in this shell.

19.2.1-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-20191009173705.graal.jdk8u-src-tar-gz-b07)
OpenJDK 64-Bit GraalVM CE 19.2.1 (build 25.232-b07-jvmci-19.2-b03, mixed mode)

Using java version 19.1.1-grl in this shell.

19.1.1-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-20190711112007.graal.jdk8u-src-tar-gz-b08)
OpenJDK 64-Bit GraalVM CE 19.1.1 (build 25.222-b08-jvmci-19.1-b01, mixed mode)

Using java version 1.0.0-rc-10-grl in this shell.

1.0.0-rc-10-grl
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (build 1.8.0_192-20181024123616.buildslave.jdk8u-src-tar--b12)
GraalVM 1.0.0-rc10 (build 25.192-b12-jvmci-0.53, mixed mode)

Using java version 15.ea.36-open in this shell.

15.ea.36-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment (build 15+36-1562)
OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)

Using java version 14.ea.11-open in this shell.

14.ea.11-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+11-371)
OpenJDK 64-Bit Server VM (build 14-ea+11-371, mixed mode, sharing)

Using java version 14.0.0-open in this shell.

14.0.0-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "14" 2020-03-17
OpenJDK Runtime Environment (build 14+36-1461)
OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

Using java version 13.0.1-open in this shell.

13.0.1-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)

Using java version 12.ea.31-open in this shell.

12.ea.31-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+31)
OpenJDK 64-Bit Server VM (build 12+31, mixed mode, sharing)

Using java version 12.0.1-open in this shell.

12.0.1-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)

Using java version 12.0.0-open in this shell.

12.0.0-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

Using java version 11.0.3-open in this shell.

11.0.3-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)

Using java version 11.0.0-open in this shell.

11.0.0-open
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

Using java version 14.0.2-sapmchn in this shell.

14.0.2-sapmchn
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "14.0.2" 2020-07-15
OpenJDK Runtime Environment SapMachine (build 14.0.2+12-sapmachine)
OpenJDK 64-Bit Server VM SapMachine (build 14.0.2+12-sapmachine, mixed mode, sharing)

Using java version 12.0.2-sapmchn in this shell.

12.0.2-sapmchn
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "12.0.2" 2019-07-17
OpenJDK Runtime Environment (build 12.0.2+9-sapmachine)
OpenJDK 64-Bit Server VM (build 12.0.2+9-sapmachine, mixed mode, sharing)

Using java version 10u23-openjdk in this shell.

10u23-openjdk
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "10-internal"
OpenJDK Runtime Environment (build 10-internal+0-adhoc.jenkins.openjdk)
OpenJDK 64-Bit Server VM (build 10-internal+0-adhoc.jenkins.openjdk, mixed mode)

Using java version 10.0.0-oracle in this shell.

10.0.0-oracle
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

Using java version 9ea170 in this shell.

9ea170
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+170)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+170, mixed mode)

Using java version 9ea163 in this shell.

9ea163
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+163)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+163, mixed mode)

Using java version 9.0.1-oracle in this shell.

9.0.1-oracle
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

Using java version 8u161-oracle in this shell.

8u161-oracle
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

Using java version 8u141-oracle in this shell.

8u141-oracle
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)

Using java version 8u131 in this shell.

8u131
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

Using java version 8u111 in this shell.

8u111
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

Using java version 7u79 in this shell.

7u79
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

Using java version 1.0.0-rc9-graal in this shell.

1.0.0-rc9-graal
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (build 1.8.0_192-20181024123616.buildslave.jdk8u-src-tar--b12)
GraalVM 1.0.0-rc9 (build 25.192-b12-jvmci-0.49, mixed mode)

Using java version 1.0.0-rc5-graal in this shell.

1.0.0-rc5-graal
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
openjdk version "1.8.0_172"
OpenJDK Runtime Environment (build 1.8.0_172-20180626105433.graaluser.jdk8u-src-tar-g-b11)
GraalVM 1.0.0-rc5 (build 25.71-b01-internal-jvmci-0.46, mixed mode)

github から Gradle のリリースのリストを取得して、 jq で RC 以外で各マイナーバージョンで最新のバージョンの値を取得する

単なる jq のメモ。

f:id:mike_neck:20200815231037p:plain


やりたいこと

github から release の一覧を取得して、 RC 以外のバージョンの最新バージョンの値を取得する

GitHub API

例えば Gradle のリリースは、 GitHubドキュメント によると次の URL で 40 件ほど取得できる

https://api.github.com/repos/gradle/gradle/releases?per_page=40

すると、このコマンドができる

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}"

なお、レスポンスの内容は、次のような json(一部省略) の配列であり、ほしい値は name である

  {
    "url": "https://api.github.com/repos/gradle/gradle/releases/22797617",
    "html_url": "https://github.com/gradle/gradle/releases/tag/v6.1.0-RC3",
    "tag_name": "v6.1.0-RC3",
    "target_commitish": "release",
    "name": "6.1 RC3",
  }

お題1 jqjson の配列から json の一部の項目だけを抜き出した配列を作る

配列を イテレータに変換 して、 プロパティを指定して 取り出す(Object Identifier-Index というらしい)

.[] | .name

したがって、現在のコマンドはこんな感じ

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
  .[] |
  .name
'

出力はこうなる

6.6
6.6 RC6
6.6 RC5
6.6 RC4
6.6 RC3
6.6 RC2
6.6 RC1
6.5.1
6.5
6.5 RC1
6.4.1
6.4
6.4 RC4
6.4 RC3
6.4 RC2
6.4 RC1
6.3
6.3 RC4

このとき、 RC のバージョンはいらないので、これを除外したい

お題2 jq で特定の文字列を含む項目を取り除く

特定の文字列を含むかテストして、含んでいたら true 、含んでいない場合は false を返す contains という関数がある。これを boolean を受け取って、出力有無を決定する select 関数に渡して絞り込む。

select(contains("RC") == false)

現在のコマンドは次の通り

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
  .[] |
  .name |
  select(contains("RC"))
'

出力は次のようになる

6.6
6.5.1
6.5
6.4.1
6.4
6.3

このとき、 6.4.1 はほしいけど、 6.4 は必要がなく、また同じフィルターで 6.36.6 も取れるようにしたい

お題3 マイナーバージョン番号を取得する

[:3] の形でマイナーバージョンの値を取得できるといえば取得できるが、当然マイナーバージョンが 10 以上にもなりうるので(例 : 1.x 2.x 4.x は実際にあった)できれば動的に取得したい。 indices を使うと、指定した部分文字列のインデックス値が取得できる。これと、 Object construction を用いて現在の値も保持する

{.value: ., indices: indices(".")}

ここで値は次のようになる。

{ "value": "6.6", "indices": [1] }
{ "value": "6.5.1", "indices": [1, 3] }
{ "value": "4.10.3", "indices": [1, 4] }
{ "value": "4.10", "indices": [1] }

次に indices を indices の二番目の要素または文字列の長さにマッピングしたい。そこで、 Alternative Operator を使って indices の二番目(インデックスは 1)の要素または 文字列の長さ を取得する。

{value: .value, index: (.indices[1] // (.value | utf8bytelength))}

ここで値は次のようになる。

{ "value": "6.6", "index": 3 }
{ "value": "6.5.1", "index": 3 }
{ "value": "4.10.3", "index": 4 }
{ "value": "4.10", "index": 4 }

最後に index の値をマイナーバージョンにマッピングする

{value: .value, minor: .value[:.index]}

以上を組み合わせると次のようなコマンドと出力になる。

コマンド

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
'

出力

{ "value":  "6.6", "minor": "6.6"}
{ "value": "6.5.1", "minor": "6.5" }
{ "value": "6.5", "minor": "6.5" }
{ "value": "6.4.1", "minor": "6.4" }
{ "value": "6.4", "minor": "6.4" }
{ "value": "6.3", "minor": "6.3" }

お題4 マイナーバージョンごとにグループ化する

グルーピングは group_by を使って、 .minor ごとにグループを組めばよいのだが、この関数は配列を入力に取るものの、現在の状態はイテレーターによるオブジェクトが入力になってしまうため型があわない。そこで、ここまでの内容を配列に変換するため、ここまでのクエリに Array construction を適用する。

コマンド

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
[
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
]
'

出力

[
  { "value":  "6.6", "minor": "6.6"},
  { "value": "6.5.1", "minor": "6.5" },
  { "value": "6.5", "minor": "6.5" },
  { "value": "6.4.1", "minor": "6.4" },
  { "value": "6.4", "minor": "6.4" },
  { "value": "6.3", "minor": "6.3" }
]

そして、改めて group_by を適用する。

コマンド

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
[
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
] |
group_by(.minor)
'

出力

[
  [
    { "value": "6.3", "minor": "6.3" }
  ],
  [
    { "value": "6.4.1", "minor": "6.4" },
    { "value": "6.4", "minor": "6.4" }
  ],
  [
    { "value": "6.5.1", "minor": "6.5" },
    { "value": "6.5", "minor": "6.5" }
  ],
  [
    { "value":  "6.6", "minor": "6.6"}
  ]
]

group_by を使うと API で取得できる配列の順番が逆になるので、 reverse を最後に適用しておく

[
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
] |
group_by(.minor) |
reverse

お題5 個々の配列からマイナーバージョンの値を取得する

配列の個々の値を変換していくので、まずイテレーターに変える。 jq では 6.4 より 6.4.1 の方が大きい値なので、 max_by を用いて最終的にほしい値の入ったオブジェクトを取り出す。最後にほしい値のプロパティを指定して取り出す。

.[] | max_by(.value) | .value

または次でも同じものが取れる

.[] | [.[] | .value] | max

コマンド

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq '
[
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
] |
group_by(.minor) |
.[] |
max_by(.value) |
.value
'

出力

"6.6"
"6.5.1"
"6.4.1"
"6.3"
"6.2.2"
"6.1.1"
"6.0.1"
"5.6.4"

ほしい値が取れたが、ダブルクォーテーションがついていると次のプロセスで使いづらい

お題6 出力された文字列のイテレーターからダブルクォーテーションを取り除く

オプション -r / --raw-output を使うと出力が文字列の際に json に則って出力するのではなく、そのままの値を出力する

よって、最終的に次のコマンドと出力を得る

コマンド

curl \
  https://api.github.com/repos/gradle/gradle/releases?per_page=40 \
    -H 'accept:application/vnd.github.v3+json' \
    -H "authorization:token ${GITHUB_TOKEN}" \
jq -r '
[
  .[] |
  .name |
  select(contains("RC")) |
  {.value: ., indices: indices(".")} |
  {value: .value, index: (.indices[1] // (.value | utf8bytelength))} |
  {value: .value, minor: .value[:.index]}
] |
group_by(.minor) |
.[] |
max_by(.value) |
.value
'

出力

6.6
6.5.1
6.4.1
6.3
6.2.2
6.1.1
6.0.1
5.6.4