quby-compiler 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitlab-ci.yml +5 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Dockerfile +11 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +133 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +44 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/rspec +29 -0
  15. data/bin/setup +8 -0
  16. data/config/locales/de.yml +58 -0
  17. data/config/locales/en.yml +57 -0
  18. data/config/locales/nl.yml +57 -0
  19. data/config/locales/rails-i18n/README.md +4 -0
  20. data/config/locales/rails-i18n/de.yml +223 -0
  21. data/config/locales/rails-i18n/en.yml +216 -0
  22. data/config/locales/rails-i18n/nl.yml +214 -0
  23. data/exe/quby-compile +56 -0
  24. data/lib/quby/array_attribute_valid_validator.rb +15 -0
  25. data/lib/quby/attribute_valid_validator.rb +14 -0
  26. data/lib/quby/compiler.rb +50 -0
  27. data/lib/quby/compiler/dsl.rb +29 -0
  28. data/lib/quby/compiler/dsl/base.rb +20 -0
  29. data/lib/quby/compiler/dsl/calls_custom_methods.rb +29 -0
  30. data/lib/quby/compiler/dsl/charting/bar_chart_builder.rb +14 -0
  31. data/lib/quby/compiler/dsl/charting/chart_builder.rb +95 -0
  32. data/lib/quby/compiler/dsl/charting/line_chart_builder.rb +34 -0
  33. data/lib/quby/compiler/dsl/charting/overview_chart_builder.rb +31 -0
  34. data/lib/quby/compiler/dsl/charting/radar_chart_builder.rb +14 -0
  35. data/lib/quby/compiler/dsl/helpers.rb +53 -0
  36. data/lib/quby/compiler/dsl/panel_builder.rb +80 -0
  37. data/lib/quby/compiler/dsl/question_builder.rb +40 -0
  38. data/lib/quby/compiler/dsl/questionnaire_builder.rb +279 -0
  39. data/lib/quby/compiler/dsl/questions/base.rb +180 -0
  40. data/lib/quby/compiler/dsl/questions/checkbox_question_builder.rb +20 -0
  41. data/lib/quby/compiler/dsl/questions/date_question_builder.rb +18 -0
  42. data/lib/quby/compiler/dsl/questions/deprecated_question_builder.rb +18 -0
  43. data/lib/quby/compiler/dsl/questions/float_question_builder.rb +21 -0
  44. data/lib/quby/compiler/dsl/questions/integer_question_builder.rb +21 -0
  45. data/lib/quby/compiler/dsl/questions/radio_question_builder.rb +20 -0
  46. data/lib/quby/compiler/dsl/questions/select_question_builder.rb +18 -0
  47. data/lib/quby/compiler/dsl/questions/string_question_builder.rb +20 -0
  48. data/lib/quby/compiler/dsl/questions/text_question_builder.rb +22 -0
  49. data/lib/quby/compiler/dsl/score_builder.rb +22 -0
  50. data/lib/quby/compiler/dsl/score_schema_builder.rb +53 -0
  51. data/lib/quby/compiler/dsl/standardized_panel_generators.rb +33 -0
  52. data/lib/quby/compiler/dsl/table_builder.rb +48 -0
  53. data/lib/quby/compiler/entities.rb +38 -0
  54. data/lib/quby/compiler/entities/charting/bar_chart.rb +17 -0
  55. data/lib/quby/compiler/entities/charting/chart.rb +101 -0
  56. data/lib/quby/compiler/entities/charting/charts.rb +42 -0
  57. data/lib/quby/compiler/entities/charting/line_chart.rb +38 -0
  58. data/lib/quby/compiler/entities/charting/overview_chart.rb +20 -0
  59. data/lib/quby/compiler/entities/charting/plottable.rb +20 -0
  60. data/lib/quby/compiler/entities/charting/radar_chart.rb +17 -0
  61. data/lib/quby/compiler/entities/definition.rb +26 -0
  62. data/lib/quby/compiler/entities/fields.rb +119 -0
  63. data/lib/quby/compiler/entities/flag.rb +55 -0
  64. data/lib/quby/compiler/entities/item.rb +40 -0
  65. data/lib/quby/compiler/entities/lookup_tables.rb +71 -0
  66. data/lib/quby/compiler/entities/outcome_table.rb +31 -0
  67. data/lib/quby/compiler/entities/panel.rb +82 -0
  68. data/lib/quby/compiler/entities/question.rb +365 -0
  69. data/lib/quby/compiler/entities/question_option.rb +96 -0
  70. data/lib/quby/compiler/entities/questionnaire.rb +440 -0
  71. data/lib/quby/compiler/entities/questions/checkbox_question.rb +82 -0
  72. data/lib/quby/compiler/entities/questions/date_question.rb +84 -0
  73. data/lib/quby/compiler/entities/questions/deprecated_question.rb +19 -0
  74. data/lib/quby/compiler/entities/questions/float_question.rb +15 -0
  75. data/lib/quby/compiler/entities/questions/integer_question.rb +15 -0
  76. data/lib/quby/compiler/entities/questions/radio_question.rb +19 -0
  77. data/lib/quby/compiler/entities/questions/select_question.rb +19 -0
  78. data/lib/quby/compiler/entities/questions/string_question.rb +15 -0
  79. data/lib/quby/compiler/entities/questions/text_question.rb +15 -0
  80. data/lib/quby/compiler/entities/score_calculation.rb +35 -0
  81. data/lib/quby/compiler/entities/score_schema.rb +25 -0
  82. data/lib/quby/compiler/entities/subscore_schema.rb +23 -0
  83. data/lib/quby/compiler/entities/table.rb +143 -0
  84. data/lib/quby/compiler/entities/text.rb +71 -0
  85. data/lib/quby/compiler/entities/textvar.rb +23 -0
  86. data/lib/quby/compiler/entities/validation.rb +17 -0
  87. data/lib/quby/compiler/entities/version.rb +23 -0
  88. data/lib/quby/compiler/entities/visibility_rule.rb +71 -0
  89. data/lib/quby/compiler/instance.rb +72 -0
  90. data/lib/quby/compiler/output.rb +13 -0
  91. data/lib/quby/compiler/outputs.rb +4 -0
  92. data/lib/quby/compiler/outputs/quby_frontend_v1_serializer.rb +362 -0
  93. data/lib/quby/compiler/outputs/quby_frontend_v2_serializer.rb +15 -0
  94. data/lib/quby/compiler/outputs/roqua_serializer.rb +108 -0
  95. data/lib/quby/compiler/outputs/seed_serializer.rb +34 -0
  96. data/lib/quby/compiler/services/definition_validator.rb +330 -0
  97. data/lib/quby/compiler/services/quby_proxy.rb +405 -0
  98. data/lib/quby/compiler/services/seed_diff.rb +116 -0
  99. data/lib/quby/compiler/services/text_transformation.rb +30 -0
  100. data/lib/quby/compiler/version.rb +5 -0
  101. data/lib/quby/markdown_parser.rb +38 -0
  102. data/lib/quby/range_categories.rb +38 -0
  103. data/lib/quby/settings.rb +86 -0
  104. data/lib/quby/text_transformation.rb +26 -0
  105. data/lib/quby/type_validator.rb +12 -0
  106. data/quby-compiler.gemspec +39 -0
  107. metadata +277 -0
