vclog 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ module VCLog
2
+
3
+ #
4
+ class Release
5
+ attr :tag
6
+ attr :changes
7
+ #
8
+ def initialize(tag, changes)
9
+ @tag = tag
10
+ @changes = changes
11
+ end
12
+
13
+ def to_h
14
+ { :tag => tag.to_h, :changes => changes }
15
+ end
16
+
17
+ def to_json
18
+ to_h.to_json
19
+ end
20
+ end
21
+
22
+ end
23
+
data/lib/vclog/tag.rb ADDED
@@ -0,0 +1,54 @@
1
+ module VCLog
2
+
3
+ class Tag
4
+ attr_accessor :name
5
+ attr_accessor :date
6
+ attr_accessor :author
7
+ attr_accessor :message
8
+
9
+ def initialize(name, date, author, message)
10
+ self.name = name
11
+ self.date = date
12
+ self.author = author
13
+ self.message = message
14
+ end
15
+
16
+ def name=(name)
17
+ @name = name.strip
18
+ end
19
+
20
+ def author=(author)
21
+ @author = author.strip
22
+ end
23
+
24
+ def date=(date)
25
+ case date
26
+ when Time
27
+ @date = date
28
+ else
29
+ @date = Time.parse(date.to_s)
30
+ end
31
+ end
32
+
33
+ def message=(msg)
34
+ @message = msg.strip
35
+ end
36
+
37
+ alias_method :tagger, :author
38
+ alias_method :tagger=, :author=
39
+
40
+ def to_json
41
+ to_h.to_json
42
+ end
43
+
44
+ def to_h
45
+ {
46
+ :name => name,
47
+ :date => date,
48
+ :author => author,
49
+ :message => message
50
+ }
51
+ end
52
+ end
53
+
54
+ end
data/lib/vclog/vcs.rb CHANGED
@@ -2,10 +2,9 @@ module VCLog
2
2
 
3
3
  require 'time'
4
4
  require 'vclog/changelog'
5
- require 'vclog/vcs/svn'
6
- require 'vclog/vcs/git'
7
- #require 'vclog/vcs/hg'
8
- #require 'vclog/vcs/darcs'
5
+ require 'vclog/history'
6
+ require 'vclog/change'
7
+ require 'vclog/tag'
9
8
 
10
9
  # TODO: Might we have a NO-VCS changelog based on
11
10
  # LOG: entries in source files?
@@ -13,29 +12,102 @@ module VCLog
13
12
  # = Version Control System
14
13
  class VCS
15
14
 
16
- attr :type
17
-
18
- def initialize(root=nil)
19
- @root = root || Dir.pwd
20
- @type = read_type
21
- raise ArgumentError, "Not a recognized version control system." unless @type
15
+ def self.factory(root=nil)
16
+ root = root || Dir.pwd
17
+ type = read_type(root)
18
+ raise ArgumentError, "Not a recognized version control system." unless type
19
+ VCS.const_get(type.upcase).new(root)
22
20
  end
23
21
 
24
- def read_type
22
+ def self.read_type(root)
25
23
  dir = nil
26
- Dir.chdir(@root) do
24
+ Dir.chdir(root) do
27
25
  dir = Dir.glob("{.svn,.git,.hg,_darcs}").first
28
26
  end
29
27
  dir[1..-1] if dir
30
28
  end
31
29
 
32
- def delegate
33
- @delegate ||= VCS.const_get(type.upcase).new
30
+ attr :root
31
+
32
+ #
33
+ def initialize(root)
34
+ @root = File.expand_path(root)
35
+ end
36
+
37
+ def tags
38
+ @tags ||= extract_tags.map{ |t| Tag===t ? t : Tag.new(*t) }
39
+ end
40
+
41
+ def changes
42
+ @changes ||= extract_changes.map{ |c| Change===c ? c : Change.new(*c) }
34
43
  end
35
44
 
36
45
  #
