なっく日報

技術やら生活やらのメモ

ktlintに`kotlin_imports_layout=idea`オプションが追加されたのでimport-orderingを無効にしなくても良くなる

対象読者

Kotlinの開発でktlintを使っている人

何の話?

ktlint で import-ordering というimport文の並び順を警告してくれるルールがあります。

Imports ordered consistently (see Custom ktlint EditorConfig properties for more) (id: import-ordering)

でもこのルール、IntelliJのデフォルトのimport順と相性が悪いのでこれまでktlintを採用したいくつかのプロジェクトではOFFにしてました。

具体的には公式README

https://github.com/pinterest/ktlint#custom-ktlint-specific-editorconfig-properties

に書いてあるように .editorconfig に以下のように書いてました。

[*.{kt,kts}]
disabled_rules=import-ordering

でもv0.37から解決された

github.com

このバージョンから以下のように書けば、IntelliJデフォルトのimportの並び順と揃えられる模様。

[*.{kt,kts}]
kotlin_imports_layout=idea 

注意点

めでたしめでたし・・・なんですがこの書き方

The predefined layouts are temporary and will be deprecated in the future, once Kotlin plugin supports EditorConfig property for imports layout.

一時的なもので、将来的には明示的に書くようにしないとダメっぽい。

↓みたいに書くとktlintとIntelliJで揃えられる感じ?(IntelliJ側が対応されるまではIntelliJ側に効かないそうですが)

ij_kotlin_imports_layout=*

まとめ

今無理に変えなくても良いかも。 でもちゃんと使えそうでありがたしという話でした。

KotlinはListでもDestructuring Declarationsが使える

初めて知ったのでメモ程度に。

Kotlinの Destructuring Declarations(分割代入の機能)

以下の公式ドキュメントにもあるとおり分割代入が使えます。

https://kotlinlang.org/docs/reference/multi-declarations.html

Pairを使った例

val (first, second) = 1 to 2
println("first=$first, second=$second") // first=1, second=2

Map.Entry<K, V> の例

val map = mapOf(
  "k1" => "v1",
  "k2" => "v2"
)
for ((k, v) in map) {
  println("k=$k, v=$v")
}
// k=k1,v=v1
// k=k2,v=v2
  
// ↓でも書ける
// map.forEach { (k, v) ->
//  println("k=$k, v=$v")
// }

data classの例

data class Foo(val first: String, val second: String)
val (first, second) = Foo("first", "second")
println("first=$first, second=$second") // first=1, second=2

実はListでもできる

val (a, b) = listOf(1, 2)
println("a=$a, b=$b") // a=1, b=2

// 利用しない値に代入しないこともできる
val (v) = listOf(1, 2)
println("v=$v") // v=1

// 要素数が少ないと例外が飛ぶ
val (v1, v2) = listOf(1)
// Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
//  at java.util.Collections$SingletonList.get (Collections.java:4815) 

補足

残りの要素数を代入するみたいなことはできないみたい。

ES2015でいうところの↓

const [a, ...b] = [1, 2, 3]; 
console.log(a); // 1
console.log(b); // [ 2, 3 ]

Pythonでいうところの↓

a, *b = [1, 2, 3]
print(a) # 1
print(b) # [2, 3]

無理やりやるなら↓だけど、 元の挙動が変わってしまうので微妙。

operator fun <T> List<T>.component2(): List<T> = drop(1)

val (head, rest) = listOf("one", "two", "three")
println(head) // "one"
println(rest) // ["two", "three"]   

// val (a, b, c)  = listOf("one", "two", "three") が変になる

参考

stackoverflow.com

JavaからKotlinに変換するときにGitの履歴を残したい

何が問題か?

.javaのファイルを.ktに変換するのは IntelliJの「Convert Java File to Kotlin File」で一発だが、 それを普通にコミットすると履歴が残らない。

例:Hoge.javaHoge.ktに変換。その後コミットして、git log Hoge.ktHoge.javaだった際の記憶が失われている・・・

解決策

Renameと変換でコミットを分ける。

IntelliJの機能を使う

知らんかったけど一番カンタン。

f:id:nakimura:20200905174609p:plain

「Extra commit for .java > .kt renames」にチェックをつけると「Rename .java to .kt」というコミットに分けてくれる。

f:id:nakimura:20200905181649p:plain

