Module: Sevgi::Function::Shell

Included in:
Sevgi::Function
Defined in:
lib/sevgi/function/shell.rb

Overview

Shell execution helpers and executable lookup utilities.

Defined Under Namespace

Classes: Result, Runner

Instance Method Summary collapse

Instance Method Details

#executable!(*args) ⇒ nil

Requires the first command argument to name an executable program.

Parameters:

  • args (Array<Object>)

    command arguments

Returns:

  • (nil)

Raises:

  • (Sevgi::Error)

    when the program cannot be found in PATH



27
28
29
30
# File 'lib/sevgi/function/shell.rb', line 27

def executable!(*args)
  program = args.first.to_s.split.first
  Error.("Missing executable: #{program}") unless executable?(program)
end

#executable?(program) ⇒ Boolean

Note:

PATH is evaluated on every call; empty PATH segments mean the current directory.

Checks whether a program exists and is executable.

Parameters:

  • program (Object)

    program name, absolute path, or relative slash-containing path

Returns:

  • (Boolean)

    true when an executable regular file is found



13
14
15
16
17
18
19
20
21
# File 'lib/sevgi/function/shell.rb', line 13

def executable?(program)
  program = program.to_s
  return false if program.empty?
  return executable_file?(program) if slash_path?(program)

  ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR, -1).any? do |dir|
    executable_file?(::File.join(dir.empty? ? "." : dir, program))
  end
end

#sh(*args) { ... } ⇒ Sevgi::Function::Shell::Result

Note:

The child's stdin is closed after the input block. During execution, the first SIGINT sends TERM to the child process and the second SIGINT sends KILL; the previous SIGINT handler is restored before return.

Runs a command and captures stdout, stderr, and exit status.

Parameters:

  • args (Array<String>)

    command and arguments

Yields:

  • optional stdin producer, evaluated once after output readers start

Yield Returns:

  • (String, nil)

    content to write to stdin; nil writes nothing

Returns:

Raises:

  • (SystemCallError)

    when the executable cannot be spawned or process pipes cannot be opened

  • (StandardError)

    when the input block raises; the child is terminated and reaped before propagation



202
# File 'lib/sevgi/function/shell.rb', line 202

def sh(...) = Runner.new.(...)

#sh!(*args) { ... } ⇒ Sevgi::Function::Shell::Result

Note:

The child's stdin is closed after the input block. During execution, the first SIGINT sends TERM to the child process and the second SIGINT sends KILL; the previous SIGINT handler is restored before return.

Runs a command, requiring both executable lookup and successful exit status.

Parameters:

  • args (Array<String>)

    command and arguments

Yields:

  • optional stdin producer, evaluated once after output readers start

Yield Returns:

  • (String, nil)

    content to write to stdin; nil writes nothing

Returns:

Raises:

  • (Sevgi::Error)

    when the executable is missing or the command fails

  • (SystemCallError)

    when the executable cannot be spawned or process pipes cannot be opened

  • (StandardError)

    when the input block raises; the child is terminated and reaped before propagation



214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/sevgi/function/shell.rb', line 214

def sh!(*args, &block)
  executable!(*args) unless args.empty?

  sh(*args, &block).tap do |result|
    unless result.ok?
      warn(result.err)
      warn("")

      Error.("Command failed: #{result.cmd}")
    end
  end
end