update_repo 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe97d312b2d580418707a7a5e139b9ce446e2564
4
- data.tar.gz: ea880a88cc78769ae33ab2f9cd13f88800243ff3
3
+ metadata.gz: b68ac5a08795af79e528b813aa2e74fe628a816f
4
+ data.tar.gz: 5efdbb27dc053c02f4bfb76dcfd2f353b7f3b290
5
5
  SHA512:
6
- metadata.gz: bc289788fbb7460a45a18154ea271e5c1f24b71a17f533f26ebfc93a66f8c2c021fdb580fe165df8f17466bb2043a5a2e5a981f5ee08eeaf162a8a95148caf49
7
- data.tar.gz: ebf55d5a2f734362bce499c0f87f7697f50fd98564f5ebdf0bfde257bdd6e12b82a23ce357ed1e1c8d0dbbb414a896fdef07baf827376f135f2ed414bced3335
6
+ metadata.gz: 47348f246c0c6e179da7e689f2fb1b35ffacf3e0da72b2b798c1536815fce3d50d6f2859565ecd9bec06bfb9aba7a20a9f1839c08dcf10d5ca28c389b13ccce2
7
+ data.tar.gz: ddc661515526cbc5414deb1de0f8bb5f6eaea8057c6efba573b743a5e94c95231cefdf64efc8288a8285f188c60a4d87a17d1726dd974578432ac1b1e6da08aa
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  .token
12
12
  .updatereporc
13
13
  *.log
14
+ *.sublime*
data/README.md CHANGED
@@ -101,6 +101,7 @@ Add functionality, not in any specific order :
101
101
  - Either add an option 'variants' or similar to allow non-standard git pull commands (eg Ubuntu kernel), or update the 'exceptions' option to do same.
102
102
  - Improve the stats / info at end-of-job :
103
103
  * errors or connection problems `[IN PROGRESS]`
104
+ * List the skipped / failed repos. Later make this dependant on 'verbose' status.
104
105
  * _more..._
105
106
  - Add command line options to override configuration, and even specify an alternate config file. Any options so specified will have precedence over settings specified in the configuration file. `[IN PROGRESS]`
106
107
  - Add command line options for verbose or quiet, with same options in config file.
@@ -110,7 +111,7 @@ Add functionality, not in any specific order :
110
111
  - Add option to only display a (text) tree of the discovered git repositories, not updating them.
111
112
  - Add Import & Export functionality :
112
113
  * ability to export a text dump of each repo location and remote as a CSV file. `[DONE]`
113
- * re-import the above dump on a different machine or after reinstall
114
+ * re-import the above dump on a different machine or after reinstall. Modify the '--prune' command to apply to this function also, removing the required number of directory levels before importing.
114
115
  - Add option to use alternative git command if required, either globally or on a case-by-case basis (see also comments on 'variants' above). Currently the script just uses a blanket `git pull` command on all repositories.
115
116
  - Document configuration file format and options. `[IN PROGRESS]`
116
117
 
data/Rakefile CHANGED
@@ -35,4 +35,4 @@ else
35
35
  end
36
36
  end
37
37
 
38
- task default: [:rubocop, :reek, :spec, :build]
38
+ task default: [:rubocop, :reek, :spec, :inch, :build]
@@ -26,13 +26,18 @@ module UpdateRepo
26
26
  end
27
27
 
28
28
  # return the configuration hash variable
29
+ # @param [none]
30
+ # @return [Class] Returns the base 'confoog' class to the caller.
31
+ # @example
32
+ # @config = @cmd.getconfig
29
33
  def getconfig
30
34
  @conf
31
35
  end
32
36
 
33
37
  # This will return the 'true' version of a command, taking into account
34
38
  # both command line (given preference) and the configuration file.
35
- # parameter is a :symbol
39
+ # @param command [symbol] The symbol of the defined command
40
+ # @return [various] Returns the true value of the comamnd symbol
36
41
  def true_cmd(command)
37
42
  cmd_given = @conf['cmd'][(command.to_s + '_given').to_sym]
38
43
  cmd_line = @conf['cmd'][command.to_sym]
@@ -49,18 +54,26 @@ module UpdateRepo
49
54
  end
50
55
  end
51
56
 
52
- # make sure the parameter combinations are valid
57
+ # rubocop:disable Metrics/LineLength
58
+ # make sure the parameter combinations are valid, terminating otherwise.
59
+ # @param [none]
60
+ # @return [void]
53
61
  def check_params
