ぽらろいどの日記

新しい知見を得たり、得られた知見を記録したり共有したりする場を予定しています。

Gradle × Codenarc × Spockをオフラインで実行する一例

概要

Gradleをオフラインで実行したい場合、どのようにCodenarcとSpockを合わせて使えば良いかの一例を示す。

初めの準備

全て書くのは煩雑なので、gradle initを実行する。

$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 2

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Project name (default: sample):
Source package (default: sample):

> Task :init

BUILD SUCCESSFUL in 35s

この時点でのレイアウト

$ tree
.
├── app
│   ├── build.gradle
│   └── src
│       ├── main
│       │   ├── groovy
│       │   │   └── sample
│       │   │       └── App.groovy
│       │   └── resources
│       └── test
│           ├── groovy
│           │   └── sample
│           │       └── AppTest.groovy
│           └── resources
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

build.gradleの変更

codenarcとspockを使えるようにするために、build.gradleを変更する。

具体的に、記述は以下の通りになる(不要な列は略記)。

plugins {
    id 'groovy'
    id 'codenarc'
}

repositories {
    flatDir {
        dirs "/home/sample/lib", "/home/sample2/lib"
    }
}

dependencies {
    // ビルド時に必要な、Groovyの複数jarファイル
    implementation fileTree(dir: '/home/sample/lib', include: '*.jar')

    testImplementation 'org.spockframework:spock-core:2.0-groovy-4.0'

    // codenarcの実行時に必要なjarファイル
    codenarc fileTree(dir: '/home/sample/lib', include: '*.jar')
    codenarc fileTree(dir: '/home/sample2/lib', include: '*.jar')
}

codenarc {
    // デフォルトのバージョン以外のcodenarcを指定する
    toolVersion = '3.1.0'
    // 実行結果をhtmlファイルではなく、consoleに出力する
    reportFormat = 'console'
}

補足として、repositoriesにローカルを指定する方法は、他の方法もある。

torutk.hatenablog.jp

また、codenarcの実行設定は、他にも幾つか設定可能な項目がある。

docs.gradle.org

codenarc.xmlの作成

codenarcは、指定されたコーディング規則だけをチェックするが、そのチェックする規則はcodenarc.xmlで指定できる。

ファイルは、デフォルトのレイアウトでは、以下の通りになるように配置する。

$ tree
.
├── app
│   ├── build.gradle
│   └── src
│       ├── main
│       │   ├── groovy
│       │   │   └── sample
│       │   │       └── App.groovy
│       │   └── resources
│       └── test
│           ├── groovy
│           │   └── sample
│           │       └── AppTest.groovy
│           └── resources
├── config
│   └── codenarc
│       └── codenarc.xml <- これ
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

xmlのベースは、サンプルとして以下があるのでこれを利用する。

また、指定する規則の一覧は以下にあるので、こちらから選んで指定する。

具体的に、記述は以下の通りになる。

<ruleset xmlns="http://codenarc.org/ruleset/1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd"
        xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd">

        <ruleset-ref path='rulesets/basic.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/braces.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/comments.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/concurrency.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/convention.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/design.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/dry.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/exceptions.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/formatting.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/generic.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/groovyism.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/imports.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/jdbc.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/junit.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/logging.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/naming.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/security.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/serialization.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/size.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/unnecessary.xml'></ruleset-ref>
        <ruleset-ref path='rulesets/unused.xml'></ruleset-ref>

</ruleset>

補足として、要件に応じてjarファイルをタスクの依存関係に加える。

また、Gradleでは以下のルールはうまく適用できないものを含むので、除外する。

これに関して、以下を参考。

実行

この状態になれば、あとはコマンドを実行し、codenarcを実行できる。

$ gradle codenarcMain
$ gradle codenarcTest
$ gradle check # 上記2つを実行する

また、コマンドを実行して、テストも実行できる。

$ gradle test

Groovyでprivateを機能させる(デフォルトコンストラクタを隠す)ために--compile-staticを使う

問題

  1. Groovyでprivateを正しく機能させたいが、普通に実行すると、privateなフィールドでもアクセスできてしまう
  2. Groovyで引数なしのコンストラクタを無効にしたいが、普通に実行すると、引数なしでコンストラクタが起動できてしまう

解決

  • groovy --compile-static x.groovy で実行し、--compile-staticオプションを有効にする
  • 引数なしのコンストラクタは、privateで修飾して外部から隠す

(まあそうですよね、という回答ではある……)

続きを読む

how to setup additional params to add .jar file (Groovy with vim-lsp-settings)

