Keep on moving

あんまりまとまってないことを書きますよ

karabiner-elementsとM1 MacBook Airでの問題が解決された

- version
macos Big Sur 11.6
karabiner elements 13.7.1

2021-09-16 update: 無事対解決 タイトルも s/解決されつつある/解決された/g とした


2021-03-04 update: バージョンが上がったが、状況変わらず

https://github.com/pqrs-org/Karabiner-Elements/issues/2517#issuecomment-787000561

こちらによると BigSur 11.3(beta)に上げると解消されたとのこと。macOS側に原因があるということなのかなぁ.


Krabiner Elements v13.1.0をインストールしているとMacを再起動やシステム終了した際に画面がピンクになり、 kernel panicになることが報告されてます。

gori.me

が、Karabiner ElementsのBeta版を使うことでこの件が修正され、正常に動作した方がいるようです。(M1 mac miniらしい)

github.com

I don't see this issue anymore after updating to 13.3.1 with M1 Mac mini and Big sur 11.2. Not sure if this is same for everyone, but anyways thanks a lot for dev team for providing this awesome app!

TL;DR

  • Karabiner-Elements beta版を使う(本日時点では 13.3.1)
  • ただし効果は人による(少なくともkarabiner-elementsを[システム終了]する前に終了すれば問題が出ない)

Krabiner-Elements Beta の使い方

  1. Krabiner-Elementsで [preference] を開く
  2. misc > [Check for beta update] を押下する

f:id:Ehren:20210208234736p:plain

  1. これだけで治る人がいるみたいですが、私の環境ではkarabiner-elementsを終了する -> システム終了 とすることで問題が出なくなりました。(因みにM1 Macbook Air)

Karabiner Elements causes Apple silicon MacBook Air to crash during system shutdown · Issue #2517 · pqrs-org/Karabiner-Elements · GitHub

参考

engisuke.hatenablog.com

先人とKarabiner-Elements開発者に感謝

aferoを使ってGoでのファイル生成のUnitTestを書きやすくする

Go言語の永遠の初心者です。 自分用の便利スクリプトを用意するときにシェルスクリプトではなくGoを使うときのTIpsです。 Goでファイル生成するときによく使っているライブラリを紹介します。

TL;DR

  • aferoを使うことでファイル生成のUnitTestが書きやすくなる

背景

Goでスクリプトを書いていてある程度処理をしてからファイルを生成することがあると思います。 ただスクリプトでの条件が増えてきたりするとそこからUnitTestsが書きたくなることがあると思います。 osライブラリを使うとファイルが作れるのですが... テストのタイミングでは現物のファイルを作るのではなく、 メモリ上でファイルを展開できるといいなーと思うことが多いですよね。

今回紹介するライブラリ

背景 のところで説明した話はこのライブラリを使うと行うことができます。 github.com

install

$ go get github.com/spf13/afero

使い方の例

import "github.com/spf13/afero"


// os packagと同じように扱える
AppFs := afero.NewOsFs()
MakeEmptyFile(AppFs, fileName)

func MakeEmptyFile(fs afero.Fs, s string) {
    dirName := filepath.Dir(s)
    exists, err := afero.DirExists(fs, dirName)
    if !exists && err != nil {
        mkdirErr := fs.MkdirAll(dirName, os.ModePerm)
        if err != nil {
            log.Fatal(mkdirErr)
        }
    }
    emptyFile, err := fs.Create(s)
    if err != nil {
        log.Fatal(err)
    }
    emptyFile.Close()
}

テストの例

func TestMakeEmptyFile(t *testing.T) {

        // テスト用にメモリ上でFSのmockを扱う
    AppFs := afero.NewMemMapFs()
    fileName := "./test.py"

        // メモリ上で扱ってくれるのでファイル本体ができることはない.
    MakeEmptyFile(AppFs, fileName)

        // でもUnitTestは実行可能
    // file exists
    exists, _ := afero.Exists(AppFs, fileName)
    assert(t, exists, true)

    // file is empty
    bytes, _ := afero.ReadFile(AppFs, fileName)
    assert(t, string(bytes), "")

}

func assert(t *testing.T, actual, expected interface{}) {
    if actual != expected {
        t.Errorf("got: %v\nwant: %v", actual, expected)
    }
}

