update_repo 0.8.8 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|