Gitの特殊な機能
Gitでは、 git-xxx
というスクリプト(実行権限付でPATH下にあるもの)があれば、git xxx という形で実行できるという特殊な機能があります。(有名な git-flow
もこの機能を使って git flow
と呼び出しています)
この機能をPythonで車輪の再発明をしてみる。
書いてみた
mygit.py
# coding: utf-8
import os
import sys
from subprocess import call
class ExtensionLoader:
def __init__(self):
# 環境変数PATHはコロンでつながれた文字列なので、
# コロンでsplitすることで配列に変換する
self.PATH = os.environ["PATH"].split(":")
def load(self, ext, args):
# ext: 'mygit init' -> 'init'
ext_absname = "mygit-{}".format(ext)
found_flag = None
extension = None
for directory in self.PATH:
# 'mygit-init'がdirectoryの中にあるかどうか
if ext_absname in os.listdir(directory):
found_flag = True
extension = os.path.join(directory, ext_absname)
if found_flag:
# 'mygit-init'を見つけたら実行
cmd = [extension]
cmd += args # ここで実行する拡張スクリプトに引数を渡している
return call(cmd)
else:
raise IOError("Extension does not found: {}".format(ext))
if __name__ == "__main__":
if len(sys.argv) == 1:
print "usage: mygit {command}"
sys.exit(1)
extloader = ExtensionLoader()
# argv: ["mygit" "command", "arg1", "arg2", "arg3"]
command = sys.argv[1]
arguments = sys.argv[2:]
exit_status = extloader.load(command, arguments)
sys.exit(exit_status)
意外と簡単でした。
問題は argparse と併用できないことですね。
argparseは一応サブコマンドをパースできますが、登録されていないコマンドが入力されるとエラーを吐くし、あらかじめ拡張スクリプトのコマンドを登録するなんてことはできませんからね…