update_repo 0.6.3 → 0.7.0

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: 95636a13072e10a0e61e827a2568a67d7cbdd5d4
4
- data.tar.gz: 6ade5972d1a78a9b1105cbfa5495dc024e4a59ac
3
+ metadata.gz: 00f7cdd0ea4d8be3e8cde3ce7af7d2bea7edfa18
4
+ data.tar.gz: b4d2f9eba172fa64293855bb3acb03e09b16024e
5
5
  SHA512:
6
- metadata.gz: 3b9ed7721e92dab35898841644d2b40047501bec8e2c3e6a7e74b546a253d1dcd6fb0832c47a96e37f4130cecc6c7114a79b5d38e2c7edd43bcce37e884dfaaa
7
- data.tar.gz: b810473dfa95026f9f70e8dc02fc0064e53d9934eaac4fd4af097d2b61fd9135903bce30993cf148f3ca80345001c5d90005e0912d4cfcdfd3ffe14e4dc5cf03
6
+ metadata.gz: 4442b8cf9ffc01891eef1828f5fcf4c88f417cfcb7a7ec2268d0d9b1e19c7b0b0ddd7e922ea3b99de9b47c1065cf871300e08ae7f84274bd553d592af91e0bd4
7
+ data.tar.gz: 25439ccabe091bcc00b4c968272c3b00043aa3ffcf4a285b740877d47423ca9d9830dd26160d84631ff109fcbbcfab618b1c82eeabaf710d166d205d0125a98a
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  .remote-sync.json
11
11
  .token
12
12
  .updatereporc
13
+ *.log
data/README.md CHANGED
@@ -78,8 +78,7 @@ Not in any specific order :
78
78
  - Error checking and reporting for the git processes `[IN PROGRESS]`
79
79
  * Add more failure cases, not all git errors fail with "fatal:"
80
80
  - retry for connection issues etc (config setting).
81
- - Add extra (optional) stats / info at end-of-job :
82
- * list of changed repos
81
+ - Improve the stats / info at end-of-job :
83
82
  * errors or connection problems `[IN PROGRESS]`
84
83
  * _more..._
85
84
  - 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.
@@ -87,9 +86,10 @@ Not in any specific order :
87
86
  - Add ability to specify a new directory (containing Git repos) to search from the command line, and optionally save this to the standard configuration.
88
87
  - Add new repo from the command line that will be cloned to the default repo directory and then updated as usual. Extra flag added for "add only, clone later" for offline use.
89
88
  - Add flag for 'default' repo directory (or another specific directory - if it does not already exist it will be created and added to the standard list) which will be used for new additions.
90
- - Option to save log file for each run.
91
89
  - Add option to only display a (text) tree of the discovered git repositories, not updating them; Similar option to just dump a list of the remote git locations.
92
- - Add ability to export a text dump of each repo location `[DONE]` and then re-import this on a different machine or after reinstall `[TODO]`
90
+ - Add Import & Export functionality :
91
+ * ability to export a text dump of each repo location `[DONE]`
92
+ * re-import the above dump on a different machine or after reinstall
93
93
  - Document configuration file format and options.
94
94
  - Add testing!
95
95
 
data/Rakefile CHANGED
@@ -35,4 +35,4 @@ else
35
35
  end
36
36
  end
37
37
 
38
- task default: [:rubocop, :inch, :reek, :spec, :build]
38
+ task default: [:rubocop, :reek, :spec, :build]
@@ -14,9 +14,6 @@ module Helpers
14
14
  File.join(path_array)
15
15
  end
16
16
 
17
- # mark these as private simply so that 'reek' wont flag as utility function.
18
- private
19
-
20
17
  # true if we are dumping the file structure and git urls instead of updating.
21
18
  def dumping?
22
19
  param_set('dump')
@@ -27,6 +24,23 @@ module Helpers
27
24
  param_set('import')
28
25
  end
29
26
 
