の続き。
コマンド引数とメインの処理をちゃんと見直す。
コマンドに渡す引数
Pull Requests | GitHub Developer Guide
にあるようにどのオーナーによる何のリポジトリのpull request情報を取得したいのかを指定すれば良いので
* * @var string */ - protected $signature = 'fetch:github {owner}'; + protected $signature = 'fetch:github + {owner : Repository owner name} + {repo : Repository name} + {--x|execute : if false, execute this command with dry run mode.} + {--number : Pull Request Number}'; /** * The console command description.
Laravelではコマンド引数の説明も上記のようにマルチラインで記載が可能になっている。デフォルトで -h
がヘルプオプションになっているので、それを指定して実行すると以下のように表示される。
$ php artisan fetch:github -h Usage: fetch:github [options] [--] <owner> <repo> Arguments: owner Repository owner name repo Repository name Options: -x, --execute if false, execute this command with dry run mode. --number Pull Request Number -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug Help: Fetch GitHub Repo data and save DB
メインの処理
/** * Execute the console command. * * @return mixed */ public function handle() { if ($this->option('execute')) { $this->dryRun = false; } else { $this->info('Dry run mode.'); } $owner = $this->argument('owner'); $repo = $this->argument('repo'); $openPullRequests = $this->client->api('pr')->all($owner, $repo, ['state' => 'open']); foreach ($openPullRequests as $pr) { $this->line('number: ' . $pr['number']); $this->line('title: ' . $pr['title']); $this->line('owner: ' . $pr['head']['user']['login']); $this->line('url: ' . "https://github.com/${owner}/${repo}"); if (!$this->dryRun) { DB::transaction(function () use ($owner, $repo, $pr) { $user = \App\User::firstOrCreate([ 'name' => $pr['head']['user']['login'], 'email' => 'dummy@example.com', 'url' => $pr['head']['user']['html_url'], ]); $review = \App\Review::updateOrCreate([ 'status' => $pr['state'] === 'open' ? 0 : 1, 'hosting_type' => 'github', 'repository_url' => "https://github.com/${owner}/${repo}", 'number' => (int)$pr['number'], 'title' => $pr['title'], 'author_id' => $user->id, ]); }); } } }
だいぶ雑にわぁーっと作ったが
- UserにPR参加者のデータをDBに入れる。
- ReviewにPRのデータをDBに入れる。
をまさにやってる。
dry-runの判定部分をメインの処理の中に本当は書きたくなかったんだが
Illuminate\Console\Command | Laravel API
を見てもbeforeとかinitializeとかないし、まぁこんなもんかな?と思って一旦書いた。
usersテーブルへのinsertはレコードがなかったら作るの firstOrCreate
を、 reviewsテーブルは INSERT...ON DUPLICATE KEY UPDATE
に当たる updateOrCreate
を利用している。
割りとdoctrine ORMの使い方と似てる *1 ので使ったことのある人なら、そんなに抵抗なく使えるかもしれない。
このコマンドのままだとopenなPRしか取ってこれない。このため、本来はreviewsテーブルにある、まだstatusがopenになってるレコード全部に対して取得の必要があるし、コメントがまだ取ってこれない。 あと、0とか1とかモロにマジックナンバーが書いてあるので、ちょっとConstクラスかなんか作って隠蔽したい。
けど、今日はここまで。
*1:というか私が真面目にコードベースに何使ってるか追いかけてないだけ。doctrine/dbal をcomposerで入れないとmigrationsだけでは使えない機能があったりするので無関係ではないと思う