そういえばビルドビルド言ってるけど何のビルド?
そうでしたねぇ...ちゃんと説明してませんでした...
今回は「Gitで管理されているArduinoプロジェクト」の管理としましょう。
Git?
流石に説明不要だと思いますが、プログラムとかのプロジェクトを管理するためのもので、変更履歴が全て保存され、バージョン管理が容易にできる物です。
また、コマンドひとつでソースコードを自分のパソコンにダウンロードしてくれる(Clone)ので、複数デバイス・複数人での開発でも重宝されるサービスとなっております。
よくGitとGitHubがごっちゃになっちゃいますが、Gitはバージョン管理ソフト、GitHubはGitのレポジトリを保存できるサーバーを提供しているものって感じです。
...なんか説明が適当になっちゃった気がするので気になる人はGitで調べて見てください。
Arduino?
マイコンです。
なんと、このアドベントカレンダーでも記事を書いているのでぜひご確認ください。
コマンドを実行するコマンドを作ろう(?)
Q. この男...何を言っているのかわからない...
A. そうだな...でも、そういうことなんだよ...
なお、ここからの記事ではGitの最低限の知識があり、すでにレポジトリが作成されていることを前提としています。
(シェル)コマンドを実行する(スラッシュ)コマンドを作っていこうというわけです。
どうやってPython上からシェルコマンドを実行するの?
様々な方法がありますが、今回はsubprocess
を使用します。
>>> import subprocess
>>> subprocess.run(["uname"])
Linux
CompletedProcess(args=['uname'], returncode=0)
subprocessではこんな風にシェルコマンドを実行することができます。
結構簡単ですね。
じゃあ、これをスラッシュコマンドに組み込んでみよう
import subprocess
from subprocess import PIPE
...
@bot.slash_command()
async def git(interaction: nextcord.Interaction):
pass
@git.subcommand()
async def status(interaction: nextcord.Interaction):
process = subprocess.run(["git", "status"], stdout=PIPE)
await interaction.response.send_message(embed=nextcord.Embed(
title="Git Status Result",
description=f"```sh\n{process.stdout.decode('utf-8')}```"
))
...
あーー!!!ちょっとまって!!!
私の前回のアドベンドカレンダーを見た人はもうわかりますよね?
そうです、subprocess.run
は同期処理です。
なので、やっぱりここは非同期処理にしないといけません。
なので早速ですがsubprocess
を捨ててasyncio.create_subprocess_shell
を使ってみましょう。
### これらは削除かコメントアウト ###
# import subprocess
# from subprocess import PIPE
import asyncio
...
@git.subcommand()
async def status(interaction: nextcord.Interaction):
process = await asyncio.create_subprocess_shell("git status", stdout=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate()
await interaction.response.send_message(embed=nextcord.Embed(
title="Git Status Result",
description=f"```sh\n{stdout.decode('utf-8')}```"
))
...
結構変わってきましたね。
まず、subprocess.run
がasyncio.create_subprocess_shell
になりました。
それによって、渡すコマンドがリストから文字列になりました。
そして、stdout
がasyncio.subprocess.PIPE
になりました。
そして、process.stdout.decode('utf-8')
がstdout.decode('utf-8')
になりました。
これで、非同期処理に対応したコマンドができました。
もうすぐだね...!
あとは簡単ですね、コマンドの中身を入れ替えるだけです。
...じゃあそのコマンドってどんな感じなんでしょうか。
と言うわけで次回から割り込み企画「何でもかんでもコンソールでやってみない?」を始めます。
コンソールで実行できればこんなふうな外部からの操作ができたりうんぬんかんぬん...
あとがき
まだ書き途中だったのに公開されちまった...ミスだぜ!