slate 0.0.5 → 0.1.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/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  *.sw*
19
+ vendor
data/README.md CHANGED
@@ -29,3 +29,8 @@ TODO: Write usage instructions here
29
29
  3. Commit your changes (`git commit -am 'Add some feature'`)
30
30
  4. Push to the branch (`git push origin my-new-feature`)
31
31
  5. Create new Pull Request
32
+
33
+ ## Contributors
34
+
35
+ Trae Robrock (https://github.com/trobrock)
36
+ Andrew Katz (https://github.com/andrewkatz)
data/lib/slate.rb CHANGED
@@ -3,6 +3,7 @@ require "slate/configuration"
3
3
  require "slate/target"
4
4
  require "slate/graph"
5
5
  require "slate/calculation"
6
+ require "slate/parser"
6
7
 
7
8
  require "slate/calculation/mean"
8
9
  require "slate/calculation/last"
@@ -0,0 +1,73 @@
1
+ require 'treetop'
2
+ require 'slate/parser/extensions'
3
+ Treetop.load File.join(File.dirname(__FILE__), 'parser', 'slate_tree')
4
+
5
+ module Slate
6
+ class NotParseable < StandardError ; end
7
+
8
+ class Parser
9
+ include Singleton
10
+
11
+ def self.parse(data)
12
+ self.instance.parse(data)
13
+ end
14
+
15
+ def initialize
16
+ @parser = SlateTreeParser.new
17
+ end
18
+
19
+ def parse(data)
20
+ raise Slate::NotParseable if data.nil?
21
+
22
+ parsed_tree = @parser.parse(data)
23
+
24
+ raise Slate::NotParseable if parsed_tree.nil?
25
+
26
+ parse_tree(parsed_tree)
27
+ end
28
+
29
+ private
30
+
31
+ def parse_tree(element, target=nil)
32
+ case element
33
+ when SlateTree::Target
34
+ target ||= Slate::Target.build(element.text_value)
35
+ when SlateTree::Function
36
+ args = arguments(element).map do |arg|
37
+ if is_target? arg
38
+ parse_tree arg
39
+ else
40
+ arg.text_value
41
+ end
42
+ end
43
+
44
+ target.add_function element.text_value, *args
45
+ end
46
+ element.elements.each { |e| target = parse_tree(e, target) } if should_recurse?(element)
47
+
48
+ target
49
+ end
50
+
51
+ def arguments(element)
52
+ element.elements.last.elements.select do |e|
53
+ is_argument?(e) || is_target?(e)
54
+ end
55
+ end
56
+
57
+ def should_recurse?(element)
58
+ !element.terminal? && !is_function?(element)
59
+ end
60
+
61
+ def is_function?(element)
62
+ element.is_a? SlateTree::Function
63
+ end
64
+
65
+ def is_argument?(element)
66
+ element.is_a? SlateTree::Argument
67
+ end
68
+
69
+ def is_target?(element)
70
+ element.is_a? SlateTree::Target
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,49 @@
1
+ module Slate
2
+ module SlateTree
3
+ class Target < Treetop::Runtime::SyntaxNode
4
+ def type
5
+ :target
6
+ end
7
+
8
+ def text_value
9
+ elements.detect{ |e| e.is_a? String }.text_value
10
+ end
11
+ end
12
+
13
+ class Function < Treetop::Runtime::SyntaxNode
14
+ def type
15
+ :function
16
+ end
17
+
18
+ def text_value
19
+ elements.detect{ |e| e.is_a? Token }.text_value
20
+ end
21
+ end
22
+
23
+ class Token < Treetop::Runtime::SyntaxNode
24
+ def type
25
+ :token
26
+ end
27
+ end
28
+
29
+ class Argument < Treetop::Runtime::SyntaxNode
30
+ def type
31
+ :argument
32
+ end
33
+
34
+ def text_value
35
+ elements.first.text_value
36
+ end
37
+ end
38
+
39
+ class String < Treetop::Runtime::SyntaxNode
40
+ def type
41
+ :string
42
+ end
43
+
44
+ def text_value
45
+ super.gsub(/"/,'')
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,31 @@
1
+ module Slate
2
+ grammar SlateTree
3
+ rule document
4
+ (target / space)*
5
+ end
6
+
7
+ rule target
8
+ space? string space '{' space? function* space? '}' <Target>
9
+ end
10
+
11
+ rule function
12
+ token space? (target / argument)* <Function>
13
+ end
14
+
15
+ rule argument
16
+ string ','? space? <Argument>
17
+ end
18
+
19
+ rule token
20
+ [a-zA-Z]+ <Token>
21
+ end
22
+
23
+ rule string
24
+ '"' ('\"' / !'"' .)* '"' <String>
25
+ end
26
+
27
+ rule space
28
+ [\s]+
29
+ end
30
+ end
31
+ end
data/lib/slate/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Slate
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
data/slate.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency "rest-client", "~> 1.6.7"
21
21
  gem.add_dependency "json", "~> 1.7.5"
22
22
  gem.add_dependency "jruby-openssl" if RUBY_PLATFORM == 'java'
23
+ gem.add_dependency "treetop", "~> 1.4.12"
23
24
 
24
25
  gem.add_development_dependency "rake"
25
26
  gem.add_development_dependency "rspec"
@@ -0,0 +1,95 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe Slate::Parser do
4
+ before do
5
+ Slate.configure { |c| c.endpoint = "http://graphite" }
6
+ end
7
+
8
+ it "should raise an exception if it cannot parse" do
9
+ expect {
10
+ Slate::Parser.parse(nil)
11
+ }.to raise_error(Slate::NotParseable)
12
+
13
+ expect {
14
+ Slate::Parser.parse("bob")
15
+ }.to raise_error(Slate::NotParseable)
16
+ end
17
+
18
+ it "should parse a basic target" do
19
+ target = Slate::Target.build("stats.web01.response_time")
20
+
21
+ Slate::Parser.parse(%q{
22
+ "stats.web01.response_time" {}
23
+ }).to_s.should == target.to_s
24
+ end
25
+
26
+ it "should be able to parse a target with one function" do
27
+ target = Slate::Target.build("stats.web01.response_time") do |t|
28
+ t.add_function :sum
29
+ end
30
+
31
+ Slate::Parser.parse(%q{
32
+ "stats.web01.response_time" { sum }
33
+ }).to_s.should == target.to_s
34
+ end
35
+
36
+ it "should be able to parse a target with one function and single arg" do
37
+ target = Slate::Target.build("stats.web01.response_time") do |t|
38
+ t.add_function :summarize, "5min"
39
+ end
40
+
41
+ Slate::Parser.parse(%q{
42
+ "stats.web01.response_time" {
43
+ summarize "5min"
44
+ }
45
+ }).to_s.should == target.to_s
46
+ end
47
+
48
+ it "should be able to parse a target with one function and multiple args" do
49
+ target = Slate::Target.build("stats.web01.response_time") do |t|
50
+ t.add_function :summarize, "5min", "avg"
51
+ end
52
+
53
+ Slate::Parser.parse(%q{
54
+ "stats.web01.response_time" {
55
+ summarize "5min", "avg"
56
+ }
57
+ }).to_s.should == target.to_s
58
+ end
59
+
60
+ it "should be able to parse a target with multiple functions" do
61
+ target = Slate::Target.build("stats.web01.response_time") do |t|
62
+ t.add_function :sum
63
+ t.add_function :summarize, "5min", "avg"
64
+ end
65
+
66
+ Slate::Parser.parse(%q{
67
+ "stats.web01.response_time" {
68
+ sum
69
+ summarize "5min", "avg"
70
+ }
71
+ }).to_s.should == target.to_s
72
+ end
73
+
74
+ it "should be able to parse a really complex target" do
75
+ nested_target = Slate::Target.build("stats_counts.rack.*.status_code.*") do |t|
76
+ t.add_function :exclude, "missing"
77
+ t.add_function :sum
78
+ end
79
+
80
+ target = Slate::Target.build("stats_counts.rack.*.status_code.success") do |t|
81
+ t.add_function :sum
82
+ t.add_function :asPercent, nested_target
83
+ end
84
+
85
+ Slate::Parser.parse(%q{
86
+ "stats_counts.rack.*.status_code.success" {
87
+ sum
88
+ asPercent "stats_counts.rack.*.status_code.*" {
89
+ exclude "missing"
90
+ sum
91
+ }
92
+ }
93
+ }).to_s.should == target.to_s
94
+ end
95
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-15 00:00:00.000000000 Z
12
+ date: 2013-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 1.7.5
46
+ - !ruby/object:Gem::Dependency
47
+ name: treetop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.12
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.4.12
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: rake
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -126,12 +142,16 @@ files:
126
142
  - lib/slate/calculation/mean.rb
127
143
  - lib/slate/configuration.rb
128
144
  - lib/slate/graph.rb
145
+ - lib/slate/parser.rb
146
+ - lib/slate/parser/extensions.rb
147
+ - lib/slate/parser/slate_tree.treetop
129
148
  - lib/slate/target.rb
130
149
  - lib/slate/version.rb
131
150
  - slate.gemspec
132
151
  - spec/slate/calculation/last_spec.rb
133
152
  - spec/slate/calculation/mean_spec.rb
134
153
  - spec/slate/graph_spec.rb
154
+ - spec/slate/parser_spec.rb
135
155
  - spec/slate_spec.rb
136
156
  - spec/spec_helper.rb
137
157
  homepage: https://github.com/trobrock/slate
@@ -148,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
168
  version: '0'
149
169
  segments:
150
170
  - 0
151
- hash: 3107282875806844725
171
+ hash: 3951322141183346689
152
172
  required_rubygems_version: !ruby/object:Gem::Requirement
153
173
  none: false
154
174
  requirements:
@@ -157,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
177
  version: '0'
158
178
  segments:
159
179
  - 0
160
- hash: 3107282875806844725
180
+ hash: 3951322141183346689
161
181
  requirements: []
162
182
  rubyforge_project:
163
183
  rubygems_version: 1.8.24
@@ -168,5 +188,6 @@ test_files:
168
188
  - spec/slate/calculation/last_spec.rb
169
189
  - spec/slate/calculation/mean_spec.rb
170
190
  - spec/slate/graph_spec.rb
191
+ - spec/slate/parser_spec.rb
171
192
  - spec/slate_spec.rb
172
193
  - spec/spec_helper.rb