expressir 1.3.3-x86_64-linux-musl

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.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.cross_rubies +28 -0
  3. data/.github/workflows/codeql.yml +47 -0
  4. data/.github/workflows/rake.yml +448 -0
  5. data/.github/workflows/release.yml +189 -0
  6. data/.github/workflows/stress.yml +53 -0
  7. data/.gitignore +23 -0
  8. data/.gitmodules +6 -0
  9. data/.hound.yml +3 -0
  10. data/.rspec +2 -0
  11. data/.rubocop.yml +18 -0
  12. data/.yardopts +11 -0
  13. data/Gemfile +4 -0
  14. data/README.adoc +155 -0
  15. data/Rakefile +17 -0
  16. data/bin/console +11 -0
  17. data/bin/rspec +29 -0
  18. data/bin/setup +8 -0
  19. data/docs/development.md +90 -0
  20. data/exe/expressir +22 -0
  21. data/exe/format +18 -0
  22. data/exe/format-test +81 -0
  23. data/exe/generate-parser +51 -0
  24. data/expressir.gemspec +48 -0
  25. data/lib/expressir/cli/ui.rb +36 -0
  26. data/lib/expressir/cli.rb +21 -0
  27. data/lib/expressir/config.rb +23 -0
  28. data/lib/expressir/express/2.7/express_parser.so +0 -0
  29. data/lib/expressir/express/3.0/express_parser.so +0 -0
  30. data/lib/expressir/express/3.1/express_parser.so +0 -0
  31. data/lib/expressir/express/3.2/express_parser.so +0 -0
  32. data/lib/expressir/express/cache.rb +51 -0
  33. data/lib/expressir/express/formatter.rb +1608 -0
  34. data/lib/expressir/express/hyperlink_formatter.rb +36 -0
  35. data/lib/expressir/express/model_visitor.rb +24 -0
  36. data/lib/expressir/express/parser.rb +83 -0
  37. data/lib/expressir/express/resolve_references_model_visitor.rb +31 -0
  38. data/lib/expressir/express/schema_head_formatter.rb +23 -0
  39. data/lib/expressir/express/visitor.rb +2591 -0
  40. data/lib/expressir/model/cache.rb +17 -0
  41. data/lib/expressir/model/data_type.rb +9 -0
  42. data/lib/expressir/model/data_types/aggregate.rb +31 -0
  43. data/lib/expressir/model/data_types/array.rb +31 -0
  44. data/lib/expressir/model/data_types/bag.rb +25 -0
  45. data/lib/expressir/model/data_types/binary.rb +22 -0
  46. data/lib/expressir/model/data_types/boolean.rb +10 -0
  47. data/lib/expressir/model/data_types/enumeration.rb +25 -0
  48. data/lib/expressir/model/data_types/enumeration_item.rb +26 -0
  49. data/lib/expressir/model/data_types/generic.rb +26 -0
  50. data/lib/expressir/model/data_types/generic_entity.rb +26 -0
  51. data/lib/expressir/model/data_types/integer.rb +10 -0
  52. data/lib/expressir/model/data_types/list.rb +28 -0
  53. data/lib/expressir/model/data_types/logical.rb +10 -0
  54. data/lib/expressir/model/data_types/number.rb +10 -0
  55. data/lib/expressir/model/data_types/real.rb +19 -0
  56. data/lib/expressir/model/data_types/select.rb +28 -0
  57. data/lib/expressir/model/data_types/set.rb +25 -0
  58. data/lib/expressir/model/data_types/string.rb +22 -0
  59. data/lib/expressir/model/declaration.rb +9 -0
  60. data/lib/expressir/model/declarations/attribute.rb +47 -0
  61. data/lib/expressir/model/declarations/constant.rb +34 -0
  62. data/lib/expressir/model/declarations/entity.rb +53 -0
  63. data/lib/expressir/model/declarations/function.rb +67 -0
  64. data/lib/expressir/model/declarations/interface.rb +28 -0
  65. data/lib/expressir/model/declarations/interface_item.rb +23 -0
  66. data/lib/expressir/model/declarations/interfaced_item.rb +37 -0
  67. data/lib/expressir/model/declarations/parameter.rb +34 -0
  68. data/lib/expressir/model/declarations/procedure.rb +64 -0
  69. data/lib/expressir/model/declarations/remark_item.rb +21 -0
  70. data/lib/expressir/model/declarations/rule.rb +71 -0
  71. data/lib/expressir/model/declarations/schema.rb +117 -0
  72. data/lib/expressir/model/declarations/schema_version.rb +22 -0
  73. data/lib/expressir/model/declarations/schema_version_item.rb +22 -0
  74. data/lib/expressir/model/declarations/subtype_constraint.rb +40 -0
  75. data/lib/expressir/model/declarations/type.rb +45 -0
  76. data/lib/expressir/model/declarations/unique_rule.rb +31 -0
  77. data/lib/expressir/model/declarations/variable.rb +34 -0
  78. data/lib/expressir/model/declarations/where_rule.rb +31 -0
  79. data/lib/expressir/model/expression.rb +9 -0
  80. data/lib/expressir/model/expressions/aggregate_initializer.rb +19 -0
  81. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +22 -0
  82. data/lib/expressir/model/expressions/binary_expression.rb +53 -0
  83. data/lib/expressir/model/expressions/entity_constructor.rb +22 -0
  84. data/lib/expressir/model/expressions/function_call.rb +22 -0
  85. data/lib/expressir/model/expressions/interval.rb +34 -0
  86. data/lib/expressir/model/expressions/query_expression.rb +35 -0
  87. data/lib/expressir/model/expressions/unary_expression.rb +27 -0
  88. data/lib/expressir/model/identifier.rb +34 -0
  89. data/lib/expressir/model/literal.rb +9 -0
  90. data/lib/expressir/model/literals/binary.rb +19 -0
  91. data/lib/expressir/model/literals/integer.rb +19 -0
  92. data/lib/expressir/model/literals/logical.rb +23 -0
  93. data/lib/expressir/model/literals/real.rb +19 -0
  94. data/lib/expressir/model/literals/string.rb +22 -0
  95. data/lib/expressir/model/model_element.rb +208 -0
  96. data/lib/expressir/model/reference.rb +9 -0
  97. data/lib/expressir/model/references/attribute_reference.rb +22 -0
  98. data/lib/expressir/model/references/group_reference.rb +22 -0
  99. data/lib/expressir/model/references/index_reference.rb +27 -0
  100. data/lib/expressir/model/references/simple_reference.rb +24 -0
  101. data/lib/expressir/model/repository.rb +23 -0
  102. data/lib/expressir/model/statement.rb +9 -0
  103. data/lib/expressir/model/statements/alias.rb +35 -0
  104. data/lib/expressir/model/statements/assignment.rb +22 -0
  105. data/lib/expressir/model/statements/case.rb +25 -0
  106. data/lib/expressir/model/statements/case_action.rb +22 -0
  107. data/lib/expressir/model/statements/compound.rb +19 -0
  108. data/lib/expressir/model/statements/escape.rb +10 -0
  109. data/lib/expressir/model/statements/if.rb +25 -0
  110. data/lib/expressir/model/statements/null.rb +10 -0
  111. data/lib/expressir/model/statements/procedure_call.rb +22 -0
  112. data/lib/expressir/model/statements/repeat.rb +47 -0
  113. data/lib/expressir/model/statements/return.rb +19 -0
  114. data/lib/expressir/model/statements/skip.rb +10 -0
  115. data/lib/expressir/model/supertype_expression.rb +9 -0
  116. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +29 -0
  117. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +19 -0
  118. data/lib/expressir/model.rb +79 -0
  119. data/lib/expressir/version.rb +3 -0
  120. data/lib/expressir.rb +44 -0
  121. data/rakelib/antlr4-native.rake +173 -0
  122. data/rakelib/cross-ruby.rake +403 -0
  123. data/spec/acceptance/version_spec.rb +30 -0
  124. data/spec/expressir/express/cache_spec.rb +89 -0
  125. data/spec/expressir/express/formatter_spec.rb +171 -0
  126. data/spec/expressir/express/parser_spec.rb +141 -0
  127. data/spec/expressir/model/model_element_spec.rb +318 -0
  128. data/spec/spec_helper.rb +24 -0
  129. data/spec/support/console_helper.rb +29 -0
  130. data/spec/syntax/multiple.exp +23 -0
  131. data/spec/syntax/multiple.yaml +198 -0
  132. data/spec/syntax/multiple_formatted.exp +71 -0
  133. data/spec/syntax/multiple_hyperlink_formatted.exp +71 -0
  134. data/spec/syntax/multiple_schema_head_hyperlink_formatted.exp +13 -0
  135. data/spec/syntax/remark.exp +193 -0
  136. data/spec/syntax/remark.yaml +471 -0
  137. data/spec/syntax/remark_formatted.exp +228 -0
  138. data/spec/syntax/single.exp +4 -0
  139. data/spec/syntax/single.yaml +18 -0
  140. data/spec/syntax/single_formatted.exp +10 -0
  141. data/spec/syntax/single_formatted.yaml +36 -0
  142. data/spec/syntax/syntax.exp +333 -0
  143. data/spec/syntax/syntax.yaml +3509 -0
  144. data/spec/syntax/syntax_formatted.exp +902 -0
  145. data/spec/syntax/syntax_hyperlink_formatted.exp +902 -0
  146. data/spec/syntax/syntax_schema_head_formatted.exp +18 -0
  147. metadata +392 -0
