Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
30
Help us understand the problem. What is going on with this article?
@KEINOS

macOS に GitHub 風の軽量 Git サーバーを一発で建てるワンライナー

簡単に Git サーバーを Mac で建てたい

Mac で GitHub のような Git サーバーを自宅/オフィス用に簡単に建てたい。しかし、MySQL や Postgres などの DB サーバーや面倒な設定のいらない俺様専用レベルの Git サーバーはないものか
@ HighSierra (OSX 10.13.6)

TL; DR (今北産業)

  1. バイナリ1つで動作する「Gitea」はいかがでしょう。
  2. brew でインストール可能(要 tap と各種設定)
  3. コマンド 1 行で SQLie3 + 日本語化 + 空きポートで安定版 Gitea がインストールできるスクリプトを用意しました。

いんふぉ

インストール

通常インストール

Gitea は上記記事のように、バイナリのダウンロード・ページから最新版をダウンロードして自身でセットアップするのが一般的です。

しかし、最新の安定バージョン確認 + SQLite3 + 日本語化の設定 + 未使用のポートを探すといった諸作業が面倒な方は、次の「一発インストール・コマンド)」をご覧ください。

一発インストール・コマンド

楽をするために苦労する性癖がウズいたので、一発でインストールするスクリプトを用意しました。

以下のコマンドを、インストールしたいディレクトリ先で叩くとインストールできます。Mac 用(64bit版)の最新の安定版バイナリをダウンロード&検証して、基本的な設定がされた状態でインストールされます
(2019/01/07 追記:同じコマンドで Gitea のアップデートにも対応しました)