54
- if true_cmd(:dump) && true_cmd(:import)
55
- Trollop.die 'Sorry, you cannot specify --dump AND --import'.red
56
- end
57
- if true_cmd(:dump) && true_cmd(:dump_remote)
58
- Trollop.die 'Sorry, you cannot specify --dump AND --dump-remote'.red
59
- end
62
+ return unless true_cmd(:dump)
63
+ # if true_cmd(:import)
64
+ Trollop.die 'You cannot use --dump AND --import'.red if true_cmd(:import)
65
+ # end
66
+ # if true_cmd(:dump_remote)
67
+ Trollop.die 'You cannot use --dump AND --dump-remote'.red if true_cmd(:dump_remote)
68
+ # end
60
69
  end
70
+ # rubocop:enable Metrics/LineLength
61
71
 
62
72
  private
63
73
 
74
+ # terminate if we cannot load the configuration file for any reason.
75
+ # @param [none]
76
+ # @return [integer] exit code 1
64
77
  def config_error
65
78
  if @conf.status[:errors] == Status::ERR_CANT_LOAD
66
79
  print_log 'Note that the the default configuration file was '.red,
@@ -69,6 +82,9 @@ module UpdateRepo
69
82
  exit 1
70
83
  end
71
84
 
85
+ # Set up the Trollop options and banner
86
+ # @param [none]
87
+ # @return [void]
72
88
  # rubocop:disable Metrics/MethodLength
73
89
  # rubocop:disable Metrics/LineLength
74
90
  def set_options
@@ -94,6 +110,7 @@ EOS
94
110
  opt :log, "Create a logfile of all program output to './update_repo.log'. Any older logs will be overwritten.", default: false
95
111
  opt :timestamp, 'Timestamp the logfile instead of overwriting. Does nothing unless the --log option is also specified.', default: false
96
112
  opt :dump_remote, 'Create a dump to screen or log listing all the git remote URLS found in the specified directories.', default: false, short: 'r'
113
+ opt :dump_tree, 'Create a dump to screen or log listing all subdirectories found below the specified locations in tree format.', default: false, short: 'u'
97
114
  # opt :quiet, 'Only minimal output to the terminal', default: false
98
115
  # opt :silent, 'Completely silent, no output to terminal at all.', default: false
99
116
  end
@@ -16,6 +16,8 @@ module Helpers
16
16
 
17
17
  # this function will simply pass the given string to 'print', and also
18
18
  # log to file if that is specified.
19
+ # @param string [array] Array of strings for print formatting
20
+ # @return [void]
19
21
  def print_log(*string)
20
22
  # log to screen regardless
21
23
  print(*string)
@@ -1,4 +1,4 @@
1
1
  module UpdateRepo
2
2
  # constant, current version of this Gem
3
- VERSION = '0.8.0'.freeze
3
+ VERSION = '0.8.1'.freeze
4
4
  end
data/lib/update_repo.rb CHANGED
@@ -22,7 +22,7 @@ module UpdateRepo
22
22
  # @return [void]
23
23
  def initialize
24
24
  @metrics = { processed: 0, skipped: 0, failed: 0, updated: 0,
25
- start_time: 0 }
25
+ start_time: 0, failed_list: [] }
26
26
  @summary = { processed: 'green', updated: 'cyan', skipped: 'yellow',
27
27
  failed: 'red' }
28
28
  # create a new instance of the CmdConfig class then read the config var
@@ -38,28 +38,44 @@ module UpdateRepo
38
38
  def start
39
39
  String.disable_colorization = !cmd(:color)
40
40
  # make sure we dont have bad cmd-line parameter combinations ...
41
- @cmd.check_params
41
+ @cmd.check_params # TODO - check this since is already called in @cmd.init
42
42
  # print out our header unless we are dumping / importing ...
43
- no_header = cmd(:dump) || cmd(:import) || cmd(:dump_remote)
44
- show_header unless no_header
43
+ show_header unless dumping?
45
44
  config['location'].each do |loc|
46
- recurse_dir(loc)
45
+ cmd(:dump_tree) ? dump_tree(File.join(loc)) : recurse_dir(loc)
47
46
  end
48
47
  # print out an informative footer unless dump / import ...
49
- footer unless no_header
48
+ footer unless dumping?
50
49
  end
51
50
 
52
- # private
51
+ private
52
+
53
+ def dumping?
54
+ cmd(:dump) || cmd(:dump_remote) || cmd(:dump_tree)
55
+ end
53
56
 
54
57
  # returns the Confoog class which can then be used to access any config var
58
+ # @return [void]
59
+ # @param [none]
55
60
  def config
56
61
  @cmd.getconfig
57
62
  end
58
63
 
