history 0.1.0 → 0.2.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.
data/.ruby CHANGED
@@ -54,14 +54,13 @@ title: History
54
54
  created: '2010-02-19'
55
55
  organization: Rubyworks
56
56
  summary: HISTORY and CHANGELOG parser
57
- version: 0.1.0
58
- description: ! 'History is a HISTORY and CHANGELOG file parser. It can parse common
59
- layouts for these
57
+ version: 0.2.0
58
+ description: ! 'History is a HISTORY file parser. It can parse common HISTORY file
59
+ layouts
60
60
 
61
- file types and provide their contents in a structured model. This can be useful
62
- for
61
+ and provide the contents in a structured model. This can be useful for
63
62
 
64
- a number of things, in particular it can be used to generate tag messages and add
63
+ a number of things, in particular it can be used to generate tag messages
65
64
 
66
- pre-release changelogs to relase announcements.'
67
- date: '2012-05-24'
65
+ and add pre-release change lists to release announcements.'
66
+ date: '2012-05-25'
data/DEMO.md ADDED
@@ -0,0 +1,113 @@
1
+ # History Gem
2
+
3
+ History is a HISTORY file parser. It can parse common HISTORY file layouts
4
+ and provide the contents in a structured model. This can be useful for
5
+ a number of things, in particular it can be used to generate tag messages
6
+ and add pre-release change lists to release announcements.
7
+
8
+ # History Class
9
+
10
+ The history class encapsulates this list of release
11
+ made by a project. It parses a text file by the
12
+ name of HISTORY into it indivdual relase entries.
13
+
14
+ Given a HISTORY project file containing:
15
+
16
+ = RELEASE HISTORY
17
+
18
+ == 1.2.0 / 2010-10-18
19
+
20
+ Some Dandy description of the 1.2.0 release.
21
+ This is multiline description.
22
+
23
+ Changes:
24
+
25
+ * This is change 1.
26
+ * This is change 2.
27
+ * This is change 3.
28
+
29
+
30
+ == 1.1.0 | 2010-06-06 | "Happy Days"
31
+
32
+ Some Dandy description of the 1.1.0 release.
33
+ This is multiline description. Notice the
34
+ header varies from the first.
35
+
36
+ The description can even have multiple paragraphs.
37
+
38
+ Changes:
39
+
40
+ * This is change 1.
41
+ * This is change 2.
42
+ * This is change 3.
43
+
44
+
45
+ == 1.0.0 / 2010-04-30
46
+
47
+ Some Dandy description of the 1.0.0 release.
48
+ This is multiline description. Notice that
49
+ the "changes:" label isn't strictly needed.
50
+
51
+ * This is change 1.
52
+ * This is change 2.
53
+ * This is change 3.
54
+
55
+
56
+ == 0.9.0 / 2010-04-10
57
+
58
+ 1. This is change 1.
59
+ 2. This is change 2.
60
+ 3. This is change 3.
61
+
62
+ Some Dandy description of the 0.9.0 release.
63
+ Notice this time that the changes are listed
64
+ first and are numerically enumerated.
65
+
66
+ The History class provides an interface to this information.
67
+ The initializer takes the root directory for the project
68
+ and looks for a file called +HISTORY+, optionally ending
69
+ in an extension such as +.txt+ or +.rdoc+, etc.
70
+
71
+ history = History.find('tmp/example')
72
+
73
+ Now we should have an enumeration of each release entry in
74
+ the HISTORY file.
75
+
76
+ history.releases.size.assert == 4
77
+
78
+ The non-plurual #release method will give us the first entry.
79
+ And we can see that it has been parsed into its component
80
+ attributes.
81
+
82
+ history.release.header.assert == '== 1.2.0 / 2010-10-18'
83
+ history.release.notes.assert.index('description of the 1.2.0')
84
+
85
+ The header is further parsed into version, date and nickname if given.
86
+
87
+ history.release.version.assert == '1.2.0'
88
+ history.release.date.assert == '2010-10-18'
89
+
90
+ We should see like results for the other release entries.
91
+
92
+ history.releases[2].version.assert == '1.0.0'
93
+ history.releases[2].date.assert == '2010-04-30'
94
+
95
+ history.releases[2].header.assert == '== 1.0.0 / 2010-04-30'
96
+ history.releases[2].notes.assert.index('description of the 1.0.0')
97
+ history.releases[2].changes.assert.index('This is change 1')
98
+
99
+ Even though there are variations in the formats of each entry they are
100
+ still parsed correctly. For example the second release has a nick name.
101
+
102
+ history.releases[1].nickname.assert == 'Happy Days'
103
+
104
+ And the last entry has it's changes listed before the description.
105
+
106
+ history.releases[3].header.assert == '== 0.9.0 / 2010-04-10'
107
+ history.releases[3].notes.assert.index('description of the 0.9.0')
108
+ history.releases[3].changes.assert.index('This is change 1')
109
+
110
+ The history parser is farily simplistic, but it is flexibile enough
111
+ to parse the most common HISTORY file formats.
112
+
113
+
data/HISTORY.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # RELEASE HISTORY
2
2
 
