しふみんのブログ

しふみんのブログです。

DockerとCircleCIを使ってRailsアプリの自動テスト&自動Herokuへのデプロイ環境を作った

はじめに

はい、標題の通りですが、DockerとCircleCIを使ってRailsアプリの自動テスト&自動Herokuへのデプロイ環境のテンプレートを作成しました。

どういうものか

Heroku用のDockerizedされたRailsアプリのテンプレートです。
docker-compse up して rails new してアプリを書いた後に、GitHubにpushすると自動テスト(RSpec)が実行されて、テストがすべて通るとHerokuへと自動デプロイされます。

  • ローカル環境
  • テスト実行
    • GitHubにpushするとCircleCIを通じてローカルと同じ構成のテスト環境でRSpecが実行される
  • デプロイ実行
    • GitHubにpushして上記のテストが全て通るとCircleCIを通じてHerokuへとデプロイされる
  • Heroku
    • ローカルと同じ構成の環境がデプロイされる

なぜ作ったか

ギョームだと、ローカルはVagrantでProductionやStagingはAWSであることが多いのですが、個人開発でいちいちVagrantに環境を整えるは面倒だし本番も雑にHerokuでいいやと思ったので、Docker+HerokuのRailsアプリのテンプレートを作成しました。加えて、楽したいからGitHubにpushしたら自動テストと自動デプロイが走るようにCircleCIの設定を整えました。

作成物

作成物は下記になります。

github.com

続けて、DockerとCirclrCIの設定を見ていきます。

Dockerfile

FROM ruby:2.5.1
ENV LANG C.UTF-8

RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       apt-transport-https \
                       libpq-dev \
                       postgresql-client \
                       --no-install-recommends

# node
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \
    && apt-get install -y nodejs

# yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" \
    | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update && apt-get install -y yarn

RUN mkdir /rails_app
WORKDIR /rails_app

COPY Gemfile /rails_app/Gemfile
COPY Gemfile.lock /rails_app/Gemfile.lock
COPY yarn.lock /rails_app/yarn.lock

RUN bundle install --jobs=4 --no-cache
COPY . /rails_app

EXPOSE 3000
RUN RAILS_ENV=production rails assets:precompile
CMD ["rails", "s", "-b", "0.0.0.0"]

Rails用のよく見る形のDockerfileだと思います。
必要なパッケージをインストールして、bundle installして、そして最後にアプリ全体をコピーしています。
rails s する直前で assets:precompile を実行しています。

docker-compose.yml

version: '3'
services:
  web:
    build:
      context: .
    tty: true
    stdin_open: true
    ports:
      - '3000:3000'
    volumes:
      - .:/rails_app
    depends_on:
      - db
  db:
    image: postgres:10.3
    ports:
      - '5432:5432'
    volumes:
      - postgresql-data:/var/lib/postgresql/data
volumes:
  postgresql-data:
    driver: local

こちらもよく見るRails+PostgreSQLの構成のdocker-compose.ymlだと思います。
特記すべき点は、2点あって、
1点目が、Dockerコンテナ内でも binding.pryデバッグ可能にするために下記の設定を追加している点です。

  web:
    tty: true
    stdin_open: true

binding.pry を埋め込んで、 docker-compose run --rm --service-ports web で起動すると他環境と同様にデバッグすることができます。

2点目が、DBのデータを永続化するために下記の設定を追加している点です。

  db:
    volumes:
      - postgresql-data:/var/lib/postgresql/data
volumes:
  postgresql-data:
    driver: local

この設定を追加することによって、DBの中身をローカルに永続化でき docker-compose up を止めてもDBの中身が消えません。

CircleCI2.0

.circleci/config.yml

