autoproj-git 1.0.4 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7474cb8e9b1582cc738897f3808029d2030e21ab
4
- data.tar.gz: 75ebdf1817d68911f86ca90595effb7510105b0f
2
+ SHA256:
3
+ metadata.gz: 378cf3a2d556f14864f326623499d2f0e08acc41b524554a5faec1725bc26ae4
4
+ data.tar.gz: de8bcaac11cd8f727724b8e318cc90d85f5004108a6dcea1c3d53da1866cf833
5
5
  SHA512:
6
- metadata.gz: ab0478a5b553af6beb1568e1d93c24f2e83c7319c4e4d6075d0af90364b6c529043bbf9cd7a38debf596c367783b60275aafe1fb3f222a740894457addf300e3
7
- data.tar.gz: 8eff2bd002be02900e6d9e11576041ad6926b41a8e6cf35ec1486f1d56475f269d21a65e171c18ce73bd25c2e3678b75fb13661595bb9dd712e9ed796af53e66
6
+ metadata.gz: 3a44911976950df946a4ba7767b31a2c495182f32b693b6439a82a39c4565aa8fe6a265532323bde42e6a151f1a8c23716f94d93b487f2ca1cf99b43de8f7f1d
7
+ data.tar.gz: b643edb72aed93af0022afc714e6657b3571348f59818cc9edfa0136ef5e7aca202d53e5c588f4faa3e0dd645caaee3813698e5eec3aa5b3e42bdf1c12aec54f
@@ -6,36 +6,64 @@ module Autoproj
6
6
  module CLI
7
7
  class Git < InspectionTool
8
8
  def cleanup(user_selection, options = Hash.new)
9
- initialize_and_load
10
- source_packages, * =
11
- finalize_setup(user_selection,
12
- non_imported_packages: :ignore)
13
- git_packages = source_packages.map do |pkg_name|
14
- pkg = ws.manifest.find_autobuild_package(pkg_name)
15
- pkg if pkg.importer.kind_of?(Autobuild::Git)
16
- end.compact
9
+ git_packages = resolve_selected_git_packages(user_selection)
10
+ run_parallel(git_packages) do |pkg, i|
11
+ cleanup_package(pkg, " [#{i}/#{git_packages.size}]",
12
+ local: options[:local],
13
+ remove_obsolete_remotes: options[:remove_obsolete_remotes])
14
+ end
15
+ end
17
16
 
18
- package_failures = []
19
- pool = Concurrent::FixedThreadPool.new(4)
20
- futures = git_packages.each_with_index.map do |pkg, i|
21
- Concurrent::Future.execute(executor: pool) do
22
- begin
23
- cleanup_package(pkg, " [#{i}/#{git_packages.size}]",
24
- local: options[:local],
25
- remove_obsolete_remotes: options[:remove_obsolete_remotes])
26
- nil
27
- rescue Autobuild::SubcommandFailed => e
28
- Autoproj.error "failed: #{e.message}"
29
- e
30
- end
17
+ MATCH_ALL = proc { true }
18
+ MATCH_NONE = proc { }
19
+
20
+ def authors(options = Hash.new)
21
+ packages = resolve_selected_git_packages([])
22
+ all_lines = run_parallel(packages) do |pkg, _|
23
+ pkg.importer.run_git(pkg, 'shortlog', '-s', '-e')
24
+ end.flatten
25
+
26
+ all_authors = Set.new
27
+ all_lines.each do |line|
28
+ match = /^\s*\d+\s+(.+)$/.match(line)
29
+ all_authors << match[1] if match
30
+ end
31
+ puts all_authors.to_a.sort.join("\n")
32
+ end
33
+
34
+ def extension_stats(options = Hash.new)
35
+ git_packages = resolve_selected_git_packages([])
36
+
37
+ stats = compute_stats(git_packages) do |pkg, filename|
38
+ File.extname(filename)
39
+ end
40
+ display_stats(stats)
41
+ end
42
+
43
+ def author_stats(authors, options = Hash.new)
44
+ git_packages = resolve_selected_git_packages([])
45
+
46
+ include_filter =
47
+ if options[:include]
48
+ Regexp.new(options[:include], Regexp::IGNORECASE)
49
+ else
50
+ MATCH_ALL
51
+ end
52
+
53
+ exclude_filter =
54
+ if options[:exclude]
55
+ Regexp.new(options[:exclude], Regexp::IGNORECASE)
56
+ else
57
+ MATCH_NONE
58
+ end
59
+
60
+
61
+ stats = compute_stats(git_packages, "--use-mailmap", *authors.map { |a| "--author=#{a}" }) do |pkg, filename|
62
+ if (include_filter === filename) && !(exclude_filter === filename)
63
+ pkg.name
31
64
  end
32
65
  end
33
- package_failures = futures.each(&:execute).map(&:value!).compact
34
- rescue Interrupt => interrupt
35
- ensure
36
- pool.shutdown if pool
37
- Autobuild::Reporting.report_finish_on_error(
38
- package_failures, on_package_failures: :raise, interrupted_by: interrupt)
66
+ display_stats(stats)
39
67
  end
