Kouhei Sutou
null+****@clear*****
Sat Feb 15 23:25:42 JST 2014
Kouhei Sutou 2014-02-15 23:25:42 +0900 (Sat, 15 Feb 2014) New Revision: 2f2bfd46a6d96c752283af8c7e60e5bcc13f6418 https://github.com/ranguba/chupa-text/commit/2f2bfd46a6d96c752283af8c7e60e5bcc13f6418 Message: Add ExternalCommand Added files: lib/chupa-text/external-command.rb test/test-external-command.rb Modified files: lib/chupa-text.rb Modified: lib/chupa-text.rb (+6 -2) =================================================================== --- lib/chupa-text.rb 2014-01-06 00:13:40 +0900 (bfc48ae) +++ lib/chupa-text.rb 2014-02-15 23:25:42 +0900 (ca388b8) @@ -26,13 +26,17 @@ require "chupa-text/loggable" require "chupa-text/configuration" require "chupa-text/configuration-loader" +require "chupa-text/mime-type" +require "chupa-text/mime-type-registry" + +require "chupa-text/external-command" + require "chupa-text/decomposer" require "chupa-text/decomposer-registry" require "chupa-text/decomposers" + require "chupa-text/extractor" require "chupa-text/formatters" -require "chupa-text/mime-type" -require "chupa-text/mime-type-registry" require "chupa-text/file-content" require "chupa-text/virtual-content" Added: lib/chupa-text/external-command.rb (+136 -0) 100644 =================================================================== --- /dev/null +++ lib/chupa-text/external-command.rb 2014-02-15 23:25:42 +0900 (261f9a0) @@ -0,0 +1,136 @@ +# Copyright (C) 2014 Kouhei Sutou <kou �� clear-code.com> +# Copyright (C) 2010 Yuto HAYAMIZU <y.hayamizu �� gmail.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "English" +require "pathname" + +module ChupaText + class ExternalCommand + def initialize(command) + @command = Pathname.new(command) + end + + def run(*arguments) + if arguments.last.is_a?(Hash) + options = arguments.pop + else + options = {} + end + spawn_options = options[:spawn_options] || {} + pid = spawn(options[:env] || {}, + @command.to_s, + *arguments, + spawn_options.merge(default_spawn_options)) + pid, status = Process.waitpid2(pid) + status.success? + end + + def exist? + if****@comma*****? + @command.file? and****@comma*****? + else + (ENV['PATH'] || "").split(File::PATH_SEPARATOR).any? do |path| + (Pathname.new(path) + @command).expand_path.exist? + end + end + end + + private + def default_spawn_options + SpawnLimitOptions.new.options + end + + class SpawnLimitOptions + attr_reader :options + def initialize + @options = {} + set_default_options + end + + private + def set_default_options + set_option(:cpu, :int) + set_option(:rss, :size) + set_option(:as, :size) + end + + def set_option(key, type) + value = ENV["CHUPA_EXTERNAL_COMMAND_LIMIT_#{key.to_s.upcase}"] + return if value.nil? + value = send("parse_#{type}", key, value) + return if value.nil? + rlimit_number = Process.const_get("RLIMIT_#{key.to_s.upcase}") + soft_limit, hard_limit = Process.getrlimit(rlimit_number) + if hard_limit < value + log_hard_limit_over_value(key, value, hard_limit) + return nil + end + limit_info = "soft-limit:#{soft_limit}, hard-limit:#{hard_limit}" + log(:info, "[#{key}][set] <#{value}>(#{limit_info})") + @options[:"rlimit_#{key}"] = value + end + + def parse_int(key, value) + begin + Integer(value) + rescue ArgumentError + log_invalid_value(key, value, type, "int") + nil + end + end + + def parse_size(key, value) + return nil if value.nil? + scale = 1 + case value + when /GB?\z/i + scale = 1024 ** 3 + number = $PREMATCH + when /MB?\z/i + scale = 1024 ** 2 + number = $PREMATCH + when /KB?\z/i + scale = 1024 ** 1 + number = $PREMATCH + when /B?\z/i + number = $PREMATCH + else + number = value + end + begin + number = Float(number) + rescue ArgumentError + log_invalid_value(key, value, "size") + return nil + end + (number * scale).to_i + end + + def log_hard_limit_over_value(key, value, hard_limit) + log(:warning, "[#{key}][large] <#{value}>(hard-limit:#{hard_limit})") + end + + def log_invalid_value(key, value, type) + log(:warning, "[#{key}][invalid] <#{value}>(#{type})") + end + + def log(level, message) + ChupaText.logger.send(level, "[external-command][limit]#{message}") + end + end + end +end Added: test/test-external-command.rb (+79 -0) 100644 =================================================================== --- /dev/null +++ test/test-external-command.rb 2014-02-15 23:25:42 +0900 (68b2794) @@ -0,0 +1,79 @@ +# Copyright (C) 2014 Kouhei Sutou <kou �� clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "rbconfig" + +class TestExternalCommand < Test::Unit::TestCase + def ruby + RbConfig.ruby + end + + def create_command(command) + ChupaText::ExternalCommand.new(command) + end + + class TestRun < self + def run_command(command, *arguments) + create_command(command).run(*arguments) + end + + def test_success + assert_true(run_command(ruby, "-e", "true")) + end + + def test_failure + error = Tempfile.new("error") + spawn_options = { + :err => error.path, + } + assert_false(run_command(ruby, + "-e", "raise 'XXX'", + :spawn_options => spawn_options)) + end + end + + class TestExist < self + def setup + @original_path = ENV["PATH"] + end + + def teardown + ENV["PATH"] = @original_path + end + + def exist?(command) + create_command(command).exist? + end + + def test_exist_absolete_path + assert_true(exist?(ruby)) + end + + def test_exist_in_path + ruby_dir, ruby_base_name = File.split(ruby) + ENV["PATH"] += "#{File::PATH_SEPARATOR}#{ruby_dir}" + assert_true(exist?(ruby_base_name)) + end + + def test_not_executable + assert_false(exist?(__FILE__)) + end + + def test_not_exist + assert_false(exist?("nonexistent")) + end + end +end -------------- next part -------------- HTML����������������������������... 下載