Goal

  • Code autocompletion for Groovy in Vim with LSP

f:id:Portal_Freud:20220415010003p:plain

What I did

Problem

f:id:Portal_Freud:20220415010140p:plain

Solution

  • run :LspSettingsGlobalEdit and write as follows
{
  "groovy-language-server": {
    "workspace_config": {
      "groovy": {
        "classpath": [
          "/path/to/groovy/4.0.1/lib",
          "/path/to/personal/.groovy/lib"
        ]
      }
    }
  }
}

glibcをローカルにインストール

マシン共有や権限ないなどの理由で「このglibc、古いけどいじるわけにもいかないな」と思っていると、新しいツール入れようとしたときに「glibcないので使えません!!」と何度も言われ、結局「glibcをいじるしかないか」と振り出しに戻る。

色々調べて見たら、ありがたいことに、glibcをローカルで使えるようにする手順が紹介されていた。

ryouto.jp

www.mizdra.net

知識不足だった。今度機会があればやってみたい。

RLogin 端末の16色カラーをモダンにする

概要

windowsからssh接続して作業する。そんな場合に自分はRLoginを使っている。多くの点で満足できており、大変アリガタイのだが、色の配置に関しては個人的に体験が悪い(一応、Pastelなど良い配色に感じるものもあるが)。

実際、いまいちだと感じて変更をしている人もいる。

auewe.hatenablog.com

そこで、以上の記事などを参考に、もっと自分好みにしてみようと思い、以下を試したので紹介する。

  • 好きな16色カラーの配色を見つける
  • 16色をRLoginに適用する

追記(20211227)

色々と下に記載をしていたのだが、各リポジトリを詳しく見ると、単にbase16-shellとbase16-vimを導入すれば、RLoginだろうと関係なくshellとvimに色を全てに適用できそう github.com

github.com

なので、base16-shellをInstallationに従って導入して、その後base16-vimをConfigurationに従って導入して、最後にコマンドでbase16-xxx-xxxと叩いて色指定をするのが一番速いし綺麗な配色で出来そう。


好きな16色カラーの配色を見つける

配色を探す

まず、どの色にしたいかを決めなければ、ろくに色も変更できない。しかし、別に自分に配色の知識があるわけでもない。このような場合は、既存で公開していただいているものをありがたく利用した方が良い。

というわけで、以下のサイトでポチポチして、好きな配色を探す。

chriskempson.com

このサイトはVimなんかでのシンタックスハイライトの配色パターンを紹介しているのだが、多分ターミナルの配色にも応用できる。もちろん、別の配色を探しても良い。

16進数のカラーコードをGETする