40
68
 
41
69
  def git_clean_invalid_refs(pkg, progress)
@@ -99,6 +127,72 @@ module Autoproj
99
127
  git_gc(pkg, progress)
100
128
  git_repack(pkg, progress)
101
129
  end
130
+
131
+ def resolve_selected_git_packages(user_selection)
132
+ initialize_and_load
133
+ source_packages, * =
134
+ finalize_setup(user_selection,
135
+ non_imported_packages: :ignore)
136
+ source_packages.map do |pkg_name|
137
+ pkg = ws.manifest.find_autobuild_package(pkg_name)
138
+ pkg if pkg.importer.kind_of?(Autobuild::Git)
139
+ end.compact
140
+ end
141
+
142
+ def run_parallel(objects, &block)
143
+ pool = Concurrent::FixedThreadPool.new(4)
144
+ futures = objects.each_with_index.map do |obj, i|
145
+ Concurrent::Future.execute(executor: pool) do
146
+ begin
147
+ result = yield(obj, i)
148
+ [result, nil]
149
+ rescue Autobuild::SubcommandFailed => e
150
+ Autoproj.error "failed: #{e.message}"
151
+ [nil, e]
152
+ end
153
+ end
154
+ end
155
+ result = futures.each(&:execute).map(&:value!).compact
156
+ failures = result.map(&:last).compact
157
+ result.map(&:first)
158
+ rescue Interrupt => interrupt
159
+ ensure
160
+ pool.shutdown if pool
161
+ Autobuild::Reporting.report_finish_on_error(
162
+ failures || [], on_package_failures: :raise, interrupted_by: interrupt)
163
+ end
164
+
165
+ def compute_stats(packages, *log_options)
166
+ all_runs = run_parallel(packages) do |pkg, _|
167
+ lines = pkg.importer.run_git(
168
+ pkg, 'log', *log_options, '--pretty=tformat:', '--numstat')
169
+ [pkg, lines]
170
+ end
171
+
172
+ all_runs.each_with_object(Hash.new) do |(pkg, lines), stats|
173
+ lines.each do |l|
174
+ match = /^\s*(\d+)\s+(\d+)\s+(.*)/.match(l)
175
+ if match && (key = yield(pkg, match[3]))
176
+ key_stats = (stats[key] ||= [0, 0])
177
+ key_stats[0] += Integer(match[1])
178
+ key_stats[1] += Integer(match[2])
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ def display_stats(stats, io: STDOUT)
185
+ total_p, total_m = 0, 0
186
+ stats.keys.sort.each do |text|
187
+ p, m = stats[text]
188
+ total_p += p
189
+ total_m += m
190
+ unless p == 0 && m == 0
191
+ io.puts format("+%6i -%6i %s", p, m, text)
192
+ end
193
+ end
194
+ io.puts format("+%6i -%6i %s", total_p, total_m, "Total")
195
+ end
102
196
  end
103
197
  end
104
198
  end
@@ -15,6 +15,40 @@ module Autoproj
15
15
  cli.cleanup(*args)
16
16
  end
17
17
  end
18
+
19
+ desc 'authors', 'list all authors (useful to tune a mailmap file)'
20
+ def authors
21
+ require 'autoproj/cli/git'
22
+ Autoproj.report(silent: true) do
23
+ cli = Git.new
24
+ _, options = cli.validate_options([], self.options)
25
+ cli.authors(options)
26
+ end
27
+ end
28
+
29
+ desc 'ext-stats', 'show diffstat statistics on a per-extension basis'
30
+ def ext_stats
31
+ require 'autoproj/cli/git'
32
+ Autoproj.report(silent: true) do
33
+ cli = Git.new
34
+ _, options = cli.validate_options([], self.options)
35
+ cli.extension_stats(options)
36
+ end
37
+ end
38
+
39
+ desc 'author-stats AUTHOR [PACKAGES]', 'show diffstat statistics about a given author'
40
+ option :include, type: :string,
41
+ desc: 'regular expression of file names that should be counted'
42
+ option :exclude, type: :string,
43
+ desc: 'regular expression of file names that should not be counted'
44
+ def author_stats(*authors)
45
+ require 'autoproj/cli/git'
46
+ Autoproj.report(silent: true) do
47
+ cli = Git.new
48
+ authors, options = cli.validate_options(authors, self.options)
49
+ cli.author_stats(authors, options)
50
+ end
51
+ end
18
52
  end
19
53
  end
20
54
  end
@@ -1,5 +1,5 @@
1
1
  module Autoproj
2
2
  module Git
3
- VERSION = "1.0.4"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoproj-git
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: autoproj
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  version: '0'
126
126
  requirements: []
127
127
  rubyforge_project:
128
- rubygems_version: 2.5.1
128
+ rubygems_version: 2.7.6
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: git-aware plugin for autoproj