subcommand has been deprecated に出会ったら

自作キーボードの先輩方、特に薙刀式の大岡氏とそのQMKファームウエアでeswai氏に、薙刀式と言う使い勝手の良い貴重な恩恵を賜った。お陰で薙刀式自作キーボードで口上を述べられる。反対給付の義務はその恩恵がもたらしたさまざまな利得を自分が占有し退蔵していると「何か悪いことが起こり下手をすると死ぬことになる」と感じさせる。僅かばかりだがこれを以下で果たしたい。

QMK SYSでQMK CLIの更新をした後、おそらく到来するだろう警告subcommand has been deprecatedの対策を以下にご提示する。同様の件でお悩みの方はお急ぎであろう。結論へと直行なされよ。

ここでお約束の一言。結論に述べる方法を実行された結果は、自己責任となる件を書き記しておく。

QMK compileが死んだ?

LEDの半田付けの失敗から左側回路を損傷したコルネキーボード、その生き残りである右側キーボードのファームウエアをショートカット入力専用として完成した。これで暫くQMKを触ることはないだろうから、久しぶりにそれを弄った時にアップデートに遅れたQMKがコンパイルエラーを吐き出さないようにCLIの更新をした。

そこで更新の無事を確認する為に右の様にコンパイルをしてみた。するとこれがどうだ。まるで「いらぬ世話の焼き蛤」と詰るように「cli._subcommand has been deprecated」と右のように嫌らしい警告を吐いてきた。で、「qmk compileが死んだ?」と泡を食ってしまった。固唾を吞んで事の成り行きを見守った。

結局、コンパイルは成功裏に終わった。しかしコンパイルする度に前述の警告を食らうのは実に気分が悪い。これを解消しようとChatGPTに対策を問いかけた。すると、「QMK CLIを更新・・・」と堂々捲りの答えをしたり、「ツールの更新後も警告が表示される場合、スクリプトやコードに手を加える」と長々しく訳の分からない幻覚を述べた。

下手の考え休むに似たり

後者はgrepコマンド やPythonスクリプトを使ってclk.subcomandに関係するCLIに内在するファイル群を検索して書き換えろ言う。迂闊にこれを実行したらそれこそQMKを殺しかねない。「これって怪しい」と引いてしまいそうになる対処法だった。で、下手の考え休むに似たりと事の解消に閃きがおりてくることを期待して一晩の時間をおいた。そして翌日、1つの質問を思いついた。

「Why cli._subcommand has been deprecated in qmk cli?」と片言英語でググってみた。すると、マシンガンの弾幕の如く打ち出される英文に「 QMK CLIのドキュメントを参照して、新しい推奨メソッドを使用してサブコマンドを適切に定義し、アクセスする方法を学んでください」を意味する一文を見つけた。それをChatGPTにこれのハルシネーションを疑いながらその方法を尋ねた。

それが冒頭でご提示した方法である。勿論、それがChatGPTの幻覚でないことを実証済みだ。頭に少し文字面が並ぶが、「qmk compile -kb crkbd/rev1 -km default」と同等に機能する。実行速度の芳しくないPythonで実行する為であろうか。生成したコマンドを実行してもプロンプトの進行が遅くて「まさか(汗)」と肝を冷やす。結局、悩ましかった警告の発生も解消できた。その手順は次の通り。

結 論

その手順は次の通り。次の3段階とチッと長い。但し、pipやPythonがインストールされていることを前提とする。もし、それらが未了ならば(これをご覧の皆さんは該当しないはずだが仮にそうならば)次をご参照いただきたい。以下の環境はwindows11のQMK SYSとMSYS2である。

繰り返すがPython(QMK SYSをインストールすると自動的に組み込まれるはず)とpip(Pythonのパッケージ管理ツールで、QMKファームウェアの開発環境に必要なPythonライブラリを管理・インストールするためのもの)を使うので、以下を個々にコマンドしてそれらの存在をご確認されたい。

python --version
pip --version

それぞれのバージョン番号(例: pip 23.2.1)が表示されればOK。もしpipがインストールされていないようなら、次をの1行目をインストール、2行目はpipを更新して無用な問題を回避する為の呪文として、個々にコマンドする。それらが完了したら再び上記のコマンドでそれらの存在を確認する。

python -m ensurepip --upgrade
python -m pip install --upgrade pip

Clickライブラリをインストールする

・pipをインストース済みのQMK SYSなどを立ち上げる
・次をコマンドして標題を実行する。

pip install click

インストール成功メッセージが表示されれば準備完了だ。「Clickは、Pythonでコマンドラインインターフェース (CLI) を簡単に構築するためのライブラリです。名前の由来は「Command Line Interface Creation Kit」の略で、コマンドラインツールを素早く、直感的に作成するための機能を提供します」とChatGPTは述べた。QMK SYSとMSYS2とで検証した結果からすると、怪しくないのでご安心ください。

