2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonその2Advent Calendar 2019

Day 24

いい感じなgitignoreエディタ作れないかなと思ったので、とりあえずMVPっぽいのを作ってみた

Last updated at Posted at 2019-12-24

起:.gitignoreのちょっとした悩み

ことの発端

プロジェクトをInitial commitした後におもむろにやる作業として、「gitignore.ioから良さげな.gitignoreを作る」というのがありますよね? 1 2

ありますよね?

時間経過で.gitignoreは変化する...こともある

最初のまま運用できれば問題ないのですが、

  1. あ、この環境用のignoreもつけたい
  2. ちょっと特殊なignoreが必要になりそう

ということが出てきたりします。

出てきたりします。

(1)のケースだと、もう一回gitignore.ioに行って再生成しないといけなかったりします。

(2)のケースだと、テンプレ生成した.gitignoreのどこかに記述しないといけなくなるのですが、
こうなってくると(1)の対応のたびに若干の手間を感じてしまったりします。多分

承:雑な思いつきと、MVPっぽいの

思いつき

そこで「.gitignore編集時にいい感じに『言語名』と『言語のignore』をいい感じに連携しつつ簡素に書くエディタ」とか作れないかなと考えてみました。lazygitみたいなUIかっこいいじゃないですか

こんなの

  • キーワードを入れると、「そのキーワードを含む言語・環境の候補」が出る
  • Tabで候補に移動して右とか押したら、、言語として反映
  • 候補がない中でキーワードを選択して右を押したら、パターンとして反映
  • 保存時に、勝手にAPIコールしてgitignore.io+パターンで構築

とかできると、派生でignoreしたいパターンなどをまとめて放り込めて便利かなーなんて。

とはいえ、こういう形式でのエディタを作成する能力は今の所ありません。

手間を掛けずにそれっぽいの(=MVP?)を作ってみる

超雑に、MVPっぽい超簡易実装を試してみました。
こちら => vigi = vi gitignore

vigi コマンドを実行すると、


# ~~~~~~

こんな感じのファイルをvimで開き、

.idea

# ~~~~~~
python
virtualenv

こんな感じで編集してvimを終了すると、

.idea

# ~~~~~~

# https://www.gitignore.io/api/python,virtualenv の中身

みたいな状態の.gitignoreを作ってくれます。

ちなみに、この状態でvigiコマンドを実行すると、gitignore.io部分はちゃんと言語のみの情報になります。編集がしやすい……かなと思います。

転:中身はこんな感じ

.giという名で仮ファイルを作って編集し、保存されたらそれを.gitignoreに変換するスタイル

import subprocess
from pathlib import Path
from subprocess import CalledProcessError, PIPE

def main():
    gi_path = Path.cwd() / '.gi'
    gitignore_path = Path.cwd() / '.gitignore'
    try:
        # Convert from ``.gitignore`` to ``.gi``
        if gitignore_path.exists():
            encode_gitignore(gitignore_path, gi_path)
        else:
            with gi_path.open('w') as fp:
                fp.write(dedent(gi_template).strip())
        # Spawn vim
        vim_args = ['/usr/bin/vim', str(gi_path)]
        vim_proc = subprocess.run(vim_args, check=True)
        # Convert from ``.gi`` to ``.gitignore``
        decode_gitignore(gi_path, gitignore_path)
    except CalledProcessError:
        pass
    finally:
        # Remove ``.gi``
        gi_path.unlink()

vimを呼ぶ

subprocess.runvimを呼出し、CalledProcessError例外がなければOKというざっくりスタイル。楽で良いですね。

.giは残さない

tryfinallyを使って、最終的に.giファイルは捨てちゃってます。エラーなら.gitignoreの編集もしないので環境に配慮されていますね。

素材をもとに.gitignoreを作る

.giファイルはこの時点でファイルシステム上に普通にあるので、普通にファイルとして開く感じです。
そして、言語側の情報をまとめてgitignore.ioにパス。
HTTPステータスが404の時に限り、通常と同じようにレスポンスを保存してますが、
これは「マスターに存在しない情報を含む」ケースが全て404になるっぽいためです。
唯一と言っていい、ちょっとした工夫点ですね。

def decode_gitignore(src, dest):
    custom = []
    online = []
    with src.open() as fp:
        # .giファイルを開いて、デリミタの前後を分けるなど
    if online:
        url = f'https://www.gitignore.io/api/{",".join(online)}'
        req = Request(url, None, headers={'User-Agent': 'vigi'})
        try:
            resp = urlopen(req)
            custom.append(resp.read().decode())
        except HTTPError as err:
            if err.code == 404:
                custom.append(resp.read().decode())
            raise err
    with dest.open('w') as fp:
        fp.write('\n'.join(custom))

結:使用感とか

一応、vigiプロジェクト内にある.gitignoreはこのコマンドベースで作りました。

編集時点で表示される行数が格段に減るのはメリットではあるかなと思います。
そういう意味ではMVPとしての仕事はきちんと全うしてくれました。

ただ、言語マスターにどんなパターンが含まれているかが、.gitignoreへの変換を終えないとわからないので、
仮にもうちょっと開発してみようと思ったら、きちんとパターン候補から言語マスターを引っ張り出すようにしないと、
本当に良いものなのかはわからないですね。何かの言語のトレーニングには向いてるかも?

  1. プロジェクトテンプレート作るとかがありますが、一旦忘れてください

  2. dotfilesで管理するなどもできますが、これも一旦忘れてください

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?