まとめ

osパッケージと同じ使い方ができるのでaferoに切り替えるのは非常に簡単です。 つまりやめたくなったら元に戻すのも簡単です。 UnitTestsもやりやすくなるのでぜひ皆様も使ってみてください。

2020振り返り

Python界隈の魅惑の何かです。久しぶりに今年の振り返りをしたいと思います。

発表

Covid-19の今年はあんまり外で話せなかったなという印象。自分から話に行くのではなく、受け身になっちゃったなとか割と反省点は多い。 そんな中でもいくつか話せて楽しかった。

masahito.hatenablog.com 初めてのオンラインでの発表を経験した。オンラインは話すの難しいなというのも感じましたね~

pyconjp.blogspot.com pyconjp.blogspot.com 実は2018,2019と連続で話させていただいていました。CfP通ったのでオンラインでも話せるように準備だけしてました。 また再開したらCfPを出させてもらおう。(pycon kyushuは今のところCfPが皆勤賞だったりします 😆

OSS活動

今年はあまり時間が取れなかったので、気がついたtypoにPR投げたりとかしていた。 仕事で使ってるやつに少しはPR投げられたのでまた来年にでも。

[BEAM-11523] Bump Gradle to 6.7.1 by masahitojp · Pull Request #13414 · apache/beam · GitHub

仕事

毎日会社に通ってた毎日からフルリモートの生活に変わって最初は非常に戸惑ったんだけど、段々慣れてはきたかなと。 チームビルディング的なことをやったり、(実は自分ではあんまり興味がなかった)振り返りとかを久々にチームでやるようになったり とか変化が大きかったなと思う。

買ってよかったもの

マイク & オーディオインターフェース

ベリンガー 2入力2出力 USBオーディオインターフェース UMC22 U-PHORIA

ベリンガー 2入力2出力 USBオーディオインターフェース UMC22 U-PHORIA

  • 発売日: 2018/09/01
  • メディア: エレクトロニクス

zoomでの会議が増えたこともあり購入。これに安めのアームをつけて受けて運用してる。 フルリモートになってから話す機会が増えたこともあり、話してる内容がクリアに相手に伝わるので重宝している。 ちなみに初めて話す方からから [マイクすごいっすね] と言ってもらえるのである程度アイスブレイク的な会話のネタにできるのも 助かっています。

イヤフォン

出張や運動用にこっちを買って使っていた。

が、zoomでの会議が増えてTwitterでも話題になっていたこともあり思い切って骨伝導のやつを買ってみたんですが大当たりでした。

特に一時間以上のミーティングでも耳が痛くならないので重宝してます。

USB type-c hub

出張用に買ったこれを在宅でも使っている。値段の割にGigabit Etherに対応してくれていて重宝している。

M1 Macbook Air

ARMで動くとか面白いじゃんと思って購入。渋川さんのこの記事はだいぶ読ませてもらっていろいろ遊んでいる。

qiita.com

Ryzenが動くPCも持ってるんだけど、起動がめんどくさいせいかこっちのpcでとりあえずコード書くとかが近頃増えてる。 バッテリーの充電間隔が前より減ったり、ベッドサイドに置いておいてとりあえず調べ物したいときに非常に便利、 おかげで久々にブログを書く気が湧いてきたりとこのpcにはいろいろありがとうと言いたい。

その他

この企画のレビューのお手伝いができたて楽しかったですね。 id:t2y-1979 さんお声がけいただいてありがとうございました. Pythonでの型ヒントも色んな人がふつーに使ってくれるようになりつつあり、個人的には嬉しい限りですね。

最後に

なんだかんだで大変な一年ではありましたが今考えると変化に富んでいて色んなことが経験できた年だったなと思います。 私は変化がない生活は考えられないタチなので、来年もいろいろ手を出しつつ生きていきたいなと思います。 何かあったら声がけしていただけるようにしてきたいなと思ってます!

来年やってみたいことはまた来年にでもまとめます。

How to upgrade dokka version 0.10.x to 1.4.x

Kotlinではドキュメント生成ツール(KDoc JavaでのJavadoc的なもの)として Dokkaというツールがあります。 自作のライブラリでdokka 0.10.1を使っていたのですが、気づいたら1.4.xにアップデートしていました。1 Gradleでの書き方も変更があり、だいぶハマったのでまとめておきます。

TL;DR

chore: update dokka to 1.4.20 · masahitojp/bqdatamapper4k@a8a6933 · GitHub

dokka 1.4.xでの変更点

公式ドキュメントでまとまってます。

github.com

/* 0.10.x */    outputDirectory = "$buildDir/javadoc"
/* 1.4.x */     outputDirectory.set(buildDir.resolve("javadoc"))

こんな感じで = で設定していた箇所がsetter methodに変わったりしてるっぽい。 が、実際にコードで使ってるプロジェクトがなかなかなく,じゃーどう書き換えればいいかよくわかりませんでした。 というわけでGithub で検索してなんとなくわかってきました。

// 0.10.xでのjavadocフォルダにhtmlを出力する設定
val dokka by tasks.getting(DokkaTask::class){
    outputFormat = "html"
    outputDirectory = "$buildDir/javadoc"
}

// 1.4.xでの同じ書き方 htmlを出力したいのでdokkaHtmlを使う
tasks.dokkaHtml.configure {
    outputDirectory.set(buildDir.resolve("javadoc"))
}

// for 1.4.x [Option]  Gfm, javadoc, Jekyll向けの設定もある
tasks.dokkaGfm.configure {}
tasks.dokkaJavadoc.configure {}
tasks.dokkaJekyll.configure {}
// for 0.10.x
val dokkaJar by tasks.creating(Jar::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Assembles Kotlin docs with Dokka"
    archiveClassifier.set("javadoc")
    // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka)
    from(dokka)
}
// for 1.4.x
val dokkaJar by tasks.creating(Jar::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Assembles Kotlin docs with Dokka"
    archiveClassifier.set("javadoc")
    // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka)
    from(tasks.dokkaHtml) // ^でのtasksの設定を入れる
}

参考

github.com

関連ドキュメント

blog.jetbrains.com

先人に感謝。


  1. https://github.com/Kotlin/dokka/releases/tag/v1.4.20 version名にalphatついているのが気になるところ.リライトしたとのことなのでまだ安定版ではないアピール?

Windows10(WSL2)の開発環境

初めに

新しいPCを買ったこともあり、久々にwindowsでの開発環境を構築しようと思いました。 折角なのでWSL2などの最新の環境を試してみました。 作業メモを書いておこうと思います。

WSL2のインストール

今回はこれが目的なので何はなくともこれを導入. この辺を参考にしました。

docs.microsoft.com

一か所はまったところがあったので共有しときます。 wslを入れた後で、the Linux kernel update packageを入れる必要があるのですが、 日本語版のページからリンクがなくなってるっぽいです。英語版のほうにはリンクがあるのでこちらからダウンロードできました。 英語版の方とかなりドキュメントの構成がちがうのでその辺の影響なのかも。なるべく英語のほうを 今は参照したほうがよさそうです。

docs.microsoft.com

Windows Terminal の導入

Windowsの世界の住人になるのでWindows TerminalとPowerShellに移行しました。 この辺りを参考にしました。 Windows TerminalとWSL2のメモ - Qiita

Scoop の導入

chocolateyを入れるのが一般的だと思うんですが、いい機会なのでScoopをいれてみました。 Windows版でのhomwbrew的な感じですかね。 windows10のパッケージ管理 scoopをインストールする | mebee

gitなども簡単に導入できました。

wsl2 intellijの環境の準備

Development under Windows under Linux with WSL2 (IntelliJ) | by JoergF-Ragin | Medium

こちらの記事を参考に入れてみました。 流れとしてはこんなかんじ

  1. wsl2側でintellijをインストール
  2. wsl2側でXserverを導入する
  3. windows側でX client をインストールする

https://rin-ka.net/windows-x-server/#toc14

var.blog.jp

PythonでJSON Linesを扱う

key value
Python 3.8 or later
Last Update 2020/09/06

こんにちは、yaml苦手っ子です。PythonJSON Linesを扱う方法を調べたのでまとめておきます。

JSON Lines とは

JSONを行区切りでファイルに書き込んだものです。

JSON Lines ここによると以下が条件みたいです.

  1. UTF-8 Encoding
  2. Each Line is a Valid JSON Value
  3. Line Separator is '\n'

Python での扱い方

ファイルから読んで、一行ごとにばらして json.load する感じです。 コードで書くとこんな感じです。

import json
from typing import Any, Dict, Iterator, List, TextIO


def filter_not_empty(list: List[str]) -> Iterator[str]:
    return filter(lambda x: len(x) > 0, list)


# TODO: DictではなくTypedDictを使うと型ヒントの恩恵に預かれて便利
def parse_jsonl(fp: TextIO) -> List[Dict[str, Any]]:
    # fileが空行を含むことがあるので念の為フィルターする
    jlines = filter_not_empty(fp.read().splitlines())
    result = [json.loads(jline) for jline in jlines]
    return result


if __name__ == "__main__":
    with open("sample.jsonl", "r") as json_file:
        print(parse_jsonl(json_file))

jqコマンドの代わりにPythonJSON Linesをpretty printする

Python 3.8から json.toolでもJSON Linesに対応しました。こんな感じでつかえます。

json --- JSON エンコーダおよびデコーダ — Python 3.8.5 ドキュメント

$ python3.8 -mjson.tool --json-lines sample.jsonl 
{
    "name": "Gilbert",
    "wins": [
        [
            "straight",
            "7\u2663"
        ],
        [
            "one pair",
            "10\u2665"
        ]
    ]
}
{
    "name": "Alexa",
    "wins": [
        [
            "two pair",
            "4\u2660"
        ],
        [
            "two pair",
            "9\u2660"
        ]
    ]
}
{
    "name": "May",
    "wins": []
}
{
    "name": "Deloise",
    "wins": [
        [
            "three of a kind",
            "5\u2663"
        ]
    ]
}

先人に感謝します。

GitHub ActionsでGradle環境でCIを回してみる

こんにちは、yaml苦手っ子です。GitHub Actions+GradleでCIする方法をまとめます。

key value
Last Update 2020/07/06

Gradle

こちらを参考にすればOK.

docs.github.com

超シンプルに書くとこんな感じ。

name: Java CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: Build with Gradle
        run: ./gradlew test

Cacheを利用する

ここをみると以下のように説明されている。

依存関係をキャッシュしてワークフローのスピードを上げる - GitHub Docs

GitHubホストランナー上のジョブは、クリーンな仮想環境で開始され、依存関係を毎回ダウンロードしなければならず、ネットワークの利用率を増大させ、実行時間が長くなり、コストが高まってしまいます。

なるほど、というわけでキャッシュの使い方をまとめてみる。

actions/cacheを使う

actions cacheを使う方法。 github.com

A repository can have up to 5GB of caches. Once the 5GB limit is reached, older caches will be evicted based on when the cache was last accessed. Caches that are not accessed within the last week will also be evicted. どうやら5GiBの制限があるみたい

READMEにちゃんと設定が書いてある。例としては以下のような感じ

name: Run Gradle unit-test on Push
on: [pull_request, push]
jobs:
  gradle:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: 8
      - name: Cache Gradle packages
        uses: actions/cache@v2
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
          restore-keys: ${{ runner.os }}-gradle
      - name: Build with Gradle
        run: ./gradlew test

gradle pluginでcacheを使う

ちなみに eskatos/gradle-command-action@v1 でもcacheを使うことが可能だったりします。

github.com このActtionではcacheを以下の3つに分けてあるとのこと。(default でwrapper-cacheのみ有効.多分キャッシュの制限が原因)

wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true

以下のような感じになる

github.com

name: "CI"

on: [pull_request, push]


jobs:
  ci:
    name: "CI"
    runs-on: ubuntu-latest
    steps:

      - name: Checkout sources
        uses: actions/checkout@v2

      - name: Setup Java 11
        uses: actions/setup-java@v1
        with:
          java-version: 11

      - name: Build with Gradle
        uses: eskatos/gradle-command-action@v1
        with:
          dependencies-cache-enabled: true
          configuration-cache-enabled: true
          arguments: test

参考

GradleでのJavaのビルドとテスト - GitHub Docs

GitHub ActionsでGradleの自動ビルド/テストをする [再掲] | Qrunch(クランチ)