ree 1.0.0

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 (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