コマンドでやる

ちょっとめんどい

git mv Hoge.java Hoge.kt
git commit -m 'Rename .java to .kt'
git revert HEAD --no-commit # 元の状態に戻すけどコミットはしない
# Convert Java File to Kotlin File して編集してコミット

雑なまとめ

  • Gitでリネームするときに履歴を残したい場合には気をつける。
  • そんでIntelliJはやっぱすごい

参考

stackoverflow.com

社内プロキシ下でもCntlmを使って快適に開発する

概要

社内プロキシ下での開発にはCntlmを使うといいよという話。

注意事項

この記事の内容を導入する場合、自己責任でお願いします。

コレ的な設定は会社のセキュリティ的にグレーになるパターンが多いと思われるので、セキュリティ担当部署に導入して良いか相談してみるのが良いでしょう。

対象とする読者

社内プロキシ下での開発に苦しんだことのある開発者。

  • パスワードが変わったからアプリとかCLIツールの設定を全部変えないとダメじゃん!
  • curl で社内のAPI叩くときはプロキシ通したくないのに社外のときは通さないとダメとかやってられん!
  • この言語のパッケージマネージャーのプロキシ設定ってあるのか?また調べないとダメなんか・・・

などなど。

社内プロキシとは?

会社によってはインターネットに出るときに通さねばならないプロキシ。

多くの場合PCでログインするときと同じユーザ名・パスワードを設定する必要があるはず。

ブラウザでサイトを閲覧するときはもちろんのこと

curl, mvn, npm, composer, docker ... みたいな開発で必要なツールも全部通さないといけない。めんどい。

対処法

  • 全てのプロキシ設定をCntlmに向ける
    • CLIツールは環境変数 HTTP_PROXY/HTTPS_PROXY を設定してCntlmにプロキシさせる
    • アプリやJVMを使ったCLIツールのプロキシ設定をCntlmに向ける
    • 社内ネットワーク向けの通信はCntlmのNO_PROXY設定で除外する

です。

こんなイメージ。

f:id:nakimura:20200718101947p:plain
全ての通信を一度Cntlmを通す

Cntlmとは?

cntlm.sourceforge.net

NTLM認証を代行してくれるプロキシ。

intended to help you break free from the chains of Microsoft proprietary world.

だそうです😃

CntlmにID/パスワードを入力すれば認証はやってくれるので、他のツールはCntlmにプロキシさせるだけでID/パスワードの設定が不要になります!

Cntlmを動かす

インストール(Windows編)

Cntlm: Fast NTLM Authentication Proxy in C からダウンロードしてインストーラをポチポチしていきましょう。

手元にWindowsがないので良さげな記事にリンクを貼らせていただきます。

sevenb.jp

インストール(Mac編)

brew がオススメです。

brew install cntlm

設定

  • Windowsの場合は C:\Program Files (x86)\Cntlm\cntlm.ini
  • Macの場合 sudo vi /usr/local/etc/cntlm.conf

を編集します。

変える項目はこの辺。

# ドメイン・ユーザ・パスワード
Username    testuser
Domain      corp-uk
Password    password

# 社内プロキシのドメインorIPとポート
Proxy proxy-xxx.example.com:11111

# 社内プロキシを経由させたくない社内システム等のドメイン|IPを指定。*が使える。
NoProxy localhost, 127.0.0.1, 10.*, 192.168.*, wiki.example.com, jinji.example.com

起動(Windows編)

[コントロールパネル]→[サービス] で起動・停止できたはず。

起動(Mac編)

brew servicesで管理するのがオススメです。

# 初回のみ
brew tap homebrew/services

# 起動
sudo brew services start cntlm

# sudo brew services stop cntlm
# sudo brew services restart cntlm
# もできる

もろもろCntlmを経由させる

インターネット・社内ネットワーク問わず通信は必ず http://127.0.0.1:3128 の Cntlm経由にするよう設定します。

127.0.0.1とかlocalhostとか予め除外できるものはしてもOK。 ただし、環境変数やアプリのプロキシ除外設定はワイルドカードが使えないケースがあるので極力Cntlm通すのが無難。

ブラウザ等のアプリ

システム全体のネットワーク設定でプロキシ設定できる場合は http://127.0.0.1:3128 に設定しておきましょう。 (Macの場合はシステム環境設定 -> ネットワーク -> 詳細 -> プロキシ)