27
+ # true if we are logging to file.
28
+ def logging?
29
+ param_set('log')
30
+ end
31
+
32
+ # this function will simply pass the given string to 'print', and also
33
+ # log to file if that is specified.
34
+ def print_log(*string)
35
+ # log to screen regardless
36
+ print(*string)
37
+ # log to file if that has been enabled
38
+ @logfile.write(string.join('').gsub(/\e\[(\d+)(;\d+)*m/, '')) if logging?
39
+ end
40
+
41
+ # mark these as private simply so that 'reek' wont flag as utility function.
42
+ private
43
+
30
44
  def gitdir?(dirpath)
31
45
  gitpath = dirpath + '/.git'
32
46
  File.exist?(gitpath) && File.directory?(gitpath)
@@ -34,17 +48,11 @@ module Helpers
34
48
 
35
49
  def show_time(duration)
36
50
  time_taken = Time.at(duration).utc
37
- time_taken.strftime('%-H hours, %-M Minutes and %-S seconds.')
51
+ time_taken.strftime('%-H hours, %-M Minutes and %-S seconds')
38
52
  end
39
53
 
40
54
  # we cant use --dump and --import on the same command line
41
55
  def no_import_export
42
56
  Trollop.die 'update_repo : Cannot specify both --dump and --import'
43
57
  end
44
-
45
- # print the specified summary metric, called from the footer.
46
- def summary(which, color, event)
47
- output = "#{which} #{event}"
48
- print ' / ', output.send(color.to_sym) unless which.zero?
49
- end
50
58
  end
@@ -1,4 +1,4 @@
1
1
  module UpdateRepo
2
2
  # constant, current version of this Gem
3
- VERSION = '0.6.3'.freeze
3
+ VERSION = '0.7.0'.freeze
4
4
  end
data/lib/update_repo.rb CHANGED
@@ -20,7 +20,10 @@ module UpdateRepo
20
20
  # Class constructor. No parameters required.
21
21
  # @return [void]
22
22
  def initialize
23
- @metrics = { count: 0, skipped: 0, failed: 0, updated: 0, start_time: 0 }
23
+ @metrics = { processed: 0, skipped: 0, failed: 0, updated: 0,
24
+ start_time: 0 }
25
+ @summary = { processed: 'green', updated: 'cyan', skipped: 'yellow',
26
+ failed: 'red' }
24
27
  # read the options from Trollop and store in temp variable.
25
28
  # we do it this way around otherwise if configuration file is missing it
26
29
  # gives the error messages even on '--help' and '--version'
@@ -29,8 +32,7 @@ module UpdateRepo
29
32
  # allows easy access to the configuration data
30
33
  @config = Confoog::Settings.new(filename: CONFIG_FILE,
31
34
  prefix: 'update_repo',
32
- autoload: true,
33
- autosave: false)
35
+ autoload: true, autosave: false)
34
36
  # store the command line variables in a configuration variable
35
37
  @config['cmd'] = temp_opt
36
38
  config_error unless @config.status[:errors] == Status::INFO_FILE_LOADED
@@ -42,20 +44,39 @@ module UpdateRepo
42
44
  # walk_repo.start
43
45
  def start
44
46
  String.disable_colorization = true unless param_set('color')
45
- no_import_export if dumping? && importing?
47
+ # make sure we dont have bad cmd-line parameter combinations ...
48
+ check_params
49
+ # print out our header ...
50
+ show_header unless dumping? || importing?
51
+ @config['location'].each do |loc|
52
+ recurse_dir(loc)
53
+ end
54
+ # print out an informative footer ...
55
+ footer unless dumping? || importing?
56
+ end
57
+
58
+ private
59
+
60
+ def check_params
61
+ setup_logfile if logging?
62
+ if dumping? && importing?
63
+ Trollop.die 'Sorry, you cannot specify both --dump and --import '.red
64
+ end
46
65
  if importing?
47
66
  Trollop.die "Sorry 'Import' functionality is not implemented yet".red
48
- else
49
- show_header
50
- @config['location'].each do |loc|
51
- recurse_dir(loc)
52
- end
53
67
  end
54
- # print out an informative footer...
55
- footer
56
68
  end
57
69
 
58
- private
70
+ def setup_logfile
71
+ filename = if param_set('timestamp')
72
+ 'updaterepo-' + Time.new.strftime('%y%m%d-%H%M%S') + '.log'
73
+ else
74
+ 'updaterepo.log'
75
+ end
76
+ # filename = 'updaterepo' + prefix + '.log'
77
+ @logfile = File.open(filename, 'w')
78
+ @logfile.sync = true
79
+ end
59
80
 
