Theories of Pleiades

技術の話とかイベントに行った話とか思ったこととか

rails newするときやってることを自動化した

前書き

インターン全落ち芸人になりました


rails newしたらうまく動かない

最近はRailsをやっています。 Railsで新しいプロジェクトを作るとき、rails newをしますよね?ぼくはします。


ところがなんかrails newをしてrails generateとかすると

rails generate model hoges hoge:string
(中略)
/home/hsm-hx/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.3/lib/bundler/spec_set.rb:91:in `block in materialize': Could not find bindex-0.5.0 in any of the sources (Bundler::GemNotFound)

とか言われちゃうので困っていました。


解決策としては以下のリンクの通りごちゃごちゃやるといい感じになっていたのですが、覚えられないしめんどくさい。

www.qoosky.io

面倒なことはpythonにやらせたいので、やらせました。

面倒なことをpythonにやらせる

やりたいこと→rails-new hogeってすると上のリンクの操作をやってくれるやつをつくる

具体的には、
1. bundle initをする
2. Gemfileでrailsを落としてくる
3. bundle exec rails newする
4. 不要なファイルを消す
5. bundle installする
です。pythonからシェル操作さえできればこっちのもんなので楽勝。


まず、引数としてアプリケーションの名前を受け取るところからやります。

難しいことはしたくなかったのでとりあえずオプションとかは考えません。プロに殺されそうですが…

pythonCLIから引数を受け取るにはsysモジュールを使います。

import sys
argv = sys.argv #引数のリストを受け取る

このときのsys.argvには実行するファイル名も含まれるので、 第一引数→sys.argv[1]、第二引数→sys.argv[2]、…となる。



引数としてアプリケーション名以外は考えたくないので、

if not len(argv) == 2:
  print("error: invalid arguments")

としておきました。



さて、ここから本筋を作っていきます。 まずはpythonからbundle initをやります。

シェルコマンドを実行するには、subprocessモジュール内のcall関数を使います。
subprocess.call("bundle init", shell=True)で動きます。



ここまでは準備運動!
で、このあとGemfileの中身を書き換えるのにどうしようか迷ったのですが、Gemfileを予め用意しておいて上書きコピーするのが楽そうだったのでそうしました。


はじめはスクリプトの中に文字列でGemfileの中身を用意しておいてechoで…って思ってたんですが改行とかめんどくさいことになりそうだったので。まあすぐ消すわけだし改行なんかなくても良いと言えばそうですが。


適当に$RAILSNEWみたいな感じでPATHを作ってgemfileの位置を指定し、cpコマンドで書き換えます。

.zshrc

export RAILSNEW = /path/to/scriptDirectory

script.py

subprocess.call("cp $RAILSNEW/gemfile Gemfile", shell=True)

どうでもいいですがPATHの記法雰囲気でしか理解してなかったのでこれを気にちゃんと理解しました。




このあとのbundle installとか要らないファイルを消すなどはそのまま実装すればできます。簡単。

躓いたのがsubprocess.callからcdコマンドを実行しても作業ディレクトリは変わってくれないっていうところでした。

これについてはosモジュールのchdir関数を使えばすぐです。 絶対パスでも相対パスでも指定ができますが第一引数と同じ名前のディレクトリに行きたいだけなのでos.chdir(argv[1])で終わりです。



最後にbundle install --path vendor/bundleをして終わり!



これでスクリプトを実行すれば面倒なことは全部pythonがやってくれるようになりました。
最後に適当なところにスクリプトとgemfileのテンプレートを動かしてaliasでrails-newみたいな雑な名前をつけてあげました。




とりあえず完成!やったー!

後書き

まあ根本的な解決にはなってないのでそのうちどうすればいいのかとか探したいと思います。

書いてから思ったけどこれ備忘録にする必要すらなくない? 日記ってことで許してください。