「qmk_cli.py の作成に際して参照したのは、以下のような一般的な情報とベストプラクティスです。すべては、ClickライブラリとPythonスクリプトの基本的な使い方、ならびにQMK CLIの標準的な使用方法に基づいています」とChatGPTは述べた。詳しくはご参考にclick公開情報をあたられたい。

コードを所定の場所に保存する

・秀丸やVSCodeなどエディタを立ち上げる
・ChatGPTで生成した下に例示したコードを貼り付ける
・ファイル名を例えばqmk_cli.pyとして所定の場所に保存する
・保存場所をQMK SYSを立ち上げた時にこれが示す場所にすると齟齬が起きない
・以下は、-c-e を含むオプションに対応したスクリプトの例である

import click
import subprocess

@click.group()
def qmk():
    """QMK CLI: キーボードの設定やコンパイルを管理"""
    pass

@qmk.command()
@click.option('--clean', '-c', is_flag=True, help='クリーンコンパイルを実行します')
@click.option('--keyboard', '-kb', required=True, help='コンパイルするキーボード名')
@click.option('--keymap', '-km', required=True, help='使用するキーマップ名')
@click.option('--env', '-e', multiple=True, help='環境変数を設定します(例: -e CONVERT_TO=promicro_rp2040)')
def compile(clean, keyboard, keymap, env):
    """
    指定されたキーボードとキーマップのファームウェアをコンパイルします。

    オプション:
    - `--clean` または `-c`: クリーンコンパイルを実行します。
    - `--keyboard` または `-kb`: キーボードの名前 (例: crkbd/rev1)。
    - `--keymap` または `-km`: キーマップの名前 (例: naginata_v15)。
    - `--env` または `-e`: 環境変数を設定します(例: -e CONVERT_TO=promicro_rp2040)。
    """
    click.echo(f'キーボード: {keyboard}')
    click.echo(f'キーマップ: {keymap}')
    if env:
        click.echo(f'環境変数: {env}')

    # コマンドの構築
    command = ['qmk', 'compile', '-kb', keyboard, '-km', keymap]
    if clean:
        command.insert(1, '-c')  # `-c` オプションを追加

    # 環境変数の構築
    env_vars = {}
    for variable in env:
        if '=' in variable:
            key, value = variable.split('=', 1)
            env_vars[key] = value
        else:
            click.echo(f'無効な環境変数: {variable}', err=True)
            return

    # QMK CLIのcompileコマンドを実行
    try:
        result = subprocess.run(command, capture_output=True, text=True, env={**env_vars, **subprocess.os.environ})
        if result.returncode == 0:
            click.echo('コンパイル成功!')
            click.echo(result.stdout)  # 標準出力の結果を表示
        else:
            click.echo('コンパイルに失敗しました。エラー内容:')
            click.echo(result.stderr)  # 標準エラー出力の結果を表示
    except FileNotFoundError:
        click.echo('エラー: QMK CLIが見つかりません。環境を確認してください。')

if __name__ == '__main__':
    qmk()

3.qmk_cli.pyを試行する
・QMK SYSなどを開きqmk_cli.pyの保存場所に移動する。
・保存場所が「C:/Users/info」なら以下のようにプロンプトする。

cd C:/Users/info

・次のコマンドを以下のコマンドを実行して、ヘルプを確認する。

python qmk_cli.py --help

・次のような表示が見られればqmk_cli.pyは使える。

Usage: qmk_cli.py [OPTIONS] COMMAND [ARGS]...
  QMK CLI: キーボードの設定やコンパイルを管理
Options:
  --help  Show this message and exit.
Commands:
  compile  指定されたキーボードとキーマップのファームウェアをコンパイルします。

qmk compileを実行する

・QMK SYSなどを開く。
・以下のコマンドで実際に qmk compile を呼び出す。

python qmk_cli.py compile -kb crkbd/rev1 -km default

・期待できる出力例(成功時)は次。但し、Pythonの処理速度からコンパイル終了までにイラッとしたくなる時間を要する。慌てて「Ctrl+C」などしてはいけない。その間お茶でも啜りながら一息いれられることが賢明だ。

キーボード: crkbd/rev1                     
キーマップ: default                        
コンパイル成功!                              
                                      
QMK Firmware miniaxe-ng15             
Making crkbd/rev1 with keymap default 
...(省略)...

勿論、「python qmk_cli.py compile -c -kb crkbd/rev1 -km naginata_v15 -e CONVERT_TO=promicro_rp2040」と「-c」オプションや、mcuをpro microからRP2040に差しかえた場合の「-e」オプション、それら付記したコンパイルにも先の「python qmk_cli.py compile」コードは対応する。

以上、subcommand has been deprecated に出会った場合の対処法をご提示した。なお、ご提示したコードが常用のオプションに未対応であれば、改善の項目を書き添えてこれをChatGPTに送信されたい。その結果は保証できないが、たぶん望みのことが叶うだろう。以上、皆さんの自作キ沼を踏破される旅の一助なれば幸いである。