version: 2
jobs:
  test:
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      - run:
          name: docker-compose build
          command: docker-compose build
      - run:
          name: docker-compose up
          command: docker-compose up -d
      - run:
          name: sleep for waiting launch db
          command: sleep 1
      - run:
          name: rails db:create and db:migrate
          command: docker-compose run web rails db:create db:migrate
      - run:
          name: rspec
          command: docker-compose run web rspec
      - run:
          name: docker-compose down
          command: docker-compose down

  deploy:
    working_directory: ~/deploy
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      - run:
          name: Build docker image
          command: docker build --rm=false -t registry.heroku.com/${HEROKU_APP_NAME}/web .
      - run:
          name: Setup Heroku command
          command: bash .circleci/setup_heroku.sh
      - run:
          name: Execute Heroku maintenance on
          command: heroku maintenance:on --app ${HEROKU_APP_NAME}
      - run:
          name: Push container to registry.heroku.com
          command: |
            docker login --username=_ --password=$HEROKU_AUTH_TOKEN registry.heroku.com
            docker push registry.heroku.com/${HEROKU_APP_NAME}/web
      - run:
          name: Execute Heroku db migrate
          command: heroku run rails db:migrate --app ${HEROKU_APP_NAME}
      - run:
          name: Execut Heroku maintenance off
          command: heroku maintenance:off --app ${HEROKU_APP_NAME}

workflows:
  version: 2
  test-deploy:
    jobs:
      - test
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: master

特記すべき点は、 test job, deploy job共に下記のように machine imageに ciecleci/classic:edge を指定していること。

  test:
    machine:
      image: circleci/classic:edge

このように設定することにより、最新のdocker-compseがインストール済みの仮想マシンを使うことができます(楽)

参考

circleci.com

.circleci/setup_heroku.sh

#!/bin/bash
wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz
sudo mkdir -p /usr/local/lib /usr/local/bin
sudo tar -xvzf heroku-linux-amd64.tar.gz -C /usr/local/lib
sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku

cat > ~/.netrc << EOF
machine api.heroku.com
  login $HEROKU_LOGIN
  password $HEROKU_API_KEY
EOF

# Add heroku.com to the list of known hosts
ssh-keyscan -H heroku.com >> ~/.ssh/known_hosts

CiecleCIのworkflowの deploy jobで実行している setup_heroku.sh は下記のリポジトリスクリプトを参考(ほぼそのまま)にさせていただきましたm( )m
内容としては、herokuコマンドを使えるようにして、herokuのログイン設定を設定ファイルに追記して、SSHのknown_hostsを更新しています。

参考

github.com

まとめ

HerokuのRailsアプリ開発環境をDockerとCircleCIを使って作成しました。 Dockerを使うことによって、Rubyのインストールすらせずに素早くローカル開発環境を用意できるだけでなく、開発環境、テスト環境、本番環境で同じDockerイメージを使いまわせて環境の違いによる謎のバグに悩ませることなくRailsアプリの開発を行うことができます。便利ですね。
気が向いたら、このテンプレートを利用して具体的にHerokuでRailsアプリを動かすところを解説する記事を書きたいと思います。

参考

library/postgres - Docker Hub
https://hub.docker.com/_/postgres/

Heroku Container Registryで作るDocker時代のRails 5 入門 - Qiita
https://qiita.com/koduki/items/3aafc38c6c518bef2af3

docker-composeでRailsを開発しCircleCI 2.0でテストしてHerokuにdeployする - Qiita
https://qiita.com/Kesin11/items/47079bc7f659e71b694c

Choosing an Executor Type - CircleCI
https://circleci.com/docs/2.0/executor-types/

Kesin11/docker_rails_sample: Dockernized rails with CircleCI and Heroku
https://github.com/Kesin11/docker_rails_sample

Macbookのなるべくホームポジションを維持するキーバインドについて考える

前置き

最近ずっとMacbookキーバインドについて考えていて、現時点での自分なりの回答を用意できたのでまとめてみたいと思います。 前提として、自分は、US配列キーボード、OSがSierraMacbook ProでiTerm2, tmux, Zsh, Vimあたりを使っているウエブケーエンジニアです(iTerm2, tmuxは特に考慮すべきキーバインドの競合がなかったけど)

各種アプリのインストール方法、設定方法等はインターネッツをご参照ください。

環境

MacBook Pro 13-inch, 2016, US配列キーボード
MacOS Sierra 10.12.5
iTerm2 3.0.15
tmux 2.5
Vim 8.0
Karabiner-Elements 0.91.8
英かな 2.2.3

やりたかったこと

なるべく指をホームポジションに維持したまま生きていきたかった。具体的には各種矢印, Esc, Delete, returnキーあたりのホームポジションから離れているキー(の機能)を複合キーにしてもいいからホームポジション近くに位置させたかった。

