Class: UpdateRepo::WalkRepo

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/update_repo.rb

Overview

An encapsulated class to walk the repo directories and update all Git repositories found therein. rubocop:disable Metrics/ClassLength

Instance Method Summary collapse

Methods included from Helpers

#print_log, #trunc_dir

Constructor Details

#initializevoid

Class constructor. No parameters required.



23
24
25
26
27
28
29
30
31
32
# File 'lib/update_repo.rb', line 23

def initialize
  @metrics = { processed: 0, skipped: 0, failed: 0, updated: 0,
               start_time: 0 }
  @summary = { processed: 'green', updated: 'cyan', skipped: 'yellow',
               failed: 'red' }
  # create a new instance of the CmdConfig class then read the config var
  @cmd = CmdConfig.new
  # set up the logfile if needed
  setup_logfile if cmd(:log)
end

Instance Method Details

#cmd(command) ⇒ Object



59
60
61
# File 'lib/update_repo.rb', line 59

def cmd(command)
  @cmd.true_cmd(command.to_sym)
end

#configObject

returns the Confoog class which can then be used to access any config var



55
56
57
# File 'lib/update_repo.rb', line 55

def config
  @cmd.getconfig
end

#do_threads(stdout, stderr) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/update_repo.rb', line 174

def do_threads(stdout, stderr)
  { out: stdout, err: stderr }.each do |key, stream|
    Thread.new do
      while (line = stream.gets)
        if key == :err && line =~ /^fatal:/
          print_log '   ', line.red
          @metrics[:failed] += 1
        else
          print_log '   ', line.cyan
          @metrics[:updated] += 1 if line =~ %r{^From\s(?:https?|git)://}
        end
      end
    end
  end
end

#do_update(repo_url) ⇒ Object



165
166
167
168
169
170
171
172
# File 'lib/update_repo.rb', line 165

def do_update(repo_url)
  print_log '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
  Open3.popen3('git pull') do |stdin, stdout, stderr, thread|
    stdin.close
    do_threads(stdout, stderr)
    thread.join
  end
end

#dump_repo(dir) ⇒ Object

this function will either dump out a CSV with the directory and remote, or just the remote depending if we called –dump or –dump-remote



192
193
194
195
196
197
198
# File 'lib/update_repo.rb', line 192

def dump_repo(dir)
  Dir.chdir(dir.chomp!('/')) do
    repo_url = `git config remote.origin.url`.chomp
    print_log "#{trunc_dir(dir, config['cmd'][:prune])}," if cmd(:dump)
    print_log "#{repo_url}\n"
  end
end

This method returns an undefined value.

print out a brief footer. This will be expanded later.



117
118
119
120
121
122
123
124
# File 'lib/update_repo.rb', line 117

def footer
  duration = Time.now - @metrics[:start_time]
  print_log "\nUpdates completed in ", show_time(duration).cyan
  print_metrics
  print_log " |\n\n"
  # close the log file now as we are done, just to be sure ...
  @logfile.close if @logfile
end

#list_exceptionsObject



134
135
136
137
138
139
140
# File 'lib/update_repo.rb', line 134

def list_exceptions
  exceptions = config['exceptions']
  if exceptions
    print_log "\nExclusions:".underline, ' ',
              exceptions.join(', ').yellow, "\n"
  end
end

#list_locationsObject



142
143
144
145
146
147
# File 'lib/update_repo.rb', line 142

def list_locations
  print_log "\nRepo location(s):\n".underline
  config['location'].each do |loc|
    print_log '-> ', loc.cyan, "\n"
  end
end

#notexception?(dir) ⇒ boolean

tests to see if the given directory is an exception and should be skipped

Parameters:

  • dir (string)

    Directory to be checked

Returns:

  • (boolean)

    True if this is NOT an exception, False otherwise



92
93
94
# File 'lib/update_repo.rb', line 92

def notexception?(dir)
  !config['exceptions'].include?(File.basename(dir))
end


126
127
128
129
130
131
132
# File 'lib/update_repo.rb', line 126

def print_metrics
  @summary.each do |metric, color|
    metric_value = @metrics[metric]
    output = "#{metric_value} #{metric.capitalize}"
    print_log ' | ', output.send(color.to_sym) unless metric_value.zero?
  end
end

#recurse_dir(dirname) ⇒ Object

take each directory contained in the Repo directory, if it is detected as a Git repository then update it (or as directed by command line)

Parameters:

  • dirname (string)

    Contains the directory to search for Git repos.



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/update_repo.rb', line 76

def recurse_dir(dirname)
  Dir.chdir(dirname) do
    Dir['**/'].each do |dir|
      next unless gitdir?(dir)
      if cmd(:dump) || cmd(:dump_remote)
        dump_repo(File.join(dirname, dir))
      else
        notexception?(dir) ? update_repo(dir) : skip_repo(dir)
      end
    end
  end
end

#setup_logfileObject



63
64
65
66
67
68
69
70
71
# File 'lib/update_repo.rb', line 63

def setup_logfile
  filename = if cmd(:timestamp)
               'updaterepo-' + Time.new.strftime('%y%m%d-%H%M%S') + '.log'
             else
               'updaterepo.log'
             end
  @logfile = File.open(filename, 'w')
  @logfile.sync = true
end

#show_headervoid

This method returns an undefined value.

Display a simple header to the console

Examples:

show_header


100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/update_repo.rb', line 100

def show_header
  # print an informative header before starting
  print_log "\nGit Repo update utility (v", VERSION, ')',
            " \u00A9 Grant Ramsay <[email protected]>\n"
  print_log "Using Configuration from '#{config.config_path}'\n"
  print_log "Command line is : #{config['cmd']}\n"
  # list out the locations that will be searched
  list_locations
  # list any exceptions that we have from the config file
  list_exceptions
  # save the start time for later display in the footer...
  @metrics[:start_time] = Time.now
  print_log "\n" # blank line before processing starts
end

#skip_repo(dirpath) ⇒ Object



149
150
151
152
153
154
155
# File 'lib/update_repo.rb', line 149

def skip_repo(dirpath)
  Dir.chdir(dirpath.chomp!('/')) do
    repo_url = `git config remote.origin.url`.chomp
    print_log '* Skipping ', Dir.pwd.yellow, " (#{repo_url})\n"
    @metrics[:skipped] += 1
  end
end

#startObject

This function will perform the required actions to traverse the Repo.

Examples:

walk_repo = UpdateRepo::WalkRepo.new
walk_repo.start


38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/update_repo.rb', line 38

def start
  String.disable_colorization = !cmd(:color)
  # make sure we dont have bad cmd-line parameter combinations ...
  @cmd.check_params
  # print out our header unless we are dumping / importing ...
  no_header = cmd(:dump) || cmd(:import) || cmd(:dump_remote)
  show_header unless no_header
  config['location'].each do |loc|
    recurse_dir(loc)
  end
  # print out an informative footer unless dump / import ...
  footer unless no_header
end

#update_repo(dirname) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/update_repo.rb', line 157

def update_repo(dirname)
  Dir.chdir(dirname.chomp!('/')) do
    repo_url = `git config remote.origin.url`.chomp
    do_update(repo_url)
    @metrics[:processed] += 1
  end
end