Class: Executor

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/exogenesis/support/executor.rb

Overview

Executor is a Singleton. Get the instance via ‘Executor.instance` If you add a public method here, please also add it to the `executor_double`. Same goes for removing public methods ;)

Instance Method Summary collapse

Constructor Details

#initializeExecutor

Returns a new instance of Executor.



16
17
18
# File 'lib/exogenesis/support/executor.rb', line 16

def initialize
  @output = Output.instance
end

Instance Method Details

#ask?(question) ⇒ Boolean

Ask the user a yes/no question

Returns:

  • (Boolean)


157
158
159
160
# File 'lib/exogenesis/support/executor.rb', line 157

def ask?(question)
  start_task("#{question} (y for yes, everything else aborts)")
  STDIN.gets == "y\n"
end

#clone_repo(git_repo, target) ⇒ Object

Clone a git repository TODO: Currently only supports Github Repos, but should work in hub-style in the future git_repo: A Github repo name target: A path object where you want to clone to



166
167
168
# File 'lib/exogenesis/support/executor.rb', line 166

def clone_repo(git_repo, target)
  execute "Cloning #{git_repo}", "git clone [email protected]:#{git_repo}.git #{target}"
end

#command_exists?(command) ⇒ Boolean

Check if a command exists

Returns:

  • (Boolean)


180
181
182
# File 'lib/exogenesis/support/executor.rb', line 180

def command_exists?(command)
  system("which #{command} &>/dev/null;")
end

#execute(description, script) ⇒ Object

Execute a shell script. The description will be printed before the execution. This method will handle failures of the executed script. If you provide a block, execute will pass the output of the execution to it. If you raise a TaskSkipped Exception, it will skip the task instead of marking it as done (and give the text you provided to the exception as additional information if verbose is active)



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/exogenesis/support/executor.rb', line 88

def execute(description, script)
  start_task description

  output, error_output, exit_status = nil
  Bundler.with_clean_env do
    Open3.popen3(script) do |_stdin, stdout, stderr, process|
      output = stdout.read
      error_output = stderr.read
      exit_status = process.value.exitstatus
    end
  end

  yield(output, error_output) if block_given?

  if exit_status > 0
    task_failed("An Error occured while executing `#{script}`: \n#{output} #{error_output}", exit_status)
  else
    task_succeeded(output)
  end
rescue TaskSkipped => e
  @output.skipped(e)
end

#execute_interactive(description, script) ⇒ Object

Executes the script via system, so the user can interact with the output. Instead of the usual output of the other commands, it will draw a border around the interactive section



115
116
117
118
119
# File 'lib/exogenesis/support/executor.rb', line 115

def execute_interactive(description, script)
  @output.start_border description
  system script
  @output.end_border
end

#get_path_for(path_as_string) ⇒ Object

Get an expanded PathName for a String



75
76
77
# File 'lib/exogenesis/support/executor.rb', line 75

def get_path_for(path_as_string)
  Pathname.new(File.expand_path(path_as_string))
end

#get_path_in_home(*path) ⇒ Object

Get a path starting from the home dir



65
66
67
# File 'lib/exogenesis/support/executor.rb', line 65

def get_path_in_home(*path)
  Pathname.new(File.join(Dir.home, *path))
end

#get_path_in_working_directory(*path) ⇒ Object

Get a path starting from the current working directory



70
71
72
# File 'lib/exogenesis/support/executor.rb', line 70

def get_path_in_working_directory(*path)
  Pathname.pwd.join(*path)
end

#info(description, information) ⇒ Object

Notify the user about something TODO: It has to be possible to give an info for a started task



53
54
55
56
# File 'lib/exogenesis/support/executor.rb', line 53

def info(description, information)
  @output.left(description)
  @output.info(information)
end

#ln_s(src, dest) ⇒ Object

Wrapper around FileUtils’ ‘ln_s`



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/exogenesis/support/executor.rb', line 142

def ln_s(src, dest)
  if dest.symlink? && dest.readlink == src
    skip_task "Linking #{src}", 'Already linked'
  else
    start_task "Linking #{src}"
    if dest.exist? || dest.symlink?
      task_failed 'Target already exists'
    else
      FileUtils.ln_s(src, dest)
      task_succeeded
    end
  end
end

#mkpath(path) ⇒ Object

Create a path Expects a PathName



60
61
62
# File 'lib/exogenesis/support/executor.rb', line 60

def mkpath(path)
  FileUtils.mkpath(path)
end

#pull_repo(git_repo, target) ⇒ Object

Pull a git repository git_repo: Is just used for the description git_repo: A Github repo name (only used for task description) target: A path object where you want to pull



174
175
176
177
# File 'lib/exogenesis/support/executor.rb', line 174

def pull_repo(git_repo, target)
  check_if_git_repo! target
  execute "Pulling #{git_repo}", "cd #{target} && git pull"
end

#rm_rf(path) ⇒ Object

Wrapper around FileUtils’ ‘rm_rf` First check if the path exists, info if it doesn’t exist If it exists, ask if the user really wants to delete it path: Needs to be a PathName



133
134
135
136
137
138
139
# File 'lib/exogenesis/support/executor.rb', line 133

def rm_rf(path)
  if path.exist?
    FileUtils.rm_rf(path) if ask?("Do you really want to `rm -rf #{path}?`")
  else
    info("Delete `#{path}`", 'Already deleted')
  end
end

#silent_execute(command) ⇒ Object

Execute without printing anything, return the result (Use instead of ‘command` to mock it)



123
124
125
126
127
# File 'lib/exogenesis/support/executor.rb', line 123

def silent_execute(command)
  Bundler.with_clean_env do
    `#{command}`
  end
end

#skip_task(description, further_information = '') ⇒ Object

Notify the user that you have skipped a task



46
47
48
49
# File 'lib/exogenesis/support/executor.rb', line 46

def skip_task(description, further_information = '')
  @output.left(description)
  @output.skipped(further_information)
end

#start_section(text, emoji_name) ⇒ Object

Start a new output section with a given text



22
23
24
# File 'lib/exogenesis/support/executor.rb', line 22

def start_section(text, emoji_name)
  @output.decorated_header(text, emoji_name)
end

#start_task(text) ⇒ Object

Notify the user that you started with a task like ‘Configure Homebrew’



28
29
30
# File 'lib/exogenesis/support/executor.rb', line 28

def start_task(text)
  @output.left(text)
end

#task_failed(further_information, exit_status = 1) ⇒ Object

Notify the user that the started task failed.



40
41
42
43
# File 'lib/exogenesis/support/executor.rb', line 40

def task_failed(further_information, exit_status = 1)
  @output.failure(further_information)
  exit(exit_status)
end

#task_succeeded(further_information = '') ⇒ Object

Notify the user that the started task was successful.



34
35
36
# File 'lib/exogenesis/support/executor.rb', line 34

def task_succeeded(further_information = '')
  @output.success(further_information)
end