64
+ # Return the true value of the specified configuration parameter. This is a
65
+ # helper function that simply calls the 'true_cmd' function in the @cmd
66
+ # class
67
+ # @param command [symbol] The defined command symbol that is to be returned
68
+ # @return [various] The value of the requested command option
69
+ # @example
70
+ # logging = cmd(:log)
59
71
  def cmd(command)
60
72
  @cmd.true_cmd(command.to_sym)
61
73
  end
62
74
 
75
+ # Set up the log file - determine if we need to timestamp the filename and
76
+ # then actually open it and set to sync.
77
+ # @param [none]
78
+ # @return [void]
63
79
  def setup_logfile
64
80
  filename = if cmd(:timestamp)
65
81
  'updaterepo-' + Time.new.strftime('%y%m%d-%H%M%S') + '.log'
@@ -72,12 +88,13 @@ module UpdateRepo
72
88
 
73
89
  # take each directory contained in the Repo directory, if it is detected as
74
90
  # a Git repository then update it (or as directed by command line)
75
- # @param dirname [string] Contains the directory to search for Git repos.
91
+ # @param dirname [string] Contains the directory to search for Git repos.]
92
+ # @return [void]
76
93
  def recurse_dir(dirname)
77
94
  Dir.chdir(dirname) do
78
95
  Dir['**/'].each do |dir|
79
96
  next unless gitdir?(dir)
80
- if cmd(:dump) || cmd(:dump_remote)
97
+ if dumping?
81
98
  dump_repo(File.join(dirname, dir))
82
99
  else
83
100
  notexception?(dir) ? update_repo(dir) : skip_repo(dir)
@@ -97,12 +114,13 @@ module UpdateRepo
97
114
  # @example
98
115
  # show_header
99
116
  # @return [void]
117
+ # @param [none]
100
118
  def show_header
101
119
  # print an informative header before starting
102
120
  print_log "\nGit Repo update utility (v", VERSION, ')',
103
121
  " \u00A9 Grant Ramsay <seapagan@gmail.com>\n"
104
122
  print_log "Using Configuration from '#{config.config_path}'\n"
105
- print_log "Command line is : #{config['cmd']}\n"
123
+ # print_log "Command line is : #{config['cmd']}\n"
106
124
  # list out the locations that will be searched
107
125
  list_locations
108
126
  # list any exceptions that we have from the config file
@@ -114,31 +132,49 @@ module UpdateRepo
114
132
 
115
133
  # print out a brief footer. This will be expanded later.
116
134
  # @return [void]
135
+ # @param [none]
117
136
  def footer
118
137
  duration = Time.now - @metrics[:start_time]
119
138
  print_log "\nUpdates completed in ", show_time(duration).cyan
120
139
  print_metrics
121
- print_log " |\n\n"
140
+ print_log " \n\n"
122
141
  # close the log file now as we are done, just to be sure ...
123
142
  @logfile.close if @logfile
124
143
  end
125
144
 
145
+ # Print end-of-run metrics to console / log
146
+ # @return [void]
147
+ # @param [none]
126
148
  def print_metrics
127
149
  @summary.each do |metric, color|
128
150
  metric_value = @metrics[metric]
129
151
  output = "#{metric_value} #{metric.capitalize}"
130
152
  print_log ' | ', output.send(color.to_sym) unless metric_value.zero?
131
153
  end
154
+ print_log ' |'
155
+ return if @metrics[:failed_list].empty?
156
+ print_log "\n\n!! Note : The following repositories ",
157
+ 'FAILED'.red.underline, ' during this run :'
158
+ @metrics[:failed_list].each do |failed|
159
+ print_log "\n [", 'x'.red, "] #{failed}"
160
+ end
132
161
  end
133
162
 
163
+ # Print a list of any defined expections that will not be updated.
164
+ # @return [void]
165
+ # @param [none]
134
166
  def list_exceptions
135
167
  exceptions = config['exceptions']
136
- if exceptions
137
- print_log "\nExclusions:".underline, ' ',
138
- exceptions.join(', ').yellow, "\n"
139
- end
168
+ return unless exceptions
169
+ # if exceptions
170
+ print_log "\nExclusions:".underline, ' ',
171
+ exceptions.join(', ').yellow, "\n"
172
+ # end
140
173
  end
141
174
 
175
+ # Print a list of all top-level directories that will be searched and any
176
+ # Git repos contained within updated.
177
+ # @return [void]
142
178
  def list_locations
143
179
  print_log "\nRepo location(s):\n".underline
144
180
  config['location'].each do |loc|
@@ -146,6 +182,12 @@ module UpdateRepo
146
182
  end
147
183
  end
148
184
 
