風柳メモ

ソフトウェア・プログラミング関連の覚書が中心。

IRC用ダイスボット「ボーンズ&カーズ」(BCDice)のtestをLinux(CentOS 6.5)上で動作させるための覚書

先日、IRC用ダイスボット「ボーンズ&カーズ」のコマンドが使用できるTwitter用botを作成した。

IRC用ダイスボット「ボーンズ&カーズ」のTwitter版を試作: 風柳亭

これは、Diceだよ!TwitterのStreaming APIを試用するための習作bot)を流用して作ったこともあり、基本Pythonで動作している。
ダイスロールは、Pythonの子プロセスとしてRubyスクリプト(cgiDiceBot.rb)を呼び出し、返ってきた結果(標準出力)を加工してツイートしているため、実はBCDiceのソースコードには全く触っていなかった。


ただ、しばらく運用しているうちに、いくつか問題が判明したため、最小限のパッチを当てる必要が出てきた。

問題点

No. 問題点 原因 対策
1 cgiDiceBot.rb実行時、 extratablesが反映されない src下にextratablesが必要*1 src下にextratablesへのシンボリックリンク作成
2 diceBot下に非公式ボットを置いた際、cgiDiceBot.rb実行時、 DiceBotLoader#loadUnknownGameで読み込まれない src下にsrc_bcdice/diceBotが必要*2 src下にsrc_bcdiceディレクトリ作成&src_bcdice下にdiceBotへのシンボリックリンク作成
3 src/test.rbでエラー発生 ruby.exeをコールしている /usr/bin/rubyへのシンボリックリンク(/usr/bin/ruby.exe)作成
4 src/test/test.rbでテストが一つも実行されない testData.txtをパースする際、\rが残ってしまっている(\r\nではなく\nで分割しているため) testData.txt読み込み時、\r\nを\nに置換
5 src/test/test.rbで標準のテストが一部失敗する test.rbが../../src_diceを基準にしている*3 ../../に、srcへのシンボリックリンク(src_bcdice)作成
6 src/test/test.rbのエラー出力が文字化けする 結果がShift-JISで出力されている UTF-8出力に変更(Windows環境下とで場合わけ)


なお、これらの問題点は、

ということが発生要因ではないかと思われる。

パッチ

BCDiceを展開したディレクトリ(BCDice-master等、srcの一つ上)に以下の patch.sh 及び test.diff を置き、patch.sh を実行。
BCDice Ver2.02.15 2014/04/29 で動作確認。

patch.sh
#! /bin/bash
CURDIR=`pwd`
if [ ! -e /usr/bin/ruby.exe ] && [ -e /usr/bin/ruby ]; then
  sudo ln -sf /usr/bin/ruby /usr/bin/ruby.exe
fi
if [ -d ./src ]; then
  if [ ! -e ./src_bcdice ]; then
    ln -sf ./src/ ./src_bcdice
  fi
  cd ./src
  if [ ! -e ./extratables ]; then
    ln -sf ../extratables/ ./extratables
  fi
  mkdir -p ./src_bcdice
  if [ -d ./src_bcdice ]; then
    cd ./src_bcdice
    if [ ! -e ./diceBot ]; then
      ln -sf ../diceBot/ ./diceBot
    fi
  fi
fi
cd $CURDIR
patch -uN ./src/test/test.rb < ./test.diff
test.diff
--- ./src/test/orig/test.rb     2014-05-28 12:56:16.929296739 +0900
+++ ./src/test/test.rb  2014-05-29 00:46:58.740404535 +0900
@@ -20,7 +20,7 @@

     resultFile = './testData.txt'

-    buffer = File.readlines(resultFile).join.toutf8
+    buffer = File.read(resultFile).toutf8.gsub(/[\r\n]+/, "\n")
     testDataList = getTestDataList(buffer)

 #    @testResultFile = open('testResult.txt', 'w+')
@@ -123,7 +123,7 @@
       log << "index:#{@testIndex}\ninput:#{@input}\nresult:#{result}\ngood  :#{@good}\nrandsText:#{@randsText}\n"
     end

-    return log.tosjis
+    return RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|cygwin|bccwin/ ? log.tosjis : log
   end

   def getTestDataList(buffer)

追記1:公式リポジトリへの反映方法考察

上記のパッチは(自分がRubyを知らないこともあって)『極力元のソースコードは変更しない』方向で実施したため、公式リポジトリへの反映を考慮した場合、このままだとシンボリックリンクの扱い等が問題になってくると思われる。


以下、

  • Windows と Linux 双方の対応。
  • リポジトリのディレクトリ構成は保ったまま、どどんとふBCDiceのいずれであってもtest.rbが走るようにする。

としたい場合の修正方法を検討する。

Windowsとの差分対応その1(問題点No.3)

いくつかのソースコード(test*.rb)中で、

command = "ruby.exe -Ku testPointer.rb #{ARGV.join(' ')}"

という箇所が出てくるが、'ruby.exe' だと Linux では実行時にエラーとなるため、'ruby' に置換する。

Windowsとの差分対応その2(問題点No.4, 6)

改行コード及び文字コードの問題なので、上記test.diffの内容を ./(src|src_bcdice)/test/test.rb に反映する。

パスの問題(問題点No.1, 2, 5)

どどんとふとBCDiceとで、ソースコードは共通であってもディレクトリ構成が異なっているために発生すると思われる問題。
なお、これらはWindows上でBCDice/src以下からtest.rbやcgiDiceBot.rbを動作させる場合にも発生するはず。
BCDiceの方でシンボリックリンクを作成することで対処可能ではあるが、Windowsとの共通化を考えた場合にはあまりうまくない。
一応、Windows上でも mklink コマンドでシンボリックリンクの作成は可能ではあるが。
いくつかのソース(TableFileData.rb、diceBot/DiceBotLoader.rb、test/test.rb)でextratablesやsrc_bcdiceディレクトリを参照している個所で、ディレクトリの存在をチェックし、存在しない場合にはパスを変更するような処理を入れるのが妥当か。

ソース名 デフォルトPATH 変更PATH
TableFileData.rb './extratables' '../extratables'
diceBot/DiceBotLoader.rb './src_bcdice' '../src'
test/test.rb '../../src_bcdice' '../../src'

*1: TableFileData.rb:40: @dir = './extratables'

*2: diceBot/DiceBotLoader.rb:4: @@bcDicePath = './src_bcdice'

*3: test/test.rb:19: DiceBotLoader.setBcDicePath( '../../src_bcdice' )