[Groonga-commit] ranguba/chupa-text at 2f2bfd4 [master] Add ExternalCommand

Back to archive index

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����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index