hotdog 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -16
- data/lib/hotdog/commands/search.rb +34 -23
- data/lib/hotdog/commands.rb +41 -69
- data/lib/hotdog/version.rb +1 -1
- data/spec/core/commands_spec.rb +122 -0
- data/spec/parser/parser_spec.rb +2 -2
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fccd372d49246c2c85768c9244a29746fafcfb40
|
4
|
+
data.tar.gz: 9b4d490218a3d93af4806b12d47dfca28f8d90f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e21eb61e7ccfc2b533e005eb1f494ead1c16c12cd21e0384d46228e88f3a5d6771a62f9006fca59bc538e680e4a7370f1a1905c3e1aa314ea368e4b97146a92
|
7
|
+
data.tar.gz: 654ccf67781c3c1a7ebc1f59fac07a5dd6319231474e6ffadcd08309d32b062efe7e543c1db83f7d821bb054a6ea31c111b7c717f63f0692b3929a6fc79df971
|
data/README.md
CHANGED
@@ -100,24 +100,33 @@ $ hotdog ssh availability-zone:us-east-1b and 'name:web-*' -t public_ipv4 -u use
|
|
100
100
|
Acceptable expressions in pseudo BNF.
|
101
101
|
|
102
102
|
```
|
103
|
-
expression:
|
104
|
-
| term
|
103
|
+
expression: expression0
|
105
104
|
;
|
106
105
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
106
|
+
expression0: expression1 "and" expression
|
107
|
+
| expression1 "or" expression
|
108
|
+
| expression1
|
109
|
+
;
|
110
|
+
|
111
|
+
expression1: "not" expression
|
112
|
+
| expression2
|
113
|
+
;
|
114
|
+
|
115
|
+
expression2: expression3 expression
|
116
|
+
| expression3
|
117
|
+
;
|
118
|
+
|
119
|
+
expression3: expression4 "&&" expression
|
120
|
+
| expression4 "||" expression
|
121
|
+
| expression4
|
122
|
+
;
|
123
|
+
|
124
|
+
expression4: '!' atom
|
125
|
+
| '~' atom
|
126
|
+
| '!' expression
|
127
|
+
| '~' expression
|
128
|
+
| atom
|
129
|
+
;
|
121
130
|
|
122
131
|
atom: '(' expression ')'
|
123
132
|
| IDENTIFIER separator ATTRIBUTE
|
@@ -79,38 +79,49 @@ module Hotdog
|
|
79
79
|
class ExpressionParser < Parslet::Parser
|
80
80
|
root(:expression)
|
81
81
|
rule(:expression) {
|
82
|
-
(
|
83
|
-
| term \
|
82
|
+
( expression0 \
|
84
83
|
)
|
85
84
|
}
|
86
|
-
rule(:
|
87
|
-
(
|
88
|
-
|
|
89
|
-
| match('[Aa]') >> match('[Nn]') >> match('[Dd]') \
|
90
|
-
| match('[Oo]') >> match('[Rr]') \
|
85
|
+
rule(:expression0) {
|
86
|
+
( expression1.as(:left) >> spacing.maybe >> binary_op.as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
87
|
+
| expression1 \
|
91
88
|
)
|
92
89
|
}
|
93
|
-
rule(:
|
94
|
-
(
|
95
|
-
|
|
90
|
+
rule(:expression1) {
|
91
|
+
( unary_op.as(:unary_op) >> spacing.maybe >> expression.as(:expression) \
|
92
|
+
| expression2 \
|
96
93
|
)
|
97
94
|
}
|
98
|
-
rule(:
|
99
|
-
(
|
100
|
-
|
|
101
|
-
| match('[Nn]') >> match('[Oo]') >> match('[Tt]') \
|
95
|
+
rule(:expression2) {
|
96
|
+
( expression3.as(:left) >> spacing.maybe.as(:binary_op) >> expression.as(:right) \
|
97
|
+
| expression3 \
|
102
98
|
)
|
103
99
|
}
|
104
|
-
rule(:
|
105
|
-
( spacing.maybe >>
|
106
|
-
| spacing.maybe >>
|
100
|
+
rule(:expression3) {
|
101
|
+
( expression4.as(:left) >> spacing.maybe >> str('&&').as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
102
|
+
| expression4.as(:left) >> spacing.maybe >> str('||').as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
103
|
+
| expression4.as(:left) >> spacing.maybe >> str('&').as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
104
|
+
| expression4.as(:left) >> spacing.maybe >> str('|').as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
105
|
+
| expression4 \
|
107
106
|
)
|
108
107
|
}
|
109
|
-
rule(:
|
110
|
-
(
|
108
|
+
rule(:expression4) {
|
109
|
+
( str('!').as(:unary_op) >> spacing.maybe >> atom.as(:expression) \
|
110
|
+
| str('~').as(:unary_op) >> spacing.maybe >> atom.as(:expression) \
|
111
|
+
| str('!').as(:unary_op) >> spacing.maybe >> expression.as(:expression) \
|
112
|
+
| str('~').as(:unary_op) >> spacing.maybe >> expression.as(:expression) \
|
111
113
|
| atom \
|
112
114
|
)
|
113
115
|
}
|
116
|
+
rule(:binary_op) {
|
117
|
+
( str('and') \
|
118
|
+
| str('or') \
|
119
|
+
)
|
120
|
+
}
|
121
|
+
rule(:unary_op) {
|
122
|
+
( str('not') \
|
123
|
+
)
|
124
|
+
}
|
114
125
|
rule(:atom) {
|
115
126
|
( spacing.maybe >> str('(') >> expression >> str(')') >> spacing.maybe \
|
116
127
|
| spacing.maybe >> identifier_regexp.as(:identifier_regexp) >> separator >> attribute_regexp.as(:attribute_regexp) >> spacing.maybe \
|
@@ -137,11 +148,11 @@ module Hotdog
|
|
137
148
|
)
|
138
149
|
}
|
139
150
|
rule(:identifier_glob) {
|
140
|
-
(
|
151
|
+
( binary_op.absent? >> unary_op.absent? >> identifier.repeat(0) >> (glob >> identifier.maybe).repeat(1) \
|
141
152
|
)
|
142
153
|
}
|
143
154
|
rule(:identifier) {
|
144
|
-
(
|
155
|
+
( binary_op.absent? >> unary_op.absent? >> match('[A-Za-z]') >> match('[-./0-9A-Z_a-z]').repeat(0) \
|
145
156
|
)
|
146
157
|
}
|
147
158
|
rule(:separator) {
|
@@ -154,11 +165,11 @@ module Hotdog
|
|
154
165
|
)
|
155
166
|
}
|
156
167
|
rule(:attribute_glob) {
|
157
|
-
(
|
168
|
+
( binary_op.absent? >> unary_op.absent? >> attribute.repeat(0) >> (glob >> attribute.maybe).repeat(1) \
|
158
169
|
)
|
159
170
|
}
|
160
171
|
rule(:attribute) {
|
161
|
-
(
|
172
|
+
( binary_op.absent? >> unary_op.absent? >> match('[-./0-9:A-Z_a-z]').repeat(1) \
|
162
173
|
)
|
163
174
|
}
|
164
175
|
rule(:glob) {
|
data/lib/hotdog/commands.rb
CHANGED
@@ -80,36 +80,7 @@ module Hotdog
|
|
80
80
|
tag_name, tag_value = split_tag(tag)
|
81
81
|
tag_name
|
82
82
|
}
|
83
|
-
|
84
|
-
if fields == fields_without_host
|
85
|
-
host_names = {}
|
86
|
-
else
|
87
|
-
host_names = Hash[
|
88
|
-
host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT).flat_map { |host_ids|
|
89
|
-
execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
|
90
|
-
}
|
91
|
-
]
|
92
|
-
end
|
93
|
-
q1 = "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags " \
|
94
|
-
"INNER JOIN hosts ON hosts_tags.host_id = hosts.id " \
|
95
|
-
"INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
|
96
|
-
"WHERE hosts_tags.host_id = ? AND tags.name IN (%s) " \
|
97
|
-
"GROUP BY tags.name;"
|
98
|
-
result = host_ids.map { |host_id|
|
99
|
-
tag_values = Hash[
|
100
|
-
fields_without_host.each_slice(SQLITE_LIMIT_COMPOUND_SELECT - 1).flat_map { |fields_without_host|
|
101
|
-
execute(q1 % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }
|
102
|
-
}
|
103
|
-
]
|
104
|
-
fields.map { |tag_name|
|
105
|
-
if tag_name == "host"
|
106
|
-
host_names.fetch(host_id, "")
|
107
|
-
else
|
108
|
-
tag_values.fetch(tag_name, "")
|
109
|
-
end
|
110
|
-
}
|
111
|
-
}
|
112
|
-
[result, fields]
|
83
|
+
get_hosts_fields(host_ids, fields)
|
113
84
|
else
|
114
85
|
if @options[:listing]
|
115
86
|
q1 = "SELECT DISTINCT tags.name FROM hosts_tags " \
|
@@ -124,61 +95,62 @@ module Hotdog
|
|
124
95
|
tag_name == @options[:primary_tag]
|
125
96
|
}
|
126
97
|
}
|
98
|
+
get_hosts_fields(host_ids, fields)
|
127
99
|
else
|
128
100
|
fields = [
|
129
101
|
"host",
|
130
102
|
] + host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT).flat_map { |host_ids|
|
131
103
|
execute(q1 % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }
|
132
104
|
}
|
105
|
+
get_hosts_fields(host_ids, fields)
|
133
106
|
end
|
134
|
-
host_names = Hash[
|
135
|
-
host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT).flat_map { |host_ids|
|
136
|
-
execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
|
137
|
-
}
|
138
|
-
]
|
139
|
-
q2 = "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags " \
|
140
|
-
"INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
|
141
|
-
"WHERE hosts_tags.host_id = ? AND tags.name IN (%s) " \
|
142
|
-
"GROUP BY tags.name;"
|
143
|
-
fields_without_host = fields.reject { |tag_name| tag_name == "host" }
|
144
|
-
result = host_ids.map { |host_id|
|
145
|
-
tag_values = Hash[
|
146
|
-
fields_without_host.each_slice(SQLITE_LIMIT_COMPOUND_SELECT - 1).flat_map { |fields_without_host|
|
147
|
-
execute(q2 % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }
|
148
|
-
}
|
149
|
-
]
|
150
|
-
fields.map { |tag_name|
|
151
|
-
if tag_name == "host"
|
152
|
-
host_names.fetch(host_id, "")
|
153
|
-
else
|
154
|
-
tag_values.fetch(tag_name, "")
|
155
|
-
end
|
156
|
-
}
|
157
|
-
}
|
158
|
-
[result, fields]
|
159
107
|
else
|
160
108
|
if @options[:primary_tag]
|
161
|
-
|
162
|
-
q1 = "SELECT tags.value FROM hosts_tags " \
|
163
|
-
"INNER JOIN hosts ON hosts_tags.host_id = hosts.id " \
|
164
|
-
"INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
|
165
|
-
"WHERE hosts_tags.host_id IN (%s) AND tags.name = ?;"
|
166
|
-
result = host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT - 1).flat_map { |host_ids|
|
167
|
-
execute(q1 % host_ids.map { "?" }.join(", "), host_ids + [@options[:primary_tag]]).map { |row| row.to_a }
|
168
|
-
}
|
169
|
-
[result, fields]
|
109
|
+
get_hosts_fields(host_ids, [@options[:primary_tag]])
|
170
110
|
else
|
171
|
-
|
172
|
-
result = host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT).flat_map { |host_ids|
|
173
|
-
execute("SELECT name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
|
174
|
-
}
|
175
|
-
[result, fields]
|
111
|
+
get_hosts_fields(host_ids, ["host"])
|
176
112
|
end
|
177
113
|
end
|
178
114
|
end
|
179
115
|
end
|
180
116
|
end
|
181
117
|
|
118
|
+
def get_hosts_fields(host_ids, fields)
|
119
|
+
if fields.empty?
|
120
|
+
[[], fields]
|
121
|
+
else
|
122
|
+
fields_without_host = fields.reject { |tag_name| tag_name == "host" }
|
123
|
+
if fields == fields_without_host
|
124
|
+
host_names = {}
|
125
|
+
else
|
126
|
+
host_names = Hash[
|
127
|
+
host_ids.each_slice(SQLITE_LIMIT_COMPOUND_SELECT).flat_map { |host_ids|
|
128
|
+
execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
|
129
|
+
}
|
130
|
+
]
|
131
|
+
end
|
132
|
+
q1 = "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags " \
|
133
|
+
"INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
|
134
|
+
"WHERE hosts_tags.host_id = ? AND tags.name IN (%s) " \
|
135
|
+
"GROUP BY tags.name;"
|
136
|
+
result = host_ids.map { |host_id|
|
137
|
+
tag_values = Hash[
|
138
|
+
fields_without_host.each_slice(SQLITE_LIMIT_COMPOUND_SELECT - 1).flat_map { |fields_without_host|
|
139
|
+
execute(q1 % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }
|
140
|
+
}
|
141
|
+
]
|
142
|
+
fields.map { |tag_name|
|
143
|
+
if tag_name == "host"
|
144
|
+
host_names.fetch(host_id, "")
|
145
|
+
else
|
146
|
+
tag_values.fetch(tag_name, "")
|
147
|
+
end
|
148
|
+
}
|
149
|
+
}
|
150
|
+
[result, fields]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
182
154
|
def close_db(db, options={})
|
183
155
|
@prepared_statements = @prepared_statements.reject { |k, statement|
|
184
156
|
(db.hash & MASK_DATABASE == k & MASK_DATABASE).tap do |delete_p|
|
data/lib/hotdog/version.rb
CHANGED
@@ -0,0 +1,122 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "hotdog/application"
|
3
|
+
require "hotdog/commands"
|
4
|
+
|
5
|
+
describe "commands" do
|
6
|
+
let(:cmd) {
|
7
|
+
Hotdog::Commands::Search.new(Hotdog::Application.new)
|
8
|
+
}
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
ENV["DATADOG_API_KEY"] = "DATADOG_API_KEY"
|
12
|
+
ENV["DATADOG_APPLICATION_KEY"] = "DATADOG_APPLICATION_KEY"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "get empty hosts" do
|
16
|
+
cmd.options[:listing] = false
|
17
|
+
cmd.options[:primary_tag] = nil
|
18
|
+
allow(cmd).to receive(:update_db)
|
19
|
+
expect(cmd.__send__(:get_hosts, [], [])).to eq([[], []])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "get hosts" do
|
23
|
+
cmd.options[:listing] = false
|
24
|
+
cmd.options[:primary_tag] = nil
|
25
|
+
allow(cmd).to receive(:update_db)
|
26
|
+
allow(cmd).to receive(:get_hosts_fields).with([1, 2, 3], ["host"])
|
27
|
+
expect(cmd.__send__(:get_hosts, [1, 2, 3], []))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "get hosts with primary tag" do
|
31
|
+
cmd.options[:listing] = false
|
32
|
+
cmd.options[:primary_tag] = "foo"
|
33
|
+
allow(cmd).to receive(:update_db)
|
34
|
+
allow(cmd).to receive(:get_hosts_fields).with([1, 2, 3], ["foo"])
|
35
|
+
expect(cmd.__send__(:get_hosts, [1, 2, 3], []))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "get hosts with tags" do
|
39
|
+
cmd.options[:listing] = false
|
40
|
+
cmd.options[:primary_tag] = nil
|
41
|
+
allow(cmd).to receive(:update_db)
|
42
|
+
allow(cmd).to receive(:get_hosts_fields).with([1, 2, 3], ["foo", "bar", "baz"])
|
43
|
+
expect(cmd.__send__(:get_hosts, [1, 2, 3], ["foo", "bar", "baz"]))
|
44
|
+
end
|
45
|
+
|
46
|
+
it "get hosts with all tags" do
|
47
|
+
cmd.options[:listing] = true
|
48
|
+
cmd.options[:primary_tag] = nil
|
49
|
+
allow(cmd).to receive(:update_db)
|
50
|
+
q1 = [
|
51
|
+
"SELECT DISTINCT tags.name FROM hosts_tags",
|
52
|
+
"INNER JOIN tags ON hosts_tags.tag_id = tags.id",
|
53
|
+
"WHERE hosts_tags.host_id IN (?, ?, ?);",
|
54
|
+
]
|
55
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [1, 2, 3]) {
|
56
|
+
[["foo"], ["bar"], ["baz"]]
|
57
|
+
}
|
58
|
+
allow(cmd).to receive(:get_hosts_fields).with([1, 2, 3], ["host", "foo", "bar", "baz"])
|
59
|
+
expect(cmd.__send__(:get_hosts, [1, 2, 3], []))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "get hosts with all tags with primary tag" do
|
63
|
+
cmd.options[:listing] = true
|
64
|
+
cmd.options[:primary_tag] = "bar"
|
65
|
+
allow(cmd).to receive(:update_db)
|
66
|
+
q1 = [
|
67
|
+
"SELECT DISTINCT tags.name FROM hosts_tags",
|
68
|
+
"INNER JOIN tags ON hosts_tags.tag_id = tags.id",
|
69
|
+
"WHERE hosts_tags.host_id IN (?, ?, ?);",
|
70
|
+
]
|
71
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [1, 2, 3]) {
|
72
|
+
[["foo"], ["bar"], ["baz"]]
|
73
|
+
}
|
74
|
+
allow(cmd).to receive(:get_hosts_fields).with([1, 2, 3], ["bar", "host", "foo", "baz"])
|
75
|
+
expect(cmd.__send__(:get_hosts, [1, 2, 3], []))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "get empty host fields" do
|
79
|
+
expect(cmd.__send__(:get_hosts_fields, [1, 2, 3], [])).to eq([[], []])
|
80
|
+
end
|
81
|
+
|
82
|
+
it "get host fields without host" do
|
83
|
+
q1 = [
|
84
|
+
"SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags",
|
85
|
+
"INNER JOIN tags ON hosts_tags.tag_id = tags.id",
|
86
|
+
"WHERE hosts_tags.host_id = ? AND tags.name IN (?, ?, ?)",
|
87
|
+
"GROUP BY tags.name;",
|
88
|
+
]
|
89
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [1, "foo", "bar", "baz"]) {
|
90
|
+
[["foo", "foo1"], ["bar", "bar1"], ["baz", "baz1"]]
|
91
|
+
}
|
92
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [2, "foo", "bar", "baz"]) {
|
93
|
+
[["foo", "foo2"], ["bar", "bar2"], ["baz", "baz2"]]
|
94
|
+
}
|
95
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [3, "foo", "bar", "baz"]) {
|
96
|
+
[["foo", "foo3"], ["bar", "bar3"], ["baz", "baz3"]]
|
97
|
+
}
|
98
|
+
expect(cmd.__send__(:get_hosts_fields, [1, 2, 3], ["foo", "bar", "baz"])).to eq([[["foo1", "bar1", "baz1"], ["foo2", "bar2", "baz2"], ["foo3", "bar3", "baz3"]], ["foo", "bar", "baz"]])
|
99
|
+
end
|
100
|
+
|
101
|
+
it "get host fields with host" do
|
102
|
+
allow(cmd).to receive(:execute).with("SELECT id, name FROM hosts WHERE id IN (?, ?, ?)", [1, 2, 3]) {
|
103
|
+
[[1, "host1"], [2, "host2"], [3, "host3"]]
|
104
|
+
}
|
105
|
+
q1 = [
|
106
|
+
"SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags",
|
107
|
+
"INNER JOIN tags ON hosts_tags.tag_id = tags.id",
|
108
|
+
"WHERE hosts_tags.host_id = ? AND tags.name IN (?, ?)",
|
109
|
+
"GROUP BY tags.name;",
|
110
|
+
]
|
111
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [1, "foo", "bar"]) {
|
112
|
+
[["foo", "foo1"], ["bar", "bar1"]]
|
113
|
+
}
|
114
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [2, "foo", "bar"]) {
|
115
|
+
[["foo", "foo2"], ["bar", "bar2"]]
|
116
|
+
}
|
117
|
+
allow(cmd).to receive(:execute).with(q1.join(" "), [3, "foo", "bar"]) {
|
118
|
+
[["foo", "foo3"], ["bar", "bar3"]]
|
119
|
+
}
|
120
|
+
expect(cmd.__send__(:get_hosts_fields, [1, 2, 3], ["foo", "bar", "host"])).to eq([[["foo1", "bar1", "host1"], ["foo2", "bar2", "host2"], ["foo3", "bar3", "host3"]], ["foo", "bar", "host"]])
|
121
|
+
end
|
122
|
+
end
|
data/spec/parser/parser_spec.rb
CHANGED
@@ -235,7 +235,7 @@ describe "parser" do
|
|
235
235
|
end
|
236
236
|
|
237
237
|
it "parses 'not foo and bar'" do
|
238
|
-
expect(cmd.parse("not foo and bar")).to eq({
|
238
|
+
expect(cmd.parse("not foo and bar")).to eq({unary_op: "not", expression: {left: {identifier: "foo"}, binary_op: "and", right: {identifier: "bar"}}})
|
239
239
|
end
|
240
240
|
|
241
241
|
it "parses '! foo and bar'" do
|
@@ -243,7 +243,7 @@ describe "parser" do
|
|
243
243
|
end
|
244
244
|
|
245
245
|
it "parses 'not foo && bar'" do
|
246
|
-
expect(cmd.parse("not foo && bar")).to eq({
|
246
|
+
expect(cmd.parse("not foo && bar")).to eq({unary_op: "not", expression: {left: {identifier: "foo"}, binary_op: "&&", right: {identifier: "bar"}}})
|
247
247
|
end
|
248
248
|
|
249
249
|
it "parses '! foo && bar'" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotdog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yamashita Yuu
|
@@ -145,6 +145,7 @@ files:
|
|
145
145
|
- lib/hotdog/formatters/yaml.rb
|
146
146
|
- lib/hotdog/version.rb
|
147
147
|
- spec/core/application_spec.rb
|
148
|
+
- spec/core/commands_spec.rb
|
148
149
|
- spec/formatter/csv_spec.rb
|
149
150
|
- spec/formatter/json_spec.rb
|
150
151
|
- spec/formatter/ltsv_spec.rb
|
@@ -183,6 +184,7 @@ specification_version: 4
|
|
183
184
|
summary: Yet another command-line tool for Datadog
|
184
185
|
test_files:
|
185
186
|
- spec/core/application_spec.rb
|
187
|
+
- spec/core/commands_spec.rb
|
186
188
|
- spec/formatter/csv_spec.rb
|
187
189
|
- spec/formatter/json_spec.rb
|
188
190
|
- spec/formatter/ltsv_spec.rb
|