File: shell.rb

package info (click to toggle)
ruby-mini-magick 5.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,584 kB
  • sloc: ruby: 1,444; makefile: 6
file content (53 lines) | stat: -rw-r--r-- 1,638 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
require "open3"

module MiniMagick
  ##
  # Sends commands to the shell (more precisely, it sends commands directly to
  # the operating system).
  #
  # @private
  #
  class Shell

    def run(command, errors: MiniMagick.errors, warnings: MiniMagick.warnings, **options)
      stdout, stderr, status = execute(command, **options)

      if status != 0
        if stderr.include?("time limit exceeded")
          fail MiniMagick::TimeoutError, "`#{command.join(" ")}` has timed out"
        elsif errors
          fail MiniMagick::Error, "`#{command.join(" ")}` failed with status: #{status.inspect} and error:\n#{stderr}"
        end
      end

      $stderr.print(stderr) if warnings

      [stdout, stderr, status]
    end

    def execute(command, stdin: "", timeout: MiniMagick.timeout)
      env = MiniMagick.restricted_env ? ENV.to_h.slice("HOME", "PATH", "LANG") : {} # Using #to_h for Ruby 2.5 compatibility.
      env.merge!(MiniMagick.cli_env)
      env["MAGICK_TIME_LIMIT"] = timeout.to_s if timeout

      stdout, stderr, status = log(command.join(" ")) do
        Open3.capture3(env, *command, stdin_data: stdin, unsetenv_others: MiniMagick.restricted_env)
      end

      [stdout, stderr, status&.exitstatus]
    rescue Errno::ENOENT, IOError
      ["", "executable not found: \"#{command.first}\"", 127]
    end

    private

    def log(command, &block)
      time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      value = block.call
      duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start
      MiniMagick.logger.debug "[%.2fs] %s" % [duration, command]
      value
    end

  end
end