その後、ひたすら個別のアプリのプロキシの設定に http://127.0.0.1:3128 を設定します。

MacのDocker DesktopとかIntelliJ IDEAとかもろもろ必要です。

ツール(CLI系)

多くのCLI環境変数のHTTP_PROXY, HTTPS_PROXYを見てくれるので設定しておきましょう。

curl, npm, composer, pipenv, bundler・・・これで通るはず。

設定場所で筆者おすすめは /etc/profile ですが、若干リスクもあるので ~/.bash_profile 等でも構いません。

↓追記する。

export HTTP_PROXY=http://127.0.0.1:3128
export http_proxy=$HTTP_PROXY
export HTTPS_PROXY=$HTTP_PROXY
export https_proxy=$HTTP_PROXY
export NO_PROXY=127.0.0.1,localhost
export no_proxy=$NO_PROXY
JVMで動くCLIツール

Maven, GradleなどJVM系のCLIツールは残念ながら HTTP_PROXYの環境変数を見てくれないようです。 個別に http://127.0.0.1:3128 に向ける必要があります。

Maven

~/.m2/settings.xml にproxies を足します。

<settings>
  <proxies>
   <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>127.0.0.1</host>
      <port>3128</port>
    </proxy>
  </proxies>
</settings>
Gradle

こんな感じでいけるはず(未検証)

Build Environment

~/.gradle/gradle.properties

systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=3128
systemProp.http.nonProxyHosts=localhost|127.0.0.1
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=3128
systemProp.https.nonProxyHosts=localhost|127.0.0.1

その他TIPS

プロキシのない環境下だと逆にサイトが見れない、CLIが動かない!

そんな場合は Cntlmの設定ファイルの NO_PROXY* にして再起動(sudo brew services restart cntlm)します。

NO_PROXY * 

全ての通信が社内プロキシを経由しなくなります(Cntlmを経由するがインターネットへ素通しになるイメージ)

ネットがつながらない

ごくまれにCntlmへの接続が多いせい?でネットにつながらなくなることがあります。

そんなときは漢らしくCntlmを再起動しましょう。

まとめ

この方法を確立してからは普段プロキシを意識することはほぼなくなりました。

社内プロキシに苦しんでいる方のお役に立てれば幸いです。

Touch Bar付きのMacBook ProでSHIFT + F6が効かない現象

現象

Touch Bar付きのMacBook ProでSHIFT + F6が効かない。IntelliJのRefactor(Rename)が使えなくて困った。。

コマンドキーとか他のファンクションキーの組み合わせも効かない。IntelliJに限った話ではなく全アプリで効かない 。。。

解決策

github.com

Karabinerの設定でした。

Preferences -> Devices にて、No product name(No manufacturer name) となっている箇所にチェックを付けたら解決。

まとめ

個人的にはなくては開発できないキーバインドなので解決してよかった。

困っている方の参考になれば幸いです。

ターミナルをAlacrittyに変えた

きっかけ

仕事で新品のMacBook Proをセットアップする機会があり、iTerm2の設定を移行しようとしました。

ところが設定をエクスポートして読み込んでも一部反映されてなかったりなんかめんどい・・・

そこで高速と噂?のAlacrittyを試してみることにしました。

github.com

インストール

これで。

brew cask install alacritty

設定

$HOME/.config/alacritty/alacritty.ymlYAML形式の設定ファイルを置きます。

なるべくデフォルトで使いたいので必要最低限の設定だけにしておきました。

私のalacritty.ymlはコレ

起動時に最大化する

SimpleFullscreenはMacでだけ有効らしい。

window:
  startup_mode: SimpleFullscreen

Font

私はHack使ってます。sizeはもっと大きくても良いかも。

font:
  size: 13.0
  normal:
    family: Hack
    style: Regular
  bold:
    family: Hack
    style: Bold
  italic:
    family: Hack
    style: Italic

Color schemes

https://github.com/alacritty/alacritty/wiki/Color-schemes

に書かれてある設定をコピれば好みの色にできます。

私はVimと揃えてTenderにしました。

キーバインド

↓くらい。なお私はJISキーボードなのでUSの人は動かんと思います。

  • Vim使った際に動きが変な箇所があったので設定
  • CMD + Enter で画面最大化をトグル
  • CMD + + でフォントサイズ+
  • CMD + - でフォントサイズ-
  • CMD + 0 でフォントサイズリセット
  • CMD + , で設定ファイル開く(これは動かないが放置・・・)
