Module: Sevgi::Function::Shell

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

Overview

Command methods promoted to Sevgi::F. This module owns the public immutable Result value but is not otherwise a consumer mixin contract.

Defined Under Namespace

Classes: Result

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



30
31
32
33
# File 'lib/sevgi/function/shell.rb', line 30

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



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

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:

  • (Sevgi::ArgumentError)

    when no command is given

  • (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



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

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::ArgumentError)

    when no command is given

  • (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



361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/sevgi/function/shell.rb', line 361

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