インストール・コマンド
bash <(curl -s https://keinos.github.io/gitea_darwin/install.sh)
サイズ
$ ls -lah
total 105344
drwxr-xr-x    4 admin  staff   136B  1  7 19:58 .
drwxr-xr-x  118 admin  staff   3.9K  1  7 19:57 ..
drwxr-xr-x    3 admin  staff   102B  1  7 19:58 custom
-rwxr-xr-x    1 admin  staff    51M  1  7 19:58 gitea

このインストーラーを使うと、Gitea のビルトイン SSH/WEB サーバー用のポートがバッティングしている(他のアプリが利用している)場合に、別のランダムな空きポートを検索しデフォルトに設定します。

あとは、ブラウザでアクセスして、設定画面でサイトの名前を設定し、アカウントを作成するだけです。(詳しくは下記 TS;DR 参照)

brew でインストール

Homebrew が入っている場合は brewGitea のインストールも可能です。しかし、その場合は未使用の空きポート確認や各種設定などはしてくれませんので自身で諸設定を行う必要があります。

$ brew tap gitea/tap https://gitea.com/gitea/homebrew-gitea
$ brew install gitea
$ gitea -h

参考文献

TS; DR (一発インストーラーに関するコマケーこと)

Gitea のインストール

以下は自分のホームディレクトリ(~/)に gitea ディレクトリを作成し、そこに Gitea を一発インストールする例です。

実行例
$ cd ~
$ mkdir -p gitea; cd $_
$ 
$ # インストールの実行
$ bash <(curl -s https://keinos.github.io/gitea_darwin/install.sh)
- Checking existing binary: no binary found ... installing newly
- Fetching latest release: OK
- Downloading files: 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   622    0   622    0     0    775      0 --:--:-- --:--:-- --:--:--   774
100 23.1M  100 23.1M    0     0  1540k      0  0:00:15  0:00:15 --:--:-- 1563k
100   626    0   626    0     0   2132      0 --:--:-- --:--:-- --:--:--  2143
100   833  100   833    0     0    859      0 --:--:-- --:--:-- --:--:--  2359
100   629    0   629    0     0   2323      0 --:--:-- --:--:-- --:--:--  2323
100    99  100    99    0     0    211      0 --:--:-- --:--:-- --:--:--   211

- Comparing checksum: gitea-1.6.3-darwin-10.6-amd64.xz: OK
- Decompressing XZ archive: OK
- Removing un-necessary files: OK
- Renaming binary file: OK
- Changing mode of the binary as executable: OK
- Installed path: 
    /Volumes/Macintosh_SD/Users/admin/gitea
- Installed version: 
    Gitea version 1.6.3 built with: bindata, sqlite
- Creating directory for application settings: OK
- Fetching ports in use: OK
- Fetching unused ports for builtin Webserver: OK (PORT: 8080)
- Fetching unused ports for builtin SSH: OK (PORT: 22)
- Creating application ini file: OK

* DONE. gitea installed successfuly.

Would you like to launch the browser to setup gitea now? (y/n):

Gitea サーバーの起動

インストール・スクリプトからインストールした場合は、「Would you like to launch the browser to setup gitea now? (y/n):」と聞かれるので「y」を入力すると、Gitea サーバーとブラウザが起動します。この時、「n」(y 以外)を選んだ場合は別途手動で起動させる必要があります。

Gitea サーバ終了後に再度起動したい場合など、手動で起動させるには ./gitea web と打つと Gitea のビルトイン WEB サーバーが起動します。

サーバーの起動
$ # Gitea のインストール先に移動
$ cd ~/gitea
$ # Gitea サーバーの起動
$ ./gitea web
2018/08/27 17:12:45 [T] AppPath: /path/to/your/installed/gitea/gitea
2018/08/27 17:12:45 [T] AppWorkPath: /path/to/your/installed/gitea
2018/08/27 17:12:45 [T] Custom path: /path/to/your/installed/gitea/custom
2018/08/27 17:12:45 [T] Log path: /path/to/your/installed/gitea/log
2018/08/27 17:12:45 [I] Gitea v1.5.0 built with: bindata, sqlite
2018/08/27 17:12:45 [I] Log Mode: Console(Info)
2018/08/27 17:12:45 [I] XORM Log Mode: Console(Info)
2018/08/27 17:12:45 [I] Cache Service Enabled
2018/08/27 17:12:45 [I] Session Service Enabled
2018/08/27 17:12:45 [I] SQLite3 Supported
2018/08/27 17:12:45 [I] Run Mode: Development
2018/08/27 17:12:45 [I] Listen: http://0.0.0.0:8080

上記の最終行「Listen: http://〜:8080」の「8080」が HTTP のポート番号になります。Gitea インストール時のポートの空き状況によって番号は変わります。

サーバーを終了する場合は Control+c で終了させます。

ネットワーク・アクセスの許可確認画面

Gitea サーバーを起動して、ネットワークのアクセス権を聞いて来た場合は、忘れずに(間違えずに)「許可」を行います。「拒否」をしてしまうとブロックされ、他の端末からもアクセスできなくなります。

スクリーンショット 2018-08-27 17.12.52.png

Gitea の起動スクリプト(サンプル)

このインストール・スクリプトは環境変数やサービスの登録などは行いません。Gitea サーバーを終了させたり Mac を再起動した場合は、別途サーバーを起動する必要があります。

そこで、Gitea サーバー起動をバックグラウンドで行う起動スクリプトのサンプルを用意しました。

Gitea 起動スクリプトのサンプル
  • 最新のスクリプトはここ @ GitHub
start.sh
#!/bin/bash

NAME_BIN_GITEA='gitea'
CMD_RUN_BIN="${NAME_BIN_GITEA} web"
PID_GITEA=$(pgrep -fo "$CMD_RUN_BIN")
PATH_DIR_SCRIPT=$(cd $(dirname $0); pwd)

function getPathFileBin() {

    which $NAME_BIN_GITEA > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        echo $(which $NAME_BIN_GITEA)
        return 0
    fi

    ./$NAME_BIN_GITEA --version > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        echo ./$NAME_BIN_GITEA
        return 0
    fi

    $PATH_DIR_SCRIPT/$NAME_BIN_GITEA --version > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        echo $PATH_DIR_SCRIPT/$NAME_BIN_GITEA
        return 0
    fi

    echo 'No Gitea bin found.'
    exit $LINENO
}

function getPathFileLog() {
    PATH_FILE_BIN=$(getPathFileBin)
    PATH_DIR_BIN=$(dirname $PATH_FILE_BIN)
    echo $PATH_DIR_BIN/log/gitea.log
}

if [ -n "$PID_GITEA" ]; then
    echo "Gitea server is already running. (PID: ${PID_GITEA})" >&2
    PATH_FILE_LOG=$(getPathFileLog) && \
    cat $PATH_FILE_LOG | grep -o "Listen: [0-9htps:\/\.]*" | tail -1
    exit $?
fi

echo -n 'Starting Gitea server ... '

PATH_DIR_BIN=$(dirname $(getPathFileBin))
cd $PATH_DIR_BIN
nohup ./$CMD_RUN_BIN > /dev/null 2>&1 &

sleep 2

PID_GITEA=$(pgrep -fo "$CMD_RUN_BIN")
if [ -n "$PID_GITEA" ]; then
    echo 'OK'
    PATH_FILE_LOG=$(getPathFileLog) && \
    cat $PATH_FILE_LOG | grep -o "Listen: [0-9htps:\/\.]*" | tail -1
    exit $?
else
    echo 'Fail starting server'
    exit $LINENO
fi

動作例
$ # 起動
$ /path/to/start.sh
Starting Gitea server ... OK
Listen: http://0.0.0.0:8080
$ 
$ # 起動の確認
$ /path/to/start.sh
Gitea server is already running. (PID: 3405)
Listen: http://0.0.0.0:8080
$ 
$ # 終了
$ kill 3405

Gitea のセットアップ

サーバーが起動したら(まだ起動していない場合は ./gitea web で起動させてから)、ブラウザからサーバにアクセスします。この時、サーバーの IP アドレスもしくはホスト名に、サーバー起動時に確認したポート番号(上記参照)を添えます。

問題なくアクセスできると、初回アクセスの「Initial Configuration」のセットアップ画面になります。

  • ホスト名によるブラウザ・アクセス

    http://XXXXX.local:<ポート番号>/
    
    http://KEINOS-no-MacBookPro.local:8080/
    

    DHCP など、IP アドレスが固定されていない場合は、サーバーのターミナルから hostname コマンドを打つと「XXXXX.local」といったコンピューター名のついた Bonjour によるホスト名が取得できます。もしくは「システム環境設定」-「共有」から「編集」を押した時に表示される「ローカルホスト名」で確認できます。

    クライアント(利用者)が Windows の場合

    Windows からのアクセスの場合、Bonjour と互換がある、もしくは Bonjour がインストールされていないとホスト名の名前解決が出来ずアクセスできません。

    Windows 10 であれば Bonjour と互換があるのですが、OS が古い場合は Bonjour for Windows を別途インストールする必要があります。

    しかし、Skype・iTunes・Adobe Photoshop などがインストールされていると、Bonjour もインストールされていることが多いので、まずは試してみて NG だった場合には別途 Bonjour Print Services などをインストールします。

    未検証ですが、Bonjour のためにあれこれインストールするのがイヤな場合、iTunes のインストーラー7-ZipWinRAR で解凍すると中に Bonjour 単体のインストーラーがあるらしいです。[出典]

    Bonjour のインストールもイヤな場合は、hostsファイルに手を加える方法もありますが、 IP アドレスでのアクセスが一番楽です。


    • IPアドレスによるブラウザ・アクセス

      http://<IPアドレス>:<ポート番号>/
      
      http://192.168.1.103:8080/
      
    • Gitea サーバーと同じマシンからセットアップする場合

      http://localhost:<ポート番号>/
      

    セットアップ画面

    インストール・スクリプトからのインストールの場合は、「SQLite3」をベースに、必要な設定はほとんどできています。必要な設定は Site Title(サイト名)を変更する程度ですが、必要に合わせて適宜設定を変更します。

    なお、ページ下部の「Administator Account Settings」で管理者のユーザー登録を同時に行えますが、設定しなくても最初に登録したユーザーが自動的に管理者になります。

    Setup.png

    ページ下部の「Gitea をインストール」でサーバーの設定が完了します。

    Gitea のユーザー登録

    無事、サーバーの設定が完了すると「Sign In」のページに転送されます。セットアップ時に管理者アカウントを設定していない場合は、ユーザーを作成しないといけないので、右上の「登録」からユーザー登録します。(初回ユーザーは管理者として登録されます)

    サインイン画面(ログイン画面)

    サインイン   KEINOS Personal Git Server.png

    ユーザー登録画面

    Register   Gitea  Git with a cup of tea.png

    トップページ画面

    スクリーンショット 2018-08-21 17.41.19.png

    ダッシュボード

    サインイン(ログイン)すると、ユーザーのダッシュボードが表示されます。

    KEINOS   ダッシュボード   Gitea  Git with a cup of tea.png

    まずは、自分のアイコンをお気に入りのものに変更してみましょう。設定できる項目や内容は GitHub とほとんど同じなので馴染みやすいと感じると思います。(あと主要な部分は日本語化されているのも良いですね)

    リポジトリの作成

    これも GitHub とほとんど同じです。右上の「+」マークから「新しいリポジトリ」を選択し、必要事項を記入し「リポジトリを作成」します。

    スクリーンショット 2018-08-27 22.42.40.png

    新しいリポジトリ   Gitea  Git with a cup of tea.png

    上記リポジトリ名にスペースが含まれていますが、GitHub 同様スペースは使えないので「-」もしくは「_」を利用してください。

    リポジトリの画面

    作成されたリポジトリの画面も GitHub と似ているので使いやすい。

    KEINOS Sample_Repo  Sample Repo   Gitea  Git with a cup of tea.png

    リポジトリのクローン(Gitea サーバからローカルへ Clone)

    もぅ、まんま GitHub と同じです。

    Gitea_how-to-clone.png

    Gitea 本体のアップデート

    本記事の Gitea インストーラー for Mac はアップデートに対応していません。現在は本家のリリースページから最新のバイナリをダウンロードして手動で差し替える必要があります。(要同一バイナリ名)

    冒頭のインストール・コマンドを再度実行すると(バイナリがすでに存在する場合は)アップデートを行うよう改善する予定はあるのですが、本家でも実装を検討していることもあり、なにぶん、、、ねぇ。やる気が。「いいね」が 10 以上付いたら、本家より先行して対応します。

    2019/01/07 更新

    「いいね」を 10 以上いただいちゃったので、Gitea のアップデートに対応しました

    同じ階層にバイナリがすでに存在する場合は、インストール・コマンドを再度実行するとアップデートを行います。Gitea が終了した状態で実行してください。また、以前のバージョンは gitea.old とリネームされているので、不具合がある場合は差し戻してください。

    bash <(curl -s https://keinos.github.io/gitea_darwin/install.sh)
    
    アップデートの実行例
    $ pwd
    /Users/admin/gitea
    $ ls
    custom      data        gitea       log
    $ 
    $ # アップデートの実行
    $ bash <(curl -s https://keinos.github.io/gitea_darwin/install.sh)
    - Checking existing binary: binary found ... updating
    - Current version: 
        Gitea version 1.5.0 built with: bindata, sqlite
    - Fetching latest release: OK
    - Downloading files: 
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   622    0   622    0     0   1046      0 --:--:-- --:--:-- --:--:--  1047
    100 23.1M  100 23.1M    0     0  1006k      0  0:00:23  0:00:23 --:--:-- 1750k
    100   626    0   626    0     0   2144      0 --:--:-- --:--:-- --:--:--  611k
    100   833  100   833    0     0    966      0 --:--:-- --:--:-- --:--:--   966
    100   629    0   629    0     0   2713      0 --:--:-- --:--:-- --:--:--  2713
    100    99  100    99    0     0    225      0 --:--:-- --:--:-- --:--:-- 99000
    
    - Comparing checksum: gitea-1.6.3-darwin-10.6-amd64.xz: OK
    - Decompressing XZ archive: OK
    - Removing un-necessary files: OK
    - Renaming binary file: OK
    - Changing mode of the binary as executable: OK
    - Installed path: 
        /Users/admin/gitea
    - Installed version: 
        Gitea version 1.6.3 built with: bindata, sqlite
    Updating finished.
    

    Gitea のアンインストール

    アンインストールはサーバーを停止し、以下のディレクトリを削除します。

    • Gitea 本体をインストールしたディレクトリ
      • 本記事の例だと ~/gitea
    • セットアップ時に設定した「リポジトリのルートパス」(残しておいても可)
      • ~/gitea-repsitories
    giteaのアンインストール
    $ cd ~
    $ rm -rf gitea*
    

    バックアップ

    本記事の場合は DB を SQLite3 にしているため、リポジトリのデータ以外は全て ~/gitea ディレクトリに入っていますが、サーバーのコマンドで ZIP アーカイブも可能です。

    サーバーを止め、サーバーのディレクトリで以下の dump コマンドを叩くと ZIP にバックアップをアーカイブしてくれます。

    $ cd ~/gitea
    $ ./gitea dump -c conf/app.ini
    2018/08/27 23:06:43 Creating tmp work dir: /var/folders/rl/pyy3j9812xn899qc7qmk9jq00000gn/T/gitea-dump-967896417
    2018/08/27 23:06:43 Dumping local repositories.../Users/admin/gitea-repositories
    2018/08/27 23:06:43 Dumping database...
    2018/08/27 23:06:43 Packing dump files...
    2018/08/27 23:06:43 Packing data directory.../Users/admin/gitea/data
    2018/08/27 23:06:43 Removing tmp work dir: /var/folders/rl/pyy3j9812xn899qc7qmk9jq00000gn/T/gitea-dump-967896417
    2018/08/27 23:06:43 Finish dumping in file gitea-dump-1535378803.zip
    $ ls
    custom              gitea-dump-1535378803.zip
    data                log
    gitea
    

    便利なリファレンス

    Gitea のドキュメントは充実しているので、一度目を通しておくと良いと思います。

    所感

    Git サーバーを求めて

    バージョン管理(VCSの必要性は頭では理解しつつも理解を深める前に触るのがトラウマになっていました。

    というのも、以前の現場で CVSSubversion が使われていたのですが、古株エンジニアさんの間で構築された暗黙のプロトコルがあり、助っ人の新参エンジニアさんがコミットするたびに、舌打ちされては怒鳴られていたのを目の当たりにしていたからです。

    デスマーチの最中であったため、コミット・ルールをドキュメント化する時間も取れず、教える時間も取れず、「既存のコミットを見て学べ」というスタンスにせざるを得なかったのです。しかし新参の方々は助っ人で呼ばれているため、コミット結果を報告しないと派遣元の営業さんから(半分パフォーマンスも含めて)公然と怒られるという、板挟みに合っているようでした。

    私は別件で呼ばれていたので横目で見ていたのですが、私自身も別の自社案件のプロジェクトで CVS を入れたものの開発者が2人であったため「手間が増えただけ」と感じ、自然と使わなくなってしまいました。そんな過去があっただけに、「バージョン管理なんて、ガントチャートみたく、マネージャーさんがクライアントに 『やってまっせ』と見せるためのツールなんだな」と感じていました。

    しかし、あれから数年が経ち、Qiita や Qiitadon を通して Git や GitHub の魅力を知り、個人で触ったり OSS に触れていくうちに Git Git な味に魅了されてしまいました。コミット増し増し、バグだくです。

    いまでこそ Git コマンドを叩いたりすることはありますが、当初は、仕組みがよくわからず、ミスが怖い(どう迷惑がかかるかわからない)ということもあったので、GitHub の「はじめての Git」に習い、純正の「GitHub Desktop」を使って、Qiita 記事の写経として(他人とコラボを前提としない)自分専用のリポジトリから始めました。

    Git を使うことのメリット

    せっかちな性格なので Git を使うことで作業効率や作業速度が速くなったとは感じません。むしろ手間が増えたと感じます。読まれもしないとわかっている業務日報を書くツラさがあります。

    GitHub でコラボするなら必要と思い、ある意味イヤイヤ使い続けていました。ところが1年くらい使ったあたりでメリットの方が大きいことを実感してきました。

    長い目で見たときに過去の自分をフォローすることができるようになったのです。

    写経がてら小さなプロジェクトに触れていると、忘れることも多くあります。そんな中、コミット履歴をざっと見れば当時を追体験できる、つまりバグの発生した時期や実装の経緯を思い出すのに役に立つからです。また、「あの時に泣く泣く削除したコード」を掘り起こして復活できたりもします。

    Git を使うメリットがコラボレーションであるならば、Git の最初のコラボレーション相手は過去を忘れた未来の自分なのだと思います。

    Git が馴染まない環境とは

    個人的な結論から言うと、下記に集約されてしまうと思います。

    保険や定期検診に頼らないでも大丈夫、先にやるべきことがあるから、と無理をしている人や環境は Git が馴染まない。

    Git はブロックチェーンと似た構造を持っています。

    そのためか、どちらも「速度や効率を主眼とした技術ではない」のと、過去の情報を担保するための「保険的な技術である」と感じました。(私がセッカチであるのもありますが)

    私自身もそうだったのですが、「病院は体を壊してから行くもの」といった感じの、定期検診やカウンセリングといった「リスクに対する意識」が低い環境や認識の間は、Git を使い始めた時は「時間や手間といったコストのロス感」がとても強く出ます。

    おそらく Git (や VCS 全般)が馴染まない方は UnitTest にも馴染めないのかもしれません。Git を保険だとすると、UnitTest は予防だからです。つまり、これらは「わかっちゃいるけど」系なんです。

    先述のように、プライベートでオープンソースのコラボ(楽しそうなこと)に参加したいがために、嫌々 Git 使って1年後に本当の良さに気づいたというのも、体調を崩し仕事を辞めてから保険のありがたみと普段からのリスクヘッジの意識の低さを実感したのと似ています。

    バージョン管理や UnitTest の必要性は感じてはいるものの、どちらにも馴染めない方は、上記のような習慣が体に残っているのかもしれません。お互い気をつけましょう。

    オー、マイ Git!

    このような経緯があり、以来、

    1. コードをいじる
    2. GitHub Desktop でコミットする
    3. 区切りがついたら GitHub Desktop で GitHub にプッシュする

    のループを繰り返すうちに、コードをいじる時はコミットメッセージに残せる範囲になり、あれこれと一気にいじらなくなりました。

    しかし、GitHub を使い続けていると、やはり自分専用の Git サーバーが欲しくなると言うもの。

    Git サーバーと言えば、日本人が作っているのに英語のみという、媚びない姿勢の Git 界のサウザー「GitBucket」、ガンダムファンならピックっとくるカッコいい名前の「Gogs」や、新しい Firefox のロゴと間違えそうな「GitLab」など、色々な Git サーバーがあります

    しかし、大半の Git サーバーは別途 DB サーバーを必要としていたり、わかっている人には簡単とは言えども、機能的にも Git Git で高カロリー過ぎて、ちょっとお試しに、という感じではありませんでした。

    Gitea に決めた理由

    個人利用であるため同時アクセスの心配をしなくてもいいことから、SQLite3 を使えるものを検討した結果 Gogs と Gitea が候補に上がったのですが、どちらもファイルを設置するだけで動くという点が大きかったです。

    Gogs と Gitea は親戚(Gitea が Gogs から分岐した)らしいので、本家の Gogs を検討していたのですが、何かしっくり来ていなかったところ、Qiitadon のユーザーから「Gitea いいよ」と聞いたので Gitea に決めました。

    触ってみて感じたのが、GitHub に慣れた人に優しいということ。逆に言えば、Gitea に慣れれば GitHub にも慣れるということでもあります。そして、日本語であることです。

    Git 信者を増やすためには、小難しいコマンドから覚えてもらうのではなく、結果をコミットする習慣が先だと考えています。

    初心者や非ソフトウェア・エンジニアのかたにコミットする習慣を付けてもらうには、GitHub Desktop + Gitea の組み合わせは打って付けではないか、と感じました。惜しむらくは GitHub Desktop が標準で日本語化されていないことです。

30
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
KEINOS
A Japanese made in Mexico with Mexican quality ;-) Who monkey around the jungle of codes. 記事の日本語がおかしかったら遠慮なく編集リクください。また、記事に「LGTM」が付くたび、やる気に比例して見直して何かしら加筆・修正してブラッシュアップしています。基本的に変更通知はお送りしません。
qiitadon
Qiitadon(β)から生まれた Qiita ユーザー・コミュニティです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
30
Help us understand the problem. What is going on with this article?