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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 893b9fd1eae35a35c0d7ce7a82b6efe253a15449
4
- data.tar.gz: 29c9899ac3a25735ac57ceb3c3d9efb831268fc0
3
+ metadata.gz: 54b552a96cddc68af766238152689994aafe1bb6
4
+ data.tar.gz: 747b8dbf6ff74ca6c9269d0f6bcf8b29407a8069
5
5
  SHA512:
6
- metadata.gz: f7666c09dddb317c4cca5a47ac27f27fbdd1a35e41ca92459c11b2e3da467e74a097669106d46008dda0134b063d9d632c3164eae60b81a201204fe696feeae3
7
- data.tar.gz: 20c9a53429cabdaf77e978c5f8ae2e092048e776af8d5c75b3adec0f5f1cbc5a603b8a93ff4ff0e3f103f586d8cfb5023d02bdc9a09d57761846170a05fefa2e
6
+ metadata.gz: 2c58773f1dcb1f4c1116cfed2961cdebb20e23384b91c563113267ff70c969a76fbc0f5e5d31dbd78bccb37e9cb2df20d4c9ba4a74a3ebe9d703410ee1180a2f
7
+ data.tar.gz: 440ec4e0c252ab6670a00816c501e0b1b51567870406babe2587b8d2365484ba3744c29ce286c7a9743b3455a3d4431f3e896d45052469be4ea622cd09d7c950
data/.reek CHANGED
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  TooManyStatements:
3
- max_statements: 10
3
+ max_statements: 8
4
+ exclude:
5
+ - set_options
4
6
 
5
7
  UtilityFunction:
6
8
  public_methods_only: true
data/.travis.yml CHANGED
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0
5
- - 2.1
6
- - 2.2
7
- - 2.3
3
+ - 1.9.3-p551
4
+ - 2.0.0-p648
5
+ - 2.1.10
6
+ - 2.2.5
7
+ - 2.3.1
8
8
  before_install: gem install bundler -v 1.13.6
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
- # opt :quiet, 'Only minimal output to the terminal', default: false
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
@@ -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
- # log to screen regardless
44
- print(*string)
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]
@@ -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
@@ -1,4 +1,4 @@
1
1
  module UpdateRepo
2
2
  # constant, current version of this Gem
3
- VERSION = '0.8.8'.freeze
3
+ VERSION = '0.9.0'.freeze
4
4
  end
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
- do_update
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
- end
124
- end
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.4' if RUBY_VERSION >= '2.1'
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.8.8
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.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.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