rtext 0.9.1 → 0.9.2
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.
- checksums.yaml +5 -5
- data/CHANGELOG +7 -1
- data/RText_Protocol +1 -1
- data/Rakefile +22 -29
- data/lib/rtext/frontend/connector.rb +120 -53
- data/lib/rtext/instantiator.rb +11 -3
- data/test/context_builder_test.rb +5 -1
- data/test/instantiator_test.rb +44 -3
- data/test/integration/test.rb +13 -6
- metadata +8 -8
- data/test/integration/frontend.log +0 -420
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 747355cc5b17bf91ec5a902b0be20b9b13639baf
|
4
|
+
data.tar.gz: 808497bcef84bfcb8e5a5f5d50b4b6cda109337a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 987cf234234bb2284fe9d7c030be5c7837667cf051701985c2634f0cbee14d77c0abe4cad9eb962dd66312c9d35b1020f0578931cccc8c9f0de4a2fa3ea08295
|
7
|
+
data.tar.gz: 5425d8b7189dd74db31d97df3123cee9d27fb59716d73913b2f3d993f79f354f561d26d1f1a6a175f8ab7cc4a813977428a602898ba5748a71d71d58700da630
|
data/CHANGELOG
CHANGED
data/RText_Protocol
CHANGED
@@ -501,7 +501,7 @@ the parent commands wrapped around it. Any sibling commands can be omitted as we
|
|
501
501
|
any lines containing closing braces and brackets. The order of lines is the same as in the
|
502
502
|
RText file.
|
503
503
|
|
504
|
-
Here is an example. Consider the following RText file with the cursor in the line of "
|
504
|
+
Here is an example. Consider the following RText file with the cursor in the line of "Command5"
|
505
505
|
at the time when the auto completion command is issued.
|
506
506
|
|
507
507
|
Command1 {
|
data/Rakefile
CHANGED
@@ -1,36 +1,22 @@
|
|
1
1
|
require 'rubygems/package_task'
|
2
|
+
|
3
|
+
require 'rake'
|
2
4
|
require 'rdoc/task'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
s.date = Time.now.strftime("%Y-%m-%d")
|
13
|
-
s.summary = %q{Ruby Textual Modelling}
|
14
|
-
s.email = %q{martin dot thiede at gmx de}
|
15
|
-
s.homepage = %q{http://ruby-gen.org}
|
16
|
-
s.description = %q{RText can be used to derive textual languages from an RGen metamodel with very little effort.}
|
17
|
-
s.authors = ["Martin Thiede"]
|
18
|
-
s.add_dependency('rgen', '>= 0.8.2')
|
19
|
-
gemfiles = Rake::FileList.new
|
20
|
-
gemfiles.include("{lib,test}/**/*")
|
21
|
-
gemfiles.include(DocFiles)
|
22
|
-
gemfiles.include("Rakefile")
|
23
|
-
gemfiles.exclude(/\b\.bak\b/)
|
24
|
-
s.files = gemfiles
|
25
|
-
s.rdoc_options = ["--main", "README.rdoc", "-x", "test"]
|
26
|
-
s.extra_rdoc_files = DocFiles
|
27
|
-
end
|
6
|
+
RTextGemSpec = eval(File.read('rtext.gemspec'))
|
7
|
+
|
8
|
+
gemfiles = Rake::FileList.new
|
9
|
+
gemfiles.include('{lib,test}/**/*')
|
10
|
+
gemfiles.include(DocFiles)
|
11
|
+
gemfiles.include('Rakefile')
|
12
|
+
gemfiles.exclude(/\b\.bak\b/)
|
13
|
+
RTextGemSpec.files = gemfiles
|
28
14
|
|
29
15
|
RDoc::Task.new do |rd|
|
30
|
-
rd.main =
|
31
|
-
rd.rdoc_files.include(
|
32
|
-
rd.rdoc_files.include(
|
33
|
-
rd.rdoc_dir =
|
16
|
+
rd.main = 'README.rdoc'
|
17
|
+
rd.rdoc_files.include(RTextGemSpec.extra_rdoc_files)
|
18
|
+
rd.rdoc_files.include('lib/**/*.rb')
|
19
|
+
rd.rdoc_dir = 'doc'
|
34
20
|
end
|
35
21
|
|
36
22
|
RTextPackageTask = Gem::PackageTask.new(RTextGemSpec) do |p|
|
@@ -38,9 +24,16 @@ RTextPackageTask = Gem::PackageTask.new(RTextGemSpec) do |p|
|
|
38
24
|
end
|
39
25
|
|
40
26
|
task :prepare_package_rdoc => :rdoc do
|
41
|
-
RTextPackageTask.package_files.include(
|
27
|
+
RTextPackageTask.package_files.include('doc/**/*')
|
42
28
|
end
|
43
29
|
|
44
30
|
task :release => [:prepare_package_rdoc, :package]
|
45
31
|
|
46
32
|
task :clobber => [:clobber_rdoc, :clobber_package]
|
33
|
+
|
34
|
+
require 'rake/testtask'
|
35
|
+
|
36
|
+
::Rake::TestTask.new(:test) do |t|
|
37
|
+
t.test_files = ['test/rtext_test.rb']
|
38
|
+
t.warning = false
|
39
|
+
end
|
@@ -21,15 +21,21 @@ def initialize(config, options={})
|
|
21
21
|
@outfile_provider = options[:outfile_provider]
|
22
22
|
@keep_outfile = options[:keep_outfile]
|
23
23
|
@connection_timeout = options[:connection_timeout] || 10
|
24
|
+
@process_id = nil
|
24
25
|
end
|
25
26
|
|
26
27
|
def execute_command(obj, options={})
|
27
|
-
timeout = options[:timeout] ||
|
28
|
+
timeout = options[:timeout] || 10
|
28
29
|
@busy = false if @busy_start_time && (Time.now > @busy_start_time + timeout)
|
29
30
|
if @busy
|
30
31
|
do_work
|
31
|
-
:backend_busy
|
32
|
-
|
32
|
+
return :backend_busy
|
33
|
+
end
|
34
|
+
unless connected?
|
35
|
+
connect unless connecting?
|
36
|
+
do_work
|
37
|
+
end
|
38
|
+
if connected?
|
33
39
|
obj["invocation_id"] = @invocation_id
|
34
40
|
obj["type"] = "request"
|
35
41
|
@socket.send(serialize_message(obj), 0)
|
@@ -66,9 +72,7 @@ def execute_command(obj, options={})
|
|
66
72
|
result
|
67
73
|
end
|
68
74
|
else
|
69
|
-
|
70
|
-
do_work
|
71
|
-
:connecting
|
75
|
+
:connecting
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
@@ -87,23 +91,68 @@ def stop
|
|
87
91
|
sleep(0.1)
|
88
92
|
end
|
89
93
|
end
|
94
|
+
ensure_process_cleanup(@process_id, @keep_outfile ? nil : @out_file, 10)
|
95
|
+
@process_id = nil
|
90
96
|
end
|
91
97
|
|
92
98
|
private
|
93
99
|
|
100
|
+
def wait_for_process_to_exit(process_id, timeout)
|
101
|
+
with_timeout timeout do
|
102
|
+
begin
|
103
|
+
waitpid(process_id, Process::WNOHANG)
|
104
|
+
process_id = nil
|
105
|
+
true
|
106
|
+
rescue Errno::ECHILD => _
|
107
|
+
false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def ensure_process_cleanup(process_id, out_file, timeout)
|
113
|
+
Thread.new do
|
114
|
+
begin
|
115
|
+
unless process_id.nil?
|
116
|
+
process_id = nil if wait_for_process_to_exit(process_id, timeout)
|
117
|
+
end
|
118
|
+
ensure
|
119
|
+
unless process_id.nil?
|
120
|
+
begin
|
121
|
+
Process.kill('QUIT', process_id)
|
122
|
+
rescue Errno::ESRCH => _
|
123
|
+
end
|
124
|
+
end
|
125
|
+
File.unlink(out_file) if !out_file.nil? && File.exist?(out_file)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def with_timeout(timeout, sleep_time = 0.1, &block)
|
131
|
+
started = Time.now
|
132
|
+
while true do
|
133
|
+
return true if block.call
|
134
|
+
if Time.now > started + timeout
|
135
|
+
return false
|
136
|
+
end
|
137
|
+
sleep(sleep_time)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
94
142
|
def connected?
|
95
|
-
@state == :
|
143
|
+
!@process_id.nil? && @state == :read_from_socket && backend_running?
|
96
144
|
end
|
97
145
|
|
98
146
|
def connecting?
|
99
|
-
@state == :
|
147
|
+
!@process_id.nil? && (@state == :wait_for_file || @state == :wait_for_port)
|
100
148
|
end
|
101
149
|
|
102
150
|
def backend_running?
|
103
151
|
if @process_id
|
104
152
|
begin
|
105
|
-
|
106
|
-
|
153
|
+
waitpid(@process_id, Process::WNOHANG)
|
154
|
+
return true
|
155
|
+
rescue Errno::ECHILD => _
|
107
156
|
end
|
108
157
|
end
|
109
158
|
false
|
@@ -121,7 +170,7 @@ def tempfile_name
|
|
121
170
|
end
|
122
171
|
|
123
172
|
def connect
|
124
|
-
|
173
|
+
return if connected?
|
125
174
|
@connect_start_time = Time.now
|
126
175
|
|
127
176
|
@logger.info @config.command if @logger
|
@@ -131,56 +180,75 @@ def connect
|
|
131
180
|
else
|
132
181
|
@out_file = tempfile_name
|
133
182
|
end
|
134
|
-
File.unlink(@out_file) if File.exist?(@out_file)
|
135
183
|
|
136
|
-
|
137
|
-
@
|
184
|
+
if @process_id.nil?
|
185
|
+
File.unlink(@out_file) if File.exist?(@out_file)
|
186
|
+
Dir.chdir(File.dirname(@config.file)) do
|
187
|
+
@process_id = spawn(@config.command.strip + " > #{@out_file} 2>&1")
|
188
|
+
@state = :wait_for_file
|
189
|
+
end
|
138
190
|
end
|
139
|
-
@work_state = :wait_for_file
|
140
191
|
end
|
141
192
|
|
142
193
|
def do_work
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
194
|
+
if @process_id.nil?
|
195
|
+
@state = :off
|
196
|
+
return false
|
197
|
+
end
|
198
|
+
if @state == :wait_for_port && !File.exist?(@out_file)
|
199
|
+
@state = :wait_for_file
|
200
|
+
end
|
201
|
+
if @state == :wait_for_file && File.exist?(@out_file)
|
202
|
+
@state = :wait_for_port
|
203
|
+
end
|
204
|
+
if @state == :wait_for_file
|
205
|
+
while true
|
206
|
+
if Time.now > @connect_start_time + @connection_timeout
|
207
|
+
cleanup
|
208
|
+
@connection_listener.call(:timeout) if @connection_listener
|
209
|
+
@state = :off
|
210
|
+
@logger.warn "process didn't startup (connection timeout)" if @logger
|
211
|
+
return false
|
212
|
+
end
|
213
|
+
sleep(0.1)
|
214
|
+
if File.exist?(@out_file)
|
215
|
+
@state = :wait_for_port
|
216
|
+
break
|
217
|
+
end
|
154
218
|
end
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
@
|
163
|
-
|
164
|
-
|
219
|
+
end
|
220
|
+
if @state == :wait_for_port
|
221
|
+
while true
|
222
|
+
break unless File.exist?(@out_file)
|
223
|
+
output = File.read(@out_file)
|
224
|
+
if output =~ /^RText service, listening on port (\d+)/
|
225
|
+
port = $1.to_i
|
226
|
+
@logger.info "connecting to #{port}" if @logger
|
227
|
+
begin
|
228
|
+
@socket = TCPSocket.new("127.0.0.1", port)
|
229
|
+
@socket.setsockopt(:SOCKET, :RCVBUF, 1000000)
|
230
|
+
rescue Errno::ECONNREFUSED
|
231
|
+
cleanup
|
232
|
+
@connection_listener.call(:timeout) if @connection_listener
|
233
|
+
@state = :off
|
234
|
+
@logger.warn "could not connect socket (connection timeout)" if @logger
|
235
|
+
return false
|
236
|
+
end
|
237
|
+
@state = :read_from_socket
|
238
|
+
@connection_listener.call(:connected) if @connection_listener
|
239
|
+
break
|
240
|
+
end
|
241
|
+
if Time.now > @connect_start_time + @connection_timeout
|
165
242
|
cleanup
|
166
243
|
@connection_listener.call(:timeout) if @connection_listener
|
167
|
-
@work_state = :done
|
168
244
|
@state = :off
|
169
245
|
@logger.warn "could not connect socket (connection timeout)" if @logger
|
246
|
+
return false
|
170
247
|
end
|
171
|
-
|
172
|
-
@work_state = :read_from_socket
|
173
|
-
@connection_listener.call(:connected) if @connection_listener
|
174
|
-
end
|
175
|
-
if Time.now > @connect_start_time + @connection_timeout
|
176
|
-
cleanup
|
177
|
-
@connection_listener.call(:timeout) if @connection_listener
|
178
|
-
@work_state = :done
|
179
|
-
@state = :off
|
180
|
-
@logger.warn "could not connect socket (connection timeout)" if @logger
|
248
|
+
sleep(0.1)
|
181
249
|
end
|
182
|
-
|
183
|
-
|
250
|
+
end
|
251
|
+
if @state == :read_from_socket
|
184
252
|
repeat = true
|
185
253
|
socket_closed = false
|
186
254
|
response_data = ""
|
@@ -208,13 +276,12 @@ def do_work
|
|
208
276
|
end
|
209
277
|
elsif !backend_running? || socket_closed
|
210
278
|
cleanup
|
211
|
-
@
|
279
|
+
@state = :off
|
212
280
|
return false
|
213
281
|
end
|
214
282
|
end
|
215
|
-
true
|
216
283
|
end
|
217
|
-
|
284
|
+
true
|
218
285
|
end
|
219
286
|
|
220
287
|
def cleanup
|
@@ -224,7 +291,7 @@ def cleanup
|
|
224
291
|
break unless backend_running?
|
225
292
|
sleep(0.1)
|
226
293
|
end
|
227
|
-
|
294
|
+
ensure_process_cleanup(@process_id, @keep_outfile ? @out_file : nil, 10)
|
228
295
|
end
|
229
296
|
|
230
297
|
end
|
data/lib/rtext/instantiator.rb
CHANGED
@@ -247,7 +247,15 @@ class Instantiator
|
|
247
247
|
element.setOrAddGeneric(feature.name, proxy)
|
248
248
|
else
|
249
249
|
begin
|
250
|
-
|
250
|
+
v_value = v.value
|
251
|
+
feature_instance_class = feature.eType.instanceClass
|
252
|
+
if feature_instance_class == String && (v_value.is_a?(Float) || v_value.is_a?(Fixnum))
|
253
|
+
element.setOrAddGeneric(feature.name, v_value.to_s)
|
254
|
+
elsif feature_instance_class == Float && v_value.is_a?(Fixnum)
|
255
|
+
element.setOrAddGeneric(feature.name, v_value.to_f)
|
256
|
+
else
|
257
|
+
element.setOrAddGeneric(feature.name, v_value)
|
258
|
+
end
|
251
259
|
rescue StandardError
|
252
260
|
# backward compatibility for RGen versions not supporting BigDecimal
|
253
261
|
if v.value.is_a?(BigDecimal)
|
@@ -302,9 +310,9 @@ class Instantiator
|
|
302
310
|
elsif feature.eType.is_a?(RGen::ECore::EEnum)
|
303
311
|
[:identifier, :string]
|
304
312
|
else
|
305
|
-
expected = { String => [:string, :identifier],
|
313
|
+
expected = { String => [:string, :identifier, :integer, :float],
|
306
314
|
Integer => [:integer],
|
307
|
-
Float => [:float],
|
315
|
+
Float => [:float, :integer],
|
308
316
|
RGen::MetamodelBuilder::DataTypes::Boolean => [:boolean],
|
309
317
|
Object => [:string, :identifier, :integer, :float, :boolean]
|
310
318
|
}[feature.eType.instanceClass]
|
@@ -914,7 +914,11 @@ def assert_context(c, options)
|
|
914
914
|
assert_equal(options[:in_array], c.position.in_array)
|
915
915
|
assert_equal(options[:in_block], c.position.in_block)
|
916
916
|
assert_equal((options[:after_label] || false), c.position.after_label)
|
917
|
-
|
917
|
+
if options[:problem]
|
918
|
+
assert_equal(options[:problem], c.problem)
|
919
|
+
else
|
920
|
+
assert_nil(c.problem)
|
921
|
+
end
|
918
922
|
if options[:feature]
|
919
923
|
assert_equal(options[:feature], c.feature.name)
|
920
924
|
else
|
data/test/instantiator_test.rb
CHANGED
@@ -106,6 +106,50 @@ class InstantiatorTest < MiniTest::Test
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
+
def test_int_float_string
|
110
|
+
root_elements = []
|
111
|
+
_, problems = instantiate(%Q(
|
112
|
+
TestNode text: 10
|
113
|
+
TestNode text: -14.55
|
114
|
+
), TestMM, :root_elements => root_elements)
|
115
|
+
assert_no_problems(problems)
|
116
|
+
assert(root_elements.first.text.is_a?(String))
|
117
|
+
assert_equal('10', root_elements.first.text)
|
118
|
+
assert(root_elements[1].text.is_a?(String))
|
119
|
+
assert_equal('-14.55', root_elements[1].text)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_int_float
|
123
|
+
env, problems = instantiate(%Q(
|
124
|
+
TestNode float: "abc"
|
125
|
+
), TestMM)
|
126
|
+
assert_equal(1, problems.length)
|
127
|
+
|
128
|
+
root_elements = []
|
129
|
+
env, problems = instantiate(%Q(
|
130
|
+
TestNode text: "some text", float: -25 {
|
131
|
+
TestNode text: "child"
|
132
|
+
TestNode text: "child2"
|
133
|
+
}
|
134
|
+
), TestMM, :root_elements => root_elements)
|
135
|
+
assert_no_problems(problems)
|
136
|
+
assert_model_simple(env)
|
137
|
+
assert(root_elements.first.float.is_a?(Float))
|
138
|
+
assert_equal(-25.0, root_elements.first.float)
|
139
|
+
|
140
|
+
root_elements = []
|
141
|
+
env, problems = instantiate(%Q(
|
142
|
+
TestNode text: "some text", float: -72.001 {
|
143
|
+
TestNode text: "child"
|
144
|
+
TestNode text: "child2"
|
145
|
+
}
|
146
|
+
), TestMM, :root_elements => root_elements)
|
147
|
+
assert_no_problems(problems)
|
148
|
+
assert_model_simple(env)
|
149
|
+
assert(root_elements.first.float.is_a?(Float))
|
150
|
+
assert_equal(-72.001, root_elements.first.float)
|
151
|
+
end
|
152
|
+
|
109
153
|
def test_simple
|
110
154
|
env, problems = instantiate(%Q(
|
111
155
|
TestNode text: "some text", nums: [1,2] {
|
@@ -729,7 +773,6 @@ class InstantiatorTest < MiniTest::Test
|
|
729
773
|
TestNode related: 1
|
730
774
|
), TestMM)
|
731
775
|
assert_problems([
|
732
|
-
[/argument 'text' can not take a integer, expected string/i, 2],
|
733
776
|
[/argument 'integer' can not take a string, expected integer/i, 3],
|
734
777
|
[/argument 'integer' can not take a boolean, expected integer/i, 4],
|
735
778
|
[/argument 'integer' can not take a float, expected integer/i, 5],
|
@@ -1728,5 +1771,3 @@ class InstantiatorTest < MiniTest::Test
|
|
1728
1771
|
end
|
1729
1772
|
|
1730
1773
|
end
|
1731
|
-
|
1732
|
-
|
data/test/integration/test.rb
CHANGED
@@ -21,7 +21,7 @@ CrashOnRequestFile = File.dirname(__FILE__)+"/model/test.crash_on_request"
|
|
21
21
|
|
22
22
|
def setup_connector(file)
|
23
23
|
@infile = file
|
24
|
-
outfile = File.dirname(__FILE__)+"/backend.out"
|
24
|
+
outfile = File.dirname(__FILE__)+"/backend.out" + Random.new.rand(100000000).to_s
|
25
25
|
logfile = File.dirname(__FILE__)+"/frontend.log"
|
26
26
|
logger = Logger.new(logfile)
|
27
27
|
File.unlink(outfile) if File.exist?(outfile)
|
@@ -29,7 +29,7 @@ def setup_connector(file)
|
|
29
29
|
man = RText::Frontend::ConnectorManager.new(
|
30
30
|
:logger => logger,
|
31
31
|
:keep_outfile => true,
|
32
|
-
:connection_timeout =>
|
32
|
+
:connection_timeout => 10,
|
33
33
|
:outfile_provider => lambda { File.expand_path(outfile) },
|
34
34
|
:connect_callback => lambda do |connector, state|
|
35
35
|
@connection_timeout = true if state == :timeout
|
@@ -936,8 +936,16 @@ def assert_link_targets(context, options)
|
|
936
936
|
{"command" => "link_targets", "context" => lines, "column" => col})
|
937
937
|
assert_equal "response", response["type"]
|
938
938
|
assert_equal options[:targets], response["targets"]
|
939
|
-
|
940
|
-
|
939
|
+
if options[:begin]
|
940
|
+
assert_equal options[:begin], response["begin_column"]
|
941
|
+
else
|
942
|
+
assert_nil response["begin_column"]
|
943
|
+
end
|
944
|
+
if options[:end]
|
945
|
+
assert_equal options[:end], response["end_column"]
|
946
|
+
else
|
947
|
+
assert_nil response["end_column"]
|
948
|
+
end
|
941
949
|
end
|
942
950
|
|
943
951
|
def assert_completions(context, expected)
|
@@ -952,11 +960,10 @@ end
|
|
952
960
|
def load_model
|
953
961
|
done = false
|
954
962
|
response = nil
|
955
|
-
while !done
|
963
|
+
while !done
|
956
964
|
response = @con.execute_command({"command" => "load_model"})
|
957
965
|
if response == :connecting && !@connection_timeout
|
958
966
|
sleep(0.1)
|
959
|
-
@con.resume
|
960
967
|
else
|
961
968
|
done = true
|
962
969
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Thiede
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rgen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.8.
|
19
|
+
version: 0.8.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.8.
|
26
|
+
version: 0.8.0
|
27
27
|
description: RText can be used to derive textual languages from an RGen metamodel
|
28
28
|
with very little effort.
|
29
29
|
email: martin dot thiede at gmx de
|
@@ -67,7 +67,6 @@ files:
|
|
67
67
|
- test/instantiator_test.rb
|
68
68
|
- test/integration/crash_on_request_editor.rb
|
69
69
|
- test/integration/ecore_editor.rb
|
70
|
-
- test/integration/frontend.log
|
71
70
|
- test/integration/model/invalid_encoding.invenc
|
72
71
|
- test/integration/model/test.crash_on_request
|
73
72
|
- test/integration/model/test.crashing_backend
|
@@ -108,7 +107,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
107
|
- !ruby/object:Gem::Version
|
109
108
|
version: '0'
|
110
109
|
requirements: []
|
111
|
-
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.5.2
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: Ruby Textual Modelling
|