blaml 1.0.0.pre
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/.autotest +23 -0
- data/.gemtest +0 -0
- data/History.rdoc +6 -0
- data/Manifest.txt +11 -0
- data/README.rdoc +77 -0
- data/Rakefile +15 -0
- data/lib/blaml.rb +93 -0
- data/lib/blaml/blamed_io.rb +165 -0
- data/lib/blaml/meta.rb +190 -0
- data/lib/blaml/to_ruby.rb +55 -0
- data/lib/blaml/tree_builder.rb +30 -0
- data/test/test_blaml.rb +8 -0
- metadata +84 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/.gemtest
ADDED
File without changes
|
data/History.rdoc
ADDED
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= Blaml
|
2
|
+
|
3
|
+
* http://github.com/yaksnrainbows/blaml
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Blaml is a parser based on Psych (ruby 1.9 only) for yaml files that have
|
8
|
+
been blamed with git.
|
9
|
+
Blaml parses the blamed yaml file and makes the blame metadata available on the
|
10
|
+
returned ruby object through a 'meta' attribute.
|
11
|
+
|
12
|
+
== FEATURES:
|
13
|
+
|
14
|
+
* Load blamed yaml files and access blame data as metadata.
|
15
|
+
|
16
|
+
* Currently only works on blamed files generated with 'git blame -f file.yml'
|
17
|
+
|
18
|
+
== SYNOPSIS:
|
19
|
+
|
20
|
+
b = Blaml.load `git blame -f file.yml`
|
21
|
+
|
22
|
+
b.meta
|
23
|
+
# => Returns metadata hash for most recent change in this data structure.
|
24
|
+
|
25
|
+
b.keys.first.meta
|
26
|
+
# => Returns metadata hash for when this key was changed.
|
27
|
+
|
28
|
+
b[:key]
|
29
|
+
# => "value"
|
30
|
+
|
31
|
+
b[:key].meta
|
32
|
+
# => {:updated_at => 2010-10-28 22:43:33 +0000, :author => 'user', :line => 12, :commit => '25kjpp43', :file => 'file.yml'}
|
33
|
+
|
34
|
+
b[:key].class
|
35
|
+
# => Blaml::MetaNode
|
36
|
+
|
37
|
+
b[:key] == "value"
|
38
|
+
# => true
|
39
|
+
|
40
|
+
b[:key].value.class
|
41
|
+
# => String
|
42
|
+
|
43
|
+
b.to_value
|
44
|
+
# => Returns the full original data structure (not wrapped in meta classes)
|
45
|
+
# => {:key => "value"}
|
46
|
+
|
47
|
+
== INSTALL:
|
48
|
+
|
49
|
+
$ gem install blaml
|
50
|
+
|
51
|
+
This task will install any missing dependencies, run the tests/specs,
|
52
|
+
and generate the RDoc.
|
53
|
+
|
54
|
+
== LICENSE:
|
55
|
+
|
56
|
+
(The MIT License)
|
57
|
+
|
58
|
+
Copyright (c) 2011 Jeremie Castagna
|
59
|
+
|
60
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
61
|
+
a copy of this software and associated documentation files (the
|
62
|
+
'Software'), to deal in the Software without restriction, including
|
63
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
64
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
65
|
+
permit persons to whom the Software is furnished to do so, subject to
|
66
|
+
the following conditions:
|
67
|
+
|
68
|
+
The above copyright notice and this permission notice shall be
|
69
|
+
included in all copies or substantial portions of the Software.
|
70
|
+
|
71
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
72
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
73
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
74
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
75
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
76
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
77
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'psych'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'hoe'
|
6
|
+
|
7
|
+
Hoe.spec 'blaml' do
|
8
|
+
developer('Jeremie Castagna', 'yaksnrainbows@gmail.com')
|
9
|
+
|
10
|
+
self.readme_file = "README.rdoc"
|
11
|
+
self.history_file = "History.rdoc"
|
12
|
+
self.extra_rdoc_files = FileList['*.rdoc']
|
13
|
+
end
|
14
|
+
|
15
|
+
# vim: syntax=ruby
|
data/lib/blaml.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'psych'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'blaml/blamed_io'
|
6
|
+
require 'blaml/tree_builder'
|
7
|
+
require 'blaml/meta'
|
8
|
+
require 'blaml/to_ruby'
|
9
|
+
|
10
|
+
class Blaml
|
11
|
+
|
12
|
+
# This gem's version.
|
13
|
+
VERSION = "1.0.0.pre"
|
14
|
+
|
15
|
+
###
|
16
|
+
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
17
|
+
# provided, the object contained in the first document will be returned.
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
#
|
21
|
+
# Psych.load("--- a") # => 'a'
|
22
|
+
# Psych.load("---\n - a\n - b") # => ['a', 'b']
|
23
|
+
|
24
|
+
def self.load yaml
|
25
|
+
result = parse(yaml)
|
26
|
+
result ? result.to_blamed_ruby : result
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
###
|
31
|
+
# Load multiple documents given in +yaml+. Returns the parsed documents
|
32
|
+
# as a list. For example:
|
33
|
+
#
|
34
|
+
# Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']
|
35
|
+
#
|
36
|
+
def self.load_stream yaml
|
37
|
+
parse_stream(yaml).children.map { |child| child.to_blamed_ruby }
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
###
|
42
|
+
# Load the document contained in +filename+. Returns the yaml contained in
|
43
|
+
# +filename+ as a ruby object
|
44
|
+
|
45
|
+
def self.load_file filename
|
46
|
+
self.load File.open(filename)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
###
|
51
|
+
# Parse a YAML string in +yaml+. Returns the first object of a YAML AST.
|
52
|
+
#
|
53
|
+
# Example:
|
54
|
+
#
|
55
|
+
# Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00>
|
56
|
+
#
|
57
|
+
# See Psych::Nodes for more information about YAML AST.
|
58
|
+
|
59
|
+
def self.parse yaml
|
60
|
+
children = parse_stream(BlamedIO.new(yaml)).children
|
61
|
+
children.empty? ? false : children.first.children.first
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
###
|
66
|
+
# Parse a file at +filename+. Returns the YAML AST.
|
67
|
+
|
68
|
+
def self.parse_file filename
|
69
|
+
File.open filename do |f|
|
70
|
+
parse f
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
###
|
76
|
+
# Returns a default parser
|
77
|
+
|
78
|
+
def self.parser blaml
|
79
|
+
Psych::Parser.new(TreeBuilder.new(blaml))
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
###
|
84
|
+
# Parse a YAML blame string in +yaml+.
|
85
|
+
# Returns the full AST for the YAML document with blame metadata.
|
86
|
+
# See Psych::parse_stream for more info.
|
87
|
+
|
88
|
+
def self.parse_stream blaml
|
89
|
+
parser = self.parser blaml
|
90
|
+
parser.parse blaml
|
91
|
+
parser.handler.root
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
class Blaml
|
2
|
+
|
3
|
+
##
|
4
|
+
# IO wrapper that removes and parses blame data and makes it
|
5
|
+
# available as metadata
|
6
|
+
|
7
|
+
class BlamedIO
|
8
|
+
|
9
|
+
DATE_MATCHER =
|
10
|
+
%r{(\d+[-\s:]){6}[^\s]+}
|
11
|
+
|
12
|
+
META_MATCHER =
|
13
|
+
%r{([^\s]+)\s+([^\s]+)\s+\(([^\s]+)\s+(#{DATE_MATCHER})\s+(\d+)\)\s}
|
14
|
+
|
15
|
+
# Accessor for currently available metadata.
|
16
|
+
attr_reader :metadata
|
17
|
+
|
18
|
+
|
19
|
+
##
|
20
|
+
# Create new BlamedIO with a string or IO object.
|
21
|
+
|
22
|
+
def initialize io
|
23
|
+
io = StringIO.new io if String === io
|
24
|
+
|
25
|
+
@io = io
|
26
|
+
@metadata = []
|
27
|
+
@meta_mode = true
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
%w{close closed? eof eof? rewind}.each do |meth|
|
32
|
+
class_eval "def #{meth}; @io.#{meth}; end"
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
##
|
37
|
+
# Retrieves the metadata for a given string that matches
|
38
|
+
# the next line in the IO stream and deletes it permanently.
|
39
|
+
|
40
|
+
def shift_metadata_for str
|
41
|
+
meta, line = @metadata.first
|
42
|
+
|
43
|
+
if line.nil? || line.empty? || line[0..0] == '#'
|
44
|
+
@metadata.shift
|
45
|
+
return meta if str.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
meta, line = @metadata.first
|
49
|
+
|
50
|
+
if str.length > line.length
|
51
|
+
|
52
|
+
while str.include? @metadata.first[1] do
|
53
|
+
tmp_meta, line = @metadata.shift
|
54
|
+
meta = tmp_meta if
|
55
|
+
!meta || !meta[:updated_at] ||
|
56
|
+
meta && meta[:updated_at] &&
|
57
|
+
tmp_meta && tmp_meta[:updated_at] &&
|
58
|
+
tmp_meta[:updated_at] > meta[:updated_at]
|
59
|
+
end
|
60
|
+
|
61
|
+
else
|
62
|
+
@metadata.first[1] = line.split(str, 2).last.strip
|
63
|
+
@metadata.first[1].gsub!(%r{^:(\s+|$)}, "")
|
64
|
+
end
|
65
|
+
|
66
|
+
#puts "#{str} -> #{meta.inspect}"
|
67
|
+
meta
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
##
|
72
|
+
# Removes leading spaces and dashes from a line of yaml data.
|
73
|
+
|
74
|
+
def sanitize_data str
|
75
|
+
str.to_s.strip.gsub(%r{^(-\s)+}, "")
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
##
|
80
|
+
# Read single char as an integer.
|
81
|
+
|
82
|
+
def getc
|
83
|
+
read(1).unpack('c')[0]
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##
|
88
|
+
# Read from the IO instance and parse the blame data.
|
89
|
+
|
90
|
+
def read length=nil, buffer=nil
|
91
|
+
buffer ||= ""
|
92
|
+
meta_line = ""
|
93
|
+
|
94
|
+
until buffer.length == length || @io.eof?
|
95
|
+
if @meta_mode
|
96
|
+
read_meta
|
97
|
+
@meta_mode = false
|
98
|
+
end
|
99
|
+
|
100
|
+
char = @io.getc
|
101
|
+
buffer << char
|
102
|
+
meta_line << char
|
103
|
+
|
104
|
+
if buffer[-1..-1] == $/
|
105
|
+
@meta_mode = true
|
106
|
+
@metadata.last << sanitize_data(meta_line)
|
107
|
+
meta_line = ""
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#puts @metadata.map{|i| i.inspect}.join("\n")
|
112
|
+
buffer
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
##
|
117
|
+
# Read a single line.
|
118
|
+
|
119
|
+
def readline sep_string=$/
|
120
|
+
buffer = ""
|
121
|
+
until buffer[-1..-1] == sep_string || @io.eof?
|
122
|
+
buffer << read(1)
|
123
|
+
end
|
124
|
+
|
125
|
+
buffer
|
126
|
+
end
|
127
|
+
|
128
|
+
alias gets readline
|
129
|
+
|
130
|
+
|
131
|
+
##
|
132
|
+
# Reads blame metadata.
|
133
|
+
|
134
|
+
def read_meta
|
135
|
+
buffer = ""
|
136
|
+
|
137
|
+
start_pos = @io.pos
|
138
|
+
|
139
|
+
until buffer =~ META_MATCHER do
|
140
|
+
|
141
|
+
# Got to the end of line with no metadata.
|
142
|
+
# Assume we're reading a regular yml IO.
|
143
|
+
if @io.eof? || buffer =~ %r{#{$/}$}
|
144
|
+
@io.pos = start_pos
|
145
|
+
@metadata << [nil]
|
146
|
+
return
|
147
|
+
end
|
148
|
+
|
149
|
+
buffer << @io.getc
|
150
|
+
end
|
151
|
+
|
152
|
+
meta_key = {
|
153
|
+
:file => $2,
|
154
|
+
:line => $6.to_i,
|
155
|
+
:author => $3,
|
156
|
+
:commit => $1,
|
157
|
+
:updated_at => Time.parse($4)
|
158
|
+
}
|
159
|
+
|
160
|
+
@metadata << [meta_key]
|
161
|
+
|
162
|
+
true
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/blaml/meta.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
class Blaml
|
2
|
+
|
3
|
+
|
4
|
+
##
|
5
|
+
# Simple wrapper class to assign metadata to object instances.
|
6
|
+
|
7
|
+
class MetaNode
|
8
|
+
|
9
|
+
|
10
|
+
# The object to assign metadata to.
|
11
|
+
attr_reader :value
|
12
|
+
|
13
|
+
# The metadata assigned to the wrapped object.
|
14
|
+
attr_writer :meta
|
15
|
+
|
16
|
+
##
|
17
|
+
# Create a new MetaNode with the value to wrap and optional metadata.
|
18
|
+
|
19
|
+
def initialize value, meta=nil
|
20
|
+
@value = value
|
21
|
+
@meta = meta
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
##
|
26
|
+
# Checks for equality against the value attribute.
|
27
|
+
|
28
|
+
def == obj
|
29
|
+
case obj
|
30
|
+
when MetaNode then obj.value == @value
|
31
|
+
else
|
32
|
+
@value == obj
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
##
|
38
|
+
# Accessor for the meta attribute.
|
39
|
+
# Overridden in MetaArray and MetaHash classes.
|
40
|
+
|
41
|
+
def meta
|
42
|
+
@meta
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
%w{to_s to_i to_f to_sym inspect}.each do |meth|
|
47
|
+
class_eval "def #{meth}; @value.#{meth}; end"
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
##
|
52
|
+
# Sends non-defined methods to the value attribute
|
53
|
+
|
54
|
+
def method_missing name, *args, &block
|
55
|
+
@value.send name, *args, &block
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
##
|
60
|
+
# Accessor for the value attribute.
|
61
|
+
# Overridden in MetaArray and MetaHash classes.
|
62
|
+
|
63
|
+
def to_value
|
64
|
+
@value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
##
|
70
|
+
# Wraps Array instances with metadata.
|
71
|
+
|
72
|
+
class MetaArray < MetaNode
|
73
|
+
|
74
|
+
##
|
75
|
+
# Returns the child metadata with the most recent change.
|
76
|
+
|
77
|
+
def meta
|
78
|
+
meta = nil
|
79
|
+
|
80
|
+
@value.each do |val|
|
81
|
+
next unless val.respond_to? :meta
|
82
|
+
|
83
|
+
meta = val.meta if !meta ||
|
84
|
+
meta && val.meta && val.meta[:updated_at] > meta[:updated_at]
|
85
|
+
end
|
86
|
+
|
87
|
+
meta
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
##
|
92
|
+
# Strips MetaNode wrapper from the value and calls to_value
|
93
|
+
# on all array elements.
|
94
|
+
|
95
|
+
def to_value
|
96
|
+
@value.map{|v| v.respond_to?(:to_value) ? v.to_value : v }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
##
|
102
|
+
# Wraps Hash instances with metadata.
|
103
|
+
|
104
|
+
class MetaHash < MetaNode
|
105
|
+
|
106
|
+
##
|
107
|
+
# Access a value of the wrapped hash.
|
108
|
+
|
109
|
+
def [] key
|
110
|
+
@value.each{|k,v| return v if k == key}
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
##
|
115
|
+
# Assign a value of the wrapped hash.
|
116
|
+
|
117
|
+
def []= key, val
|
118
|
+
@value.each{|k,v| @value[k] = val and return if k == key}
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
##
|
123
|
+
# Merge with and modify the wrapped hash.
|
124
|
+
|
125
|
+
def merge! hash
|
126
|
+
hash.each do |k,v|
|
127
|
+
key = @value.keys.find{|vk| vk == k || k == vk } || k
|
128
|
+
@value.delete key
|
129
|
+
@value[k] = v
|
130
|
+
end
|
131
|
+
|
132
|
+
self
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
##
|
137
|
+
# Create a new MetaHash merged with the given hash or metahash.
|
138
|
+
|
139
|
+
def merge hash
|
140
|
+
clone = @value.dup
|
141
|
+
hash.each do |k,v|
|
142
|
+
key = clone.keys.find{|vk| vk == k || k == vk } || k
|
143
|
+
clone.delete key
|
144
|
+
clone[k] = v
|
145
|
+
end
|
146
|
+
|
147
|
+
clone
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
##
|
152
|
+
# Returns the child metadata with the most recent change.
|
153
|
+
|
154
|
+
def meta
|
155
|
+
meta = nil
|
156
|
+
|
157
|
+
@value.each do |key, val|
|
158
|
+
if val.respond_to? :meta
|
159
|
+
meta = val.meta if !meta ||
|
160
|
+
meta && val.meta && val.meta[:updated_at] > meta[:updated_at]
|
161
|
+
end
|
162
|
+
|
163
|
+
if key.respond_to? :meta
|
164
|
+
meta = key.meta if !meta ||
|
165
|
+
meta && val.meta && key.meta[:updated_at] > meta[:updated_at]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
meta
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
##
|
174
|
+
# Strips MetaNode wrapper from the value and calls to_value
|
175
|
+
# on all hash elements.
|
176
|
+
|
177
|
+
def to_value
|
178
|
+
clone = Hash.new
|
179
|
+
|
180
|
+
@value.each do |k, v|
|
181
|
+
key = k.respond_to?(:to_value) ? k.to_value : k
|
182
|
+
val = v.respond_to?(:to_value) ? v.to_value : v
|
183
|
+
|
184
|
+
clone[key] = val
|
185
|
+
end
|
186
|
+
|
187
|
+
clone
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Blaml
|
2
|
+
|
3
|
+
##
|
4
|
+
# Subclass Psych's to_ruby to build node values with metadata.
|
5
|
+
|
6
|
+
class ToRuby < Psych::Visitors::ToRuby
|
7
|
+
|
8
|
+
##
|
9
|
+
# Wraps ruby object with MetaNode.
|
10
|
+
# See Psych::Visitors::ToRuby
|
11
|
+
|
12
|
+
def visit_Psych_Nodes_Scalar o
|
13
|
+
MetaNode.new super, o.meta
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
# Wraps ruby Arrays with MetaArray.
|
19
|
+
# See Psych::Visitors::ToRuby
|
20
|
+
|
21
|
+
def visit_Psych_Nodes_Sequence o
|
22
|
+
seq = super
|
23
|
+
return seq unless Array === seq
|
24
|
+
|
25
|
+
MetaArray.new seq
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
##
|
31
|
+
# Wraps ruby Arrays with MetaHash.
|
32
|
+
# See Psych::Visitors::ToRuby
|
33
|
+
|
34
|
+
def visit_Psych_Nodes_Mapping o
|
35
|
+
mapp = super
|
36
|
+
return mapp unless Hash === mapp
|
37
|
+
|
38
|
+
MetaHash.new mapp
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
class Psych::Nodes::Node
|
45
|
+
|
46
|
+
# Metadata accessor.
|
47
|
+
attr_accessor :meta
|
48
|
+
|
49
|
+
##
|
50
|
+
# Tells Psych nodes to use Blaml::ToRuby.
|
51
|
+
|
52
|
+
def to_blamed_ruby
|
53
|
+
Blaml::ToRuby.new.accept self
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Blaml
|
2
|
+
|
3
|
+
class TreeBuilder < Psych::TreeBuilder
|
4
|
+
|
5
|
+
def initialize meta_binding
|
6
|
+
@meta_binding = meta_binding
|
7
|
+
super()
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
##
|
12
|
+
# Sets the @meta instance variable to the metadata
|
13
|
+
# matched for the string object.
|
14
|
+
# Returns the passed instance.
|
15
|
+
|
16
|
+
def add_meta obj
|
17
|
+
obj.meta = @meta_binding.shift_metadata_for obj.value
|
18
|
+
obj
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
##
|
23
|
+
# Calls parent and applies metadata to return value.
|
24
|
+
|
25
|
+
def scalar value, anchor, tag, plain, quoted, style
|
26
|
+
super
|
27
|
+
add_meta @last.children.last
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/test/test_blaml.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blaml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeremie Castagna
|
9
|
+
autorequire: !!null
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-02-03 00:00:00.000000000 -08:00
|
13
|
+
default_executable: !!null
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
requirement: &2156751600 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.9.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2156751600
|
26
|
+
description: ! 'Blaml is a parser based on Psych (ruby 1.9 only) for yaml files that
|
27
|
+
have
|
28
|
+
|
29
|
+
been blamed with git.
|
30
|
+
|
31
|
+
Blaml parses the blamed yaml file and makes the blame metadata available on the
|
32
|
+
|
33
|
+
returned ruby object through a ''meta'' attribute.'
|
34
|
+
email:
|
35
|
+
- yaksnrainbows@gmail.com
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files:
|
39
|
+
- Manifest.txt
|
40
|
+
- History.rdoc
|
41
|
+
- README.rdoc
|
42
|
+
files:
|
43
|
+
- .autotest
|
44
|
+
- History.rdoc
|
45
|
+
- Manifest.txt
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- lib/blaml.rb
|
49
|
+
- lib/blaml/blamed_io.rb
|
50
|
+
- lib/blaml/meta.rb
|
51
|
+
- lib/blaml/to_ruby.rb
|
52
|
+
- lib/blaml/tree_builder.rb
|
53
|
+
- test/test_blaml.rb
|
54
|
+
- .gemtest
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/yaksnrainbows/blaml
|
57
|
+
licenses: []
|
58
|
+
post_install_message: !!null
|
59
|
+
rdoc_options:
|
60
|
+
- --main
|
61
|
+
- README.rdoc
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>'
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.1
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project: blaml
|
78
|
+
rubygems_version: 1.5.0
|
79
|
+
signing_key: !!null
|
80
|
+
specification_version: 3
|
81
|
+
summary: Blaml is a parser based on Psych (ruby 1.9 only) for yaml files that have
|
82
|
+
been blamed with git
|
83
|
+
test_files:
|
84
|
+
- test/test_blaml.rb
|