mgit 0.3.2 → 0.3.3

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: 4447be436da4ce6283adfef2ca2e65f522715644
4
- data.tar.gz: 2b898725657dea57e19a3a28a7ec0691007fa234
3
+ metadata.gz: 8174b6f645364ef888f498ffa24274882cf9dd39
4
+ data.tar.gz: b6752daa7ac077dae28c7c46a47785e05b5b430a
5
5
  SHA512:
6
- metadata.gz: d1deafe5dfa39f02dbc3b2c9be66fe5830acb45c628fb7be70a27c32685d28f59efdd18c8b89e91427f27472cb05d5d7892389503014c08be01e59f3fed2e12d
7
- data.tar.gz: bf2c584feefe6d708e5f04ed660132f836322ad89e874a51ac5a4fe4babfe294c4e7e74352044e8658e79b0da78100866b47d61f31d01f2512cc2569b0f7f178
6
+ metadata.gz: b4d6463d5a85e932aaa3d575b5c440b2a1b13f352a2efc3a2e366afe6cc81ac782ab66a2efb60e4cf62ddafaa21fdc3cb1d02ef3cc8ee8dc5fc7c85f52f2d671
7
+ data.tar.gz: fbc6b246c055889649963d7b06d1f82618068d8f27817af27aa6a03394b2ae3fd0f99bc13a912e7d70997b76a9a1f359cc5879df31f114e33d84befdfadd4799
@@ -1,12 +1,31 @@
1
+ require 'open3'
2
+
1
3
  module MGit
2
4
  class FetchCommand < Command
3
5
  def execute(args)
4
- Registry.chdir_each do |repo|
5
- `git remote`.split.each do |remote|
6
- pinfo "Fetching #{remote} in repository #{repo.name}..."
7
- `git fetch #{remote}`
6
+ threads = []
7
+ Registry.each do |repo|
8
+ threads << Thread.new do
9
+ remotes, st = Open3.capture2('git remote', :chdir => repo.path)
10
+
11
+ if st.exitstatus != 0
12
+ perror "Failed to read remotes for repository #{repo.name}! Abort."
13
+ Thread.exit
14
+ end
15
+
16
+ remotes.split.each do |remote|
17
+ sout, st = Open3.capture2("git fetch #{remote}", :chdir => repo.path)
18
+ if st.exitstatus == 0
19
+ pinfo "Fetched #{remote} in repository #{repo.name}."
20
+ else
21
+ perror "Failed to fetch #{remote} in repository #{repo.name}! Abort."
22
+ break
23
+ end
24
+ end
8
25
  end
9
26
  end
27
+
28
+ threads.each { |t| t.join }
10
29
  end
11
30
 
12
31
  def arity
@@ -0,0 +1,100 @@
1
+ require 'set'
2
+
3
+ module MGit
4
+ class StatisticsCommand < Command
5
+ def execute(args)
6
+ total_authors = {}
7
+ total_punchcard = {}
8
+ Registry.chdir_each do |repo|
9
+ current_authors = {}
10
+ current_punchcard = {}
11
+
12
+ collect do |author, time, changes|
13
+ current_authors[author] ||= 0
14
+ current_authors[author] += changes
15
+
16
+ total_punchcard[time.wday] ||= {}
17
+ total_punchcard[time.wday][time.hour / 4] ||= 0
18
+ total_punchcard[time.wday][time.hour / 4] += changes
19
+ end
20
+
21
+ print_authors current_authors, repo.name
22
+ puts
23
+
24
+ current_authors.each do |author, changes|
25
+ total_authors[author] ||= 0
26
+ total_authors[author] += changes
27
+ end
28
+ end
29
+
30
+ print_authors total_authors, 'TOTAL'
31
+ puts
32
+ print_punchcard total_punchcard, 'TOTAL'
33
+ end
34
+
35
+ def arity
36
+ [nil, 0]
37
+ end
38
+
39
+ def usage
40
+ 'statistics'
41
+ end
42
+
43
+ def description
44
+ 'display authorship statistics for each repository and in total'
45
+ end
46
+
47
+ register_command :statistics
48
+
49
+ # Too close to :status?
50
+ #register_alias :stats
51
+
52
+ private
53
+
54
+ def collect
55
+ log = `git log --format='<><>%ct %aN' --shortstat --all`.strip
56
+ commits = log.split('<><>').drop(1)
57
+
58
+ commits.each do |c|
59
+ lines = c.split("\n")
60
+
61
+ time = lines[0].split(' ')[0]
62
+ author = lines[0].split(' ')[1..-1].join(' ')
63
+
64
+ if lines.size >= 3
65
+ m = /changed(?:, (\d+) insertion(?:s)?\(\+\))?(?:, (\d+) deletion(?:s)?\(\-\))?/.match(lines[2])
66
+ changes = (m.captures[0] || 0).to_i + (m.captures[1] || 0).to_i
67
+ else
68
+ changes = 0
69
+ end
70
+
71
+ yield author, Time.at(time.to_i), changes
72
+ end
73
+ end
74
+
75
+ def print_authors(data, name)
76
+ pinfo "Authorship statistics (#{name}):"
77
+ ptable (data.to_a.sort_by { |v| v[1] }.reverse), :columns => [24, nil]
78
+ end
79
+
80
+ def print_punchcard(data, name)
81
+ pinfo "Punchcard (#{name}):"
82
+
83
+ t = []
84
+ t << ['', '0-4', '4-8', '8-12', '12-16', '16-20', '20-24']
85
+ ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].each_with_index do |day, wday|
86
+ l = [day]
87
+ 6.times do |h|
88
+ if (data[wday] && data[wday][h])
89
+ l << data[wday][h].to_s
90
+ else
91
+ l << '0'
92
+ end
93
+ end
94
+ t << l
95
+ end
96
+
97
+ ptable t
98
+ end
99
+ end
100
+ end
@@ -4,7 +4,7 @@ module MGit
4
4
  class StatusCommand < Command
