Class: Tetra::Bash

Inherits:
Object
  • Object
show all
Includes:
Logging, ProcessRunner
Defined in:
lib/tetra/facades/bash.rb

Overview

runs Bash with tetra-specific options

Instance Method Summary collapse

Methods included from ProcessRunner

#run, #run_interactive

Methods included from Logging

#log

Constructor Details

#initialize(project) ⇒ Bash

Returns a new instance of Bash.



8
9
10
# File 'lib/tetra/facades/bash.rb', line 8

def initialize(project)
  @project = project
end

Instance Method Details

#bash(command = nil) ⇒ Object

runs bash in a subshell, returns list of commands that were run in the session



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
54
55
56
57
58
59
60
61
# File 'lib/tetra/facades/bash.rb', line 14

def bash(command = nil)
  Tempfile.open("tetra-history") do |history_file|
    Tempfile.open("tetra-bashrc") do |bashrc_file|
      kit = Tetra::Kit.new(@project)

      ant_path = kit.find_executable("ant")
      ant_commandline = Tetra::Ant.commandline(@project.full_path, ant_path)

      mvn_path = kit.find_executable("mvn")
      mvn_commandline = Tetra::Mvn.commandline(@project.full_path, mvn_path)

      gradle_commandline = Tetra::Gradle.commandline(@project.full_path)

      bashrc_content = Bashrc.new(
        history_file: history_file.path,
        ant_in_kit: !ant_path.nil?,
        ant_commandline: ant_commandline,
        mvn_in_kit: !mvn_path.nil?,
        mvn_commandline: mvn_commandline,
        gradle_commandline: gradle_commandline
      ).to_s

      log.debug("writing bashrc file: #{bashrc_file.path}")
      log.debug(bashrc_content)

      bashrc_file.write(bashrc_content)
      bashrc_file.flush

      if command
        # SECURITY: Use array execution to prevent shell injection via 'command'
        # The 'bash -c' flag normally takes a single string, so we must be careful.
        # Ideally, passing it as a single array element ["bash", ..., "-c", command]
        # is handled safely by ProcessRunner if it uses exec/system/spawn.
        run(["bash", "--rcfile", bashrc_file.path, "-i", "-c", command])
        [command]
      else
        # Interactive mode
        run_interactive(["bash", "--rcfile", bashrc_file.path, "-i"])

        history = File.read(history_file)
        log.debug("history contents:")
        log.debug(history)

        history.split("\n").map(&:strip)
      end
    end
  end
end