設定したキーバインド

下記が今回設定したキーバインド

USキーボードなので大前提として設定したキーバインド

左コマンドキー単体で押下 -> 英数キー
右コマンドキー単体で押下 -> かなキー
コロン -> セミコロン
セミコロン -> コロン
Caps Lockを他のキーと一緒に押下 -> Controlキーとして扱う

やりたかったキーバインド

Caps LockをContorlに変えたので下記のControlはaキーの横にあるCaps Lockを押す想定。

Control + H -> (fn)←(矢印の左)
Control + J -> (fn)↓
Control + H -> (fn)↑
Control + L -> (fn)→
Control + M -> enter
Control + , -> delete # Windowsでいうところのbackspace
Control + . -> fowarded_delete # 同上 delete

Caps Lock単体で押下 -> Escapeキー

その他(ついでに追加した設定)

Shiftキー + deleteキー -> forward delete)

必要なアプリとその設定

上記のキーバインド設定のために使用するアプリはKarabiner-Elements英かなの2つ。 それ以外はシステム環境設定も含めて特に設定はしていません。 それぞれのアプリの設定は下記の通り。

Karabiner-Elements

設定は画像の通りです。

f:id:shifumin:20170720224929p:plain

英かな

設定は画像の通りです。

f:id:shifumin:20170720224936p:plain

競合するキーバインド

上記のキーバインドを設定することによる潰れる(私の使用している)各ツールのキーバインドは下記の通り。

Zsh

$ bindkey -L
(抜粋)
bindkey "^H" backward-char
bindkey "^J" history-substring-search-down
bindkey "^K" history-substring-search-up
bindkey "^L" forward-char
bindkey "^M" accept-line
bindkey "^[," _history-complete-newer

使用コマンドのsearchはpecoに任せているので問題なし。

Vim

$ vim
:help index.txt
(抜粋)
1. Insert mode
CTRL-H          same as <BS>
CTRL-J          same as <CR>
CTRL-K {char1} {char2}
                enter digraph
CTRL-L          when 'insertmode' set: Leave Insert mode
CTRL-M          same as <CR>

2. Normal mode
CTRL-H          1  same as "h"
CTRL-J          1  same as "j"
CTRL-K             not used
CTRL-L             redraw screen
CTRL-M          1  same as <CR>

3. Visual mode
CTRL-H          2  same as <BS>

4. Command-line editing
CTRL-H          same as <BS>
CTRL-J          same as <CR>
CTRL-K {char1} {char2}
                enter digraph
CTRL-L          do completion on the pattern in front of the
                cursor and insert the longest common part
CTRL-M          same as <CR>

特に問題ないように思える。

Neosnippet

Vim本体は問題なかったが、プラグインでNeosnippet(neocomplete)を利用しており 公式のキーバインド設定をそのまま流用しているので、下記の設定の移行先を考える必要がある。

imap <C-k>     <Plug>(neosnippet_expand_or_jump)
smap <C-k>     <Plug>(neosnippet_expand_or_jump)
xmap <C-k>     <Plug>(neosnippet_expand_target)

候補としては<C-s>あたりが有力かなと考えている。

その他

MacOS標準IME

標準IMEの下記キーバインドが潰れる。 これは結構痛いかも、、、

Control + J -> ひらがなに変換
Control + K -> カタカナに変換
Control + L -> 全角英字に変換
Control + ; -> 英字に変換

雑感箇条書き

  • 当初は英かなを使わずにKarabiner-Elementsのみで設定しようとしてcomplex_modificationsを自作すれば設定自体はできたが、Controlを押したままm/,を押してもenter/deleteが連続で押されないのを解消できなかったのでKarabiner-Elementsと英かなを併用している
  • Google Chromeのアドレスバーに単語を入れてのウェブ検索だけ、標準のreturnとCtrl + m で設定したreturnの挙動が異なっていて困っている。
    • 具体的には後者の場合、例えば"ほげ"と入力してキーを押すと「"ほげ"で検索」されずに「http://www.ほげ.com/」にジャンプしようとする
  • Ctrl + m / , / . に設定した return / delete / forward に慣れないのでしばらく指を鳴らす必要がありそう


以上です。

参考