@@ -0,0 +1,403 @@
1
+ require "rbconfig"
2
+ require "shellwords"
3
+
4
+ WINDOWS_PLATFORM_REGEX = /mingw|mswin/.freeze
5
+ LINUX_GNU_PLATFORM_REGEX = /linux-gnu/.freeze
6
+ LINUX_MUSL_PLATFORM_REGEX = /linux-musl/.freeze
7
+ DARWIN_PLATFORM_REGEX = /darwin/.freeze
8
+ GLIBC_MIN_VERSION = "2.17".freeze
9
+
10
+ CrossRuby = Struct.new(:version, :host) do
11
+ def dll_staging_path
12
+ "tmp/#{platform}/stage/lib/expressir/express/#{minor_ver}/express_parser.#{dll_ext}"
13
+ end
14
+
15
+ def darwin?
16
+ !!(platform =~ DARWIN_PLATFORM_REGEX)
17
+ end
18
+
19
+ def linux_gnu?
20
+ !!(platform =~ LINUX_GNU_PLATFORM_REGEX)
21
+ end
22
+
23
+ def linux_musl?
24
+ !!(platform =~ LINUX_MUSL_PLATFORM_REGEX)
25
+ end
26
+
27
+ def windows?
28
+ !!(platform =~ WINDOWS_PLATFORM_REGEX)
29
+ end
30
+
31
+ def ver
32
+ @ver ||= version[/\A[^-]+/]
33
+ end
34
+
35
+ def minor_ver
36
+ @minor_ver ||= ver[/\A\d\.\d(?=\.)/]
37
+ end
38
+
39
+ def minor_ver_digi
40
+ @minor_ver_digi = minor_ver.delete(".").to_i
41
+ end
42
+
43
+ def ucrt?
44
+ minor_ver_digi >= 31
45
+ end
46
+
47
+ def api_ver_suffix
48
+ case minor_ver
49
+ when nil
50
+ raise "CrossRuby.api_ver_suffix: unsupported version: #{ver}"
51
+ else
52
+ minor_ver.delete(".") << "0"
53
+ end
54
+ end
55
+
56
+ # rubocop:disable Metrics/MethodLength
57
+ # rubocop:disable Metrics/CyclomaticComplexity
58
+ def platform
59
+ @platform ||=
60
+ case host
61
+ when /\Ax86_64.*mingw32/
62
+ if ucrt?
63
+ "x64-mingw-ucrt"
64
+ else
65
+ "x64-mingw32"
66
+ end
67
+ when "x86_64-linux-gnu"
68
+ "x86_64-linux-gnu"
69
+ when "aarch64-linux-gnu"
70
+ "aarch64-linux-gnu"
71
+ when "x86_64-linux-musl"
72
+ "x86_64-linux-musl"
73
+ when "aarch64-linux-musl"
74
+ "aarch64-linux-musl"
75
+ when /\Ax86_64-darwin/
76
+ "x86_64-darwin"
77
+ when /\Aarm64-darwin/
78
+ "arm64-darwin"
79
+ else
80
+ raise "CrossRuby.platform: unsupported host: #{host}"
81
+ end
82
+ end
83
+
84
+ def tag
85
+ @tag ||=
86
+ case platform
87
+ when "x86_64-linux-gnu"
88
+ "x86_64-linux"
89
+ when "aarch64-linux-gnu"
90
+ "aarch64-linux"
91
+ else
92
+ platform
93
+ end
94
+ end
95
+
96
+ def tool(name)
97
+ (@binutils_prefix ||=
98
+ case platform
99
+ when /x64-mingw(32|-ucrt)/
100
+ "x86_64-w64-mingw32-"
101
+ when /(x86_64|aarch64)-linux-(gnu|musl)/
102
+ # We do believe that we are on Linux and can use native tools
103
+ ""
104
+ when /x86_64.*darwin/
105
+ "x86_64-apple-darwin-"
106
+ when /a.*64.*darwin/
107
+ "aarch64-apple-darwin-"
108
+ else
109
+ raise "CrossRuby.tool: unmatched platform: #{platform}"
110
+ end) + name
111
+ end
112
+
113
+ def target_file_format
114
+ case platform
115
+ when /64-mingw(32|-ucrt)/
116
+ "pei-x86-64"
117
+ when /x86_64-linux-(gnu|musl)/
118
+ "elf64-x86-64"
119
+ when /aarch64-linux-(gnu|musl)/
120
+ "elf64-little"
121
+ when "x86_64-darwin"
122
+ "Mach-O 64-bit x86-64"
123
+ when "arm64-darwin"
124
+ "Mach-O arm64"
125
+ else
126
+ raise "CrossRuby.target_file_format: unmatched platform: #{platform}"
127
+ end
128
+ end
129
+ # rubocop:enable Metrics/MethodLength
130
+ # rubocop:enable Metrics/CyclomaticComplexity
131
+
132
+ def dll_ext
133
+ darwin? ? "bundle" : "so"
134
+ end
135
+
136
+ def verify_format(dump, dll)
137
+ format_match = (/file format #{Regexp.quote(target_file_format)}\s/ === dump)
138
+ format_error = "Unexpected file format for '#{dll}', '#{target_file_format}' required"
139
+ raise format_error unless format_match
140
+ end
141
+
142
+ def verify_entry_windows(dump, dll)
143
+ unless /Table.*\sInit_express_parser\s/mi === dump
144
+ raise "Export function Init_express_parser not in dll #{dll}"
145
+ end
146
+ end
147
+
148
+ def verify_entry_linux(dll)
149
+ nm = `#{["env", "LANG=C", tool("nm"), "-D", dll].shelljoin}`
150
+ unless nm.include?(" T Init_express_parser")
151
+ raise "Export function Init_express_parser not in dll #{dll}"
152
+ end
153
+ end
154
+
155
+ def verify_entry_darwin(dll)
156
+ nm = `#{["env", "LANG=C", tool("nm"), "-g", dll].shelljoin}`
157
+ unless / T _?Init_express_parser/.match?(nm)
158
+ raise "Export function Init_express_parser not in dll #{dll}"
159
+ end
160
+ end
161
+
162
+ def verify_entry(dump, dll)
163
+ case platform
164
+ when WINDOWS_PLATFORM_REGEX
165
+ verify_entry_windows(dump, dll)
166
+ when LINUX_GNU_PLATFORM_REGEX, LINUX_MUSL_PLATFORM_REGEX
167
+ verify_entry_linux(dll)
168
+ when DARWIN_PLATFORM_REGEX
169
+ verify_entry_darwin(dll)
170
+ else
171
+ raise "CrossRuby.verify_entry: unmatched platform: #{platform}"
172
+ end
173
+ end
174
+
175
+ # rubocop:disable Metrics/MethodLength
176
+ def allowed_dlls_ucrt
177
+ ["kernel32.dll",
178
+ "api-ms-win-crt-convert-l1-1-0.dll",
179
+ "api-ms-win-crt-environment-l1-1-0.dll",
180
+ "api-ms-win-crt-heap-l1-1-0.dll",
181
+ "api-ms-win-crt-locale-l1-1-0.dll",
182
+ "api-ms-win-crt-private-l1-1-0.dll",
183
+ "api-ms-win-crt-runtime-l1-1-0.dll",
184
+ "api-ms-win-crt-stdio-l1-1-0.dll",
185
+ "api-ms-win-crt-string-l1-1-0.dll",
186
+ "api-ms-win-crt-time-l1-1-0.dll",
187
+ "api-ms-win-crt-filesystem-l1-1-0.dll",
188
+ "api-ms-win-crt-math-l1-1-0.dll",
189
+ "libwinpthread-1.dll",
190
+ "x64-ucrt-ruby#{api_ver_suffix}.dll"]
191
+ end
192
+ # rubocop:enable Metrics/MethodLength
193
+
194
+ def allowed_dlls_mingw
195
+ [
196
+ "kernel32.dll",
197
+ "msvcrt.dll",
198
+ "libwinpthread-1.dll",
199
+ "x64-msvcrt-ruby#{api_ver_suffix}.dll",
200
+ ]
201
+ end
202
+
203
+ def allowed_dlls_windows
204
+ if ucrt?
205
+ allowed_dlls_ucrt
206
+ else
207
+ allowed_dlls_mingw
208
+ end
209
+ end
210
+
211
+ def allowed_dlls_linux_gnu
212
+ suffix = (platform == "x86_64-linux-gnu" ? "x86-64" : "aarch64")
213
+ [
214
+ "ld-linux-#{suffix}.so",
215
+ "libc.so",
216
+ "libm.so",
217
+ "libstdc++.so",
218
+ "libgcc_s.so",
219
+ "libpthread.so",
220
+ ]
221
+ end
222
+
223
+ def allowed_dlls_linux_musl
224
+ suffix = (platform == "x86_64-linux-gnu" ? "x86-64" : "aarch64")
225
+ [
226
+ "ld-linux-#{suffix}.so",
227
+ "libstdc++.so",
228
+ "libc.so",
229
+ "libgcc_s.so",
230
+ ]
231
+ end
232
+
233
+ def allowed_dlls_darwin
234
+ [
235
+ "/usr/lib/libSystem.B.dylib",
236
+ "/usr/lib/libc++.1.dylib",
237
+ ]
238
+ end
239
+
240
+ def allowed_dlls # rubocop:disable Metrics/MethodLength
241
+ case platform
242
+ when WINDOWS_PLATFORM_REGEX
243
+ allowed_dlls_windows
244
+ when LINUX_GNU_PLATFORM_REGEX
245
+ allowed_dlls_linux_gnu
246
+ when LINUX_MUSL_PLATFORM_REGEX
247
+ allowed_dlls_linux_musl
248
+ when DARWIN_PLATFORM_REGEX
249
+ allowed_dlls_darwin
250
+ else
251
+ raise "CrossRuby.allowed_dlls: unmatched platform: #{platform}"
252
+ end
253
+ end
254
+
255
+ def actual_dlls_linux(dump)
256
+ dump.scan(/NEEDED\s+(.*)/).map(&:first).uniq
257
+ end
258
+
259
+ def actual_dlls_windows(dump)
260
+ dump.scan(/DLL Name: (.*)$/).map { |x| x.first.downcase }.uniq
261
+ end
262
+
263
+ def actual_dlls_darwin(dll)
264
+ ldd = `#{[tool("otool"), "-L", dll].shelljoin}`
265
+ ldd.scan(/^\t([^ ]+) /).map(&:first).uniq
266
+ end
267
+
268
+ def actual_dlls(dump, dll)
269
+ case platform
270
+ when DARWIN_PLATFORM_REGEX
271
+ actual_dlls_darwin(dll)
272
+ when LINUX_GNU_PLATFORM_REGEX, LINUX_MUSL_PLATFORM_REGEX
273
+ actual_dlls_linux(dump)
274
+ when WINDOWS_PLATFORM_REGEX
275
+ actual_dlls_windows(dump)
276
+ else
277
+ raise "CrossRuby.actual_dlls: unmatched platform: #{platform}"
278
+ end
279
+ end
280
+
281
+ def verify_imports(dump, dll)
282
+ l = actual_dlls(dump, dll)
283
+ libs = allowed_dlls
284
+ l.delete_if { |ln| libs.any? { |lib| ln.include?(lib) } }
285
+ unless l.empty?
286
+ raise "Unexpected references in '#{dll}' : #{l}"
287
+ end
288
+ end
289
+
290
+ def lib_ref_versions(data)
291
+ # Build a hash of library versions like {"LIBUDEV"=>"183", "GLIBC"=>"2.17"}
292
+ data.each.with_object({}) do |(lib, ver), h|
293
+ if !h[lib] || ver.split(".").map(&:to_i).pack("C*") > h[lib].split(".").map(&:to_i).pack("C*")
294
+ h[lib] = ver
295
+ end
296
+ end
297
+ end
298
+
299
+ def verify_glibc_version(dump, dll)
300
+ ref_versions_data = dump.scan(/0x[\da-f]+ 0x[\da-f]+ \d+ (\w+)_([\d.]+)$/i)
301
+ ref_ver = lib_ref_versions(ref_versions_data)
302
+
303
+ unless ref_ver["GLIBC"].delete(".").to_i <= GLIBC_MIN_VERSION.delete(".").to_i
304
+ raise "Unexpected GLIBC version #{ref_ver['GLIBC']} for #{dll}, #{GLIBC_MIN_VERSION} or lower is expected"
305
+ end
306
+ end
307
+ end
308
+
309
+ CROSS_RUBIES = File.read(".cross_rubies").split("\n").filter_map do |line|
310
+ case line
311
+ when /\A([^#]+):([^#]+)/
312
+ CrossRuby.new($1, $2)
313
+ end
314
+ end
315
+
316
+ ENV["RUBY_CC_VERSION"] = CROSS_RUBIES.map(&:ver).uniq.join(":")
317
+
318
+ require "rake_compiler_dock"
319
+
320
+ def verify_dll(dll, cross_ruby)
321
+ dump = `#{["env", "LANG=C", cross_ruby.tool("objdump"), "-p", dll].shelljoin}`
322
+ cross_ruby.verify_format(dump, dll)
323
+ cross_ruby.verify_entry(dump, dll)
324
+ cross_ruby.verify_imports(dump, dll)
325
+ # Not sure if it is required, probably not
326
+ # I am keeping related code as a reference for future advances
327
+ # cross_ruby.verify_glibc_version(dump, dll) if cross_ruby.linux_gnu?
328
+
329
+ puts "#{dll}: passed shared library sanity checks"
330
+ end
331
+
332
+ CROSS_RUBIES.each do |cross_ruby|
333
+ unless Rake::Task.task_defined?(cross_ruby.dll_staging_path)
334
+ task cross_ruby.dll_staging_path do |t|
335
+ verify_dll t.name, cross_ruby
336
+ end
337
+ end
338
+ end
339
+
340
+ def gem_builder(plat)
341
+ # use Task#invoke because the pkg/*gem task is defined at runtime
342
+ Rake::Task["native:#{plat}"].invoke
343
+ Rake::Task["pkg/#{GEMSPEC.full_name}-#{Gem::Platform.new(plat)}.gem"].invoke
344
+ end
345
+
346
+ REDHAT_PREREQ = "sudo yum install -y git".freeze
347
+ UBUNTU_PREREQ = "sudo apt-get update -y && sudo apt-get install -y automake autoconf libtool build-essential".freeze
348
+
349
+ def pre_req(plat)
350
+ case plat
351
+ when /linux/
352
+ "if [[ $(awk -F= '/^NAME/{print $2}' /etc/os-release) == '\"Ubuntu\"' ]]; then #{UBUNTU_PREREQ}; else #{REDHAT_PREREQ}; fi"
353
+ else
354
+ UBUNTU_PREREQ.to_s
355
+ end
356
+ end
357
+
358
+ namespace "gem" do
359
+ CROSS_RUBIES.find_all { |cr| cr.windows? || cr.linux_gnu? || cr.linux_musl? || cr.darwin? }.map(&:platform).uniq.each do |plat|
360
+ desc "build native gem for #{plat} platform"
361
+ task plat do
362
+ RakeCompilerDock.sh <<~RCD, platform: plat
363
+ #{pre_req(plat)} && gem install bundler --no-document &&
364
+ bundle && bundle exec rake gem:#{plat}:builder MAKE="nice make -j`nproc`"
365
+ RCD
366
+ end
367
+
368
+ namespace plat do
369
+ desc "build native gem for #{plat} platform (guest container)"
370
+ task "builder" do
371
+ gem_builder(plat)
372
+ end
373
+ end
374
+ end
375
+
376
+ desc "build native gems for windows"
377
+ multitask "windows" => CROSS_RUBIES.find_all(&:windows?).map(&:platform).uniq
378
+
379
+ desc "build native gems for linux-gnu"
380
+ multitask "linux-gnu" => CROSS_RUBIES.find_all(&:linux_gnu?).map(&:platform).uniq
381
+
382
+ desc "build native gems for linux-musl"
383
+ multitask "linux-musl" => CROSS_RUBIES.find_all(&:linux_musl?).map(&:platform).uniq
384
+
385
+ desc "build native gems for darwin"
386
+ multitask "darwin" => CROSS_RUBIES.find_all(&:darwin?).map(&:platform).uniq
387
+ end
388
+
389
+ require "rake/extensiontask"
390
+
391
+ Rake::ExtensionTask.new("express_parser", GEMSPEC) do |ext|
392
+ ext.ext_dir = "ext/express_parser"
393
+ ext.lib_dir = File.join(*["lib", "expressir", "express", ENV.fetch("FAT_DIR", nil)].compact)
394
+ ext.config_options << ENV.fetch("EXTOPTS", nil)
395
+ ext.cross_compile = true
396
+ ext.cross_platform = CROSS_RUBIES.map(&:platform).uniq
397
+ ext.cross_config_options << "--enable-cross-build"
398
+
399
+ ext.cross_compiling do |spec|
400
+ spec.files.reject! { |path| File.fnmatch?("ext/*", path) }
401
+ spec.dependencies.reject! { |dep| dep.name == "rice" }
402
+ end
403
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Expressir" do
4
+ describe "version" do
5
+ it "has a version number" do |example|
6
+ GC.stress = ENV["GC_STRESS"] == "true"
7
+ puts "Running tests in GC stress mode. It may take a couple of hours ..." if GC.stress
8
+
9
+ print "\n[#{example.description}] "
10
+ expect(Expressir::VERSION).not_to be nil
11
+
12
+ # Validate Object Space
13
+ GC.start
14
+ GC.verify_compaction_references
15
+ GC.verify_internal_consistency
16
+ end
17
+
18
+ it "displays the current verison" do |example|
19
+ print "\n[#{example.description}] "
20
+ command = %w(version)
21
+ output = capture_stdout { Expressir::Cli.start(command) }
22
+ expect(output).to include("Version #{Expressir::VERSION}")
23
+
24
+ # Validate Object Space
25
+ GC.start
26
+ GC.verify_compaction_references
27
+ GC.verify_internal_consistency
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,89 @@
1
+ require "yaml"
2
+ require "tempfile"
3
+ require "spec_helper"
4
+ require "expressir/express/parser"
5
+ require "expressir/express/cache"
6
+
7
+ TEST_VERSION = "0.0.0".freeze
8
+
9
+ RSpec.describe Expressir::Express::Cache do
10
+ describe ".to_file" do
11
+ it "exports an object" do |example|
12
+ print "\n[#{example.description}] "
13
+ temp_file = Tempfile.new
14
+
15
+ repository = Expressir::Model::Repository.new
16
+
17
+ begin
18
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
19
+
20
+ size = File.size(temp_file)
21
+
22
+ expect(size).to be > 0
23
+ ensure
24
+ temp_file.close
25
+ temp_file.unlink
26
+ end
27
+
28
+ # Validate Object Space
29
+ GC.start
30
+ GC.verify_compaction_references
31
+ GC.verify_internal_consistency
32
+ end
33
+ end
34
+
35
+ describe ".from_file" do
36
+ it "throws an exception if the cache file does not exist" do |example|
37
+ print "\n[#{example.description}] "
38
+ expect do
39
+ Expressir::Express::Cache.from_file("non-existing-file", test_overwrite_version: TEST_VERSION)
40
+ end.to raise_error(Errno::ENOENT)
41
+ end
42
+
43
+ it "loads a cache file" do |example|
44
+ print "\n[#{example.description}] "
45
+ temp_file = Tempfile.new
46
+
47
+ repository = Expressir::Model::Repository.new
48
+
49
+ begin
50
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
51
+
52
+ result = Expressir::Express::Cache.from_file(temp_file, test_overwrite_version: TEST_VERSION)
53
+
54
+ expect(result).to be_instance_of(Expressir::Model::Repository)
55
+ ensure
56
+ temp_file.close
57
+ temp_file.unlink
58
+ end
59
+
60
+ # Validate Object Space
61
+ GC.start
62
+ GC.verify_compaction_references
63
+ GC.verify_internal_consistency
64
+ end
65
+
66
+ it "fails parsing a cache from a different Expressir version" do |example|
67
+ print "\n[#{example.description}] "
68
+ temp_file = Tempfile.new
69
+
70
+ repository = Expressir::Model::Repository.new
71
+
72
+ begin
73
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
74
+
75
+ expect do
76
+ Expressir::Express::Cache.from_file(temp_file)
77
+ end.to raise_error(Expressir::Error)
78
+ ensure
79
+ temp_file.close
80
+ temp_file.unlink
81
+ end
82
+
83
+ # Validate Object Space
84
+ GC.start
85
+ GC.verify_compaction_references
86
+ GC.verify_internal_consistency
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,171 @@
1
+ require "yaml"
2
+ require "spec_helper"
3
+ require "expressir/express/parser"
4
+ require "expressir/express/formatter"
5
+ require "expressir/express/schema_head_formatter"
6
+ require "expressir/express/hyperlink_formatter"
7
+
8
+ RSpec.describe Expressir::Express::Formatter do
9
+ describe ".format" do
10
+ it "exports an object (single.exp)" do |example|
11
+ print "\n[#{example.description}] "
12
+ exp_file = Expressir.root_path.join("spec", "syntax", "single.exp")
13
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "single_formatted.exp")
14
+ repo = Expressir::Express::Parser.from_file(exp_file)
15
+ result = Expressir::Express::Formatter.format(repo)
16
+ # File.write(formatted_exp_file, result)
17
+ expected_result = File.read(formatted_exp_file)
18
+
19
+ expect(result).to eq(expected_result)
20
+
21
+ # Validate Object Space
22
+ GC.start
23
+ GC.verify_compaction_references
24
+ GC.verify_internal_consistency
25
+ end
26
+
27
+ it "exports an object (multiple.exp)" do |example|
28
+ print "\n[#{example.description}] "
29
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
30
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_formatted.exp")
31
+
32
+ repo = Expressir::Express::Parser.from_file(exp_file)
33
+
34
+ result = Expressir::Express::Formatter.format(repo)
35
+ # File.write(formatted_exp_file, result)
36
+ expected_result = File.read(formatted_exp_file)
37
+
38
+ expect(result).to eq(expected_result)
39
+ GC.start
40
+ GC.verify_compaction_references
41
+ GC.verify_internal_consistency
42
+ end
43
+
44
+ it "exports an object (remark.exp)" do |example|
45
+ print "\n[#{example.description}] "
46
+ exp_file = Expressir.root_path.join("spec", "syntax", "remark.exp")
47
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "remark_formatted.exp")
48
+
49
+ repo = Expressir::Express::Parser.from_file(exp_file)
50
+
51
+ result = Expressir::Express::Formatter.format(repo)
52
+ # File.write(formatted_exp_file, result)
53
+ expected_result = File.read(formatted_exp_file)
54
+
55
+ expect(result).to eq(expected_result)
56
+
57
+ # Validate Object Space
58
+ GC.start
59
+ GC.verify_compaction_references
60
+ GC.verify_internal_consistency
61
+ end
62
+
63
+ it "exports an object (syntax.exp)" do |example|
64
+ print "\n[#{example.description}] "
65
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
66
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_formatted.exp")
67
+
68
+ repo = Expressir::Express::Parser.from_file(exp_file)
69
+
70
+ result = Expressir::Express::Formatter.format(repo)
71
+ # File.write(formatted_exp_file, result)
72
+ expected_result = File.read(formatted_exp_file)
73
+
74
+ expect(result).to eq(expected_result)
75
+
76
+ # Validate Object Space
77
+ GC.start
78
+ GC.verify_compaction_references
79
+ GC.verify_internal_consistency
80
+ end
81
+
82
+ it "exports an object with schema head formatter (syntax.exp)" do |example|
83
+ print "\n[#{example.description}] "
84
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
85
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_schema_head_formatted.exp")
86
+
87
+ repo = Expressir::Express::Parser.from_file(exp_file)
88
+
89
+ formatter = Class.new(Expressir::Express::Formatter) do
90
+ include Expressir::Express::SchemaHeadFormatter
91
+ end
92
+ result = formatter.format(repo)
93
+ # File.write(formatted_exp_file, result)
94
+ expected_result = File.read(formatted_exp_file)
95
+
96
+ expect(result).to eq(expected_result)
97
+
98
+ # Validate Object Space
99
+ GC.start
100
+ GC.verify_compaction_references
101
+ GC.verify_internal_consistency
102
+ end
103
+
104
+ it "exports an object with hyperlink formatter (syntax.exp)" do |example|
105
+ print "\n[#{example.description}] "
106
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
107
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_hyperlink_formatted.exp")
108
+
109
+ repo = Expressir::Express::Parser.from_file(exp_file)
110
+
111
+ formatter = Class.new(Expressir::Express::Formatter) do
112
+ include Expressir::Express::HyperlinkFormatter
113
+ end
114
+ result = formatter.format(repo)
115
+ # File.write(formatted_exp_file, result)
116
+ expected_result = File.read(formatted_exp_file)
117
+
118
+ expect(result).to eq(expected_result)
119
+
120
+ # Validate Object Space
121
+ GC.start
122
+ GC.verify_compaction_references
123
+ GC.verify_internal_consistency
124
+ end
125
+
126
+ it "exports an object with hyperlink formatter (multiple.exp)" do |example|
127
+ print "\n[#{example.description}] "
128
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
129
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_hyperlink_formatted.exp")
130
+
131
+ repo = Expressir::Express::Parser.from_file(exp_file)
132
+
133
+ formatter = Class.new(Expressir::Express::Formatter) do
134
+ include Expressir::Express::HyperlinkFormatter
135
+ end
136
+ result = formatter.format(repo)
137
+ # File.write(formatted_exp_file, result)
138
+ expected_result = File.read(formatted_exp_file)
139
+
140
+ expect(result).to eq(expected_result)
141
+
142
+ # Validate Object Space
143
+ GC.start
144
+ GC.verify_compaction_references
145
+ GC.verify_internal_consistency
146
+ end
147
+
148
+ it "exports an object with schema head and hyperlink formatter (multiple.exp)" do |example|
149
+ print "\n[#{example.description}] "
150
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
151
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_schema_head_hyperlink_formatted.exp")
152
+
153
+ repo = Expressir::Express::Parser.from_file(exp_file)
154
+
155
+ formatter = Class.new(Expressir::Express::Formatter) do
156
+ include Expressir::Express::SchemaHeadFormatter
157
+ include Expressir::Express::HyperlinkFormatter
158
+ end
159
+ result = formatter.format(repo)
160
+ # File.write(formatted_exp_file, result)
161
+ expected_result = File.read(formatted_exp_file)
162
+
163
+ expect(result).to eq(expected_result)
164
+
165
+ # Validate Object Space
166
+ GC.start
167
+ GC.verify_compaction_references
168
+ GC.verify_internal_consistency
169
+ end
170
+ end
171
+ end