vclog 1.8.2 → 1.9.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.
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