Class: Morpheus::Cli::DotFile

Inherits:
Object
  • Object
show all
Includes:
Term::ANSIColor
Defined in:
lib/morpheus/cli/dot_file.rb

Constant Summary collapse

DEFAULT_EXEC_PROC =
lambda {|args|

}
EXPORTED_ALIASES_HEADER =
"# exported aliases"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fn) ⇒ DotFile

Returns a new instance of DotFile.



32
33
34
35
# File 'lib/morpheus/cli/dot_file.rb', line 32

def initialize(fn)
  @filename = fn
  #load_file()
end

Instance Attribute Details

#cmd_resultsObject (readonly)

Returns the value of attribute cmd_results.



30
31
32
# File 'lib/morpheus/cli/dot_file.rb', line 30

def cmd_results
  @cmd_results
end

#commandsObject (readonly)

Returns the value of attribute commands.



29
30
31
# File 'lib/morpheus/cli/dot_file.rb', line 29

def commands
  @commands
end

#file_contentsObject (readonly)

Returns the value of attribute file_contents.



28
29
30
# File 'lib/morpheus/cli/dot_file.rb', line 28

def file_contents
  @file_contents
end

#filenameObject (readonly)

Returns the value of attribute filename.



27
28
29
# File 'lib/morpheus/cli/dot_file.rb', line 27

def filename
  @filename
end

Class Method Details

.morpheus_profile_filenameObject

the path of the profile source file this is executed when ‘morpheus` is run



17
18
19
# File 'lib/morpheus/cli/dot_file.rb', line 17

def self.morpheus_profile_filename
  File.join(Morpheus::Cli.home_directory, ".morpheus_profile")
end

.morpheusrc_filenameObject

the path of the shell source file this is executed when ‘morpheus shell` is run



23
24
25
# File 'lib/morpheus/cli/dot_file.rb', line 23

def self.morpheusrc_filename
  File.join(Morpheus::Cli.home_directory, ".morpheusrc")
end

Instance Method Details

#execute(stop_on_failure = false, &block) ⇒ Array

execute this file as a morpheus shell script

Parameters:

  • stop_on_failure (true, false) (defaults to: false)

    the will halt execution if a command returns false. Default is false, keep going…

Returns:

  • (Array)

    exit codes of all the commands that were run.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/morpheus/cli/dot_file.rb', line 43

def execute(stop_on_failure=false, &block)
  if !File.exists?(@filename)
    print "#{Term::ANSIColor.red}source file not found: #{@filename}#{Term::ANSIColor.reset}\n" # if Morpheus::Logging.debug?
  else
    print "#{dark} #=> executing source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
  end
  file_contents ||= File.read(@filename)
  lines = file_contents.split("\n")
  cmd_results = []
  line_num = 0
  lines.each_with_index do |line, line_index|
    line_num = line_index + 1
    line = line.strip
    next if line.empty?
    next if line =~ /^\#/ # skip comments
    
    # print "#{dark} #=> executing source file line #{line_num}: #{line}#{reset}\n" if Morpheus::Logging.debug?

    # todo: allow semicolons inside arguments too..
    command_list = line.strip.split(';').compact
    command_list.each do |input|
      input = input.strip
      if input.empty?
        next
      end
      argv = Shellwords.shellsplit(input)

      if Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
        #log_history_command(input)
        cmd_result = nil
        begin
          cmd_result = Morpheus::Cli::CliRegistry.exec(argv[0], argv[1..-1])
        rescue SystemExit => err
          if err.success?
            cmd_result = true
          else
            puts "#{red} source file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset} error: exited non zero - #{err}"
            cmd_result = false
          end
        rescue => err
          # raise err
          puts "#{red} source file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset} error: unexpected error - #{err}"
          cmd_result = false
        end
        cmd_results << cmd_result
        # next command please!
      else
        puts "#{red}Unrecognized source command file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset}"
        cmd_result = false
      end
      if cmd_result == false
        if stop_on_failure
          return cmd_results
        end
      end
    end

  end
  return cmd_results