3
+ ## 0.2.0 / 2012-05-25
4
+
5
+ This the first usable release. There's actual code now ;)
6
+
7
+ Changes:
8
+
9
+ * Port code from POM project for initial implementation.
10
+ * Place variant from VCLog project in work directory for reference.
11
+
12
+
3
13
  ## 0.1.0 / 2012-05-24
4
14
 
5
15
  This is a place holder release until the first working addition
data/README.md CHANGED
@@ -9,10 +9,10 @@
9
9
 
10
10
  ## Description
11
11
 
12
- History is a HISTORY and CHANGELOG file parser. It can parse common layouts for these
13
- file types and provide their contents in a structured model. This can be useful for
14
- a number of things, in particular it can be used to generate tag messages and add
15
- pre-release changelogs to relase announcements.
12
+ History is a HISTORY file parser. It can parse common HISTORY file layouts
13
+ and provide the contents in a structured model. This can be useful for
14
+ a number of things, in particular it can be used to generate tag messages
15
+ and add pre-release change lists to release announcements.
16
16
 
17
17
 
18
18
  ## Copyrights
data/demo/00_intro.md ADDED
@@ -0,0 +1,6 @@
1
+ # History Gem
2
+
3
+ History is a HISTORY file parser. It can parse common HISTORY file layouts
4
+ and provide the contents in a structured model. This can be useful for
5
+ a number of things, in particular it can be used to generate tag messages
6
+ and add pre-release change lists to release announcements.
@@ -0,0 +1,105 @@
1
+ # History Class
2
+
3
+ The history class encapsulates this list of release
4
+ made by a project. It parses a text file by the
5
+ name of HISTORY into it indivdual relase entries.
6
+
7
+ Given a HISTORY project file containing:
8
+
9
+ = RELEASE HISTORY
10
+
11
+ == 1.2.0 / 2010-10-18
12
+
13
+ Some Dandy description of the 1.2.0 release.
14
+ This is multiline description.
15
+
16
+ Changes:
17
+
18
+ * This is change 1.
19
+ * This is change 2.
20
+ * This is change 3.
21
+
22
+
23
+ == 1.1.0 | 2010-06-06 | "Happy Days"
24
+
25
+ Some Dandy description of the 1.1.0 release.
26
+ This is multiline description. Notice the
27
+ header varies from the first.
28
+
29
+ The description can even have multiple paragraphs.
30
+
31
+ Changes:
32
+
33
+ * This is change 1.
34
+ * This is change 2.
35
+ * This is change 3.
36
+
37
+
38
+ == 1.0.0 / 2010-04-30
39
+
40
+ Some Dandy description of the 1.0.0 release.
41
+ This is multiline description. Notice that
42
+ the "changes:" label isn't strictly needed.
43
+
44
+ * This is change 1.
45
+ * This is change 2.
46
+ * This is change 3.
47
+
48
+
49
+ == 0.9.0 / 2010-04-10
50
+
51
+ 1. This is change 1.
52
+ 2. This is change 2.
53
+ 3. This is change 3.
54
+
55
+ Some Dandy description of the 0.9.0 release.
56
+ Notice this time that the changes are listed
57
+ first and are numerically enumerated.
58
+
59
+ The History class provides an interface to this information.
60
+ The initializer takes the root directory for the project
61
+ and looks for a file called +HISTORY+, optionally ending
62
+ in an extension such as +.txt+ or +.rdoc+, etc.
63
+
64
+ history = History.find('tmp/example')
65
+
66
+ Now we should have an enumeration of each release entry in
67
+ the HISTORY file.
68
+
69
+ history.releases.size.assert == 4
70
+
71
+ The non-plurual #release method will give us the first entry.
72
+ And we can see that it has been parsed into its component
73
+ attributes.
74
+
75
+ history.release.header.assert == '== 1.2.0 / 2010-10-18'
76
+ history.release.notes.assert.index('description of the 1.2.0')
77
+
78
+ The header is further parsed into version, date and nickname if given.
79
+
80
+ history.release.version.assert == '1.2.0'
81
+ history.release.date.assert == '2010-10-18'
82
+
83
+ We should see like results for the other release entries.
84
+
85
+ history.releases[2].version.assert == '1.0.0'
86
+ history.releases[2].date.assert == '2010-04-30'
87
+
88
+ history.releases[2].header.assert == '== 1.0.0 / 2010-04-30'
89
+ history.releases[2].notes.assert.index('description of the 1.0.0')
90
+ history.releases[2].changes.assert.index('This is change 1')
91
+
92
+ Even though there are variations in the formats of each entry they are
93
+ still parsed correctly. For example the second release has a nick name.
94
+
95
+ history.releases[1].nickname.assert == 'Happy Days'
96
+
97
+ And the last entry has it's changes listed before the description.
98
+
99
+ history.releases[3].header.assert == '== 0.9.0 / 2010-04-10'
100
+ history.releases[3].notes.assert.index('description of the 0.9.0')
101
+ history.releases[3].changes.assert.index('This is change 1')
102
+
103
+ The history parser is farily simplistic, but it is flexibile enough
104
+ to parse the most common HISTORY file formats.
105
+
@@ -0,0 +1,2 @@
1
+ require 'ae'
2
+ require 'ae/should'
@@ -0,0 +1,25 @@
1
+ require 'fileutils'
2
+
3
+ FIXTURE_DIR = 'tmp/example/'
4
+
5
+ # Remove the example project if it exists.
6
+ Before :all do
7
+ FileUtils.rm_r(FIXTURE_DIR) if File.exist?(FIXTURE_DIR)
8
+ File.open(FIXTURE_DIR + '/.ruby', 'w'){ |f| f << "" }
9
+ end
10
+
11
+ When 'Given an empty project directory' do
12
+ FileUtils.rm_r(FIXTURE_DIR) if File.exist?(FIXTURE_DIR)
13
+ end
14
+
15
+ When 'iven a ((([\.\w]+))) project file' do |name, text|
16
+ FileUtils.mkdir_p(FIXTURE_DIR)
17
+ File.open(FIXTURE_DIR + name, 'w') do |f|
18
+ f << text
19
+ end
20
+ end
21
+
22
+ When 'no ((([\.\w]+))) file in a project' do |name|
23
+ FileUtils.rm(FIXTURE_DIR + name)
24
+ end
25
+
@@ -0,0 +1 @@
1
+ require 'history'
data/lib/history.rb CHANGED
@@ -1 +1,124 @@
1
- # TODO
1
+ #require 'history/core_ext'
2
+ require 'history/release'
3
+
4
+ # The History class is a HISTORY file parser. It parses HISTORY files
5
+ # into a structure of individual release sections.
6
+ #
7
+ # The file is expected to be in RDoc or simple Markdown format with
8
+ # each section beginning with a secondary header (`==` or `##`) giving
9
+ # *version* and *date* of release, then a *note* followed by a point by
10
+ # point outline of *changes*.
11
+ #
12
+ # For example:
13
+ #
14
+ # == 1.0.0 / 2009-10-07
15
+ #
16
+ # Say something about this version.
17
+ #
18
+ # Changes:
19
+ #
20
+ # * outline oimportant changelog items
21
+ #
22
+ # `Changes:` is used as a parsing marker. While optional, it helps the
23
+ # parser find the list of changes, rather than looking for an asterisk
24
+ # or digit, so that ordered and unordered lists can be used in the note
25
+ # section too.
26
+ #
27
+ # Ideally, this class will be continuely imporved to handle greater
28
+ # variety of layout.
29
+ #
30
+ class History
31
+
32
+ # File glob for finding the HISTORY file.
33
+ DEFAULT_FILE = '{History}{,.*}'
34
+
35
+ # Match against version number string.
36
+ HEADER_RE = /^[=#]+\s*\d+\.\S+/
37
+
38
+ # Convenience constant for `File::FNM_CASEFOLD`.
39
+ CASEFOLD = File::FNM_CASEFOLD
40
+
41
+ #
42
+ def self.parse(text, opts={})
43
+ opts[:text] = text
44
+ new(opts[:file], opts)
45
+ end
46
+
47
+ def self.text(text, opts={})
48
+ parse(text, opts)
49
+ end
50
+
51
+ #
52
+ def self.file(file)
53
+ new(file)
54
+ end
55
+
56
+ #
57
+ def self.find(root=Dir.pwd)
58
+ file = Dir.glob(File.join(root, DEFAULT_FILE), CASEFOLD).first
59
+ new(file)
60
+ end
61
+
62
+ # HISTORY file's path.
63
+ attr :file
64
+
65
+ # HISTORY file's raw contents.
66
+ attr :text
67
+
68
+ # List of release entries.
69
+ attr :releases
70
+
71
+ # New History.
72
+ def initialize(file=nil, opts={})
73
+ if Hash === file
74
+ opts = file
75
+ file = nil
76
+ end
77
+
78
+ @file = file
79
+ @text = opts[:text]
80
+
81
+ if @file
82
+ # if file is given but no text, raise error if file not found
83
+ raise "file not found" unless File.exist?(@file) unless @text
84
+ else
85
+ @file = Dir.glob(DEFAULT_FILE, CASEFOLD).first || 'HISTORY'
86
+ end
87
+
88
+ unless @text
89
+ @text = File.read(@file) if File.exist?(@file)
90
+ end
91
+
92
+ parse
93
+ end
94
+
95
+ # Read and parse the Histoy file.
96
+ def parse
97
+ @releases = []
98
+ entry = nil
99
+
100
+ if text
101
+ text.each_line do |line|
102
+ if HEADER_RE =~ line
103
+ @releases << Release.new(entry) if entry
104
+ entry = line
105
+ else
106
+ next unless entry
107
+ entry << line
108
+ end
109
+ end
110
+ @releases << Release.new(entry)
111
+ end
112
+ end
113
+
114
+ # Lookup release by version.
115
+ def [](version)
116
+ releases.find{ |r| r.version == version }
117
+ end
118
+
119
+ # Returns first entry in releases list.
120
+ def release
121
+ releases.first
122
+ end
123
+
124
+ end #class History
data/lib/history.yml ADDED
@@ -0,0 +1,66 @@
1
+ ---
2
+ source:
3
+ - var
4
+ authors:
5
+ - name: trans
6
+ email: transfire@gmail.com
7
+ copyrights:
8
+ - holder: Rubyworks
9
+ year: '2012'
10
+ license: BSD-2-Clause
11
+ requirements:
12
+ - name: detroit
13
+ groups:
14
+ - build
15
+ development: true
16
+ - name: qed
17
+ groups:
18
+ - test
19
+ development: true
20
+ - name: ae
21
+ groups:
22
+ - test
23
+ development: true
24
+ dependencies: []
25
+ alternatives: []
26
+ conflicts: []
27
+ repositories:
28
+ - uri: git://github.com/rubyworks/history.git
29
+ scm: git
30
+ name: upstream
31
+ resources:
32
+ - uri: http://rubyworks.github.com/history
33
+ label: Website
34
+ type: home
35
+ - uri: http://github.com/rubyworks/history
36
+ label: Source Code
37
+ type: code
38
+ - uri: http://github.com/rubyworks/history/issues
39
+ label: Issue Tracker
40
+ type: bugs
41
+ - uri: http://groups.google.com/groups/rubyworks-mailinglist
42
+ label: Mailing List
43
+ type: mail
44
+ - uri: irc://us.chat.freenode.net/rubyworks
45
+ label: IRC Channel
46
+ type: chat
47
+ categories: []
48
+ extra: {}
49
+ load_path:
50
+ - lib
51
+ revision: 0
52
+ name: history
53
+ title: History
54
+ created: '2010-02-19'
55
+ organization: Rubyworks
56
+ summary: HISTORY and CHANGELOG parser
57
+ version: 0.2.0
58
+ description: ! 'History is a HISTORY file parser. It can parse common HISTORY file
59
+ layouts
60
+
61
+ and provide the contents in a structured model. This can be useful for
62
+
63
+ a number of things, in particular it can be used to generate tag messages
64
+
65
+ and add pre-release change lists to release announcements.'
66
+ date: '2012-05-25'
@@ -0,0 +1,91 @@
1
+ class History
2
+
3
+ # History release entry.
4
+ #
5
+ class Release
6
+
7
+ # The full text of the release note.
8
+ attr :text
9
+
10
+ # The header.
11
+ attr :header
12
+
13
+ # The description.
14
+ attr :notes
15
+
16
+ # The list of changes.
17
+ attr :changes
18
+
19
+ # Version number (as a string).
20
+ attr :version
21
+
22
+ # Release date.
23
+ attr :date
24
+
25
+ # Nick name of the release, if any.
26
+ attr :nickname
27
+
28
+ #
29
+ def initialize(text)
30
+ @text = text.strip
31
+ parse
32
+ end
33
+
34
+ # Returns the complete text.
35
+ def to_s
36
+ text
37
+ end
38
+
39
+ ;; private
40
+
41
+ # Parse the release text into +header+, +notes+
42
+ # and +changes+ components.
43
+ def parse
44
+ lines = text.lines.to_a
45
+
46
+ @header = lines.shift.strip
47
+
48
+ parse_release_stamp(@header)
49
+
50
+ # remove blank lines from top
51
+ lines.shift until lines.first !~ /^\s+$/
52
+
53
+ # find line that looks like the startt of a list of c hanges.
54
+ idx = nil
55
+ idx ||= lines.index{ |line| /^changes\:\s*$/i =~ line }
56
+ idx ||= lines.index{ |line| /^1.\ / =~ line }
57
+ idx ||= lines.index{ |line| /^\*\ / =~ line }
58
+
59
+ if idx.nil?
60
+ @notes = lines.join
61
+ @changes = ''
62
+ elsif idx > 0
63
+ @notes = lines[0...idx].join
64
+ @changes = lines[idx..-1].join
65
+ else
66
+ gap = lines.index{ |line| /^\s*$/ =~ line }
67
+ @changes = lines[0...gap].join
68
+ @notes = lines[gap..-1].join
69
+ end
70
+ end
71
+
72
+ # Parse out the different components of the header, such
73
+ # as `version`, release `date` and release `nick name`.
74
+ def parse_release_stamp(text)
75
+ # version
76
+ if md = /\b(\d+\.\d.*?)(\s|$)/.match(text)
77
+ @version = md[1]
78
+ end
79
+ # date
80
+ if md = /\b(\d+\-\d+\-.*?\d)(\s|\W|$)/.match(text)
81
+ @date = md[1]
82
+ end
83
+ # nickname
84
+ if md = /\"(.*?)\"/.match(text)
85
+ @nickname = md[1]
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: history
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-24 00:00:00.000000000 Z
12
+ date: 2012-05-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: detroit
16
- requirement: &23265980 !ruby/object:Gem::Requirement
16
+ requirement: &16961460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *23265980
24
+ version_requirements: *16961460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: qed
27
- requirement: &23264740 !ruby/object:Gem::Requirement
27
+ requirement: &16983160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *23264740
35
+ version_requirements: *16983160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: ae
38
- requirement: &23263820 !ruby/object:Gem::Requirement
38
+ requirement: &16979640 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,16 +43,15 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *23263820
47
- description: ! 'History is a HISTORY and CHANGELOG file parser. It can parse common
48
- layouts for these
46
+ version_requirements: *16979640
47
+ description: ! 'History is a HISTORY file parser. It can parse common HISTORY file
48
+ layouts
49
49
 
50
- file types and provide their contents in a structured model. This can be useful
51
- for
50
+ and provide the contents in a structured model. This can be useful for
52
51
 
53
- a number of things, in particular it can be used to generate tag messages and add
52
+ a number of things, in particular it can be used to generate tag messages
54
53
 
55
- pre-release changelogs to relase announcements.'
54
+ and add pre-release change lists to release announcements.'
56
55
  email:
57
56
  - transfire@gmail.com
58
57
  executables: []
@@ -61,12 +60,21 @@ extra_rdoc_files:
61
60
  - LICENSE.txt
62
61
  - HISTORY.md
63
62
  - README.md
63
+ - DEMO.md
64
64
  files:
65
65
  - .ruby
66
+ - demo/00_intro.md
67
+ - demo/01_history.md
68
+ - demo/applique/ae.rb
69
+ - demo/applique/fixtures.rb
70
+ - demo/applique/history.rb
71
+ - lib/history/release.rb
66
72
  - lib/history.rb
73
+ - lib/history.yml
67
74
  - LICENSE.txt
68
75
  - HISTORY.md
69
76
  - README.md
77
+ - DEMO.md
70
78
  homepage: http://rubyworks.github.com/history
71
79
  licenses:
72
80
  - BSD-2-Clause