vclog 1.8.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.ruby +4 -3
  2. data/.yardopts +7 -0
  3. data/HISTORY.rdoc +207 -0
  4. data/README.rdoc +44 -27
  5. data/bin/vclog +4 -2
  6. data/bin/vclog-autotag +6 -0
  7. data/bin/vclog-bump +6 -0
  8. data/bin/vclog-formats +6 -0
  9. data/bin/vclog-version +6 -0
  10. data/lib/vclog.rb +1 -1
  11. data/lib/vclog.yml +58 -0
  12. data/lib/vclog/adapters.rb +2 -1
  13. data/lib/vclog/adapters/abstract.rb +87 -232
  14. data/lib/vclog/adapters/darcs.rb +72 -67
  15. data/lib/vclog/adapters/git.rb +166 -140
  16. data/lib/vclog/adapters/hg.rb +98 -62
  17. data/lib/vclog/adapters/svn.rb +116 -113
  18. data/lib/vclog/change.rb +110 -81
  19. data/lib/vclog/change_point.rb +77 -0
  20. data/lib/vclog/changelog.rb +58 -296
  21. data/lib/vclog/cli.rb +6 -70
  22. data/lib/vclog/cli/abstract.rb +64 -81
  23. data/lib/vclog/cli/autotag.rb +1 -3
  24. data/lib/vclog/cli/bump.rb +3 -4
  25. data/lib/vclog/cli/formats.rb +4 -4
  26. data/lib/vclog/cli/log.rb +86 -0
  27. data/lib/vclog/cli/version.rb +3 -3
  28. data/lib/vclog/{facets.rb → core_ext.rb} +0 -0
  29. data/lib/vclog/heuristics.rb +112 -38
  30. data/lib/vclog/heuristics/rule.rb +52 -12
  31. data/lib/vclog/heuristics/{label.rb → type.rb} +2 -2
  32. data/lib/vclog/history_file.rb +2 -2
  33. data/lib/vclog/metadata.rb +13 -1
  34. data/lib/vclog/release.rb +26 -12
  35. data/lib/vclog/repo.rb +191 -27
  36. data/lib/vclog/report.rb +187 -0
  37. data/lib/vclog/tag.rb +66 -39
  38. data/lib/vclog/templates/changelog.ansi.rb +9 -26
  39. data/lib/vclog/templates/changelog.atom.erb +3 -3
  40. data/lib/vclog/templates/changelog.gnu.rb +4 -11
  41. data/lib/vclog/templates/changelog.html.erb +11 -2
  42. data/lib/vclog/templates/changelog.markdown.rb +4 -4
  43. data/lib/vclog/templates/changelog.rdoc.rb +4 -4
  44. data/lib/vclog/templates/changelog.rss.erb +2 -6
  45. data/lib/vclog/templates/changelog.xml.erb +14 -2
  46. data/lib/vclog/templates/history.ansi.rb +10 -17
  47. data/lib/vclog/templates/history.atom.erb +4 -4
  48. data/lib/vclog/templates/history.gnu.rb +5 -7
  49. data/lib/vclog/templates/history.html.erb +11 -4
  50. data/lib/vclog/templates/history.json.rb +1 -1
  51. data/lib/vclog/templates/history.markdown.rb +5 -7
  52. data/lib/vclog/templates/history.rdoc.rb +5 -9
  53. data/lib/vclog/templates/history.rss.erb +3 -5
  54. data/lib/vclog/templates/history.xml.erb +15 -3
  55. data/lib/vclog/templates/history.yaml.rb +1 -1
  56. data/man/man1/vclog-autotag.1 +1 -1
  57. data/man/man1/vclog-autotag.1.html +1 -1
  58. data/man/man1/vclog-bump.1 +1 -1
  59. data/man/man1/vclog-bump.1.html +1 -1
  60. data/man/man1/vclog-version.1 +1 -1
  61. data/man/man1/vclog-version.1.html +1 -1
  62. data/man/man1/vclog.1 +25 -13
  63. data/man/man1/vclog.1.html +29 -20
  64. data/man/man1/vclog.1.ronn +31 -18
  65. data/test/unit/case_metadata.rb +1 -1
  66. metadata +48 -34
  67. data/lib/vclog/cli/changelog.rb +0 -33
  68. data/lib/vclog/cli/help.rb +0 -42
  69. data/lib/vclog/cli/history.rb +0 -39
  70. data/lib/vclog/formatter.rb +0 -123
  71. data/lib/vclog/history.rb +0 -131
  72. data/lib/vclog/kernel.rb +0 -12
  73. data/man/man1/vclog-changelog.1 +0 -47
  74. data/man/man1/vclog-changelog.1.html +0 -123
  75. data/man/man1/vclog-changelog.1.ronn +0 -39
  76. data/man/man1/vclog-history.1 +0 -44
  77. data/man/man1/vclog-history.1.html +0 -122
  78. data/man/man1/vclog-history.1.ronn +0 -38