end

#export_aliases(alias_definitions) ⇒ Object

this saves the source file, upserting alias definitions at the bottom todo: smarter logic to allow the user to put stuff AFTER this section too under the section titled ‘# exported aliases’

Parameters:

  • alias_definitions (Map)

    Map of alias_name => command_string

Returns:

  • nil



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/morpheus/cli/dot_file.rb', line 109

def export_aliases(alias_definitions)
  if !@filename
    print "#{Term::ANSIColor.dark}Skipping source file save because filename has not been set#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
    return false
  end
  if !Dir.exists?(File.dirname(@filename))
    FileUtils.mkdir_p(File.dirname(@filename))
  end
  if !File.exists?(@filename)
    print "#{Term::ANSIColor.dark}Initializing source file #{@filename}#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
    FileUtils.touch(@filename)
  else
    print "#{dark} #=> Saving source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
  end


  config_text = File.read(@filename)
  config_lines = config_text.split(/\n/)
  new_config_lines = []
  existing_alias_definitions = {}
  header_line_index = config_lines.index {|line| line.strip.include?(EXPORTED_ALIASES_HEADER) }
  if header_line_index
    # keep everything before the exported alias section
    new_config_lines = config_lines[0..header_line_index-1]
    existing_alias_lines = config_lines[header_line_index..config_lines.size-1]
    # parse out the existing alias definitions
    existing_alias_lines.each do |line|
      if line =~ /^alias\s+/
        alias_name, command_string = Morpheus::Cli::CliRegistry.parse_alias_definition(line)
        if alias_name.empty? || command_string.empty?
          print "#{dark} #=> removing bad config line #{line_num} invalid alias definition: #{line}\n" if Morpheus::Logging.debug?
        else
          existing_alias_definitions[alias_name] = command_string
        end
      end
    end
  else
    new_config_lines = config_lines
    new_config_lines << "" # blank line before alias header
  end

  # append header line
  new_config_lines << EXPORTED_ALIASES_HEADER
  new_config_lines << "# Do not put anything below here, or it will be lost when aliases are exported"
  #new_config_lines << ""

  # update aliases, sort them, and append the lines
  new_alias_definitions = existing_alias_definitions.merge(alias_definitions)
  new_alias_definitions.keys.sort.each do |alias_name|
    new_config_lines << "alias #{alias_name}='#{new_alias_definitions[alias_name]}'"
  end
  
  # include a blank line after this section
  new_config_lines << ""
  new_config_lines << ""

  new_config_text = new_config_lines.join("\n")
  
  File.open(@filename, 'w') {|f| f.write(new_config_text) }
  return true
end

#remove_aliases(alias_names) ⇒ Object

this saves the source file, removing alias definitions at the bottom todo: smarter logic to allow the user to put stuff AFTER this section too under the section titled ‘# exported aliases’

Parameters:

  • alias_definitions (Map)

    Map of alias_name => command_string

Returns:

  • nil



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/morpheus/cli/dot_file.rb', line 176

def remove_aliases(alias_names)
  if !@filename
    print "#{Term::ANSIColor.dark}Skipping source file save because filename has not been set#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
    return false
  end
  if !Dir.exists?(File.dirname(@filename))
    FileUtils.mkdir_p(File.dirname(@filename))
  end
  if !File.exists?(@filename)
    print "#{Term::ANSIColor.dark}Initializing source file #{@filename}#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
    FileUtils.touch(@filename)
  else
    print "#{dark} #=> Saving source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
  end


  config_text = File.read(@filename)
  config_lines = config_text.split(/\n/)
  
  new_config_lines = config_lines.reject {|line|
    alias_names.find {|alias_name| /^alias\s+#{Regexp.escape(alias_name)}\s?\=/ }
  }
  
  new_config_text = new_config_lines.join("\n")
  
  File.open(@filename, 'w') {|f| f.write(new_config_text) }
  return true
end