@@ -0,0 +1,214 @@
1
+ ---
2
+ nl:
3
+ activerecord:
4
+ errors:
5
+ messages:
6
+ record_invalid: 'Validatie mislukt: %{errors}'
7
+ restrict_dependent_destroy:
8
+ has_one: Kan item niet verwijderen omdat %{record} afhankelijk is
9
+ has_many: Kan item niet verwijderen omdat afhankelijke %{record} bestaan
10
+ date:
11
+ abbr_day_names:
12
+ - zo
13
+ - ma
14
+ - di
15
+ - wo
16
+ - do
17
+ - vr
18
+ - za
19
+ abbr_month_names:
20
+ -
21
+ - jan
22
+ - feb
23
+ - mrt
24
+ - apr
25
+ - mei
26
+ - jun
27
+ - jul
28
+ - aug
29
+ - sep
30
+ - okt
31
+ - nov
32
+ - dec
33
+ day_names:
34
+ - zondag
35
+ - maandag
36
+ - dinsdag
37
+ - woensdag
38
+ - donderdag
39
+ - vrijdag
40
+ - zaterdag
41
+ formats:
42
+ default: "%d-%m-%Y"
43
+ long: "%e %B %Y"
44
+ short: "%e %b"
45
+ month_names:
46
+ -
47
+ - januari
48
+ - februari
49
+ - maart
50
+ - april
51
+ - mei
52
+ - juni
53
+ - juli
54
+ - augustus
55
+ - september
56
+ - oktober
57
+ - november
58
+ - december
59
+ order:
60
+ - :day
61
+ - :month
62
+ - :year
63
+ datetime:
64
+ distance_in_words:
65
+ about_x_hours:
66
+ one: ongeveer een uur
67
+ other: ongeveer %{count} uur
68
+ about_x_months:
69
+ one: ongeveer een maand
70
+ other: ongeveer %{count} maanden
71
+ about_x_years:
72
+ one: ongeveer een jaar
73
+ other: ongeveer %{count} jaar
74
+ almost_x_years:
75
+ one: bijna een jaar
76
+ other: bijna %{count} jaar
77
+ half_a_minute: een halve minuut
78
+ less_than_x_seconds:
79
+ one: minder dan een seconde
80
+ other: minder dan %{count} seconden
81
+ less_than_x_minutes:
82
+ one: minder dan een minuut
83
+ other: minder dan %{count} minuten
84
+ over_x_years:
85
+ one: meer dan een jaar
86
+ other: meer dan %{count} jaar
87
+ x_seconds:
88
+ one: 1 seconde
89
+ other: "%{count} seconden"
90
+ x_minutes:
91
+ one: 1 minuut
92
+ other: "%{count} minuten"
93
+ x_days:
94
+ one: 1 dag
95
+ other: "%{count} dagen"
96
+ x_months:
97
+ one: 1 maand
98
+ other: "%{count} maanden"
99
+ x_years:
100
+ one: 1 jaar
101
+ other: "%{count} jaar"
102
+ prompts:
103
+ second: seconde
104
+ minute: minuut
105
+ hour: uur
106
+ day: dag
107
+ month: maand
108
+ year: jaar
109
+ errors:
110
+ format: "%{attribute} %{message}"
111
+ messages:
112
+ accepted: moet worden geaccepteerd
113
+ blank: moet opgegeven zijn
114
+ confirmation: komt niet overeen met %{attribute}
115
+ empty: moet opgegeven zijn
116
+ equal_to: moet gelijk zijn aan %{count}
117
+ even: moet even zijn
118
+ exclusion: is gereserveerd
119
+ greater_than: moet groter zijn dan %{count}
120
+ greater_than_or_equal_to: moet groter dan of gelijk zijn aan %{count}
121
+ inclusion: is niet in de lijst opgenomen
122
+ invalid: is ongeldig
123
+ less_than: moet minder zijn dan %{count}
124
+ less_than_or_equal_to: moet minder dan of gelijk zijn aan %{count}
125
+ model_invalid: 'Validatie mislukt: %{errors}'
126
+ not_a_number: is geen getal
127
+ not_an_integer: moet een geheel getal zijn
128
+ odd: moet oneven zijn
129
+ other_than: moet anders zijn dan %{count}
130
+ present: moet leeg zijn
131
+ required: moet bestaan
132
+ taken: is al in gebruik
133
+ too_long:
134
+ one: is te lang (maximaal %{count} teken)
135
+ other: is te lang (maximaal %{count} tekens)
136
+ too_short:
137
+ one: is te kort (minimaal %{count} teken)
138
+ other: is te kort (minimaal %{count} tekens)
139
+ wrong_length:
140
+ one: heeft onjuiste lengte (moet 1 teken lang zijn)
141
+ other: heeft onjuiste lengte (moet %{count} tekens lang zijn)
142
+ template:
143
+ body: 'Er zijn problemen met de volgende velden:'
144
+ header:
145
+ one: "%{model} niet opgeslagen: 1 fout gevonden"
146
+ other: "%{model} niet opgeslagen: %{count} fouten gevonden"
147
+ helpers:
148
+ select:
149
+ prompt: Maak een keuze
150
+ submit:
151
+ create: "%{model} toevoegen"
152
+ submit: "%{model} opslaan"
153
+ update: "%{model} bijwerken"
154
+ number:
155
+ currency:
156
+ format:
157
+ delimiter: "."
158
+ format: "%u %n"
159
+ precision: 2
160
+ separator: ","
161
+ significant: false
162
+ strip_insignificant_zeros: false
163
+ unit: "€"
164
+ format:
165
+ delimiter: "."
166
+ precision: 2
167
+ separator: ","
168
+ significant: false
169
+ strip_insignificant_zeros: false
170
+ human:
171
+ decimal_units:
172
+ format: "%n %u"
173
+ units:
174
+ billion: miljard
175
+ million: miljoen
176
+ quadrillion: biljard
177
+ thousand: duizend
178
+ trillion: biljoen
179
+ unit: ''
180
+ format:
181
+ delimiter: ''
182
+ precision: 3
183
+ significant: true
184
+ strip_insignificant_zeros: true
185
+ storage_units:
186
+ format: "%n %u"
187
+ units:
188
+ byte:
189
+ one: byte
190
+ other: bytes
191
+ gb: GB
192
+ kb: KB
193
+ mb: MB
194
+ tb: TB
195
+ percentage:
196
+ format:
197
+ delimiter: ''
198
+ format: "%n%"
199
+ precision:
200
+ format:
201
+ delimiter: ''
202
+ support:
203
+ array:
204
+ last_word_connector: " en "
205
+ two_words_connector: " en "
206
+ words_connector: ", "
207
+ time:
208
+ am: "'s ochtends"
209
+ formats:
210
+ default: "%a %d %b %Y %H:%M:%S %Z"
211
+ long: "%d %B %Y %H:%M"
212
+ short: "%d %b %H:%M"
213
+ pm: "'s middags"
214
+
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require 'fileutils'
5
+ require 'optparse'
6
+
7
+ require "quby/compiler"
8
+
9
+ output_path = "output"
10
+ lookup_tables_path = "lookup_tables"
11
+ seeds_path = "seeds"
12
+
13
+ OptionParser.new do |opts|
14
+ opts.banner = "Usage: quby-compile FILE_OR_DIRS [options]"
15
+ opts.on("--output=OUTPUT", "Destination directory") do |value|
16
+ output_path = value
17
+ end
18
+
19
+ opts.on("--lookup-tables=INPUT") do |value|
20
+ lookup_tables_path = value
21
+ end
22
+
23
+ opts.on("--seeds=INPUT") do |value|
24
+ seeds_path = value
25
+ end
26
+ end.parse!
27
+
28
+ paths = ARGV.flat_map do |file_or_dir|
29
+ if FileTest.file?(file_or_dir)
30
+ file_or_dir
31
+ else
32
+ Dir[File.join(file_or_dir, "**/*.rb")]
33
+ end
34
+ end
35
+
36
+ lookup_tables = Quby::Compiler::Entities::LookupTables.new(lookup_tables_path)
37
+
38
+ paths.each do |path|
39
+ puts "Compiling #{path}"
40
+
41
+ key = File.basename(path, File.extname(path))
42
+ sourcecode = File.read(path)
43
+ last_update = File.mtime(path)
44
+ seed_path = File.join(seeds_path, "#{key}.yml")
45
+ seeds = File.exist?(seed_path) ? YAML.load(File.read(seed_path)) : nil
46
+ compiled = Quby::Compiler.compile(key, sourcecode, path: path, seeds: seeds, lookup_tables: lookup_tables, last_update: last_update)
47
+
48
+ FileUtils.mkdir_p(File.join(output_path, key))
49
+
50
+ compiled[:outputs].each do |type, output|
51
+ next unless output
52
+ File.open(File.join(output_path, key, output.filename), 'w') do |file|
53
+ file.write(output.content)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_model'
2
+
3
+ module Quby
4
+ class ArrayAttributeValidValidator < ActiveModel::EachValidator
5
+ def validate_each(record, attribute, value)
6
+ value&.each&.with_index do |element, index|
7
+ if !element.respond_to?(:valid?)
8
+ record.errors.add(attribute, "element ##{index} does not respond_to valid?")
9
+ elsif !element.valid?
10
+ record.errors.add(attribute, "element ##{index} #{element.errors.full_messages.join(', ')}")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'active_model'
2
+
3
+ module Quby
4
+ class AttributeValidValidator < ActiveModel::EachValidator
5
+ def validate_each(record, attribute, value)
6
+ return if value.blank?
7
+ if value.respond_to?(:valid?)
8
+ record.errors.add(attribute, value.errors.full_messages.join(', ')) unless value.valid?
9
+ else
10
+ record.errors.add(attribute, 'does not respond_to valid?')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry-struct'
4
+ require 'i18n'
5
+ I18n.load_path += Dir[File.expand_path("../../config/locales", __dir__) + "/**/*.yml"]
6
+ I18n.default_locale = :nl
7
+ I18n.config.enforce_available_locales = true
8
+
9
+ require 'active_support/all'
10
+ require 'tempfile'
11
+
12
+ module Quby
13
+ module Types
14
+ include Dry.Types()
15
+ end
16
+ end
17
+
18
+ require 'quby/array_attribute_valid_validator'
19
+ require 'quby/attribute_valid_validator'
20
+ require 'quby/markdown_parser'
21
+ require 'quby/range_categories'
22
+ require 'quby/type_validator'
23
+
24
+ require 'quby/compiler/instance'
25
+ require 'quby/compiler/entities'
26
+ require 'quby/compiler/dsl'
27
+ require 'quby/compiler/output'
28
+ require 'quby/compiler/outputs'
29
+
30
+ module Quby
31
+ module Compiler
32
+ def self.compile(key, sourcecode, path: nil, seeds:, lookup_tables:, last_update: nil, &block)
33
+ Quby::Compiler::Instance.new(lookup_tables: lookup_tables).compile(
34
+ key: key,
35
+ sourcecode: sourcecode,
36
+ path: path,
37
+ seeds: seeds,
38
+ last_update: last_update,
39
+ &block
40
+ )
41
+ end
42
+
43
+ def self.validate(key, sourcecode)
44
+ Quby::Compiler::Instance.new(lookup_tables: lookup_tables).validate(
45
+ key: key,
46
+ sourcecode: sourcecode,
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'quby/compiler/dsl/base'
4
+ require 'quby/compiler/dsl/helpers'
5
+ require 'quby/compiler/dsl/questionnaire_builder'
6
+ require 'quby/compiler/dsl/score_schema_builder'
7
+
8
+ module Quby
9
+ module Compiler
10
+ module DSL
11
+ def self.build_from_definition(definition)
12
+ Entities::Questionnaire.new(definition.key, last_update: definition.timestamp).tap do |questionnaire|
13
+ builder = QuestionnaireBuilder.new(questionnaire)
14
+ builder.instance_eval(definition.sourcecode, definition.path) if definition.sourcecode
15
+ questionnaire.callback_after_dsl_enhance_on_questions
16
+ end
17
+ end
18
+
19
+ def self.build(key, sourcecode = nil, path: nil, timestamp: nil, &block)
20
+ Entities::Questionnaire.new(key, last_update: timestamp).tap do |questionnaire|
21
+ builder = QuestionnaireBuilder.new(questionnaire)
22
+ builder.instance_eval(sourcecode, path || key) if sourcecode
23
+ builder.instance_eval(&block) if block
24
+ questionnaire.callback_after_dsl_enhance_on_questions
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'quby/compiler/dsl/helpers'
4
+ require 'quby/compiler/dsl/calls_custom_methods'
5
+
6
+ module Quby
7
+ module Compiler
8
+ module DSL
9
+ class Base
10
+ include Helpers
11
+
12
+ def self.build(*args, &block)
13
+ builder = new(*args)
14
+ builder.instance_eval(&block) if block
15
+ builder.build
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Quby
4
+ module Compiler
5
+ module DSL
6
+ module CallsCustomMethods
7
+ attr_reader :custom_methods
8
+
9
+ def initialize(*args)
10
+ options = args.last.is_a?(::Hash) ? args.last : {}
11
+ @custom_methods = options[:custom_methods] || {}
12
+ super
13
+ end
14
+
15
+ def method_missing(method_sym, *args, &block)
16
+ if @custom_methods.key? method_sym
17
+ instance_exec(*args, &custom_methods[method_sym])
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def respond_to_missing?(method_name, include_private = false)
24
+ custom_methods.key?(method_name) || super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'quby/compiler/entities/charting/bar_chart'
4
+ require_relative 'chart_builder'
5
+
6
+ module Quby
7
+ module Compiler
8
+ module DSL
9
+ class BarChartBuilder < ChartBuilder
10
+ set_chart_class(Entities::Charting::BarChart)
11
+ end
12
+ end
13
+ end
14
+ end