- 投稿日:2019-12-21T23:22:24+09:00
SwiftUIでgit-blame-pr.plをMacアプリにしてみた
この記事は、ZOZOテクノロジーズ #4 AdventCalendar2019の記事です。
昨日は@satto_sannさんの「FastAPIの負荷実験環境を作ってみる」でした。さて、あるコードが、どういった背景や意図で変更されたのかを知りたいことは、よくあることだと思います。そういった場合にgit-blame-pr.plを使うと、そのコードがどのプルリクエストで変更されたかを簡単に知ることができます。
これはCLIでそのまま使うだけでも十分便利です。
ただ使用頻度が高いこともあり、ユースケースに沿ったGUIが欲しくなりました。
そこで、git-blame-pr.plが出力した結果の行をクリックするだけで、該当のWebページに遷移できるMacアプリを作ってみました。出来上がったものは下記のリポジトリで公開しています。
https://github.com/maoyama/GitBlamePR
GitHubのリリースから最新のGitBlamePR.app.zipをダウンロード、解凍するだけで使えます。ぜひ試してみてください。
※macOS Catalinaが必要です。実装内容の紹介
UIはAppKitではなくSwiftUIで実装しています。
以下のコードがUIにおいては全てです。SwiftUIを使っているので、Storyboardやxibファイルもありません。struct GitBlamePRView: View { var model: GitBlamePRViewModel var textOnCommit: (String) -> Void @State private(set) var fullPath: String = "" var body: some View { VStack(alignment: .leading, spacing: 0) { TextField( "Enter full path", text: $fullPath, onEditingChanged: {_ in }, onCommit: { self.textOnCommit(self.fullPath) } ).lineLimit(1) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() Divider() ScrollView(.vertical, showsIndicators: true) { VStack(alignment: .leading) { if !model.error.isEmpty { Text(model.error) } ForEach(model.lines, id: \.id) { line in HStack(alignment: .top, spacing: 12) { Text(line.message) .font(Font.system(.caption, design: .monospaced)) .foregroundColor(.accentColor) .frame(width: 80, height: nil, alignment: .trailing) .onTapGesture { NSWorkspace.shared.open(line.url) } Text(line.code) .font(Font.system(.caption, design: .monospaced)) .frame(width: nil, height: nil, alignment: .leading) } } HStack { Spacer() EmptyView() } }.padding() }.background(Color(NSColor.textBackgroundColor)) } } }「Better apps. Less code.」とAppleが謳っている通り、とても少ないコードで実現できています。
またSwiftUIは、全てのAppleプラットフォームで使えます。そのため、僕のような普段はiOSアプリの開発をしているプログラマでも、macOSで動くアプリを作る敷居がとても低くなりました。この記事は以上です。
明日は@alpha_gotoさんです。お楽しみに!
- 投稿日:2019-12-21T21:48:40+09:00
git の保存パスワードをクリアして、再度パスワードを保存する設定
- 投稿日:2019-12-21T16:42:52+09:00
最近のgit操作環境(2019/12/21時点)
最近、Gitの環境を整理して使いやすい環境になってきたので記事にしてまとめておこうと思います。
使用している OS は Ubuntu 18.04 です。シェル
現在使用しているシェルは fish を利用しています。
fishは構文の強調表示、入力時に入力候補の表示、タブ補完などの機能をデフォルトで使用することができます。インストール
下記コマンドを実行すれば完了です。
fishのインストールsudo apt-add-repository ppa:fish-shell/release-3 sudo apt-get update sudo apt-get install fishデフォルトのシェルをfishに設定します。
chsh -s $(which fish)ログインしなおせばシェルがfishに設定されているはずです。
ついでにfishのパッケージを管理するツール、fisherをインストールします。
fisherのインストールcurl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fishリポジトリ操作
リポジトリの移動
私が設定しているGit関連の設定は以下の2つです
- cloneしたリポジトリへの移動
- ブランチ移動
この2つについて、キーバインドで完結できるように設定します。
まずはじめに fzf というコマンドラインで使用できる対話式のフィルタツールを使用します。
これと似たツールにpecoというものもありますが、fzfではあいまい検索ができるため、こちらを使っています。ではインストールしていきます。インストールは以下のコマンドで行うことができます。
fzfのインストールgit clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install --no-bash --no-zsh --key-bindings --completion --update-rc
次に、にcloneしてきたリポジトリを管理する方法として ghq を使います。
ざっくりと説明するとcloneしてきたリポジトリを特定のディレクトリに配置して一括管理できるようにしてくれるツールです。インストールについてはghqのリポジトリを参考にしてインストールします。
ghqには
ghq list
というghqでcloneしたリポジトリをリスト表示する機能があるのですが、この機能とfzfのあいまい検索を連携させるためのプラグインをfisherでインストールします。fisher add decors/fish-ghqインストール後、Ctrl+Gで
ghq get
で取得したリポジトリがfzfのインターフェースでリストアップされあいまい検索と対話的選択でリポジトリを移動することができるようになります。リポジトリのブランチ移動
ブランチの移動には gitコマンドとfzfコマンドを組み合わせて移動します。
fzfのwikiにあるfishでの例で紹介されているコマンドを使ってキーバインドでのブランチ移動を実現します。~/.config/fish/functions/__git_branch.fishfunction __git_branch -d "Fuzzy-find and checkout a branch" git branch --all | grep -v HEAD | string trim | fzf | read -l result; and git checkout "$result" commandline -f repaint end次に、先程作成したコマンドをキーバインドに紐付けます。
~/.config/fish/conf.d/keybinding.fishbind \cb '__git_branch' if bind -M insert > /dev/null 2>/dev/null bind -M insert \cb '__git_branch' endfishにログインしなおせばキーバインドの紐付けが完了しているはずなので、Ctrl+bでリポジトリの移動時のような画面で現在のリポジトリのブランチを対話的に切り替える事ができるようになります。
以上で、最近のgit操作今日の紹介は終わりにしようと思います。
これら使っていく中でよりよいものがあれば追記していこうと思います。
- 投稿日:2019-12-21T15:59:36+09:00
マイグレーションファイルの作成、変更、削除まで
今回は、物件のファイルを作ることを想定します。
流れ
マイグレファイル作成→カラムすべて間違い→もう一度入れ直したい
1.マイグレファイルを作成する
$ rails g migration CreateHomes2.作成したマイグレファイルをエディターで編集する
create_homes.rbclass CreateHomes < ActiveRecord::Migration[5.2] def change create_table :homes do |t| t.string :"物件名" t.string :"賃料" t.string :"住所" t.text :"備考" end end end3.マイグレーションをターミナル上で入力
$ rails db:migrate4.マイグレファイルを削除するため、削除用のファイルを作る
rails g migration RemoveColumnsFromeHomes5.作ったファイルを編集する
remove_columns_from_homes.rbclass RemoveColumnsFromHomes < ActiveRecord::Migration[5.2] def change remove_column :Homes, :"物件名", :string remove_column :Homes, :"賃料", :text remove_column :Homes, :"住所", :text remove_column :Homes, :"備考", :text end end6.マイグレーションをターミナル上で入力
$ rails db:migrate※こうすることで、再び作り直すことができます。
rollbackでも削除は、可能ですが複数開発のときに何を編集したのか分からなくなるのでやめましょう。7. カラムを追加するためのマイグレファイル作成
$ rails g migration AddColumnsToHomes8.マイグレファイルを編集
add_columns_to_homes.rbclass AddColumnsToHomes < ActiveRecord::Migration[5.2] def change add_column :homes, :property, :string add_column :homes, :rent, :text add_column :homes, :address, :text add_column :homes, :age, :text add_column :homes, :remarks, :text end end何かを分からないことがありましたら、コメントを頂ければ1日以内に返信するように致します。
- 投稿日:2019-12-21T15:50:06+09:00
Gitが浸透していない社内に普及させたい(現在進行系)
ITCアドベントカレンダーの記事です。
「射撃教習申請について 他」とか書いてたんですが、結局申請出してないし内容を変えます。何の記事か
アルバイト先で新しく受注案件が発生したのですが、弊社は
- 手動でソースを管理し
- 作業場所として開発サーバーに
〇〇_kakimoto/
のようなディレクトリを作成し- それまでのソースと目grepをし
- SFTPで直接反映する
という状況のため、かねてよりミスが危惧されていました。
今回、新規に立ち上げであることと、最初期の開発者は自分一人であること、のちのち開発に加わるメンバーもそろそろフローを変えたいと思っていたということでGit/GitHubの導入を決めました。導入にあたってしたことを備忘録としてまとめましたので記事とします。
要件
- PHP, MySQLを使った管理ツール
- なるべく覚えることは少なく
- それまでのスタイルを大幅には崩さないこと
- →つまりLaravel等のフレームワークは学習コストが大きいため避ける
の3点をまず最初に意識しました。2と3は今後社内に普及させることを考えて導入ハードルを下げるために意識します。
セキュリティを担保する
我々が趣味で作るクソみたいなコードと違って、プロダクトとして開発をする以上一定のセキュリティを担保する必要があります。
リモートリポジトリを選定する上で、自社で管理できるGitLabも挙がりましたが、インストールと管理のコストを考え今回は見送りました。
選択肢としては
- GitHub
- GitLab
- Backlog
ぐらいがメジャーかなと思います。
Backlogも良いかなと今となっては思うのですが、個人的に私が使い慣れたGitHubにし、メンバーのうち社員のアカウント内にPrivateリポジトリとして設定することにしました。その他、GitHubアカウントの乗っ取りも最近起きているということなのでDBへの接続情報なども.gitignoreで監視対象から外すなどの対策を考えます。
GitHubにするにあたって必要なこと
- メンバー全員のGitHubアカウントを作成
- メンバーの作業PCとGitHubをSSH接続できるようにする
- リポジトリを設置するアカウントを決める
- コラボレーターにメンバーを設定するのか
- オーガナイゼーションを作成するのか
当初オーガナイゼーションを作成するつもりでしたが、軽く調べたところプライベートにするには課金が必要そうだったため断念。また私がリポジトリを作成しても良かったのですが、あくまでアルバイトですし、新卒就職時には辞めることが決定しているため、期間的な意味でも、社員のメンバーに作成してもらいました。
プライベートリポジトリにする場合コラボレーターは3人までとのことですが、今回の案件は3人以上になることは無いと思われるためこちらは問題になりませんでした。Gitのフローについて
今回は
- masterブランチ(リリース/客先レビュー用)
- developブランチ(デフォルト)
- featureブランチ(開発時用)
とするGitHubフローとしました。
タスク管理をどうするかの話が決まっていないため、現時点ではIssueを利用することにし、featureブランチの番号はIssue番号に対応させることにします。なお今回は、開発メンバーがmasterブランチのみでコミットを積んでいくことはしたことがあるとのことだったため、基本的なGitの操作についての説明はある程度省略します。
開発者は、
- 最新のdevelopブランチをpull
- 実装するタスクのIssueを確認し、
feature/<Issue番号>
ブランチにチェックアウト- コーディング
git add
+git commit
+git push origin feature/<Issue番号>
- Pull Requestを作成
- PRをmerge
- developブランチに戻り、1.に戻る
というフローを繰り返します。今回はコードレビューなどは省略になるかと思います。
また、GitHub Actionsなどは設定しません。ローカル環境の準備
これまでは開発用のサーバーを用意し、そこに全てのソースを保存していましたが、それだと誰かがブランチを切り替えることができないため、必然的に各自で競合しない開発環境(=ローカルに設置する)を用意する必要が出てきました。
集権サーバーであったときは同じ開発用のDBサーバーに接続すればよかったため、誰か一人がテーブルに対する変更を管理していればよかったのですが、各自がDBを用意するところもカバーする必要があります。
また、DBに対する変更があった場合は作業者がSQLをメモした上で、リリースの際手動で入力する必要がありました。これは作業ミスを誘発すると考え、テーブルやDBに対して変更を生じるSQLも、Gitリポジトリに含めることにしました。以上のことから、
- 誰が見ても同じ環境を準備できること
- なるべくコマンド量を少なく、わからなくても打てば動く状態にすること
- 必要な情報は1箇所にまとまっていること = README.mdを整備する
を優先しました。
実際のREADME.mdの冒頭は以下です。
ローカルの開発環境を用意する
- git clone
- create databese
<project_name>
- DB接続情報を/common/database/db_config.php 36行目以降に記載
/common/database/migrate/
配下SQLファイルを実行(yyyymmdd + 01 ~ 99の連番 + テーブルに対する変更内容 ファイルの順に実行)cd public && php -S localhost:8000
実行- http://localhost:8000
create database って書いてますが、sql文ではなくて手動で作ってねって意味です。
また、プロジェクトルートにはコンフィグファイル群を設置した/common
ディレクトリと、サーバーのドキュメントルートにあたる/public
を設置しており、ローカルサーバー起動時にpublicに移動してphp -S
コマンドで立ち上げる想定です。
こうすることで、現状の開発サーバーと同じパスにすることができました。
migrateionっぽく連番を振ることでテーブル間の整合性を取ろうとしています。
今の所上から順にSQLファイルを実行するだけで、テーブル重複に対しても各SQLファイル実行前にDROP TABLE IF EXISTS `users`;といったことしかしていませんので、今後よしなにするシェルスクリプトなどを作れればなと思っています。
今後について
上記で触れたマイグレーションを管理するものであったり、Gitフローを周知する上でわかりやすいドキュメントを整備などしていく予定です。
- 投稿日:2019-12-21T11:45:27+09:00
コミットメッセージについて考えてみた
ある日の出来事です。
いつも優しくて、すごくお世話になっている先輩が、それを見た瞬間、鬼の形相になりました。# コミットメッセージ Update: 開発完了冷や汗が止まりませんでした。。
もう二度とこのような悲しい出来事を生まないために、コミットメッセージの重要さと書くべきことについて考えていきます。なぜ重要なのか
コミットメッセージは将来の効率化のために書くものだと思っています。
例えば、
コードレビューをする際も、
レビュアーがメッセージを見ただけで
どのような改修をしたかが分かる状態になっていれば、スムーズにレビューを行うことができます。
コード修正においても、修正意図が分かるだけで、対象コードの修正要否が判断しやすくなると思います。
git blame
したときに「開発完了」とだけ伝えられても何も分からず、
結局コードや過去の案件を調べなきゃいけなくなりますよね。(本当にごめんなさい。)書くべきこと
5W1Hという言葉をよく耳にしますが、
gitでは以下のことが把握できるようになっています。
- When(いつ)
- いつ変更を加えたのかはタイムスタンプを見れば分かる
- Where(どこで)
- 何に変更を加えたのかはリソース (file/dir) 名で分かる
- Who(誰が)
- 誰が変更を加えたのかは author を見れば分かる
- What(何を)
- どうやって変更を加えたのかはdiffを読めば分かる
- Why(なぜ)
- なぜ変更を加えたのかはコミットメッセージを読めば分かる
- How(どのように)
- どうやって変更を加えたのかは実装を読めば分かる
つまり、コミットメッセージには「Why」を書くべきで、変更の意図を伝えることが大事だということです。
加えて、プレフィックスをつけると、
どのような変更があったのかも分かりやすくなります。プレフィックス例
- Add:
- 機能の追加やファイル追加
- Fix:
- バグ修正
- Update:
- 更新
- Delete:
- 機能削除やファイルの削除
- Revert:
- コミットの巻き戻し
- Marge:
- 統合
- Move:
- リソースの移動
- Rename:
- 名前の変更
過ちを正してみた
beforeUpdate: 開発完了afterUpdate: ○○システム Topページのロゴ画像を変更まだまだ改善の余地はありそうですが、
一旦、鬼の形相は見なくて済みそうです。最後に
私自身、コミットメッセージはとりあえず書いておけばいいと思っていました。
それは大きな間違いで、
将来の仲間への大きな負担となってしまい、
開発効率低下へと繋がっていきます。思い当たる節がある方は、本記事をきっかけに改善していきましょう!
参考文献
お知らせ
エイチームグループでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひともエイチームグループ採用ページ(Webエンジニア詳細ページ)よりお問い合わせ下さい。あるいは、Qiita Jobsの引越し侍Webエンジニアチーム、自社サービスWebエンジニア/インフラからサービス改善まで!、求む!引越し侍大規模リプレイスにおけるフロントエンドのリードエンジニア募集!の記事をみて、興味が出てきた方は是非Qiita Jobsのチャットでメッセージをください。
明日は「キング・クリムゾン.js」で沸かせてくれた@heronaの記事になります!
乞うご期待!!