diff --git a/Gemfile b/Gemfile index e2d3f18f..1497b46a 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source 'https://rubygems.org' gem 'activesupport', '~> 4.2' gem 'cinch', github: 'cinchrb/cinch', ref: 'e4e33ce154977168963e35067c22805d3677a8e4' gem 'twitter', '~> 5.11' +gem 'lumberjack', '~> 1.0' gem 'sysexits', '~> 1.2' group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 1b32063f..3d8abb51 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,6 +42,7 @@ GEM http_parser.rb (0.6.0) i18n (0.7.0) json (1.8.2) + lumberjack (1.0.9) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) method_source (0.8.2) @@ -126,6 +127,7 @@ DEPENDENCIES activesupport (~> 4.2) cinch! coveralls + lumberjack (~> 1.0) pry (~> 0.10) rake (~> 10.4) rspec (~> 3.1) diff --git a/lib/rgrb/exec/irc_bot.rb b/lib/rgrb/exec/irc_bot.rb index d128b818..d9fbed23 100644 --- a/lib/rgrb/exec/irc_bot.rb +++ b/lib/rgrb/exec/irc_bot.rb @@ -1,5 +1,6 @@ # vim: fileencoding=utf-8 +require 'lumberjack' require 'cinch' require 'optparse' require 'sysexits' @@ -12,8 +13,8 @@ module RGRB module Exec # IRC ボットの実行ファイルの処理を担うクラス class IRCBot - # 設定ファイルの標準パス(相対パス) - DEFAULT_CONFIG_PATH = 'config/rgrb.yaml' + # 既定の設定 ID + DEFAULT_CONFIG_ID = 'rgrb' # 新しい RGRB::Exec::IRCBot インスタンスを返す # @param [String] rgrb_root_path RGRB のルートディレクトリの絶対パス @@ -23,15 +24,24 @@ def initialize(rgrb_root_path, argv) @argv = argv @debug = false - @config_path = "#{@root_path}/#{DEFAULT_CONFIG_PATH}" + @config_id = DEFAULT_CONFIG_ID @opt = new_opt_parser + @logger = new_logger end # プログラムを実行する # @return [void] def execute @opt.parse!(@argv) - load_config + + @logger.level = + if @debug + Lumberjack::Logger::DEBUG + else + Lumberjack::Logger::INFO + end + + @config = load_config(@config_id, @root_path, @logger) load_plugins bot = new_bot @@ -58,11 +68,27 @@ def print_error(message) private :print_error # 設定を読み込む - # @return [void] - def load_config - @config = RGRB::Config.load_yaml_file(@config_path) + # @param [String] config_id 設定 ID + # @param [String] root_path RGRB のルートディレクトリの絶対パス + # @param [Logger] logger ロガー + # @raise [ArgumentError] config_id に '../' が含まれる場合 + # @return [Config] + def load_config(config_id, root_path, logger) + if config_id.include?('../') + fail( + ArgumentError, + "#{config_id}: ディレクトリトラバーサルの疑い" + ) + end + + yaml_path = "#{root_path}/config/#{config_id}.yaml" + RGRB::Config.load_yaml_file(yaml_path) + + logger.warn("設定 #{config_id} を読み込みました") rescue => e - print_error("設定ファイルの読み込みに失敗しました (#{e})") + logger.fatal('設定ファイルの読み込みに失敗しました') + logger.fatal(e) + Sysexits.exit(:config_error) end private :load_config @@ -132,7 +158,7 @@ def new_opt_parser opt.banner = <