37
- def method_missing(s, *a, &b)
38
- delegate.send(s, *a, &b)
46
+ def extract_tags
47
+ raise "Not Implemented"
48
+ end
49
+
50
+ #
51
+ def extract_changes
52
+ raise "Not Implemented"
53
+ end
54
+
55
+ #
56
+ def changelog
57
+ ChangeLog.new(changes)
58
+ end
59
+
60
+ #
61
+ def history(opts={})
62
+ @history ||= History.new(self, opts)
63
+ end
64
+
65
+ # Provides a bumped version number.
66
+ def bump(part=nil)
67
+ return part unless ['major', 'minor', 'patch', ''].include?(part.to_s)
68
+
69
+ if tags.last
70
+ v = tags.last.name # TODO: ensure the latest version
71
+ else
72
+ v = '0.0.0'
73
+ end
74
+ v = v.split(/\W/) # TODO: preserve split chars
75
+ case part.to_s
76
+ when 'major'
77
+ v[0] = v[0].succ
78
+ (1..(v.size-1)).each{ |i| v[i] = '0' }
79
+ v.join('.')
80
+ when 'minor'
81
+ v[1] = '0' unless v[1]
82
+ v[1] = v[1].succ
83
+ (2..(v.size-1)).each{ |i| v[i] = '0' }
84
+ v.join('.')
85
+ when 'patch'
86
+ v[1] = '0' unless v[1]
87
+ v[2] = '0' unless v[2]
88
+ v[2] = v[2].succ
89
+ (3..(v.size-1)).each{ |i| v[i] = '0' }
90
+ v.join('.')
91
+ else
92
+ v[-1] = '0' unless v[-1]
93
+ v[-1] = v[-1].succ
94
+ v.join('.')
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ # Looks for a "[type]" indicator at the end of the message.
101
+ def split_type(note)
102
+ note = note.strip
103
+ if md = /\A.*?\[(.*?)\]\s*$/.match(note)
104
+ t = md[1].strip.downcase
105
+ n = note.sub(/\[#{md[1]}\]\s*$/, "")
106
+ else
107
+ n, t = note, nil
108
+ end
109
+ n.gsub!(/^\s*?\n/m,'') # remove blank lines
110
+ return n, t
39
111
  end
40
112
 
41
113
  =begin
@@ -78,5 +150,10 @@ module VCLog
78
150
 
79
151
  end
80
152
 
153
+ require 'vclog/vcs/svn'
154
+ require 'vclog/vcs/git'
155
+ #require 'vclog/vcs/hg'
156
+ #require 'vclog/vcs/darcs'
157
+
81
158
  end
82
159
 
data/lib/vclog/vcs/git.rb CHANGED
@@ -1,30 +1,33 @@
1
1
  module VCLog
2
2
 
3
- class VCS
3
+ require 'vclog/vcs'
4
4
 
5
- ### = GIT
6
- ###
7
- class GIT
5
+ class VCS
8
6
 
9
- def initialize
7
+ # = GIT Adapter
8
+ #
9
+ class GIT < VCS
10
10
 
11
- end
11
+ #def initialize
12
+ #end
12
13
 
13
14
  #
14
- def changelog
15
- @changelog ||= generate_changelog
16
- end
15
+ #def changelog
16
+ # @changelog ||= ChangeLog.new(changes)
17
+ #end
17
18
 
18
- #
19
- def generate_changelog
20
- log = Changelog.new
21
-
22
- changelog ||= `git-log`.strip
19
+ #
20
+ #def history(opts={})
21
+ # @history ||= History.new(self, opts)
22
+ #end
23
23
 
24
+ # Collect changes.
25
+ #
26
+ def extract_changes
27
+ list = []
28
+ changelog = `git-log`.strip
24
29
  changes = changelog.split(/^commit/m)
25
-
26
30
  changes.shift # throw the first (empty) entry away
27
-
28
31
  changes.each do |text|
29
32
  date, who, rev, msg = nil, nil, nil, []
30
33
  text.each_line do |line|
@@ -40,15 +43,43 @@ module VCLog
40
43
  msg << line.strip
41
44
  end
42
45
  end
43
- log.change(date, who, rev, msg.join("\n"))
46
+ msg = msg.join("\n")
47
+ msg, type = *split_type(msg)
48
+ list << [rev, date, who, msg, type]
44
49
  end
50
+ list
51
+ end
45
52
 
46
- @changelog = log
53
+ # Collect tags.
54
+ #
55
+ # `git show 1.0` produces:
56
+ #
57
+ # tag 1.0
58
+ # Tagger: 7rans <transfire@gmail.com>
59
+ # Date: Sun Oct 25 09:27:58 2009 -0400
60
+ #
61
+ # version 1.0
62
+ # commit
63
+ # ...
64
+ #
65
+ def extract_tags
66
+ list = []
67
+ tags = `git tag -l`
68
+ tags.split(/\s+/).each do |tag|
69
+ info = `git show #{tag}`
70
+ md = /\Atag(.*?)\n(.*?)^commit/m.match(info)
71
+ who, date, *msg = *md[2].split(/\n/)
72
+ who = who.split(':')[1].strip
73
+ date = date[date.index(':')+1..-1].strip
74
+ msg = msg.join("\n")
75
+ list << [tag, date, who, msg]
76
+ end
77
+ list
47
78
  end
48
79
 
49
- end
80
+ end#class GIT
50
81
 
51
- end
82
+ end#class VCS
52
83
 
53
- end
84
+ end#module VCLog
54
85
 
data/lib/vclog/vcs/svn.rb CHANGED
@@ -4,26 +4,18 @@ module VCLog
4
4
 
5
5
  # = SVN
6
6
  #
7
- # Raw SVN format:
7
+ # SVN's raw log format:
8
8
  #
9
9
  # ------------------------------------------------------------------------
10
10
  # r34 | transami | 2006-08-02 22:10:11 -0400 (Wed, 02 Aug 2006) | 2 lines
11
11
  #
12
12
  # change foo to work better
13
13
  #
14
- class SVN
14
+ class SVN < VCS
15
15
 
16
- def initialize
17
- end
18
-
19
- ###
20
- def changelog
21
- @changelog ||= generate_changelog
22
- end
23
-
24
- ###
25
- def generate_changelog
26
- log = Changelog.new
16
+ #
17
+ def extract_changes
18
+ log = []
27
19
 
28
20
  txt = `svn log`.strip
29
21
 
@@ -44,15 +36,71 @@ module VCLog
44
36
 
45
37
  date = Time.parse(date)
46
38
 
47
- log.change(date, who, rev, msg)
39
+ msg, type = *split_type(msg)
40
+
41
+ log << [rev, date, who, msg, type]
48
42
  end
49
43
 
50
- @changelog = log
44
+ log
45
+ end
46
+
47
+ #
48
+ def extract_tags
49
+ list = []
50
+ tagdir = tag_directory
51
+
52
+ if tagdir
53
+ tags = Dir.entries(tagdir).select{ |e| e.index('.') != 0 && e =~ /\d(.*)$/ }
54
+ else
55
+ tags = []
56
+ end
57
+
58
+ tags.each do |path|
59
+ dir = File.join(tagdir, path)
60
+
61
+ info = `svn info #{dir}`
62
+ info = YAML.load(info)
63
+ md = /(\d.*)$/.match(info['Path'])
64
+ name = md ? md[1] : path
65
+ date = info['Last Changed Date']
66
+ who = info['Last Changed Author']
67
+ rev = info['Revision']
68
+
69
+ commit = `svn log -r BASE #{dir}`
70
+ msg = commit.lines.to_a[2..-2].join("\n").strip
71
+
72
+ list << [name, date, who, msg]
73
+ end
74
+ list
75
+ end
76
+
77
+ # This isn't perfect, but is there really anyway for it to be?
78
+ # It ascends up the current directory tree looking for the
79
+ # best candidate for a tags directory.
80
+ def tag_directory
81
+ fnd = nil
82
+ dir = root
83
+ while dir != '/' do
84
+ entries = Dir.entries(dir)
85
+ if entries.include?('.svn')
86
+ if entries.include?('tags')
87
+ break(fnd = File.join(dir, 'tags'))
88
+ else
89
+ entries = entries.reject{ |e| e.index('.') == 0 }
90
+ entries = entries.reject{ |e| e !~ /\d$/ }
91
+ break(fnd = dir) unless entries.empty?
92
+ end
93
+ else
94
+ break(fnd=nil)
95
+ end
96
+ dir = File.dirname(dir)
97
+ end
98
+ fnd
51
99
  end
52
100
 
53
- end
101
+ end#class SVN
54
102
 
55
- end
103
+ end#class VCS
56
104
 
57
- end
105
+ end#module VCLog
58
106
 
data/meta/version CHANGED
@@ -1 +1 @@
1
- 1.1
1
+ 1.2
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vclog
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.1"
4
+ version: "1.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Sawyer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-23 00:00:00 -04:00
12
+ date: 2009-10-26 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,9 +41,13 @@ files:
41
41
  - README
42
42
  - TODO
43
43
  - bin/vclog
44
+ - lib/vclog/change.rb
44
45
  - lib/vclog/changelog.rb
45
- - lib/vclog/command.rb
46
+ - lib/vclog/cli.rb
46
47
  - lib/vclog/facets.rb
48
+ - lib/vclog/history.rb
49
+ - lib/vclog/release.rb
50
+ - lib/vclog/tag.rb
47
51
  - lib/vclog/vcs.rb
48
52
  - lib/vclog/vcs/darcs.rb
49
53
  - lib/vclog/vcs/git.rb