60
81
  # Determine options from the command line and configuration file. Command
61
82
  # line takes precedence
@@ -65,8 +86,8 @@ module UpdateRepo
65
86
 
66
87
  def config_error
67
88
  if @config.status[:errors] == Status::ERR_CANT_LOAD
68
- print 'Note that the the default configuration file was '.red,
69
- "changed to ~/#{CONFIG_FILE} from v0.4.0 onwards\n\n".red
89
+ print_log 'Note that the the default configuration file was '.red,
90
+ "changed to ~/#{CONFIG_FILE} from v0.4.0 onwards\n\n".red
70
91
  end
71
92
  exit 1
72
93
  end
@@ -93,9 +114,10 @@ EOS
93
114
  opt :dump, 'Dump a list of Directories and Git URL\'s to STDOUT in CSV format', default: false
94
115
  opt :prune, "Number of directory levels to remove from the --dump output.\nOnly valid when --dump or -d specified", default: 0
95
116
  opt :import, "Import a previous dump of directories and Git repository URL's,\n(created using --dump) then proceed to clone them locally.", default: false
117
+ opt :log, "Create a logfile of all program output to './update_repo.log'. Any older logs will be overwritten.", default: false
118
+ opt :timestamp, 'Timestamp the logfile instead of overwriting. Does nothing unless the --log option is also specified.', default: false
96
119
  # opt :quiet, 'Only minimal output to the terminal', default: false
97
- # opt :silent, 'Completely silent, no output to terminal at all.',
98
- # default: false
120
+ # opt :silent, 'Completely silent, no output to terminal at all.', default: false
99
121
  end
100
122
  end
101
123
  # rubocop:enable Metrics/MethodLength
@@ -110,8 +132,6 @@ EOS
110
132
  next unless gitdir?(dir)
111
133
  if dumping?
112
134
  dump_repo(File.join(dirname, dir))
113
- elsif importing?
114
- # placeholder
115
135
  else
116
136
  notexception?(dir) ? update_repo(dir) : skip_repo(dir)
117
137
  end
@@ -133,53 +153,57 @@ EOS
133
153
  def show_header
134
154
  # print an informative header before starting
135
155
  # unless we are dumping the repo information
136
- return if dumping?
137
- print "\nGit Repo update utility (v", VERSION, ')',
138
- " \u00A9 Grant Ramsay <seapagan@gmail.com>\n"
139
- print "Using Configuration from '#{@config.config_path}'\n"
140
- print "Command line is : #{@config['cmd']}\n"
156
+ print_log "\nGit Repo update utility (v", VERSION, ')',
157
+ " \u00A9 Grant Ramsay <seapagan@gmail.com>\n"
158
+ print_log "Using Configuration from '#{@config.config_path}'\n"
159
+ # print_log "Command line is : #{@config['cmd']}\n"
141
160
  # list out the locations that will be searched
142
161
  list_locations
143
162
  # list any exceptions that we have from the config file
144
163
  list_exceptions
145
164
  # save the start time for later display in the footer...
146
165
  @metrics[:start_time] = Time.now
147
- print "\n" # blank line before processing starts
166
+ print_log "\n" # blank line before processing starts
148
167
  end
149
168
 
150
169
  # print out a brief footer. This will be expanded later.
151
170
  # @return [void]
152
171
  def footer
153
- # no footer if we are dumping the repo information
154
- return if dumping?
155
172
  duration = Time.now - @metrics[:start_time]
156
- print "\nUpdates completed : ", @metrics[:count].to_s.green,
157
- ' repositories processed'.green
158
- summary(@metrics[:updated], 'cyan', 'updated')
159
- summary(@metrics[:skipped], 'yellow', 'skipped')
160
- summary(@metrics[:failed], 'red', 'failed')
161
- print ' in ', show_time(duration).cyan, "\n\n"
173
+ print_log "\nUpdates completed in ", show_time(duration).cyan
174
+ print_metrics
175
+ print_log " |\n\n"
176
+ # close the log file now as we are done, just to be sure ...
177
+ @logfile.close if @logfile
178
+ end
179
+
180
+ def print_metrics
181
+ @summary.each do |metric, color|
182
+ metric_value = @metrics[metric]
183
+ output = "#{metric_value} #{metric.capitalize}"
184
+ print_log ' | ', output.send(color.to_sym) unless metric_value.zero?
185
+ end
162
186
  end
