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

Note:

The first argument is checked as one exact argv entry; it is never shell-split.

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



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

def executable!(*args)
  program = args.first.to_s
  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 as KILL to each active child outside trap context, then restores the previous handler.

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



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

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 as KILL to each active child outside trap context, then restores the previous handler.

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



313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/sevgi/function/shell.rb', line 313

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