key_bindings:
  - { key: F,            mods: Command,           chars: "\x1bf"                         }
  - { key: B,            mods: Command,           chars: "\x1bb"                         }
  - { key: D,            mods: Command,           chars: "\x1bd"                         }
  - { key: LBracket,     mods: Control,           chars: "\x1b"                          }
  - { key: Backslash,    mods: Alt,               chars: "\x5c"                          }
  - { key: Key0,         mods: Command,           action: ResetFontSize                  }
  - { key: Semicolon,    mods: Command|Shift,     action: IncreaseFontSize               }
  - { key: Minus,        mods: Command|Shift,     action: DecreaseFontSize               }
  - { key: 36,           mods: Command,           action: ToggleSimpleFullscreen         }
  - { key: Comma,        mods: Command,           command: { program: "open", args: ["~/.config/alacritty/alacritty.yml"]} }

ハマりどころ

日本語が文字化けしたため、2点設定しました。

※ 最新版を入れれば設定不要かも Release Alacritty Version 0.4.3 · alacritty/alacritty · GitHub

1. .bash_profileexport LANG=ja_JP.UTF-8 追加

.bashrc 読み込むようにしている人はそちらでも良いかも。

2. tmux -u で tmux を起動

これは1設定したら不要な気もしますが、何か alias tmux='tmux -u -2' としてました(試行錯誤した跡かも)

-u            Write UTF-8 output to the terminal even if the first environment variable of LC_ALL, LC_CTYPE, or LANG that is set does not contain "UTF-8" or "UTF8".
-2            Force tmux to assume the terminal supports 256 colours.

というオプションだそう。関係あるとしたら -u の方。

使ってみてどう?

iTerm2よりキビキビ動く気がする。
あとYAMLで設定管理できるのはやっぱ最高。

一点、日本語入力がインラインでできない(候補が出てから決定するまで入力されない)という問題があるがまあ良いかなという感じ。

一ヶ月ほど使ってますが、特に困ったこともおきてないのでiTerm2とは完全におさらばしました。

tmux使っていてターミナルに多くの機能を求めない人にはオススメです。

asdf-vm入れてみた

asdf-vmなるものがあると知りMacに入れてみた際のメモ

github.com

asdf-vmとはなにか?

各言語やツールのバージョン統一的に管理してくれるツールです。

xxxenvとかxxxbrewの代替になるツール。

似たツールとしては anyenvがあります。

github.com

言語/ツール対応がすごい(語彙力)ようです。

www.thoughtworks.com

ThoughtWorksのTechnology Radarでも取り上げられています。

入れてみた

とりあえずnodebrewを置き換えてみることにしました。

# HomeBrewで入れる
brew install asdf

# 普段使いがfishなので↓  bash使いの人は https://asdf-vm.com/#/core-manage-asdf-vm みるべし
echo "source "(brew --prefix asdf)"/asdf.fish" >> ~/.config/fish/config.fish

# ↓ Node.jsの場合必要 https://github.com/asdf-vm/asdf-nodejs#macos
brew install coreutils gpg

# Node.js用のプラグインを追加
asdf plugin-add nodejs
bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring

# バージョンを指定していれる
# asdf list-all  nodejs でバージョンは確認できる
asdf install nodejs 12.14.1

# 利用するバージョンを指定する
asdf global nodejs 12.14.1

# 普通に使える
node -v 
# v12.14.1

Node.jsでハマる箇所

bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring を実行しないと下記のようなエラーがなんか出ます。

❯ asdf install nodejs 12.14.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3684    0  3684    0     0  48473      0 --:--:-- --:--:-- --:--:-- 48473
Authenticity of checksum file can not be assured! Please be sure to check the README of asdf-nodejs in case you did not yet bootstrap trust. If you already did that then that is the point to become SUSPICIOUS! There must be a reason why this is failing. If you are installing an older NodeJS version you might need to import OpenPGP keys of previous release managers. Exiting.

まとめ

正直nodebrewのほうが使いやすい・・・ですが、言語・ツール問わず統一的なインターフェースで使えるのは魅力かなと思います。

もうちょっと使い続けてみます。