update_repo 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -1
- data/Rakefile +1 -1
- data/lib/update_repo/cmd_config.rb +25 -8
- data/lib/update_repo/helpers.rb +2 -0
- data/lib/update_repo/version.rb +1 -1
- data/lib/update_repo.rb +90 -21
- data/update_repo.gemspec +2 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b68ac5a08795af79e528b813aa2e74fe628a816f
|
4
|
+
data.tar.gz: 5efdbb27dc053c02f4bfb76dcfd2f353b7f3b290
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47348f246c0c6e179da7e689f2fb1b35ffacf3e0da72b2b798c1536815fce3d50d6f2859565ecd9bec06bfb9aba7a20a9f1839c08dcf10d5ca28c389b13ccce2
|
7
|
+
data.tar.gz: ddc661515526cbc5414deb1de0f8bb5f6eaea8057c6efba573b743a5e94c95231cefdf64efc8288a8285f188c60a4d87a17d1726dd974578432ac1b1e6da08aa
|
data/.gitignore
CHANGED
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
@@ -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
|
-
#
|
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
|
-
#
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
data/lib/update_repo/helpers.rb
CHANGED
@@ -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)
|
data/lib/update_repo/version.rb
CHANGED
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
|
-
|
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
|
48
|
+
footer unless dumping?
|
50
49
|
end
|
51
50
|
|
52
|
-
|
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
|
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 "
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
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
|
-
|
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
|
-
|
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.
|
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
|
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:
|