ree 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +13 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +5 -0
  6. data/CODE_OF_CONDUCT.md +84 -0
  7. data/Gemfile +9 -0
  8. data/Gemfile.lock +41 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +474 -0
  11. data/Rakefile +8 -0
  12. data/bin/console +8 -0
  13. data/bin/setup +8 -0
  14. data/exe/ree +264 -0
  15. data/lib/ree/args.rb +34 -0
  16. data/lib/ree/bean_dsl.rb +24 -0
  17. data/lib/ree/cli/generate_package.rb +18 -0
  18. data/lib/ree/cli/generate_package_schema.rb +54 -0
  19. data/lib/ree/cli/generate_packages_schema.rb +17 -0
  20. data/lib/ree/cli/generate_template.rb +20 -0
  21. data/lib/ree/cli/init.rb +22 -0
  22. data/lib/ree/cli/spec_runner.rb +184 -0
  23. data/lib/ree/cli.rb +12 -0
  24. data/lib/ree/container.rb +67 -0
  25. data/lib/ree/contracts/arg_contracts/any.rb +15 -0
  26. data/lib/ree/contracts/arg_contracts/array_of.rb +52 -0
  27. data/lib/ree/contracts/arg_contracts/block.rb +15 -0
  28. data/lib/ree/contracts/arg_contracts/bool.rb +21 -0
  29. data/lib/ree/contracts/arg_contracts/eq.rb +28 -0
  30. data/lib/ree/contracts/arg_contracts/exactly.rb +28 -0
  31. data/lib/ree/contracts/arg_contracts/hash_of.rb +59 -0
  32. data/lib/ree/contracts/arg_contracts/ksplat.rb +141 -0
  33. data/lib/ree/contracts/arg_contracts/kwargs.rb +22 -0
  34. data/lib/ree/contracts/arg_contracts/nilor.rb +16 -0
  35. data/lib/ree/contracts/arg_contracts/none.rb +15 -0
  36. data/lib/ree/contracts/arg_contracts/optblock.rb +11 -0
  37. data/lib/ree/contracts/arg_contracts/or.rb +30 -0
  38. data/lib/ree/contracts/arg_contracts/range_of.rb +51 -0
  39. data/lib/ree/contracts/arg_contracts/set_of.rb +54 -0
  40. data/lib/ree/contracts/arg_contracts/splat.rb +297 -0
  41. data/lib/ree/contracts/arg_contracts/splat_of.rb +64 -0
  42. data/lib/ree/contracts/arg_contracts/squarable.rb +11 -0
  43. data/lib/ree/contracts/arg_contracts/subclass_of.rb +28 -0
  44. data/lib/ree/contracts/arg_contracts.rb +29 -0
  45. data/lib/ree/contracts/called_args_validator.rb +291 -0
  46. data/lib/ree/contracts/contract_definition.rb +142 -0
  47. data/lib/ree/contracts/contractable.rb +34 -0
  48. data/lib/ree/contracts/core.rb +17 -0
  49. data/lib/ree/contracts/engine.rb +71 -0
  50. data/lib/ree/contracts/engine_proxy.rb +13 -0
  51. data/lib/ree/contracts/errors/bad_contract_error.rb +4 -0
  52. data/lib/ree/contracts/errors/contract_error.rb +4 -0
  53. data/lib/ree/contracts/errors/error.rb +4 -0
  54. data/lib/ree/contracts/errors/return_contract_error.rb +4 -0
  55. data/lib/ree/contracts/method_decorator.rb +158 -0
  56. data/lib/ree/contracts/truncatable.rb +9 -0
  57. data/lib/ree/contracts/utils.rb +9 -0
  58. data/lib/ree/contracts/validators/array_validator.rb +51 -0
  59. data/lib/ree/contracts/validators/base_validator.rb +27 -0
  60. data/lib/ree/contracts/validators/class_validator.rb +17 -0
  61. data/lib/ree/contracts/validators/default_validator.rb +20 -0
  62. data/lib/ree/contracts/validators/hash_validator.rb +100 -0
  63. data/lib/ree/contracts/validators/proc_validator.rb +17 -0
  64. data/lib/ree/contracts/validators/range_validator.rb +17 -0
  65. data/lib/ree/contracts/validators/regexp_validator.rb +17 -0
  66. data/lib/ree/contracts/validators/valid_validator.rb +28 -0
  67. data/lib/ree/contracts/validators.rb +42 -0
  68. data/lib/ree/contracts.rb +45 -0
  69. data/lib/ree/core/link_validator.rb +42 -0
  70. data/lib/ree/core/object.rb +132 -0
  71. data/lib/ree/core/object_error.rb +9 -0
  72. data/lib/ree/core/object_link.rb +21 -0
  73. data/lib/ree/core/object_schema.rb +47 -0
  74. data/lib/ree/core/object_schema_builder.rb +110 -0
  75. data/lib/ree/core/package.rb +177 -0
  76. data/lib/ree/core/package_dep.rb +9 -0
  77. data/lib/ree/core/package_env_var.rb +12 -0
  78. data/lib/ree/core/package_loader.rb +95 -0
  79. data/lib/ree/core/package_schema.rb +27 -0
  80. data/lib/ree/core/package_schema_builder.rb +53 -0
  81. data/lib/ree/core/package_schema_loader.rb +170 -0
  82. data/lib/ree/core/packages_detector.rb +43 -0
  83. data/lib/ree/core/packages_schema.rb +19 -0
  84. data/lib/ree/core/packages_schema_builder.rb +50 -0
  85. data/lib/ree/core/packages_schema_loader.rb +95 -0
  86. data/lib/ree/core/packages_schema_locator.rb +27 -0
  87. data/lib/ree/core/packages_store.rb +32 -0
  88. data/lib/ree/core/path_helper.rb +104 -0
  89. data/lib/ree/dsl/build_package_dsl.rb +155 -0
  90. data/lib/ree/dsl/domain_error.rb +4 -0
  91. data/lib/ree/dsl/error_builder.rb +39 -0
  92. data/lib/ree/dsl/error_dsl.rb +27 -0
  93. data/lib/ree/dsl/import_dsl.rb +106 -0
  94. data/lib/ree/dsl/link_import_builder.rb +66 -0
  95. data/lib/ree/dsl/object_dsl.rb +319 -0
  96. data/lib/ree/dsl/object_hooks.rb +6 -0
  97. data/lib/ree/dsl/package_require.rb +44 -0
  98. data/lib/ree/error.rb +11 -0
  99. data/lib/ree/facades/packages_facade.rb +197 -0
  100. data/lib/ree/fn_dsl.rb +24 -0
  101. data/lib/ree/gen/init.rb +64 -0
  102. data/lib/ree/gen/package.rb +56 -0
  103. data/lib/ree/gen.rb +8 -0
  104. data/lib/ree/handlers/template_handler.rb +118 -0
  105. data/lib/ree/link_dsl.rb +175 -0
  106. data/lib/ree/object_compiler.rb +149 -0
  107. data/lib/ree/package_dsl.rb +34 -0
  108. data/lib/ree/rspec_link_dsl.rb +19 -0
  109. data/lib/ree/spec_runner/command_generator.rb +49 -0
  110. data/lib/ree/spec_runner/command_params.rb +9 -0
  111. data/lib/ree/spec_runner/runner.rb +200 -0
  112. data/lib/ree/spec_runner/spec_filename_matcher.rb +27 -0
  113. data/lib/ree/spec_runner/view.rb +30 -0
  114. data/lib/ree/spec_runner.rb +11 -0
  115. data/lib/ree/templates/init/.gitignore +1 -0
  116. data/lib/ree/templates/init/.irbrc +13 -0
  117. data/lib/ree/templates/init/.rspec +3 -0
  118. data/lib/ree/templates/init/.ruby-version +1 -0
  119. data/lib/ree/templates/init/Gemfile +7 -0
  120. data/lib/ree/templates/init/Packages.schema.json +1 -0
  121. data/lib/ree/templates/init/bin/console +5 -0
  122. data/lib/ree/templates/init/readme.md +2 -0
  123. data/lib/ree/templates/init/ree.setup.rb +21 -0
  124. data/lib/ree/templates/init/spec.init.rb +7 -0
  125. data/lib/ree/templates/package/.gitignore +0 -0
  126. data/lib/ree/templates/package/.rspec +2 -0
  127. data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>/.gitkeep +0 -0
  128. data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>.rb +15 -0
  129. data/lib/ree/templates/package/Package.schema.json +0 -0
  130. data/lib/ree/templates/package/bin/console +5 -0
  131. data/lib/ree/templates/package/spec/package_schema_spec.rb +14 -0
  132. data/lib/ree/templates/package/spec/spec_helper.rb +3 -0
  133. data/lib/ree/templates/template_detector.rb +35 -0
  134. data/lib/ree/templates/template_renderer.rb +55 -0
  135. data/lib/ree/utils/render_utils.rb +20 -0
  136. data/lib/ree/utils/string_utils.rb +29 -0
  137. data/lib/ree/version.rb +5 -0
  138. data/lib/ree.rb +279 -0
  139. data/sig/ree.rbs +4 -0
  140. metadata +199 -0
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::ObjectCompiler
4
+ def initialize(packages_facade)
5
+ @packages_facade = packages_facade
6
+ @link_validator = Ree::LinkValidator.new(packages_facade)
7
+ end
8
+
9
+ # @param [Symbol] package_name
10
+ # @param [Symbol] object_name
11
+ # @return [Ree::Object]
12
+ def call(package_name, object_name)
13
+ @packages_facade.get_loaded_package(package_name)
14
+ object = @packages_facade.load_package_object(package_name, object_name)
15
+
16
+ object.set_as_compiled(true)
17
+ Ree.logger.debug("compile_object(:#{package_name}, :#{object_name}), object_id=#{object.object_id}")
18
+
19
+ klass = object.klass
20
+ links = object.links
21
+ eval_list = []
22
+
23
+ eval_list.push("\n# #{object.klass}")
24
+ indent = ""
25
+
26
+ links.each do |_|
27
+ eval_list.push(indent + "private attr_reader :#{_.as}")
28
+ end
29
+
30
+ eval_list.push("\n")
31
+
32
+ if object.singleton
33
+ eval_list.push(indent + "if !const_defined?(:SEMAPHORE)")
34
+ eval_list.push(indent + " SEMAPHORE = Mutex.new")
35
+ eval_list.push(indent + " private_constant :SEMAPHORE")
36
+ eval_list.push(indent + "end")
37
+ eval_list.push("\n")
38
+ end
39
+
40
+ if object.factory || object.singleton
41
+ eval_list.push(indent + "def self.new(**kwargs)")
42
+
43
+ if object.singleton
44
+ eval_list.push(indent + " SEMAPHORE.synchronize do")
45
+ eval_list.push(indent + " obj_links = #{links.map(&:as).inspect}")
46
+ eval_list.push(indent + " if (obj_links & kwargs.keys).size == 0")
47
+ eval_list.push(indent + " @__instance ||= begin")
48
+
49
+ if object.factory
50
+ eval_list.push(indent + " super(**kwargs).#{object.factory}")
51
+ else
52
+ eval_list.push(indent + " super(**kwargs)")
53
+ end
54
+
55
+ eval_list.push(indent + " end")
56
+ eval_list.push(indent + " else")
57
+
58
+ if object.factory
59
+ eval_list.push(indent + " super(**kwargs).#{object.factory}")
60
+ else
61
+ eval_list.push(indent + " super(**kwargs)")
62
+ end
63
+
64
+ eval_list.push(indent + " end")
65
+ eval_list.push(indent + " end")
66
+ else
67
+ eval_list.push(indent + " super(**kwargs).#{object.factory}")
68
+ end
69
+
70
+ eval_list.push(indent + "end")
71
+ end
72
+
73
+ eval_list.push("\n")
74
+ eval_list.push(indent + "def initialize(**kwargs)")
75
+
76
+ indent = inc_indent(indent)
77
+
78
+ links.each do |_|
79
+ @link_validator.call(object, _)
80
+ pckg = @packages_facade.get_loaded_package(_.package_name)
81
+ obj = pckg.get_object(_.object_name)
82
+
83
+ @packages_facade.load_package_object(pckg.name, obj.name)
84
+
85
+ eval_list.push(indent + "@#{_.as} = kwargs[:#{_.as}] || #{obj.klass}.new(**kwargs)")
86
+ end
87
+
88
+ if object.after_init?
89
+ eval_list.push(indent + "#{object.after_init}")
90
+ end
91
+
92
+ if object.compiled_frozen
93
+ eval_list.push(indent + 'freeze')
94
+ end
95
+
96
+ indent = dec_indent(indent)
97
+
98
+ eval_list.push(indent + 'end')
99
+
100
+ links.each do |_|
101
+ pckg = @packages_facade.get_loaded_package(_.package_name)
102
+ obj = pckg.get_object(_.object_name)
103
+
104
+ if obj.fn?
105
+ eval_list.push(indent + "\nprivate def #{_.as}(*args, **kwargs, &block)")
106
+ indent = inc_indent(indent)
107
+ eval_list.push(indent + "@#{_.as}.call(*args, **kwargs, &block)")
108
+ indent = dec_indent(indent)
109
+ eval_list.push(indent + "end")
110
+ else
111
+ eval_list.push(indent + "\nprivate def #{_.as}")
112
+ indent = inc_indent(indent)
113
+ eval_list.push(indent + "@#{_.as}")
114
+ indent = dec_indent(indent)
115
+ eval_list.push(indent + "end")
116
+ end
117
+ end
118
+
119
+ indent = dec_indent(indent)
120
+
121
+ str = eval_list.join("\n")
122
+
123
+ klass.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
124
+ #{str}
125
+ ruby_eval
126
+
127
+ # compile all linked objects
128
+ links.each do |link|
129
+ pckg = @packages_facade.get_loaded_package(link.package_name)
130
+ obj = pckg.get_object(link.object_name)
131
+
132
+ if !obj.compiled?
133
+ self.call(obj.package_name, obj.name)
134
+ end
135
+ end
136
+
137
+ object
138
+ end
139
+
140
+ private
141
+
142
+ def inc_indent(indent)
143
+ indent += " "
144
+ end
145
+
146
+ def dec_indent(indent)
147
+ indent.slice(0, indent.size - 2)
148
+ end
149
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal = true
2
+
3
+ module Ree::PackageDSL
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ def self.extended(base)
9
+ base.extend(ClassMethods)
10
+ end
11
+
12
+ module ClassMethods
13
+ def package(&proc)
14
+ dsl = Ree::BuildPackageDsl.new(
15
+ Ree.container.packages_facade, self
16
+ )
17
+
18
+ dsl.instance_exec(&proc) if block_given?
19
+
20
+ return if dsl.package.preloaded?
21
+ dsl.package.set_preloaded(true)
22
+
23
+ dsl.package.preload.each do |env, list|
24
+ next if !Ree.preload_for?(env)
25
+
26
+ list.each do |object_name|
27
+ Ree.container.compile_object(
28
+ "#{dsl.package.name}/#{object_name}",
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module Ree::RSpecLinkDSL
2
+ def link(obj_name, as: nil, from:)
3
+ obj = Ree.container.compile(from, obj_name)
4
+
5
+ if obj.nil?
6
+ raise Ree::Error.new("object :#{obj_name} was not found for package :#{from}")
7
+ end
8
+
9
+ as ||= obj_name
10
+
11
+ define_method as do |*args, **kwargs, &proc|
12
+ if obj.object?
13
+ obj.klass.new
14
+ else
15
+ obj.klass.new.call(*args, **kwargs, &proc)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::SpecRunner::CommandGenerator
4
+ attr_accessor :package_name, :package_path, :spec_matcher, :spec_string_number
5
+
6
+ def initialize(package_name:, package_path:, spec_matcher:, spec_string_number:, show_output: true)
7
+ @package_name = package_name
8
+ @package_path = File.expand_path(package_path)
9
+ @spec_matcher = spec_matcher
10
+ @spec_string_number = spec_string_number
11
+ @output = show_output ? '$stdout' : 'File::NULL'
12
+ end
13
+
14
+ def spec_count
15
+ Dir[File.join(package_path, 'spec/**/*_spec.rb')].size
16
+ end
17
+
18
+ def command
19
+ package_spec_path = File.join(package_path, 'spec')
20
+ package_spec_helper = File.join(package_path, 'spec', 'spec_helper.rb')
21
+ matcher = ""
22
+
23
+ if spec_matcher
24
+ matched_file = File.expand_path(spec_matcher, package_path)
25
+ matcher = File.exist?(matched_file) ? matcher_with_number(matched_file, spec_string_number) : matcher_with_number(spec_matcher, spec_string_number)
26
+ end
27
+
28
+ "print_message(
29
+ '**** Package: #{package_name} *****') \\
30
+ && system('cd #{Ree.root_dir} \\
31
+ && bundle exec rspec --color --tty #{matcher} --default-path=#{package_spec_path} --require=#{package_spec_helper}', \\
32
+ out: #{@output.to_s}, err: :out)"
33
+ end
34
+
35
+ def generate
36
+ Ree::SpecRunner::CommandParams.new.tap do |cp|
37
+ cp.package_name = package_name
38
+ cp.package_path = package_path
39
+ cp.command = command
40
+ cp.spec_count = spec_count
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def matcher_with_number(matcher_string, string_number)
47
+ string_number == 0 ? matcher_string : [matcher_string, string_number].join(':')
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::SpecRunner::CommandParams
4
+ attr_accessor :package_name, :package_path, :spec_matcher, :spec_count, :command, :exitstatus
5
+
6
+ def success?
7
+ @exitstatus == 0
8
+ end
9
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::SpecRunner::Runner
4
+ attr_accessor :no_specs_packages
5
+ attr_accessor :prepared_command_params
6
+
7
+ def initialize(path: nil, package: nil, spec_matcher: nil, show_missing_packages: true,
8
+ stdout: $stdout, show_output: true )
9
+ @package_name = package
10
+ @no_specs_packages = []
11
+ @spec_matcher = spec_matcher.to_s.split(':')[0]
12
+ @spec_string_number = spec_matcher.to_s.split(':')[1].to_i
13
+ @path = path
14
+ @stdout = stdout
15
+ @show_output = show_output
16
+ end
17
+
18
+ def run
19
+ if @spec_matcher
20
+ find_matched_files(@package_name)
21
+ end
22
+
23
+ prepare!
24
+ check_input_params!
25
+ display_missing_specs if @show_missing_packages
26
+ print_message view.specs_header_message if @show_missing_packages
27
+
28
+ execute_command
29
+ end
30
+
31
+ private
32
+
33
+ def prepare!
34
+ prepared_command_params = []
35
+ no_specs_packages = []
36
+ @command_params_list = []
37
+ prepare_command_params
38
+ prepare_no_specs_packages
39
+ prepare_command
40
+ end
41
+
42
+ def is_package_included?(package_name)
43
+ !prepared_command_params.select do |x|
44
+ x.package_name == package_name
45
+ end.empty?
46
+ end
47
+
48
+ def prepare_command_params
49
+ @prepared_command_params ||= begin
50
+ [
51
+ Ree::SpecRunner::CommandGenerator.new(
52
+ package_name: selected_package.name,
53
+ package_path: File.join(@path, selected_package.dir),
54
+ spec_matcher: @spec_matcher,
55
+ spec_string_number: @spec_string_number,
56
+ show_output: @show_output
57
+ ).generate
58
+ ]
59
+ end
60
+ end
61
+
62
+ def prepare_command
63
+ @command_params_list += prepare_single_package_command(@package_name)
64
+ end
65
+
66
+ def prepare_no_specs_packages
67
+ prepared_command_params
68
+ .select { |cp| cp.spec_count == 0 }
69
+ .map { |cp| no_specs_packages << cp.package_name }
70
+ end
71
+
72
+ def prepare_single_package_command(package_name)
73
+ selected = prepared_command_params.detect do |cmd_params|
74
+ cmd_params.package_name == package_name
75
+ end
76
+
77
+ prepare_commands_for_packages([selected])
78
+ end
79
+
80
+ def prepare_commands_for_packages(packages_command_params)
81
+ running_packages = packages_command_params
82
+ .select { |cmd_params| cmd_params.spec_count > 0 }
83
+ .sort_by { |cmd_params| cmd_params.package_name }
84
+
85
+ running_packages
86
+ end
87
+
88
+ def execute_command
89
+ @command_params_list.each do |command_param|
90
+ eval(command_param.command);
91
+
92
+ command_param.exitstatus = $?.exitstatus
93
+ end
94
+
95
+ failed = @command_params_list.select {|cmd_param| !cmd_param.success?}
96
+
97
+ if failed.any?
98
+ total_count = @command_params_list.count
99
+ failed_count = failed.count
100
+
101
+ print_message("#{failed_count} of #{total_count} packages failed:")
102
+ print_message(failed.map(&:package_name))
103
+ print_message("\n")
104
+
105
+ exit(1)
106
+ end
107
+ end
108
+
109
+ def check_input_params!
110
+ if @package_name
111
+ unless is_package_included?(@package_name)
112
+ exit_with_message(
113
+ view.package_not_found_message(@package_name, prepared_command_params)
114
+ )
115
+ end
116
+
117
+ if no_specs_packages.include?(@package_name)
118
+ print_message(
119
+ view.no_specs_for_package(@package_name)
120
+ )
121
+ end
122
+ end
123
+ end
124
+
125
+ def display_missing_specs
126
+ if !no_specs_packages.empty?
127
+ print_message view.missing_specs_message(no_specs_packages)
128
+ end
129
+ end
130
+
131
+ def find_matched_files(package_name)
132
+ @spec_file_matches = Ree::SpecRunner::SpecFilenameMatcher.find_matches(
133
+ package_path: File.join(@path, selected_package.dir),
134
+ spec_matcher: @spec_matcher
135
+ )
136
+
137
+ case @spec_file_matches.size
138
+ when 0
139
+ raise Ree::Error.new("No spec were found for #{@spec_matcher}")
140
+ when 1
141
+ format_string_number = @spec_string_number == 0 ? "" : ":#{@spec_string_number}"
142
+ @spec_matcher = @spec_file_matches.first
143
+ puts "Following spec matches your input: #{@spec_matcher + format_string_number}"
144
+ else
145
+ format_spec_files = @spec_file_matches.map.with_index { |file, idx| "#{idx + 1}. #{file}" }.join("\n")
146
+
147
+ puts "Following specs match your input:"
148
+ puts format_spec_files
149
+ print "Enter space-separated file numbers, ex: '1 2': "
150
+ selected_files_numbers = $stdin.gets.chomp
151
+ .split(' ')
152
+ .map {|x| Integer(x) rescue nil }
153
+ .compact
154
+ .map { |n| n - 1 }
155
+ .reject { |n| n >= @spec_file_matches.size }
156
+
157
+
158
+ @spec_file_matches
159
+ .select
160
+ .with_index { |_file, idx| selected_files_numbers.include?(idx) }
161
+ .each do |file|
162
+ Ree::SpecRunner::Runner.new(
163
+ path: @path,
164
+ package: package_name,
165
+ spec_matcher: file,
166
+ show_output: @show_output,
167
+ stdout: @stdout
168
+ ).run
169
+ end
170
+
171
+ exit(0)
172
+ end
173
+ end
174
+
175
+ def container
176
+ @container = Ree.container
177
+ end
178
+
179
+ def selected_package
180
+ @selected_package ||= packages.find { |p| p.name == @package_name }
181
+ end
182
+
183
+ def packages
184
+ @packages ||= container.packages_facade.load_packages_schema.packages
185
+ end
186
+
187
+ def view
188
+ @view ||= Ree::SpecRunner::View.new
189
+ end
190
+
191
+ def print_message(msg)
192
+ @stdout.puts msg
193
+ true
194
+ end
195
+
196
+ def exit_with_message(msg)
197
+ print_message(msg)
198
+ exit 1
199
+ end
200
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::SpecRunner::SpecFilenameMatcher
4
+ class << self
5
+ def find_matches(package_path:, spec_matcher:)
6
+ Ree::SpecRunner::SpecFilenameMatcher.new(package_path, spec_matcher).find_matches
7
+ end
8
+ end
9
+
10
+ def initialize(package_path, spec_matcher)
11
+ @package_path = File.expand_path(package_path)
12
+ @spec_matcher = spec_matcher
13
+ end
14
+
15
+ def find_matches
16
+ expected_filename = File.join(@package_path, @spec_matcher)
17
+
18
+ if File.exist?(expected_filename)
19
+ return Pathname.new(expected_filename).relative_path_from(Pathname.new(@package_path)).to_s.split
20
+ end
21
+
22
+ Dir.glob(File.join(@package_path, '**/*_spec.rb'))
23
+ .select { |fn| File.file?(fn) }
24
+ .map {|file| Pathname.new(file).relative_path_from(Pathname.new(@package_path)).to_s }
25
+ .grep(/#{@spec_matcher.split('').join('.*')}/)
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal = true
2
+
3
+ class Ree::SpecRunner::View
4
+ def packages_menu(prepared_command_params)
5
+ prepared_command_params
6
+ .sort_by(&:package_path)
7
+ .map { |x| " - #{x.package_name} (#{x.spec_count} spec files)" }
8
+ .join("\n")
9
+ end
10
+
11
+ def package_not_found_message(package_name, prepared_command_params)
12
+ "Package #{package_name} not found! \nPossible packages:\n\n#{packages_menu(prepared_command_params)}"
13
+ end
14
+
15
+ def missing_specs_message(skipped_packages)
16
+ "NO SPECS FOUND FOR PACKAGES: \n#{skipped_packages.map { |x| " - #{x}" }.join("\n")}\n\n"
17
+ end
18
+
19
+ def skipping_specs_message(skipped_packages)
20
+ "FOLLOWING PACKAGES WERE SKIPPED BY .runignore FILE: \n#{skipped_packages.map { |x| " - #{x}" }.join("\n")}\n\n"
21
+ end
22
+
23
+ def specs_header_message
24
+ "**** SPECS *****"
25
+ end
26
+
27
+ def no_specs_for_package(package_name)
28
+ "Package #{package_name} has no specs to execute!"
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal = true
2
+
3
+ module Ree
4
+ module SpecRunner
5
+ autoload :SpecFilenameMatcher, 'ree/spec_runner/spec_filename_matcher'
6
+ autoload :CommandGenerator, 'ree/spec_runner/command_generator'
7
+ autoload :CommandParams, 'ree/spec_runner/command_params'
8
+ autoload :Runner, 'ree/spec_runner/runner'
9
+ autoload :View, 'ree/spec_runner/view'
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ .irb_history
@@ -0,0 +1,13 @@
1
+ class Object
2
+ def local_methods
3
+ (instance_methods - Object.instance_methods).sort
4
+ end
5
+ end
6
+
7
+ def link(obj_name, from:)
8
+ obj = Ree.container.packages_facade.get_object(from, obj_name)
9
+
10
+ define_method obj_name do |*args, **kwargs, &proc|
11
+ obj.klass.new.call(*args, **kwargs, &proc)
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require ./spec.init.rb
@@ -0,0 +1 @@
1
+ <%= RUBY_VERSION %>
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'ree'
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "ree"
4
+
5
+ Ree.init(__dir__, irb: true)
@@ -0,0 +1,2 @@
1
+ # Ree usage information:
2
+ - run `ree help` to get information about all available ree commands
@@ -0,0 +1,21 @@
1
+
2
+ Ree.add_error_types(
3
+ :invalid_param,
4
+ :not_found,
5
+ :validation
6
+ )
7
+
8
+ # Switch Ree.logger to debug level
9
+ # Ree.set_logger_debug
10
+
11
+ if ENV['RUBY_ENV'] == 'test'
12
+ Ree.enable_contracts
13
+ end
14
+
15
+ if ENV['RUBY_ENV'] == 'production'
16
+ # Define preload context for registered objects
17
+ Ree.preload_for(:production)
18
+
19
+ # Use performance mode to load packages and registered objects based on schema files
20
+ Ree.set_performance_mode
21
+ end
@@ -0,0 +1,7 @@
1
+ # Put global rspec configuration here. It will be loaded before each spec run.
2
+ # Run `ree spec --help` to get usage information.
3
+
4
+ require 'rspec'
5
+ require 'ree'
6
+
7
+ Ree.init(__dir__)
File without changes
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,15 @@
1
+ module <%= Ree::StringUtils.camelize(package_name) %>
2
+ include Ree::PackageDSL
3
+
4
+ package do
5
+ # Example of usage:
6
+ # tags ['wip']
7
+ # depends_on :package_name
8
+ # env_var 'ENV_VAR_NAME'
9
+ # preload(
10
+ # production: [
11
+ # :bean_or_fn
12
+ # ]
13
+ # )
14
+ end
15
+ end
File without changes
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "ree"
4
+
5
+ Ree.init(__dir__, irb: true)
@@ -0,0 +1,14 @@
1
+ RSpec.describe "<%= Ree::StringUtils.camelize(package_name) %>" do
2
+ it "generates package schema" do
3
+ require 'fileutils'
4
+
5
+ packages_schema_path = Ree.locate_packages_schema(__dir__)
6
+ packages_schema_dir = Pathname.new(packages_schema_path).dirname.to_s
7
+
8
+ FileUtils.cd packages_schema_dir do
9
+ expect(
10
+ system("bundle exec ree gen.package_json <%= package_name %> --silence")
11
+ ).to eq(true)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.extend Ree::RSpecLinkDSL
3
+ end