5
5
  def execute(args)
6
6
  t = []
7
- Registry.chdir_each { |repo| t << [repo.name, repo.current_branch, flags(repo).to_a.join(', ')] }
7
+ Registry.chdir_each { |repo| t << [repo.name, repo.current_branch, decorate_flags(repo)] }
8
8
  ptable t, :columns => [24, nil, nil]
9
9
  end
10
10
 
@@ -17,7 +17,7 @@ module MGit
17
17
  end
18
18
 
19
19
  def description
20
- 'display status for each repositories'
20
+ 'display status for each repository'
21
21
  end
22
22
 
23
23
  register_command :status
@@ -25,27 +25,24 @@ module MGit
25
25
 
26
26
  private
27
27
 
28
- def flags(repo)
29
- flags = []
30
-
31
- fs = repo.flags
32
- flags << 'Index'.red if fs.include?(:index)
33
- flags << 'Dirty'.red if fs.include?(:dirty)
34
- flags << 'Untracked'.yellow if fs.include?(:untracked)
35
- flags << 'Detached'.yellow if fs.include?(:detached)
28
+ def decorate_flags(repo)
29
+ flags = repo.flags
30
+ labels = decorate_simple_flags(flags)
31
+ labels.concat(decorate_divergence_flags(repo.divergence)) if flags.include?(:diverged)
32
+ labels = ['Clean'.green] if labels.empty?
33
+ labels.to_a.join(', ')
34
+ end
36
35
 
37
- if fs.include?(:diverged)
38
- ds = repo.divergence
39
- ds.each do |d|
40
- flags << "#{d.first[0].to_s.capitalize} of #{d.first[1][:branch]} by #{d.first[1][:by]}".blue
41
- end
42
- end
36
+ def decorate_simple_flags(flags)
37
+ { :index => :red, :dirty => :red, :untracked => :yellow, :detached => :yellow }
38
+ .select { |f,_| flags.include?(f) }
39
+ .map { |f,c| f.to_s.capitalize.send(c) }
40
+ end
43
41
 
44
- if flags.empty?
45
- flags << 'Clean'.green
42
+ def decorate_divergence_flags(divergence)
43
+ divergence.map do |d|
44
+ "#{d.first[0].to_s.capitalize} of #{d.first[1][:branch]} by #{d.first[1][:by]}".blue
46
45
  end
47
-
48
- flags
49
46
  end
50
47
  end
51
48
  end
@@ -3,7 +3,7 @@ module MGit
3
3
  def execute(args)
4
4
  t = []
5
5
  Registry.chdir_each { |repo| t << [repo.name, *latest_tag] }
6
- ptable t, :columns => [24, nil]
6
+ ptable t, :columns => [24, nil, nil]
7
7
  end
8
8
 
9
9
  def arity
data/lib/mgit/registry.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module MGit
2
2
  module Registry
3
3
  def self.all
4
- self.load.map { |name, path| Repository.new(name, path) }.sort_by(&:path)
4
+ self.load.map { |name, path| Repository.new(name, path) }.sort_by(&:path).select(&:available?)
5
5
  end
6
6
 
7
7
  def self.each(&block)
@@ -2,6 +2,8 @@ require 'set'
2
2
 
3
3
  module MGit
4
4
  class Repository
5
+ include Output
6
+
5
7
  attr_reader :name, :path
6
8
 
7
9
  def initialize(name, path)
@@ -9,6 +11,15 @@ module MGit
9
11
  @path = path
10
12
  end
11
13
 
14
+ def available?
15
+ if !File.directory?(path)
16
+ pwarn "Repository #{name} is not available anymore. Failed to read #{path}."
17
+ return false
18
+ end
19
+
20
+ true
21
+ end
22
+
12
23
  def current_branch
13
24
  in_repo {
14
25
  b = `git rev-parse --abbrev-ref HEAD 2>&1`.strip
data/lib/mgit/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module MGit
2
- VERSION = '0.3.2'
2
+ VERSION = '0.3.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mgit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - FlavourSys Technology GmbH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-10 00:00:00.000000000 Z
11
+ date: 2014-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -83,6 +83,7 @@ files:
83
83
  - lib/mgit/commands/list.rb
84
84
  - lib/mgit/commands/grep.rb
85
85
  - lib/mgit/commands/remove_all.rb
86
+ - lib/mgit/commands/statistics.rb
86
87
  - lib/mgit/commands/version.rb
87
88
  - lib/mgit/commands/fetch.rb
88
89
  - lib/mgit/commands/head.rb