185
+ # Takes the specified Repo and does not update it, outputing a note to the
186
+ # console / log to this effect.
187
+ # @param dirpath [string] The directory with Git repository to be skipped
188
+ # @return [void]
189
+ # @example
190
+ # skip_repo('/Repo/Personal/work-in-progress')
149
191
  def skip_repo(dirpath)
150
192
  Dir.chdir(dirpath.chomp!('/')) do
151
193
  repo_url = `git config remote.origin.url`.chomp
@@ -154,30 +196,49 @@ module UpdateRepo
154
196
  end
155
197
  end
156
198
 
199
+ # Takes the specified Repo outputs information and the repo URL then calls
200
+ # #do_update to actually update it.
201
+ # @param dirname [string] The directory that will be updated
202
+ # @return [void]
203
+ # @example
204
+ # update_repo('/Repo/linux/stable')
157
205
  def update_repo(dirname)
158
206
  Dir.chdir(dirname.chomp!('/')) do
159
- repo_url = `git config remote.origin.url`.chomp
160
- do_update(repo_url)
207
+ # repo_url = `git config remote.origin.url`.chomp
208
+ do_update
161
209
  @metrics[:processed] += 1
162
210
  end
163
211
  end
164
212
 
165
- def do_update(repo_url)
213
+ # Actually perform the update of this specific repository, calling the
214
+ # function #do_threads to handle the output to screen and log.
215
+ # @param none
216
+ # @return [void]
217
+ def do_update
218
+ repo_url = `git config remote.origin.url`.chomp
166
219
  print_log '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
167
220
  Open3.popen3('git pull') do |stdin, stdout, stderr, thread|
168
221
  stdin.close
169
- do_threads(stdout, stderr)
222
+ do_threads(stdout, stderr, repo_url)
170
223
  thread.join
171
224
  end
172
225
  end
173
226
 
174
- def do_threads(stdout, stderr)
227
+ # Create 2 individual threads to handle both STDOUT and STDERR streams,
228
+ # writing to console and log if specified.
229
+ # @param stdout [stream] STDOUT Stream from the popen3 call
230
+ # @param stderr [stream] STDERR Stream from the popen3 call
231
+ # @param repo_url [string] URL of the associated repository
232
+ # @return [void]
233
+ def do_threads(stdout, stderr, repo_url)
175
234
  { out: stdout, err: stderr }.each do |key, stream|
176
235
  Thread.new do
177
236
  while (line = stream.gets)
178
- if key == :err && line =~ /^fatal:/
237
+ if key == :err && line =~ /^fatal:|^error:/
179
238
  print_log ' ', line.red
180
239
  @metrics[:failed] += 1
240
+ fullpath = Dir.pwd.red
241
+ @metrics[:failed_list].push("#{fullpath} (#{repo_url})")
181
242
  else
182
243
  print_log ' ', line.cyan
183
244
  @metrics[:updated] += 1 if line =~ %r{^From\s(?:https?|git)://}
@@ -189,6 +250,8 @@ module UpdateRepo
189
250
 
190
251
  # this function will either dump out a CSV with the directory and remote,
191
252
  # or just the remote depending if we called --dump or --dump-remote
253
+ # @param dir [string] The local directory for the repository
254
+ # @return [void]
192
255
  def dump_repo(dir)
193
256
  Dir.chdir(dir.chomp!('/')) do
194
257
  repo_url = `git config remote.origin.url`.chomp
@@ -196,5 +259,11 @@ module UpdateRepo
196
259
  print_log "#{repo_url}\n"
197
260
  end
198
261
  end
262
+
263
+ # This function will recurse though all the subdirectories of the specified
264
+ # directory and print only the directory name in a tree format.
265
+ def dump_tree(dir)
266
+ print "here for #{dir}\n"
267
+ end
199
268
  end
200
269
  end
data/update_repo.gemspec CHANGED
@@ -37,6 +37,8 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency 'colorize'
38
38
  spec.add_dependency 'confoog'
39
39
  spec.add_dependency 'trollop'
40
+ # on Ruby 1.9.3 we lock the 'term-ansicolor' gem to very 1.3.2
41
+ spec.add_dependency 'term-ansicolor', '= 1.3.2' if RUBY_VERSION < '2.0'
40
42
 
41
43
  # Depends on Ruby version if we can use 'Reek'
42
44
  spec.add_development_dependency 'reek', '~> 3.3' if RUBY_VERSION >= '2.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: update_repo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Ramsay
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-01 00:00:00.000000000 Z
11
+ date: 2016-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -314,3 +314,4 @@ signing_key:
314
314
  specification_version: 4
315
315
  summary: A Simple Gem to keep multiple locally-cloned Git Repositories up to date
316
316
  test_files: []
317
+ has_rdoc: