【作業効率化】Laravelのartisanをカスタムしてgitコマンドを簡単にすると便利！

# はじめに
gitを使ってる方はCLIでcommiしたり、pushしたりしていると思いますが、毎度コマンドに打つの面倒ですよね。
独自にシェルスクリプトを書いても十分簡易化できますが、今回はLaravelのartisanの自作コマンドで１コマンドで完結する便利コマンドを作ってみましょう。

# 完成したコマンドでできること
* git add ~ commit ~ pushが**１コマンドで完了**できる
* pushした後、GitHubのcompare画面を開くことができる （オプション）

▼完成コマンド
$<code>php artisan git:push 不要なクラスを削除 -c renewal-develop -s</code>

▼実行されること
1. git add --all
2. git commit -m {コメント}
3. git push -u HEAD
4. compare renewal-develop..作業ブランチ画面を起動する

＊オプションなどはこの後説明します！

# 早速作ろう！
## 1.コマンドクラスを作る
Laravelのプロジェクトフォルダにて以下のコマンドを実行
<code>php artisan make:command GitCommand</code>

## 2.コマンドを書く
▼before

```GitCommnad.php
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';
```


▼after

```GitCommnad.php
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'git:push {comment} {--c|compare} {target=master} {--s|nostatus} {--i|issue=}';
```

引数１ : <code>{comment}</code>
→ git commit -m {コメント}の部分を引数とする

引数２　： <code>{target=master}</code>
→ compareのbase（マージ先)を指定する。指定しない場合はデフォルト値がmasterとなる。

OPTION(1) ： <code>{--c|compare}</code>
→ compare画面を開く場合に指定する。　
（-cまたは--compareと入力できる）

OPTION(2) ： <code>{--s|nostatus}</code>
→ はじめにgit statusを実行するか。オプションをつけるとgit statusと実行の確認をしないようになる。　
（-sまたは--nostatusと入力できる）

OPTION(3) ： <code>{--i|issue}</code>
→ コメントにissue番号をつけたい時につける。　
（-iまたは--issueと入力できる）
＊コメントに直接書けばいいのでなくてもいいオプション笑


## 3.引数を受け取れるようにする
<code>getArguments()</code> Methodを以下のようにオーバーライドします。

```GitCommand.php
    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return [
            ['comment', InputArgument::REQUIRED, 'Your git comment'],
            ['target', InputArgument::NOT_REQUIRED, 'Git Base Branch Name (merge target)'],
        ];
    }
```

## 4.オプションを受け取れるようにする
<code>getOptions()</code> Methodを以下のようにオーバーライドします。

```GitCommand.php
    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [
          ['nostatus', '-nostatus', InputOption::VALUE_OPTIONAL, 'Run without git status command'],
          ['issue', '-issue', InputOption::VALUE_OPTIONAL, 'GitHub issue no'],
          ['compare', '-compare', InputOption::VALUE_OPTIONAL, 'If you execute github compare, add this option'],
        ];
    }
```


## 5.実行処理を書く

以下の流れで実行するように実装します。 

git status
　↓
git add --all
　↓
git commit-m {コメント}
　↓
git push -u origin HEAD
　↓
hub compare {target}..{HEAD：作業ブランチ}
　↓
Finished!!

```GitCommand.php
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
      if (!$this->option('nostatus')) {
        // git status
        $this->comment("Run: git status");
        $this->info(shell_exec("git status"));
        $confirmed = $this->confirm('Do you commit to all files?');
        if (! $confirmed) {
            $this->comment('Please remove untraced file and re-run this command.');
            return;
        }
      }

      // git add
      $this->comment("Run: git add --all");
      $this->info(shell_exec("git add --all"));

      // git commit
      $comment = trim($this->argument('comment'));
      if ($this->option('issue')) {
        $comment = "#".$this->option('issue')." ".$comment;
      }
      $this->comment("Run: git commit -m {your input comment}");
      $this->info(shell_exec('git commit -m "'.$comment.'"'));

      // git push
      $this->comment("Run: git push -u origin HEAD");
      $this->info(shell_exec('git push -u origin HEAD'));

      if (!$this->option('compare')) {
        $this->comment("Finished!!");
        return;
      }
      // Show github compare page.
      $current = shell_exec('git rev-parse --abbrev-ref HEAD');
      $base = $this->argument('target');
      $this->info(shell_exec('hub compare '.$base.'..'.$current));
      $this->comment("Finished!!");
    }
```


**Note:**
$this->option('hoge') → オプションの値を取ります。

$this->argument('hoge') → 引数の値を取ります。

$this->info(shell_exec('hoge'))　→ 任意のシェルコマンドを実行して、実行内容をコンソールに出力します。

細かいところは以下の記事を参考にしてください。
■ [Laravelでコマンドラインアプリケーションを作成する](https://qiita.com/nenokido2000/items/abbf70c87c9ad86a2b89)
■ [シェルスクリプトで現在のブランチ名を取得する（git rev-parse）](http://blog.penginmura.tech/entry/2018/01/12/093400)

## 6. hubをインストールする
hub compareを動かすために、[hub](https://github.com/github/hub)をインストールします。

# 完成！！
あとはもう好きにコマンドを実行して動かしてみましょう。

【ケース１】オプションを何も指定しないシンプルなコマンド
$<code>php artisan git:push コメント</code>
![スクリーンショット 2019-03-03 17.58.12.png](https://qiita-image-store.s3.amazonaws.com/0/246680/2977a1d3-7d11-5523-7c36-fb5313ad77a4.png)
git statusがされて、全部コミットOK？と確認をします。
不要なファイルがある場合はnoを入力、問題なければyesを入力してください。
![スクリーンショット 2019-03-03 17.58.44.png](https://qiita-image-store.s3.amazonaws.com/0/246680/74050bd0-536c-abc6-469e-e2be323c9102.png)

ちゃんと実行されました！！


【ケース2】git statusの確認は不要で即コミット&プッシュしたいパターン
$<code>php artisan git:push コメント -s</code> (または--nostatus）
![スクリーンショット 2019-03-03 18.04.36.png](https://qiita-image-store.s3.amazonaws.com/0/246680/315fef70-ceb2-7567-64dd-54a94f515415.png)


いい感じですね！！

【ケース３】プッシュした後、compare画面を開きたい
$<code>php artisan git:push コメント -c -s</code>（-cまたは--compare）
![Mar-03-2019 18-15-03.gif](https://qiita-image-store.s3.amazonaws.com/0/246680/f312979b-e187-dad7-0269-99ac05ad68d9.gif)

ブラウザが起動してGitのCompare画面が開きました！！ 
（尺が足りず表示できてませんが問題ないです）

【ケース4】プッシュした後、compare画面を開きたい（マージ先を指定）
$<code>php artisan git:push コメント -c renewal-develop -s</code>（-sは任意）

（キャプチャは割愛します）

#終わりに
hubではプルリクエストの作成までできたりするので、工夫して作業をドンドン効率化して快適なプログラミングワークをしましょう！

#記事作成者
NARI: [twitter](https://twitter.com/NARI_Creator)
フリーランスのエンジニアをしています。

この記事が少しでも参考になったらいいね、シェアされると嬉しいです！