このサイトで良い物を見つけたら、その配色の中身(16進数のカラーコード、例えば#FAFAFAなど)を見つけに、以下のページから適切なリポジトリに赴く。

github.com

例えば、material-lighterが良いと思ったひとは、https://github.com/ntpeters/base16-materialtheme-scheme/blob/master/material-lighter.yamlに辿り着くことになる。

そうしたら、各ライセンスに配慮しつつ、この16進数のコードをメモする。

16色をRLoginに適用する

色を10進数に変換する

良い配色を手にしたら早速適用したいところだが、すぐには適用できない。なぜなら、RLoginでは10進数の数値で配色を設定しなければならないからである。つまり、 「#fabbcd」であれば「250, 187, 205」に変換する必要がある(R, G, B = fa, bb, cd = 250, 187, 205)。

調べると色々なサイトがあるので、それらを利用させていただき、各16進数の数値を10進数の数値に変換する(別にpythonやらで変換しても良い)。

色をRLoginに適用する

10進数に変換できたら、あとは適用するだけである。かといって、一つ一つ真心をこめて打ち込むのは心が折れる。ちゃんとこういうときのためにRLoginでは、以下の通り、色変更の手順が示されているので、それに従って変更すると楽ちん。

kmiya-culti.github.io

いろいろ書いてあるが、とりあえずは、以下のようにExcelに16色のRGB値を入力してから、

f:id:Portal_Freud:20211202225203p:plain
この数値は適当

それをコピーして、以下のように 表示 > オプション設定 > 16色カラーテーブル > 編集 で出た画面に張り付ける。

f:id:Portal_Freud:20211202225432p:plain

あとは、OKないし適用を選択して、保存するか問われたら「はい」を選択して恒久的に適用するようにしておく。

もし適用してみていまいちだったら、個別に色をダブルクリックすると色彩選択画面が出るので、そこで調整ができる。

f:id:Portal_Freud:20211202231135p:plain
例えば、先のmaterial-lighterだと色が薄いので、幾つか明るさを変更して濃い色にするなど。

以上で、配色を好みに変更できる。

結語

以下の記事を見かけたときは、これを入れればすぐに解決すると歓喜したが、なぜかssh接続がうまくいかなかった。悲しい。

zenn.dev

手短な方法がないときは地道に変更するしかない。

exitを含むスクリプトを、sourceで読み込む

概要

  • exitを含むスクリプトを、sourceで読み込むときの問題と対策

例題

関数をテストしたい

  • 以下のファイルを読み込んで、関数をテストするスクリプトを作りたい
#!/bin/bash

sub_var="this is sub_var."

# この関数をテストしたい
print_sub_var() {
  echo "${sub_var}"
}

if [[ "$1" == "print" ]]; then
  print_sub_var
fi

exit 0

問題点

sourceできない

  • sourceすると、そのまま終了してしまう
#!/bin/bash -x

source ./sub.sh

if [[ "$(print_sub_var)" == "this is sub_var." ]]; then
  echo success!
fi
$ ./main.sh
+ . ./sub.sh
++ sub_var='this is sub_var.'
++ [[ '' == \p\r\i\n\t ]]
++ exit 0

解決策

関数だけを切り出して、別ファイルにする

  • 関数だけを切り出して、別ファイルにする
    • 諸々の理由で実施できないことアリ

aliasを使って、終了処理を書き換える

#!/bin/bash -x

shopt -s expand_aliases
alias exit="true"

source ./sub.sh

unalias exit

if [[ "$(print_sub_var)" == "this is sub_var." ]]; then
  echo success!
fi

exit()関数を自作して、終了処理を書き換える

  • exit()関数を自作して、exitをtrueに書き換える
    • exitの中身を暫定的にすり替えるだけなので、わりと汎用的かも?
#!/bin/bash -x

exit(){ true; }

source ./sub.sh

unset exit

if [[ "$(print_sub_var)" == "this is sub_var." ]]; then
  echo success!
fi

bash-completion:Git & Bashが古いけど、タブ補完したいから半ば自作する

作成の動機

ゴール

  • linuxでgitコマンドを補完したい

制限

  • git-completion.bashがあるが、最新はgit --list-cmdsを内部で使うため、Gitは2.18以上である必要がある
  • git、及びbashのバージョンが古く、バージョンアップするのは難しい
  • 適切な古いバージョンのgit-completion.bashを入れるのは難しい

解決案

  • 幾つかのコマンドに対応するだけなら、自力でなんとかできないか?
    • 個人用なので、品質は不問

調査

作成のヒント

結論

スクリプト

  • .bashrcに記載
    • あるいは別ファイルにして読み込む
# 必要なモジュールを読み込む(bash-completion.shの内容は以下のコピー)
# https://github.com/scop/bash-completion/blob/master/bash_completion
. ~/bash-completion.sh

# 補完候補
declare -r GIT_OPT="branch checkout diff"

_git(){
  # cur=入力中の語、prev=一個前に入力した語、cword=入力済みの語数
  local cur prev cword
  local git_checkout_opt

  # cur, prev, cwordに値をセットする
  _init_completion || return 

  case "${cword}" in
    1)
      # COMPREPLYに格納した文字列が、タブ補完される
      # compgenは${GIT_OPT}の内、${cur}から始まるものだけを出力する
      COMPREPLY=( $(compgen -W "${GIT_OPT}" -- "${cur}") )
      ;;
    *)
      if [[ "${prev}" == "checkout" ]]; then
        # 都度ブランチを取得して、補完候補とする
        git_checkout_opt="$(git branch | sed ':a;N;$!ba;s/[\n|*]/ /g' 2>/dev/null)"
        COMPREPLY=( $(compgen -W "${git_checkout_opt}" -- "${cur}") )
      fi
      ;;
  esac
}

# gitコマンド補完の関数として設定
complete -F _git git

拡張予定

  • 他のコマンド例を参考に、モジュールを利用して拡張する
  • 例えば
    1. fileを補完してほしい場合は_filedirを呼ぶ
    2. cur, prev以外に全ての入力を取得したい場合は、_init_completionの前にlocal cur prev words cwordと宣言し、wordsで入力を取得する

まとめ

ひとまずこれでgitコマンドで幾つか補完できるようになった。凝ると余計な時間がかかってしまいそうなので、コスパを考えつつ可能な範囲で拡張していきたい。とはいえ、既に用意されたものをそのまま利用できればそれが一番であることは間違いない……。