tekezo/Karabiner-Elements: The next generation Karabiner for macOS Sierra
https://github.com/tekezo/Karabiner-Elements

Karabiner-Elements complex_modifications rules
https://pqrs.org/osx/karabiner/complex_modifications/

⌘英かな
https://ei-kana.appspot.com/

Shougo/neosnippet.vim: neo-snippet plugin contains neocomplcache snippets source
https://github.com/Shougo/neosnippet.vim

Twilogをスクレイピングしてツイートを取得して表示するRailsのWebアプリを作った

作ったもの

ツイスク

http://shifumin.com/twisc

f:id:shifumin:20151124223358p:plain f:id:shifumin:20151124223403p:plain

ツイスク(Twilog Scraping)Twilog( http://twilog.org/ ) に登録されてある指定したTwitterIDの指定した日付のツイートをまとめて取得して表示するRailsのWebアプリです。 なんと、TwilogスクレイピングするためTwilogに登録されていないアカウントには使えません!

用途として、例えば、フォロワーのあの人は今年のエイプリルフールに一体どんなクソツイートをしたんだろうと思って知りたい時にTwitterIDと2015年4月1日を入力して使うみたいなのを想定しています(想定していない)

構成

さくらVPS1Gプラン, CentOS6.7, Apache2.2.15, Passenger5.0.21, Ruby2.2.3, Ruby on Rails4.2.3

スクレイピングに使ったgemはNokogiriです。

コードは、Githubに上げています(inital commitってタイポしていて恥ずかしい……)

github.com

作った背景

構成については、RubyRailsを勉強していて、何かアプリを1つ作ったら学びがありそうだなと考えて、VPSを借りているからそこで公開したらついでに必然的にWebサーバの勉強にもなるなと思ったのでこういう構成になりました。

機能については、自分大好きな人間なので過去の自分のツイートをつぶやくBotを作成しようとして、ツイートをスクレイピングして取得するスクリプト自体は書いていたので、それを少し改良してあるTwitterIDのある日付のツイートを取得するようにしました。

四方山話

  • 当初は、 ある月 のツイートを取得して表示する実装にしていたのですが、1日から30日(31日)のページまで30回(31回)Nokogiriでスクレイピングする方法しか思い浮かばなくて、流石に短時間に30回連続でTwilogのサーバに負荷をかけるのはまずいんじゃないかと思って、 ある日 のツイートを取得するように変更しました。

  • 当初は、WebサーバはUnicorn + nginxという構成にしようとしたけど、とりあえず形になったらいいかと思ってApache + Passengerを採用しました。Unicorn + nginxは速くて軽いと聞くので機を見てリプレースしたいと思います。

  • CSSというかデザインが全く分からなかったし、現時点ではあまり時間をかけたくなかったので、RailsチュートリアルのBootstrapのスタイルシートを丸パク……参考にしました。CSSもBootstrapも全然分からないけど、せめて年と月と日の入力フォームを横に表示させたい……

今後

超絶簡単なRailsアプリをWeb上に公開するまでの知見は得られたので、これからも何かを作っていきたいですね。

Yahoo!ファイナンススクレイピングして一番連続した日数値下がりしている株を見つけて「〇〇は△日連続で値下がりしているので明日は上がる!買えば捗るぞ!!(自己責任)」みたいに雑な投資推奨情報を提供するアプリとか(今適当に思いついた)

Rubyプロジェクトの始め方の備忘録

Rubyプロジェクトの始め方の備忘録

自分の記憶力が薄弱すぎて、Rubyで何か書くかとなった時にいつも下準備の仕方を調べている気がするので、後で楽するために備忘録を残しておきたいと思います。

余談ですが、自分の記憶力が薄弱すぎて(大事なことなので2回繰り返した)「自分のために残すメモ的な意味の熟語なんだっけ?忘備録だったっけ?」って思ってググったら、「備忘録」(忘れるのに備える記録で備忘録)が正しくて、よく見る「忘備録」は誤記で「備えるのを忘れた記録になる」という意味になってしまうようです。 勉強になりました。

前提となる環境

  • Mac OS X
  • giboをインストール済
  • ruby-build,rbenvをインストール済

準備

ディレクトリを作ってgit initしてからgiboで.gitignoreをお手軽に作成する。giboは、RubyOSXVimを引数に指定する(OSXVimはなくてもいいかも)

$ mkdir rubyproject
$ cd rubyproject
$ git init
$ touch .gitignore
$ gibo Ruby OSX Vim >> .gitignore

simonwhitaker/gibo · GitHub https://github.com/simonwhitaker/gibo

Rubyの設定

使用するRubyの設定をする。 rbenvでその時点での最新版のRubyを入れる。

$ rbenv install -l
$ rbenv install x.x.x(インストールするRubyのバージョン)
$ rbenv local x.x.x
$ rbenv rehash

sstephenson/rbenv · GitHub https://github.com/sstephenson/rbenv

Bundlerの設定

基本的にプロジェクトで使用するBundlerでgemはローカルディレクトリに保存するけど、Bundlerとrubocopはシステムワイドにインストールしているので、その2つを最新版にする。 その後使用するgemをローカルにインストールする。

$ gem update --system
$ gem update bundler
$ gem update rubocop
$ bundle init
$ vim Gemfile
(使うgemを記述する)
$ bundle install --path vendor/bundle

Bundler: The best way to manage a Ruby application's gems http://bundler.io/

Gemfile

プロジェクトで使用するgem以外のデバッグ等に使用するgemは以下を使っている。

source "https://rubygems.org"

ruby 'x.x.x'(インストールしたRUbyのバージョン)

group :development do
  gem 'awesome_print'
  gem 'tapp'
  gem 'pry'
  gem 'pry-doc'
  gem 'pry-byebug'
  gem 'pry-stack_explorer'
  gem 'refe2'
end
  • awesome_print

デバッグ時等にオブジェクトのデータ構造を分かりやすく表示してくれる。 .pryrcに下記のように書いてpry起動時に自動的にrequireするようにしている。

# awesome_print
begin
  require "awesome_print"
  AwesomePrint.pry!
rescue LoadError => e
  puts "no awesome_print"

michaeldv/awesome_print · GitHub https://github.com/michaeldv/awesome_print

  • tapp

メソッドチェーンの途中に挟むと、pp(puts)しながらレシーバを返すObject#tappやObject#taputsが使えるようになる。 プリントデバッグが捗る。

esminc/tapp · GitHub https://github.com/esminc/tapp

  • pry

強いirb

pry/pry · GitHub https://github.com/pry/pry

  • pry-doc

show-source でCで書かれているRuby組み込みのクラスやメソッドのソースを見ることができる。

pry/pry-doc · GitHub https://github.com/pry/pry-doc

  • pry-byebug

binding.pryデバッグする時にピンポイントで処理を止めてステップ実行できる。

deivid-rodriguez/pry-byebug · GitHub https://github.com/deivid-rodriguez/pry-byebug

  • pry-stack_explorer

デバッグ時に show-stack でその時のスタックの情報が見られる。

pry/pry-stack_explorer · GitHub https://github.com/pry/pry-stack_explorer

  • refe2

refeコマンドラインからRubyリファレンスマニュアルを見ることができる。

refe2 | RubyGems.org | your community gem host https://rubygems.org/gems/refe2/versions/0.9.0

終わりに

Ruby初心者なので、Rubyで小規模な開発を行う時に便利なgemが他にあったら教えてほしいです。

vagrant up した時に共有フォルダのマウントでエラーが出る問題

問題

大分前から vagrant up した時に共有フォルダのマウントに時間がかかり下記のエラーが出ていた。

$ vagrant up
(中略)
==> web: Mounting shared folders...
    web: /vagrant => /Users/hoge/path/to/dir/project
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

エラーメッセージを雑に読むと、ゲストとホストで共有フォルダのマウントが上手くいってないようだ。

しかし、その後に普通に vagrant sshしたら接続はできるのでずっと放置していた。 放置していたが、さすがにそろそろ解決しようと思って色々と調べて解決した。

自分の環境

解決方法

まずはvagrantに接続しvboxのリビルドを試す。 以下はvagrant内でのコマンド操作。

$ sudo /etc/init.d/vboxadd setup
Removing existing VirtualBox non-DKMS kernel modules       [  OK  ]
Building the VirtualBox Guest Additions kernel modules
The headers for the current running kernel were not found. If the following
module compilation fails then this could be the reason.
The missing package can be probably installed with
yum install kernel-devel-2.6.32-504.el6.x86_64

Building the main Guest Additions module                   [失敗]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions              [  OK  ]

Guest Additions の構築に失敗する。 メッセージ通り、 kernel-devel-2.6.32-504.el6.x86_64yum install してみる。

$ sudo yum install kernel-devel-2.6.32-504.el6.x86_64
読み込んだプラグイン:fastestmirror
インストール処理の設定をしています
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * epel: ftp.kddilabs.jp
 * extras: www.ftp.ne.jp
 * remi-safe: remi.kazukioishi.net
 * updates: www.ftp.ne.jp
パッケージ kernel-devel.2.6 は利用できません。
エラー: 何もしません

そんなものは存在しない!

仕方がないので、 kernel-devel-2.6.32-504.el6.x86_64 をキーワードにググり、web上のrpmパッケージを拾ってきてインストールする。

ググったらヒットした RPM Scientific Linux 6 kernel-devel 2.6.32 x86_64 rpm の中から適当なリンクのrpmパッケージをインストールする。

$ sudo yum install ftp://mirror.switch.ch/pool/4/mirror/scientificlinux/6.6/x86_64/os/Packages/kernel-devel-2.6.32-504.el6.x86_64.rpm

インストール後にもう一度vboxのリビルドを行う。

$ sudo /etc/init.d/vboxadd setup
Removing existing VirtualBox non-DKMS kernel modules       [  OK  ]
Building the VirtualBox Guest Additions kernel modules
Building the main Guest Additions module                   [  OK  ]
Building the shared folder support module                  [  OK  ]
Building the OpenGL support module                         [  OK  ]
Doing non-kernel setup of the Guest Additions              [  OK  ]
Starting the VirtualBox Guest Additions                    [  OK  ]

今度は成功した。

その後、ホストに戻り、vagrant halt & vagrant up してもエラーが出ずにすぐに環境構築できるようになって解決した(Building the VirtualBox Guest Additions kernel modules にOKが出ていないのが気になるけど)。

Vimのカラースキームを設定できない問題

問題

VimのカラースキームをSolarizedに設定しようとして、.vimrcに以下のように書いて

NeoBundle 'altercation/vim-colors-solarized'
syntax enable
set background=dark
colorscheme solarized

何かファイルを開こうとすると、以下の Cannot find color scheme のエラーが出てカラースキームが設定されない。

$ vim .vimrc
Error detected while processing /Users/user/.vimrc:
line  100:
E185: Cannot find color scheme 'solarized'
Press ENTER or type command to continue

解決方法

Cannot find color scheme solarized · Issue #104 · altercation/vim-colors-solarized

によると、 colorscheme solarizedcall vundle#end() の後に書けとのこと。

というわけで、.vimrcを

·
·
·
NeoBundle 'altercation/vim-colors-solarized'
·
·
·
call neobundle#end()
·
·
·
syntax enable
set background=dark
colorscheme solarized

と書くようにしたら、エラーを解消してカラースキームの設定をすることができた。

ファイルの文字列をソートし直しててファイルに出力するRubyスクリプト

コマンドライン引数に指定されたファイルに書かれてある文字列をソートし直して1行ずつ新たなファイルに出力するRubyスクリプトを書いた。

ファイルの文字列をソートし直しててファイルに出力するRubyスクリプト

# -*- coding: utf-8 -*-

input_file = ARGV[0]
added_filename = '_in_line'

# 入力ファイルネームが'hoge.txt'なら出力ファイルネームは'hoge_in_line.txt'とする
output_file = File.basename(input_file, '.*') + added_filename + File.extname(input_file)

File.open input_file do |i_file|
  File.open output_file, 'w' do |o_file|
    o_file.puts i_file.read.split(/\s+/).sort
  end
end

こんなファイルを

aaa ddd
eee     ggg
       fff
    ccc hhh iii

bbb

以下のように出力し直す。

aaa
bbb
ccc
ddd
eee
fff
ggg
hhh
iii

動機として、 $ brew list で出力されたものを1行ずつ改行した形でファイルに出力したものが欲しかったので書いた。 ただ、すぐに $ brew list > hoge.txt とリダイレクトを使えば望むものが手に入ることが分かったので、今後は使うことはないと思う。