update_repo 0.8.8 → 0.9.0
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/.reek +3 -1
- data/.travis.yml +5 -5
- data/README.md +2 -0
- data/exe/update_repo +0 -0
- data/lib/update_repo/cmd_config.rb +4 -2
- data/lib/update_repo/console_output.rb +1 -1
- data/lib/update_repo/git_control.rb +83 -0
- data/lib/update_repo/logger.rb +44 -4
- data/lib/update_repo/metrics.rb +1 -20
- data/lib/update_repo/version.rb +1 -1
- data/lib/update_repo.rb +11 -32
- data/update_repo.gemspec +2 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54b552a96cddc68af766238152689994aafe1bb6
|
4
|
+
data.tar.gz: 747b8dbf6ff74ca6c9269d0f6bcf8b29407a8069
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c58773f1dcb1f4c1116cfed2961cdebb20e23384b91c563113267ff70c969a76fbc0f5e5d31dbd78bccb37e9cb2df20d4c9ba4a74a3ebe9d703410ee1180a2f
|
7
|
+
data.tar.gz: 440ec4e0c252ab6670a00816c501e0b1b51567870406babe2587b8d2365484ba3744c29ce286c7a9743b3455a3d4431f3e896d45052469be4ea622cd09d7c950
|
data/.reek
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,8 @@ A Simple Gem to keep multiple locally-cloned Git Repositories up to date.
|
|
11
11
|
This is the conversion to a Gem of one of my standalone Ruby scripts. Still very much a work in progress but the required basic functionality is there.
|
12
12
|
The script will simply run `git pull` on every local clone of a git repository that it finds under the specified directory or directories.
|
13
13
|
|
14
|
+
__Note:__ From version 0.9.0 onwards, the default mode of operation is non-verbose. If you wish the same output as previous versions then specify `--verbose` on the command line or `verbose: true` in the configuration file.
|
15
|
+
|
14
16
|
## Installation
|
15
17
|
|
16
18
|
#### Pre-requirements
|
data/exe/update_repo
CHANGED
File without changes
|
@@ -38,6 +38,7 @@ module UpdateRepo
|
|
38
38
|
# both command line (given preference) and the configuration file.
|
39
39
|
# @param command [symbol] The symbol of the defined command
|
40
40
|
# @return [various] Returns the true value of the comamnd symbol
|
41
|
+
# ignore the :reek:NilCheck for this function
|
41
42
|
def true_cmd(command)
|
42
43
|
cmd_given = @conf['cmd'][(command.to_s + '_given').to_sym]
|
43
44
|
cmd_line = @conf['cmd'][command.to_sym]
|
@@ -101,13 +102,14 @@ Options:
|
|
101
102
|
EOS
|
102
103
|
opt :color, 'Use colored output', default: true
|
103
104
|
opt :dump, 'Dump a list of Directories and Git URL\'s to STDOUT in CSV format', default: false
|
104
|
-
opt :prune, "Number of directory levels to remove from the --dump output.\nOnly valid when --dump or -d specified", default: 0
|
105
|
+
opt :prune, "Number of directory levels to remove from the --dump output.\nOnly valid when --dump or -d specified.", default: 0
|
105
106
|
# 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
|
106
107
|
opt :log, "Create a logfile of all program output to './update_repo.log'. Any older logs will be overwritten.", default: false
|
107
108
|
opt :timestamp, 'Timestamp the logfile instead of overwriting. Does nothing unless the --log option is also specified.', default: false
|
108
109
|
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'
|
109
110
|
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'
|
110
|
-
|
111
|
+
opt :verbose, 'Display each repository and the git output to screen', default: false, short: 'V'
|
112
|
+
opt :quiet, 'Run completely silent, with no output to the terminal (except fatal errors).', default: false
|
111
113
|
# opt :silent, 'Completely silent, no output to terminal at all.', default: false
|
112
114
|
end
|
113
115
|
end
|
@@ -16,7 +16,7 @@ module UpdateRepo
|
|
16
16
|
# console = ConsoleOutput.new(@log)
|
17
17
|
def initialize(logger, metrics, config)
|
18
18
|
@summary = { processed: 'green', updated: 'cyan', skipped: 'yellow',
|
19
|
-
failed: 'red' }
|
19
|
+
failed: 'red', unchanged: 'white' }
|
20
20
|
@metrics = metrics
|
21
21
|
@log = logger
|
22
22
|
@config = config.getconfig
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'update_repo/version'
|
2
|
+
require 'update_repo/helpers'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module UpdateRepo
|
6
|
+
# Class : GitControl.
|
7
|
+
# This class will update one git repo, and send the output to the logger.
|
8
|
+
# It will also return status of the operation in #status.
|
9
|
+
class GitControl
|
10
|
+
include Helpers
|
11
|
+
|
12
|
+
# @return [hash] Return the status hash
|
13
|
+
attr_reader :status
|
14
|
+
|
15
|
+
# Constructor for the GitControl class.
|
16
|
+
# @param repo [string] Repo name
|
17
|
+
# @param logger [instance] pointer to the Logger class
|
18
|
+
# @param metrics [instance] pointer to the Metrics class
|
19
|
+
# @return [void]
|
20
|
+
# @example
|
21
|
+
# git = GitControl.new(repo_url, @logger, @metrics)
|
22
|
+
def initialize(repo, logger, metrics)
|
23
|
+
@status = { updated: false, failed: false, unchanged: false }
|
24
|
+
@repo = repo
|
25
|
+
@log = logger
|
26
|
+
@metrics = metrics
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update the git repo that was specified in the initializer.
|
30
|
+
# @param [none]
|
31
|
+
# @return [void]
|
32
|
+
def update
|
33
|
+
print_log '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
|
34
|
+
Open3.popen3('git pull') do |stdin, stdout, stderr, thread|
|
35
|
+
stdin.close
|
36
|
+
do_threads(stdout, stderr)
|
37
|
+
thread.join
|
38
|
+
end
|
39
|
+
# reset the updated status in the rare case than both update and failed
|
40
|
+
# are set. This does happen!
|
41
|
+
@status[:updated] = false if @status[:updated] && @status[:failed]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Create 2 individual threads to handle both STDOUT and STDERR streams,
|
47
|
+
# writing to console and log if specified.
|
48
|
+
# @param stdout [stream] STDOUT Stream from the popen3 call
|
49
|
+
# @param stderr [stream] STDERR Stream from the popen3 call
|
50
|
+
# @return [void]
|
51
|
+
def do_threads(stdout, stderr)
|
52
|
+
{ out: stdout, err: stderr }.each do |key, stream|
|
53
|
+
Thread.new do
|
54
|
+
while (line = stream.gets)
|
55
|
+
handle_err(line) if key == :err
|
56
|
+
handle_output(line) if key == :out
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# output an error line and update the metrics
|
63
|
+
# @param line [string] The string containing the error message
|
64
|
+
# @return [void]
|
65
|
+
def handle_err(line)
|
66
|
+
return unless line =~ /^fatal:|^error:/
|
67
|
+
print_log ' ', line.red
|
68
|
+
@status[:failed] = true
|
69
|
+
err_loc = Dir.pwd + " (#{@repo})"
|
70
|
+
@metrics[:failed_list].push(loc: err_loc, line: line)
|
71
|
+
end
|
72
|
+
|
73
|
+
# print a git output line and update the metrics if an update has occurred
|
74
|
+
# @param line [string] The string containing the git output line
|
75
|
+
# @return [void]
|
76
|
+
# rubocop:disable Metrics/LineLength
|
77
|
+
def handle_output(line)
|
78
|
+
print_log ' ', line.cyan
|
79
|
+
@status[:updated] = true if line =~ /^Updating\s[0-9a-f]{7}\.\.[0-9a-f]{7}/
|
80
|
+
@status[:unchanged] = true if line =~ /^Already up-to-date./
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/update_repo/logger.rb
CHANGED
@@ -10,11 +10,14 @@ module UpdateRepo
|
|
10
10
|
# Constructor for the Logger class.
|
11
11
|
# @param enabled [boolean] True if we log to file
|
12
12
|
# @param timestamp [boolean] True if we timestamp the filename
|
13
|
+
# @param verbose [boolean] True if verbose flag is set
|
14
|
+
# @param quiet [boolean] True if quiet flag is set
|
13
15
|
# @return [void]
|
14
16
|
# @example
|
15
17
|
# log = Logger.new(true, false)
|
16
|
-
def initialize(enabled, timestamp)
|
17
|
-
@settings = { enabled: enabled, timestamp: timestamp
|
18
|
+
def initialize(enabled, timestamp, verbose, quiet)
|
19
|
+
@settings = { enabled: enabled, timestamp: timestamp, verbose: verbose,
|
20
|
+
quiet: quiet }
|
18
21
|
# don't prepare a logfile unless it's been requested.
|
19
22
|
return unless @settings[:enabled]
|
20
23
|
# generate a filename depending on 'timestamp' setting.
|
@@ -40,13 +43,50 @@ module UpdateRepo
|
|
40
43
|
# @param string [array] Array of strings for print formatting
|
41
44
|
# @return [void]
|
42
45
|
def output(*string)
|
43
|
-
#
|
44
|
-
|
46
|
+
# nothing to screen if we want to be --quiet
|
47
|
+
unless @settings[:quiet]
|
48
|
+
# log header and footer to screen regardless
|
49
|
+
print(*string) if @settings[:verbose] || !repo_text?
|
50
|
+
end
|
45
51
|
# log to file if that has been enabled
|
46
52
|
return unless @settings[:enabled]
|
47
53
|
@logfile.write(string.join('').gsub(/\e\[(\d+)(;\d+)*m/, ''))
|
48
54
|
end
|
49
55
|
|
56
|
+
# function repostat - outputs the passed char at the passed color,
|
57
|
+
# only if we are not in quiet nor verbose mode.
|
58
|
+
# @param status [hash] pointer to GitControl.status hash
|
59
|
+
# @return [void]
|
60
|
+
def repostat(status)
|
61
|
+
# only print if not quiet and not verbose!
|
62
|
+
return if @settings[:quiet] || @settings[:verbose]
|
63
|
+
if status[:failed]
|
64
|
+
print 'x'.red
|
65
|
+
elsif status[:updated]
|
66
|
+
print '^'.green
|
67
|
+
elsif status[:unchanged]
|
68
|
+
print '.'
|
69
|
+
elsif status[:skipped]
|
70
|
+
print 's'.yellow
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# returns non nil if we have been called originally by one of the Repo
|
75
|
+
# update output functions.
|
76
|
+
# @param [none]
|
77
|
+
# @return [boolean] True if we have been called during repo update
|
78
|
+
def repo_text?
|
79
|
+
# get calling function - need to skip first 2, also remove 'block in '
|
80
|
+
# prefix if exists
|
81
|
+
calling_fn = caller_locations[2].label.gsub(/block in /, '')
|
82
|
+
|
83
|
+
# array with the functions we want to skip
|
84
|
+
repo_output = %w(do_update handle_output handle_err skip_repo update)
|
85
|
+
|
86
|
+
# return the name in string if DOES match.
|
87
|
+
calling_fn if repo_output.include?(calling_fn)
|
88
|
+
end
|
89
|
+
|
50
90
|
# close the logfile, if it exists
|
51
91
|
# @param [none]
|
52
92
|
# @return [void]
|
data/lib/update_repo/metrics.rb
CHANGED
@@ -13,7 +13,7 @@ module UpdateRepo
|
|
13
13
|
def initialize(logger)
|
14
14
|
@log = logger
|
15
15
|
@metrics = { processed: 0, skipped: 0, failed: 0, updated: 0,
|
16
|
-
start_time: 0, failed_list: [] }
|
16
|
+
unchanged: 0, start_time: 0, failed_list: [] }
|
17
17
|
end
|
18
18
|
|
19
19
|
# Read the metric 'key'
|
@@ -30,24 +30,5 @@ module UpdateRepo
|
|
30
30
|
def []=(key, value)
|
31
31
|
@metrics[key] = value
|
32
32
|
end
|
33
|
-
|
34
|
-
# output an error line and update the metrics
|
35
|
-
# @param line [string] The string containing the error message
|
36
|
-
# @return [void]
|
37
|
-
def handle_err(line)
|
38
|
-
return unless line =~ /^fatal:|^error:/
|
39
|
-
print_log ' ', line.red
|
40
|
-
@metrics[:failed] += 1
|
41
|
-
err_loc = Dir.pwd + " (#{repo_url})"
|
42
|
-
@metrics[:failed_list].push(loc: err_loc, line: line)
|
43
|
-
end
|
44
|
-
|
45
|
-
# print a git output line and update the metrics if an update has occurred
|
46
|
-
# @param line [string] The string containing the git output line
|
47
|
-
# @return [void]
|
48
|
-
def handle_output(line)
|
49
|
-
print_log ' ', line.cyan
|
50
|
-
@metrics[:updated] += 1 if line =~ %r{^From\s(?:https?|git)://}
|
51
|
-
end
|
52
33
|
end
|
53
34
|
end
|
data/lib/update_repo/version.rb
CHANGED
data/lib/update_repo.rb
CHANGED
@@ -4,11 +4,11 @@ require 'update_repo/cmd_config'
|
|
4
4
|
require 'update_repo/logger'
|
5
5
|
require 'update_repo/console_output'
|
6
6
|
require 'update_repo/metrics'
|
7
|
+
require 'update_repo/git_control'
|
7
8
|
require 'yaml'
|
8
9
|
require 'colorize'
|
9
10
|
require 'confoog'
|
10
11
|
require 'trollop'
|
11
|
-
require 'open3'
|
12
12
|
|
13
13
|
# Overall module with classes performing the functionality
|
14
14
|
# Contains Class UpdateRepo::WalkRepo
|
@@ -26,7 +26,7 @@ module UpdateRepo
|
|
26
26
|
# create a new instance of the CmdConfig class then read the config var
|
27
27
|
@cmd = CmdConfig.new
|
28
28
|
# set up the output and logging class
|
29
|
-
@log = Logger.new(cmd(:log), cmd(:timestamp))
|
29
|
+
@log = Logger.new(cmd(:log), cmd(:timestamp), cmd(:verbose), cmd(:quiet))
|
30
30
|
# create instance of the Metrics class
|
31
31
|
@metrics = Metrics.new(@log)
|
32
32
|
# instantiate the console output class for header, footer etc
|
@@ -107,6 +107,8 @@ module UpdateRepo
|
|
107
107
|
repo_url = `git config remote.origin.url`.chomp
|
108
108
|
print_log '* Skipping ', Dir.pwd.yellow, " (#{repo_url})\n"
|
109
109
|
@metrics[:skipped] += 1
|
110
|
+
@log.repostat(skipped: true)
|
111
|
+
@metrics[:processed] += 1
|
110
112
|
end
|
111
113
|
end
|
112
114
|
|
@@ -118,38 +120,15 @@ module UpdateRepo
|
|
118
120
|
# update_repo('/Repo/linux/stable')
|
119
121
|
def update_repo(dirname)
|
120
122
|
Dir.chdir(dirname.chomp!('/')) do
|
121
|
-
|
123
|
+
# create the git instance and then perform the update
|
124
|
+
git = GitControl.new(repo_url, @log, @metrics)
|
125
|
+
git.update
|
122
126
|
@metrics[:processed] += 1
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
# Actually perform the update of this specific repository, calling the
|
127
|
-
# function #do_threads to handle the output to screen and log.
|
128
|
-
# @param none
|
129
|
-
# @return [void]
|
130
|
-
def do_update
|
131
|
-
# repo_url = `git config remote.origin.url`.chomp
|
132
|
-
print_log '* Checking ', Dir.pwd.green, " (#{repo_url})\n"
|
133
|
-
Open3.popen3('git pull') do |stdin, stdout, stderr, thread|
|
134
|
-
stdin.close
|
135
|
-
do_threads(stdout, stderr)
|
136
|
-
thread.join
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Create 2 individual threads to handle both STDOUT and STDERR streams,
|
141
|
-
# writing to console and log if specified.
|
142
|
-
# @param stdout [stream] STDOUT Stream from the popen3 call
|
143
|
-
# @param stderr [stream] STDERR Stream from the popen3 call
|
144
|
-
# @return [void]
|
145
|
-
def do_threads(stdout, stderr)
|
146
|
-
{ out: stdout, err: stderr }.each do |key, stream|
|
147
|
-
Thread.new do
|
148
|
-
while (line = stream.gets)
|
149
|
-
@metrics.handle_err(line) if key == :err
|
150
|
-
@metrics.handle_output(line) if key == :out
|
151
|
-
end
|
127
|
+
# update the metrics
|
128
|
+
[:failed, :updated, :unchanged].each do |metric|
|
129
|
+
@metrics[metric] += 1 if git.status[metric]
|
152
130
|
end
|
131
|
+
@log.repostat(git.status)
|
153
132
|
end
|
154
133
|
end
|
155
134
|
|
data/update_repo.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# rubocop:disable LineLength
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
3
4
|
lib = File.expand_path('../lib', __FILE__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
require 'update_repo/version'
|
@@ -36,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
36
37
|
# Below this we fix to the last working versions to keep Ruby 1.9.3 compat or
|
37
38
|
# we ignore completely - Reek and Rubocop working in the latest versions is
|
38
39
|
# enough since the code base is common.
|
39
|
-
spec.add_development_dependency 'reek', '~> 4.
|
40
|
+
spec.add_development_dependency 'reek', '~> 4.5' if RUBY_VERSION >= '2.1'
|
40
41
|
spec.add_development_dependency 'rubocop' if RUBY_VERSION >= '2.0'
|
41
42
|
|
42
43
|
if RUBY_VERSION < '2.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: update_repo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grant Ramsay
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '4.
|
173
|
+
version: '4.5'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '4.
|
180
|
+
version: '4.5'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rubocop
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- lib/update_repo.rb
|
260
260
|
- lib/update_repo/cmd_config.rb
|
261
261
|
- lib/update_repo/console_output.rb
|
262
|
+
- lib/update_repo/git_control.rb
|
262
263
|
- lib/update_repo/helpers.rb
|
263
264
|
- lib/update_repo/logger.rb
|
264
265
|
- lib/update_repo/metrics.rb
|