@@ -1,72 +1,8 @@
1
- module VCLog
1
+ require 'vclog/repo'
2
2
 
3
- #
4
- def self.cli(*argv)
5
- argv ||= ARGV.dup
6
- begin
7
- #opt = global_parser.order!(argv)
8
- cmd = argv.shift unless argv.first =~ /^-/
9
- cmd = cmd || 'changelog'
10
- cli = CLI.factory(cmd)
11
- cli.run(argv)
12
- rescue => err
13
- if $DEBUG
14
- raise err
15
- else
16
- puts err.message
17
- exit -1
18
- end
19
- end
20
- end
3
+ require 'vclog/cli/log'
4
+ require 'vclog/cli/formats'
5
+ require 'vclog/cli/bump'
6
+ require 'vclog/cli/version'
7
+ require 'vclog/cli/autotag'
21
8
 
22
- # = Command Line Interface
23
- #
24
- # == SYNOPSIS
25
- #
26
- # VCLog provides cross-vcs ChangeLogs. It works by
27
- # parsing the native changelog a VCS system produces
28
- # into a common model, which then can be used to
29
- # produce Changelogs in a variety of formats.
30
- #
31
- # VCLog currently support git, hg and svn, with cvs and darcs in the works.
32
- #
33
- # == EXAMPLES
34
- #
35
- # To produce a GNU-like changelog:
36
- #
37
- # $ vclog
38
- #
39
- # For XML format:
40
- #
41
- # $ vclog -f xml
42
- #
43
- # Or for a micorformat-ish HTML:
44
- #
45
- # $ vclog -f html
46
- #
47
- # To use the library programmatically, please see the API documentation.
48
-
49
- module CLI
50
- require 'vclog/repo'
51
-
52
- require 'vclog/cli/help'
53
- require 'vclog/cli/changelog'
54
- require 'vclog/cli/history'
55
- require 'vclog/cli/formats'
56
- require 'vclog/cli/bump'
57
- require 'vclog/cli/version'
58
- require 'vclog/cli/autotag'
59
-
60
- #
61
- def self.factory(name)
62
- # find the closet matching term
63
- terms = register.map{ |cli| cli.terms }.flatten
64
- term = terms.select{ |term| /^#{name}/ =~ term }.first
65
- # get the class that goes with the term
66
- cmdclass = register.find{ |cli| cli.terms.include?(term) }
67
- raise "Unknown command -- #{name}" unless cmdclass
68
- cmdclass.new
69
- end
70
-
71
- end
72
- end
@@ -1,109 +1,92 @@
1
+ require 'vclog'
1
2
  require 'optparse'
2
3
 
3
4
  module VCLog
4
- module CLI
5
5
 
6
- #
7
- def self.register
8
- @register ||= []
9
- end
10
-
11
- #
12
- class Abstract
13
-
14
- #
15
- def self.inherited(subclass)
16
- CLI.register << subclass
17
- end
6
+ module CLI
18
7
 
19
8
  #
20
- def self.terms
21
- [name.split('::').last.downcase]
22
- end
23
-
24
- # TODO: change +extra+ to +summarize+ and reverse boolean value.
25
- def initialize
26
- @options = {}
27
- @options[:extra] = true
9
+ def self.register
10
+ @register ||= []
28
11
  end
29
12
 
13
+ # Abstract base class for all command classes.
30
14
  #
31
- def options
32
- @options
33
- end
34
-
35
- #
36
- def parser(&block)
37
- parser = OptionParser.new(&block)
38
-
39
- parser.separator " "
40
- parser.separator "SYSTEM OPTIONS:"
41
- parser.on('--debug', 'show debugging information') do
42
- $DEBUG = true
43
- end
44
- parser.on('--help' , '-h', 'display this help information') do
45
- puts parser
46
- exit
15
+ class Abstract
16
+
17
+ #
18
+ def self.run(argv)
19
+ new.run(argv)
20
+ rescue => err
21
+ if $DEBUG
22
+ raise err
23
+ else
24
+ puts err.message
25
+ exit -1
26
+ end
47
27
  end
48
- parser
49
- end
50
28
 
51
- # Setup options common to templating commands.
52
- #
53
- # parser - instance of options parser
54
- #
55
- # Returns a instance of OptionParser.
56
- def template_options(parser)
57
- parser.separator(" ")
58
- parser.separator("OUTPUT OPTIONS: (use varies with format)")
59
- parser.on('--format', '-f FORMAT', "output format") do |format|
60
- options[:format] = format.to_sym
29
+ #
30
+ def self.inherited(subclass)
31
+ CLI.register << subclass
61
32
  end
62
- parser.on('--style <URI>', "provide a stylesheet URI (css or xsl) for HTML or XML format") do |uri|
63
- options[:stylesheet] = uri
64
- end
65
- parser.on('--title', '-t TITLE', "document title") do |string|
66
- options[:title] = string
33
+
34
+ #
35
+ def self.terms
36
+ [name.split('::').last.downcase]
67
37
  end
68
- parser.on('--summarize', '-s', "produce summary output") do
69
- options[:extra] = false
38
+
39
+ #
40
+ def initialize
41
+ @options = {}
70
42
  end
71
- parser.on('--id', "include revision id") do
72
- options[:revision] = true
43
+
44
+ #
45
+ def options
46
+ @options
73
47
  end
74
- parser.on('--level', '-l NUMBER', "lowest level of commit to display [0]") do |num|
75
- options[:level] = num.to_i
48
+
49
+ #
50
+ def parser(&block)
51
+ parser = OptionParser.new(&block)
52
+
53
+ parser.separator " "
54
+ parser.separator "SYSTEM OPTIONS:"
55
+ parser.on('--debug', 'show debugging information') do
56
+ $DEBUG = true
57
+ end
58
+ parser.on('--help' , '-h', 'display this help information') do
59
+ puts parser
60
+ exit
61
+ end
62
+ parser
76
63
  end
77
- #parser.on('--typed', "catagorize by commit type") do
78
- # typed = true
79
- #end
80
- parser
81
- end
82
64
 
83
- # Run the command.
84
- def run(argv=nil)
85
- argv ||= ARGV.dup
65
+ # Run the command.
66
+ def run(argv=nil)
67
+ argv ||= ARGV.dup
86
68
 
87
- parser.parse!(argv)
69
+ parser.parse!(argv)
88
70
 
89
- @arguments = argv
71
+ @arguments = argv
90
72
 
91
- root = Dir.pwd # TODO: find root
73
+ root = Dir.pwd # TODO: find root
92
74
 
93
- @repo = VCLog::Repo.new(root, options)
75
+ @repo = VCLog::Repo.new(root, options)
94
76
 
95
- execute
96
- end
77
+ execute
78
+ end
97
79
 
98
- # Repo is set in #run.
99
- def repo
100
- @repo
101
- end
80
+ # Repo is set in #run.
81
+ def repo
82
+ @repo
83
+ end
102
84
 
103
- #
104
- attr :arguments
85
+ #
86
+ attr :arguments
87
+
88
+ end
105
89
 
106
90
  end
107
91
 
108
92
  end
109
- end
@@ -1,7 +1,6 @@
1
1
  require 'vclog/cli/abstract'
2
2
 
3
- module VCLog
4
- module CLI
3
+ module VCLog::CLI
5
4
 
6
5
  #
7
6
  class Autotag < Abstract
@@ -35,4 +34,3 @@ module CLI
35
34
  end
36
35
 
37
36
  end
38
- end
@@ -1,8 +1,8 @@
1
1
  require 'vclog/cli/abstract'
2
2
 
3
- module VCLog
4
- module CLI
3
+ module VCLog::CLI
5
4
 
5
+ #
6
6
  class Bump < Abstract
7
7
 
8
8
  #
@@ -13,7 +13,7 @@ module CLI
13
13
  #
14
14
  def parser
15
15
  super do |opt|
16
- opt.banner = "Usage: vclog bump"
16
+ opt.banner = "Usage: vclog-bump"
17
17
  opt.separator(" ")
18
18
  opt.separator("Display a bumped version number.")
19
19
  end
@@ -27,4 +27,3 @@ module CLI
27
27
  end
28
28
 
29
29
  end
30
- end
@@ -1,8 +1,9 @@
1
1
  require 'vclog/cli/abstract'
2
2
 
3
- module VCLog
4
- module CLI
3
+ module VCLog::CLI
5
4
 
5
+ # Command to display a list of available formats.
6
+ #
6
7
  class Formats < Abstract
7
8
 
8
9
  #
@@ -13,7 +14,7 @@ module CLI
13
14
  #
14
15
  def parser
15
16
  super do |opt|
16
- opt.banner = "Usage: vclog formats"
17
+ opt.banner = "Usage: vclog-formats"
17
18
  end
18
19
  end
19
20
 
@@ -25,4 +26,3 @@ module CLI
25
26
  end
26
27
 
27
28
  end
28
- end
@@ -0,0 +1,86 @@
1
+ require 'vclog/cli/abstract'
2
+
3
+ module VCLog::CLI
4
+
5
+ # VCLog provides cross-vcs ChangeLogs. It works by
6
+ # parsing the native changelog a VCS system produces
7
+ # into a common model, which then can be used to
8
+ # produce Changelogs in a variety of formats.
9
+ #
10
+ # VCLog currently support git, hg and svn, with cvs and
11
+ # darcs in the works.
12
+ #
13
+ # To produce a GNU-like changelog:
14
+ #
15
+ # $ vclog
16
+ #
17
+ # For XML format:
18
+ #
19
+ # $ vclog -f xml
20
+ #
21
+ # Or for a micorformat-ish HTML:
22
+ #
23
+ # $ vclog -f html
24
+ #
25
+ # To use the library programmatically, please see the API documentation.
26
+ #
27
+ class Log < Abstract
28
+
29
+ # Setup options for log command.
30
+ #
31
+ # Returns a instance of OptionParser.
32
+ def parser
33
+ super do |parser|
34
+ parser.banner = 'Usage: vclog [options]'
35
+ parser.separator(' ')
36
+ parser.separator('Print a change log or release history.')
37
+ parser.separator(' ')
38
+ parser.separator('OPTIONS: (use varies with format)')
39
+ parser.on('-f', '--format FORMAT', 'output format (ansi,gnu,html,...)') do |format|
40
+ options[:format] = format.to_sym
41
+ end
42
+ parser.on('-r', '--release', '--history', 'show release history, instead of changelog') do
43
+ options[:type] = :history
44
+ end
45
+ parser.on('-t', '--title TITLE', 'document title') do |string|
46
+ options[:title] = string
47
+ end
48
+ parser.on('-v', '--version NUM', 'use as current version number') do |num|
49
+ options[:version] = num
50
+ end
51
+ parser.on('-l', '--level NUMBER', 'lowest level of commit to display (default: 0)') do |num|
52
+ options[:level] = num.to_i
53
+ end
54
+ parser.on('-p', '--point', 'split commit message into per-point entries') do
55
+ options[:point] = true
56
+ end
57
+ parser.separator(' ')
58
+ parser.separator('XML/HTML OPTIONS: (applies only to xml/html formats)')
59
+ parser.on('-S', '--style URI', 'provide a stylesheet URI (css or xsl)') do |uri|
60
+ options[:stylesheet] = uri
61
+ end
62
+ parser.separator(' ')
63
+ parser.separator('TEXT OPTIONS: (applies only to text formats)')
64
+ parser.on('-i', '--id', 'include reference/revision id in output') do
65
+ options[:reference] = true # TODO: change to :id ?
66
+ end
67
+ parser.on('-d', '--detail', 'include commit message details (no effect if -p)') do
68
+ options[:detail] = true
69
+ end
70
+ parser.on('-s', '--summary', 'exclude commit messages from report') do
71
+ options[:summary] = true
72
+ end
73
+ #parser.on('--typed', "catagorize by commit type") do
74
+ # typed = true
75
+ #end
76
+ end
77
+ end
78
+
79
+ #
80
+ def execute
81
+ puts repo.report(options)
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -1,8 +1,9 @@
1
1
  require 'vclog/cli/abstract'
2
2
 
3
- module VCLog
4
- module CLI
3
+ module VCLog::CLI
5
4
 
5
+ # Display the current version.
6
+ #
6
7
  class Version < Abstract
7
8
 
8
9
  #
@@ -27,4 +28,3 @@ module CLI
27
28
  end
28
29
 
29
30
  end
30
- end
File without changes
@@ -1,24 +1,31 @@
1
- require 'vclog/heuristics/label'
1
+ require 'vclog/heuristics/type'
2
2
  require 'vclog/heuristics/rule'
3
3
 
4
4
  module VCLog
5
5
 
6
+ # Heuristics stores a set of rules to be applied to commmits
7
+ # in order to assign them priority levels and report labels.
6
8
  #
7
9
  class Heuristics
8
10
 
9
11
  # Load heuristics from a designated file.
10
12
  #
11
- # @param file [String] configuration file
13
+ # @param [String] file
14
+ # Configuration file.
12
15
  #
13
16
  def self.load(file)
14
17
  raise LoadError unless File.exist?(file)
15
18
  new{ instance_eval(File.read(file), file) }
16
19
  end
17
20
 
18
- #
21
+ # Setup new heurtistics set.
19
22
  def initialize(&block)
20
- @rules = []
21
- @labels = {}
23
+ @rules = []
24
+
25
+ @types = Hash.new{ |h,k| h[k] = h[:default] }
26
+ @types[:default] = Type.new(:default, -1, "Nominal Changes")
27
+
28
+ @colors = [:blue, :blue, :cyan, :green, :yellow, :red, :red]
22
29
 
23
30
  if block
24
31
  instance_eval(&block)
@@ -27,60 +34,127 @@ module VCLog
27
34
  end
28
35
  end
29
36
 
37
+ # Apply heuristics to a commit.
30
38
  #
31
- def lookup(message)
32
- type_msg = nil
33
- @rules.find{|rule| type_msg = rule.call(message)}
34
- type, msg = *type_msg
35
- if type
36
- type = type.to_sym
37
- if @labels.key?(type)
38
- @labels[type].to_a + [msg || message]
39
- else
40
- [type, 0, "#{type.to_s.capitalize} Enhancements", msg || message]
41
- end
42
- else
43
- [nil, 0, 'General Enhancements', msg || message]
39
+ # @param [Change] commit
40
+ # Instance of Change encapsulates an SCM commit.
41
+ #
42
+ def apply(commit)
43
+ # apply rules, breaking on first rule found that fits.
44
+ @rules.find{ |rule| rule.call(commit) }
45
+
46
+ unless commit.level
47
+ commit.level = types[commit.type].level
44
48
  end
49
+
50
+ unless commit.label
51
+ commit.label = types[commit.type].label
52
+ end
53
+
54
+ # apply color for commit level
55
+ color = @colors[commit.level + (@colors.size / 2)]
56
+ color ||= (commit.level > 0 ? @colors.first : @colors.last)
57
+ commit.color = color
45
58
  end
46
59
 
47
- #
48
- def on(pattern, &block)
60
+ # Define a new rule.
61
+ def on(pattern=nil, &block)
49
62
  @rules << Rule.new(pattern, &block)
50
63
  end
51
64
 
65
+ # Convenience method for setting-up commit types, which can
66
+ # be easily assigned, setting both label and level in one go.
67
+ def type(type, level, label)
68
+ @types[type.to_sym] = Type.new(type, level, label)
69
+ end
70
+
71
+ # @deprecated
72
+ alias_method :set, :type
73
+
74
+ # Access to defined types.
52
75
  #
53
- def set(type, level, label)
54
- @labels[type.to_sym] = Label.new(type, level, label)
76
+ # @example
77
+ # commit.type = :major
78
+ #
79
+ attr :types
80
+
81
+ # Set color list. The center element cooresponds to `level=0`.
82
+ # Elements before the center are incrementally higher levels
83
+ # and those after are lower.
84
+ #
85
+ # @example
86
+ # colors :red, :yellow, :green, :cyan, :blue
87
+ #
88
+ def colors(*list)
89
+ @colors = list
55
90
  end
56
91
 
57
92
  # Default settings.
58
93
  def default
59
- set :major, 1, "Major Enhancements"
60
- set :bug, 0, "Bug Fixes"
61
- set :minor, -1, "Minor Enhancements"
62
- set :doc, -1, "Documentation Changes"
63
- set :admin, -2, "Administrative Changes"
64
-
65
- on /^(\w+):/ do |msg, md|
66
- word = md[1]
67
- [word.to_sym, md.post_match]
94
+ type :major, 3, "Major Enhancements"
95
+ type :minor, 2, "Minor Enhancements"
96
+ type :bug, 1, "Bug Fixes"
97
+ type :default, 0, "Nominal Changes"
98
+ type :doc, -1, "Documentation Changes"
99
+ type :test, -2, "Test/Spec Adjustments"
100
+ type :admin, -3, "Administrative Changes"
101
+
102
+ on /\A(\w+):/ do |commit, md|
103
+ type = md[1].to_sym
104
+ commit.type = type
105
+ commit.message = commit.message.sub(md[0],'').strip
106
+ true
68
107
  end
69
108
 
70
- on /\[(\w+)\]\s*$/ do |msg, md|
71
- word = md[1]
72
- [word.to_sym, md.pre_match]
109
+ on /\[(\w+)\]\s*$/ do |commit, md|
110
+ type = md[1].to_sym
111
+ commit.type = type
112
+ commit.message = commit.message.sub(md[0],'').strip
113
+ true
73
114
  end
74
115
 
75
- on /updated? (README|PROFILE|PACKAGE|VERSION|MANIFEST)/ do
76
- :admin
116
+ on /updated? (README|PROFILE|PACKAGE|VERSION|MANIFEST)/ do |commit|
117
+ commit.type = :admin
77
118
  end
78
119
 
79
- on /(bump|bumped|prepare) version/ do
80
- :admin
120
+ on /(bump|bumped|prepare) version/ do |commit|
121
+ commit.type = :admin
81
122
  end
82
123
  end
83
124
 
125
+ # Work on next-gen default heuristics.
126
+ def default2
127
+ type :major, 3, "Major Enhancements"
128
+ type :minor, 2, "Minor Enhancements"
129
+ type :bug, 1, "Bug Fixes"
130
+ type :default, 0, "Nominal Changes"
131
+ type :doc, -1, "Documentation Changes"
132
+ type :test, -2, "Test/Spec Adjustments"
133
+ type :admin, -3, "Administrative Changes"
134
+
135
+ # test/spec file only changes
136
+ on do |commit|
137
+ if commit.files.all?{ |f| f.start_with?('test') || f.start_with?('spec') }
138
+ commit.type = :test
139
+ end
140
+ end
141
+ end
142
+
143
+ private
144
+
145
+ # TODO: applies types that are "close", to help overlook typos.
146
+ #
147
+ #def close_type(type)
148
+ # case type.to_s
149
+ # when 'maj', 'major' then :major
150
+ # when 'min', 'minor' then :minor
151
+ # when 'bug' then :bug
152
+ # when '' then :other
153
+ # else
154
+ # type.to_sym
155
+ # end
156
+ #end
157
+
84
158
  end
85
159
 
86
160
  end