163
187
 
164
188
  def list_exceptions
165
189
  exceptions = @config['exceptions']
166
190
  if exceptions
167
- print "\nExclusions:".underline, ' ',
168
- exceptions.join(', ').yellow, "\n"
191
+ print_log "\nExclusions:".underline, ' ',
192
+ exceptions.join(', ').yellow, "\n"
169
193
  end
170
194
  end
171
195
 
172
196
  def list_locations
173
- print "\nRepo location(s):\n".underline
197
+ print_log "\nRepo location(s):\n".underline
174
198
  @config['location'].each do |loc|
175
- print '-> ', loc.cyan, "\n"
199
+ print_log '-> ', loc.cyan, "\n"
176
200
  end
177
201
  end
178
202
 
179
203
  def skip_repo(dirpath)
180
204
  Dir.chdir(dirpath.chomp!('/')) do
181
205
  repo_url = `git config remote.origin.url`.chomp
182
- print '* Skipping ', Dir.pwd.yellow, " (#{repo_url})\n"
206
+ print_log '* Skipping ', Dir.pwd.yellow, " (#{repo_url})\n"
183
207
  @metrics[:skipped] += 1
184
208
  end
185
209
  end
@@ -188,13 +212,14 @@ EOS
188
212
  Dir.chdir(dirname.chomp!('/')) do
189
213
  repo_url = `git config remote.origin.url`.chomp
190
214
  do_update(repo_url)
191
- @metrics[:count] += 1
215
+ @metrics[:processed] += 1
192
216
  end
193
217
  end
194
218
 
195
219
  def do_update(repo_url)
196
- print '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
197
- Open3.popen3('git pull') do |_stdin, stdout, stderr, thread|
220
+ print_log '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
221
+ Open3.popen3('git pull') do |stdin, stdout, stderr, thread|
222
+ stdin.close
198
223
  do_threads(stdout, stderr)
199
224
  thread.join
200
225
  end
@@ -205,12 +230,11 @@ EOS
205
230
  Thread.new do
206
231
  while (line = stream.gets)
207
232
  if key == :err && line =~ /^fatal:/
208
- print ' ', line.red
233
+ print_log ' ', line.red
209
234
  @metrics[:failed] += 1
210
235
  else
211
- print ' ', line.cyan
212
- # @metrics[:updated] += 1 if line =~ /files?\schanged/
213
- @metrics[:updated] += 1 if line =~ /^From\shttps?:\/\//
236
+ print_log ' ', line.cyan
237
+ @metrics[:updated] += 1 if line =~ %r{^From\shttps?://}
214
238
  end
215
239
  end
216
240
  end
@@ -220,7 +244,7 @@ EOS
220
244
  def dump_repo(dir)
221
245
  Dir.chdir(dir.chomp!('/')) do
222
246
  repo_url = `git config remote.origin.url`.chomp
223
- print "#{trunc_dir(dir, @config['cmd'][:prune])},#{repo_url}\n"
247
+ print_log "#{trunc_dir(dir, @config['cmd'][:prune])},#{repo_url}\n"
224
248
  end
225
249
  end
226
250
  end
data/update_repo.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'pry'
27
27
  spec.add_development_dependency 'fakefs'
28
28
  spec.add_development_dependency 'json', '= 1.8.3'
29
+ spec.add_development_dependency 'tins', '= 1.6.0'
29
30
  spec.add_development_dependency 'coveralls'
30
31
  spec.add_development_dependency 'inch'
31
32
  spec.add_development_dependency 'simplecov', '~> 0.10'
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.6.3
4
+ version: 0.7.0
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-07-27 00:00:00.000000000 Z
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
96
  version: 1.8.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: tins
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 1.6.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 1.6.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: coveralls
99
113
  requirement: !ruby/object:Gem::Requirement