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
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/ree ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'commander'
6
+ require 'ree'
7
+
8
+ class ReeCliRunner
9
+ TEST_FRAMEWORKS = %w[minitest rspec]
10
+ include Commander::Methods
11
+
12
+ def run
13
+ program :name, 'Ree'
14
+ program :version, Ree::VERSION
15
+ program :description, 'An enterprise ruby framework'
16
+ program :help, 'Author', 'Ruslan Gatiyatov'
17
+
18
+ command :"init" do |c|
19
+ c.syntax = 'ree init'
20
+ c.description = 'generates project scaffold in a passed directory'
21
+ c.summary = '> ' + c.description
22
+ c.example 'generate scaffold with minitest', 'ree init --test=minitest'
23
+ c.example 'generate scaffold with rspec', 'ree init --test=rspec'
24
+ c.example 'generate scaffold with irb', 'ree init --console=irb'
25
+ c.example 'generate scaffold with pry', 'ree init --console=pry'
26
+ c.option '--test FRAMEWORK', TEST_FRAMEWORKS, "select test framework: #{TEST_FRAMEWORKS.join(", ")}"
27
+ c.option '--project_path [PROJECT_ROOT_DIR]', String, 'Path for the root project dir'
28
+ c.action do |args, options|
29
+ defaults = {
30
+ test: "rspec",
31
+ console: "irb",
32
+ project_path: File.expand_path(Dir.pwd)
33
+ }
34
+
35
+ options_hash = options.__hash__
36
+ options_hash.delete(:trace)
37
+
38
+ if options_hash[:project_path]
39
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
40
+ end
41
+
42
+ options_with_defaults = defaults.merge!(options_hash)
43
+ Ree::CLI::Init.run(**options_with_defaults)
44
+ Ree::CLI::GeneratePackagesSchema.run(options_with_defaults[:project_path])
45
+ end
46
+ end
47
+
48
+ command :"gen.package" do |c|
49
+ c.syntax = 'ree gen.package PACKAGE_NAME [options]'
50
+ c.description = 'generates a package scaffold in a specified folder'
51
+ c.summary = '> ' + c.description
52
+ c.example "generate 'accounts' package",
53
+ 'ree gen.package accounts --path bc/accounts'
54
+ c.example 'generate events package within /some/other/path folder',
55
+ 'ree gen.package events --path core/domain/events --project_path /data/my_project'
56
+ c.example 'generate auth package without tests', 'ree gen.package auth --path subsystems/auth'
57
+ c.option '--path [RELATIVE_PACKAGE_PATH]', String, 'Relative package path'
58
+ c.option '--project_path [ROOT_PROJECT_DIR]', String, 'Root project dir path'
59
+
60
+ c.action do |args, options|
61
+ package_name = args.first.to_s.strip
62
+
63
+ if package_name.empty?
64
+ raise Ree::Error.new("Package name should be provided")
65
+ end
66
+
67
+ defaults = {
68
+ project_path: File.expand_path(Dir.pwd),
69
+ package_name: package_name,
70
+ }
71
+
72
+ options_hash = options.__hash__
73
+
74
+ if options_hash[:project_path]
75
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
76
+ end
77
+
78
+ if options_hash[:path].nil?
79
+ raise Ree::Error.new("Path name should be provided")
80
+ end
81
+
82
+ options_hash.delete(:trace)
83
+
84
+ options_with_defaults = defaults.merge!(options_hash)
85
+
86
+ Ree::CLI::GeneratePackage.run(**options_with_defaults)
87
+ Ree::CLI::GeneratePackagesSchema.run(options_with_defaults[:project_path])
88
+
89
+ Ree::CLI::GeneratePackageSchema.run(
90
+ package_name: options_with_defaults[:package_name],
91
+ project_path: options_with_defaults[:project_path],
92
+ include_objects: false,
93
+ silence: false
94
+ )
95
+ end
96
+ end
97
+
98
+ command :"gen.packages_json" do |c|
99
+ c.syntax = 'ree gen.packages_json'
100
+ c.description = 'generates Packages.schema.json'
101
+ c.summary = '> ' + c.description
102
+ c.example 'ree gen.packages_json', ''
103
+ c.option '--project_path [ROOT_PROJECT_DIR]', String, 'Root project dir path'
104
+ c.action do |_, options|
105
+ options_hash = options.__hash__
106
+
107
+ if options_hash[:project_path]
108
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
109
+ end
110
+
111
+ project_path = options_hash[:project_path] || Dir.pwd
112
+ Ree::CLI::GeneratePackagesSchema.run(project_path)
113
+ end
114
+ end
115
+
116
+ command :"gen.package_json" do |c|
117
+ c.syntax = 'ree gen.package_json PACKAGE_NAME'
118
+ c.description = 'generates Package.schema.json for specific package'
119
+ c.summary = '> ' + c.description
120
+ c.example 'ree gen.packages_json PACKAGE_NAME', ''
121
+ c.option '--skip_objects', String, 'Skip generation of object schemas'
122
+ c.option '--silence', String, 'Silence all logs'
123
+ c.option '--project_path [ROOT_PROJECT_DIR]', String, 'Root project dir path'
124
+ c.action do |args, options|
125
+ package_name = args.first || ""
126
+ options_hash = options.__hash__
127
+
128
+ if options_hash[:project_path]
129
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
130
+ end
131
+
132
+ default_options = {
133
+ package_name: package_name,
134
+ project_path: options_hash[:project_path] || File.expand_path(Dir.pwd),
135
+ include_objects: !options_hash.has_key?(:skip_objects),
136
+ silence: options_hash.has_key?(:silence)
137
+ }
138
+
139
+ Ree::CLI::GeneratePackageSchema.run(**default_options)
140
+ end
141
+ end
142
+
143
+ command :"gen.template" do |c|
144
+ c.syntax = "ree gen.template TEMPLATE_NAME [options]"
145
+ c.description = "generates template from ROOT/.ree/templates folder with specified variables"
146
+ c.summary = '> ' + c.description
147
+ c.example 'creating new repository_template, mapper and dao files',
148
+ 'ree gen.template repository_template --path infrastructure/storage'
149
+ c.option '--path [RELATIVE_PATH]', String, 'Location of generated folders'
150
+ c.option '--project_path [ROOT_PROJECT_DIR]', String, 'Root project dir path'
151
+ c.option '--OPTION_NAME [OPTION_VALUE]', String, 'Local variables for template handler'
152
+ c.action do |args, options|
153
+ template_name = args.first || ""
154
+ options_hash = options.__hash__
155
+ options_hash.delete(:trace)
156
+
157
+ defaults = {
158
+ project_path: File.expand_path(Dir.pwd),
159
+ template_name: template_name
160
+ }
161
+
162
+ if options_hash[:path].nil? || options_hash[:path].empty?
163
+ raise Ree::Error.new('Relative path for template should be provided')
164
+ end
165
+
166
+ if options_hash[:project_path]
167
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
168
+ end
169
+
170
+ options_with_defaults = defaults.merge!(options_hash)
171
+
172
+ Ree::CLI::GenerateTemplate.run(
173
+ template_name: options_with_defaults[:template_name],
174
+ project_path: options_with_defaults[:project_path],
175
+ local_path: options_with_defaults[:path],
176
+ locals: options_with_defaults
177
+ )
178
+ end
179
+ end
180
+
181
+ command :"exec" do |c|
182
+ c.syntax = 'ree exec PACKAGE_NAME PATH_TO_EXEC [options]'
183
+ c.description = 'change directory to package folder and run executable bash file'
184
+ c.summary = '> ' + c.description
185
+ c.example "run executable file 'bin/run' for 'accounts' package",
186
+ 'ree exec accounts bin/run'
187
+ c.option '-x', TrueClass, "run 'chmod +X' before the command"
188
+
189
+ c.action do |args, options|
190
+ package_name = args[0]&.to_sym || (raise Ree::Error.new("package name should be provided"))
191
+ executable_path = args[1] || (raise Ree::Error.new("executable path should be provided"))
192
+ run_chmod_x = options.x
193
+
194
+ puts("Executing #{executable_path} for :#{package_name} package")
195
+
196
+ Ree.init(Dir.pwd)
197
+
198
+ package = Ree.container.packages_facade.get_loaded_package(package_name)
199
+ package_abs_path = Ree::PathHelper.abs_package_dir(package)
200
+ exec_abs_path = Pathname.new(package_abs_path).join(Pathname.new(executable_path)).to_s
201
+
202
+ raise Ree::Error.new("File #{exec_abs_path} not found") unless File.exists?(exec_abs_path)
203
+
204
+ system("chmod +x #{exec_abs_path}") if run_chmod_x
205
+ system(exec_abs_path)
206
+ end
207
+ end
208
+
209
+ command :"spec" do |c|
210
+ c.syntax = "ree spec PACKAGE_NAME SPEC_MATCHER [options]"
211
+ c.description = "run tests for specified package"
212
+ c.example 'ree spec accounts', "Run specs for 'accounts' package"
213
+ c.example 'ree spec -p accounts -p roles', 'Run specs for several packages'
214
+ c.example 'ree spec accounts welcome_email:42', 'Run specific spec from specified package using spec matcher'
215
+ c.example 'ree spec --tag wip', 'Run specs for packages which have "wip" tag'
216
+ c.option '--project_path [ROOT_DIR]', String, 'Root project dir path'
217
+ c.option '--tag TAG_NAME', String, 'Run specs for packages with specified tag'
218
+ c.option '--with_children', TrueClass, 'Run specs for all children dependent packages'
219
+ c.option '--with_ancestors', TrueClass, 'Run specs for all ancestors dependent packages'
220
+ c.option '-p PACKAGE_NAME', '--package PACKAGE_NAME', String, 'Package names' do |o|
221
+ @package_names ||= []
222
+ @package_names << o.to_sym
223
+ end
224
+
225
+ c.action do |args, options|
226
+ @package_names ||= []
227
+
228
+ package_name = args[0]&.to_sym
229
+ spec_matcher = args[1]
230
+
231
+ options_hash = options.__hash__
232
+ options_hash.delete(:trace)
233
+
234
+ if options_hash[:project_path]
235
+ options_hash[:project_path] = File.expand_path(options_hash[:project_path])
236
+ end
237
+
238
+ if package_name
239
+ @package_names ||= []
240
+ @package_names << package_name
241
+ end
242
+
243
+ if package_name.nil? && options_hash.keys.empty? && \
244
+ spec_matcher.nil? && @package_names.empty?
245
+ @run_all = true
246
+ end
247
+
248
+ Ree::CLI::SpecRunner.run(
249
+ package_names: @package_names,
250
+ spec_matcher: spec_matcher,
251
+ tag_name: options_hash[:tag],
252
+ with_children: options_hash[:with_children],
253
+ with_ancestors: options_hash[:with_ancestors],
254
+ run_all: @run_all,
255
+ path: options_hash[:project_path] || File.expand_path(Dir.pwd)
256
+ )
257
+ end
258
+ end
259
+
260
+ run!
261
+ end
262
+ end
263
+
264
+ ReeCliRunner.new.run
data/lib/ree/args.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal = true
2
+
3
+ module Ree::Args
4
+ def check_arg(value, name, klass)
5
+ if !value.is_a?(klass)
6
+ raise Ree::Error.new(
7
+ ":#{name} should be a #{klass}. Got #{value.class}: #{Ree::StringUtils.truncate(value.inspect)}",
8
+ :invalid_arg
9
+ )
10
+ end
11
+ end
12
+
13
+ def check_bool(value, name)
14
+ check_arg_any(value, name, [TrueClass, FalseClass])
15
+ end
16
+
17
+ def check_arg_array_of(value, name, klass)
18
+ if !value.is_a?(Array) && value.detect { |_| !_.is_a?(Symbol)}
19
+ raise Ree::Error.new(":#{name} should be array of #{klass.inspect}. Got #{value.class}: #{Ree::StringUtils.truncate(value.inspect)}", :invalid_arg)
20
+ end
21
+ end
22
+
23
+ def check_arg_any(value, name, klasses)
24
+ if !klasses.detect {|klass| value.is_a?(klass)}
25
+ raise Ree::Error.new(":#{name} should be any of #{klasses.inspect}", :invalid_arg)
26
+ end
27
+ end
28
+
29
+ def not_nil(value, name)
30
+ if value.nil?
31
+ raise Ree::Error(":#{name} should not be nil", :invalid_arg)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ree::BeanDSL
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 bean(name, &proc)
14
+ dsl = Ree::ObjectDsl.new(
15
+ Ree.container.packages_facade, name, self, :object
16
+ )
17
+
18
+ dsl.instance_exec(&proc) if block_given?
19
+ dsl.object.set_as_compiled(false)
20
+
21
+ Ree.container.compile(dsl.package, name)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Ree
2
+ module CLI
3
+ class GeneratePackage
4
+ class << self
5
+ def run(package_name:, project_path:, path:, locals: {}, stdout: $stdout)
6
+ generated_files_list = Ree::Gen::Package.generate(
7
+ project_path: project_path,
8
+ local_path: path,
9
+ package_name: package_name,
10
+ locals: locals
11
+ )
12
+
13
+ generated_files_list.compact.each { |file| stdout.puts "Generated: #{file}" }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,54 @@
1
+ require 'fileutils'
2
+
3
+ module Ree
4
+ module CLI
5
+ class GeneratePackageSchema
6
+ class << self
7
+ def run(package_name:, project_path:, include_objects: false, silence: false)
8
+ ENV['REE_SKIP_ENV_VARS_CHECK'] = 'true'
9
+
10
+ path = Ree.locate_packages_schema(project_path)
11
+ dir = Pathname.new(path).dirname.to_s
12
+
13
+ Ree.init(dir)
14
+ Ree.set_dev_mode
15
+
16
+ if package_name.strip.empty?
17
+ puts("Generating Package.schema.json for all packages") if !silence
18
+ Ree.generate_schemas_for_all_packages(silence)
19
+ return
20
+ end
21
+
22
+ puts("Generating Package.schema.json for :#{package_name} package") if !silence
23
+
24
+ package_name = package_name.to_sym
25
+
26
+ Ree.container.packages_facade.load_packages_schema
27
+ package = Ree.load_package(package_name)
28
+ Ree.container.packages_facade.write_package_schema(package_name)
29
+
30
+ package = Ree.container.packages_facade.get_package(package_name)
31
+ schema_path = Ree::PathHelper.abs_package_schema_path(package)
32
+
33
+ if include_objects
34
+ schemas_path = Ree::PathHelper.abs_package_object_schemas_path(package)
35
+
36
+ FileUtils.rm_rf(schemas_path)
37
+ FileUtils.mkdir_p(schemas_path)
38
+
39
+ package.objects.each do |object|
40
+ Ree.write_object_schema(package.name, object.name)
41
+
42
+ path = Ree::PathHelper.abs_object_schema_path(object)
43
+
44
+ puts(" #{object.name}: #{path}") if !silence
45
+ end
46
+ end
47
+
48
+ puts("output: #{schema_path}") if !silence
49
+ puts("done") if !silence
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ module Ree
2
+ module CLI
3
+ class GeneratePackagesSchema
4
+ class << self
5
+ def run(project_path)
6
+ Ree.init(project_path)
7
+
8
+ puts("Generating Packages.schema.json")
9
+ Ree::PackagesFacade.write_packages_schema
10
+
11
+ puts("output: #{Ree.packages_schema_path}")
12
+ puts("done")
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Ree
2
+ module CLI
3
+ class GenerateTemplate
4
+ class << self
5
+ def run(template_name:, project_path:, local_path:, locals:)
6
+ generated_files_list = Ree::TemplateHandler.generate(
7
+ template_name: template_name,
8
+ project_path: project_path,
9
+ local_path: local_path,
10
+ locals: locals
11
+ )
12
+
13
+ generated_files_list.compact.each { |file| puts("Generated: #{file}") }
14
+
15
+ puts("done")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module Ree
2
+ module CLI
3
+ class Init
4
+ class << self
5
+ def run(project_path:, test:, console:, stdout: $stdout)
6
+ generated_files_list = Ree::Gen::Init.generate(
7
+ project_path: project_path,
8
+ test: test,
9
+ console: console,
10
+ stdout: stdout
11
+ )
12
+
13
+ generated_files_list.compact.each { |file| stdout.puts "Generated: #{file}" }
14
+ rescue Errno::ENOENT => e
15
+ stdout.puts "Error occurred. Possible reasons:\n #{project_path} not found. Please run on empty directory \n#{e.inspect}"
16
+ rescue Ree::Error => e
17
+ stdout.puts e.message
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,184 @@
1
+ require 'set'
2
+
3
+ module Ree
4
+ module CLI
5
+ class SpecRunner
6
+ attr_reader :packages_to_run
7
+
8
+ class << self
9
+ def run(path:, package_names:, spec_matcher:, tag_name:,
10
+ with_children:, with_ancestors:, run_all: false)
11
+ SpecRunner.new(
12
+ package_names: package_names,
13
+ spec_matcher: spec_matcher,
14
+ tag_name: tag_name,
15
+ with_children: with_children,
16
+ with_ancestors: with_ancestors,
17
+ path: path,
18
+ run_all: run_all
19
+ ).run
20
+ end
21
+ end
22
+
23
+ def initialize(package_names:, spec_matcher:, tag_name:, with_children:,
24
+ with_ancestors:, run_all: false, path:, stdout: STDOUT)
25
+ @package_names = package_names || []
26
+ @packages_to_run = @package_names
27
+ @spec_matcher = spec_matcher
28
+ @tag_name = tag_name
29
+ @with_children = with_children
30
+ @with_ancestors = with_ancestors
31
+ @run_all = run_all
32
+ @path = path
33
+ @stdout = stdout
34
+ end
35
+
36
+ def run
37
+ schema_path = Ree.locate_packages_schema(@path)
38
+ schema_dir = Pathname.new(schema_path).dirname.to_s
39
+
40
+ Ree.init(schema_dir)
41
+
42
+ unless non_existent_packages.empty?
43
+ non_existent_packages.map do |pack|
44
+ puts "Package #{pack} not found"
45
+ @package_names.delete(pack)
46
+ end
47
+ end
48
+
49
+ if @tag_name
50
+ puts "Trying to find packages with tag \"#{@tag_name}\"..."
51
+
52
+ tagged_packages = find_tagged_packages
53
+
54
+ if tagged_packages.empty?
55
+ puts "No packages found with tag #{@tag_name}"
56
+ end
57
+
58
+ @packages_to_run.push(*tagged_packages)
59
+ end
60
+
61
+ if @with_children
62
+ children_packages = @package_names.map do |package_name|
63
+ puts "Trying to find children packages for #{package_name}"
64
+
65
+ find_children_packages(package_name)
66
+ end
67
+
68
+ @packages_to_run.push(*children_packages)
69
+ end
70
+
71
+ if @with_ancestors
72
+ ancestors_packages = @package_names.map do |package_name|
73
+ puts "Trying to find ancestors packages for #{package_name}"
74
+
75
+ find_ancestors_packages(package_name)
76
+ end
77
+
78
+ @packages_to_run.push(*ancestors_packages)
79
+ end
80
+
81
+ if @run_all
82
+ puts "Running specs for all packages..."
83
+
84
+ @packages_to_run.push(*packages.map(&:name))
85
+ end
86
+
87
+ @packages_to_run = @packages_to_run.flatten.uniq
88
+
89
+ if @packages_to_run.empty?
90
+ puts "No packages found with specified options"
91
+ end
92
+
93
+ @packages_to_run.each do |package|
94
+ ree_package = Ree.container.packages_facade.get_package(package)
95
+
96
+ Ree::SpecRunner::Runner.new(
97
+ path: Ree::PathHelper.project_root_dir(ree_package),
98
+ package: package,
99
+ spec_matcher: @spec_matcher,
100
+ stdout: $stdout
101
+ ).run
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def project_packages(packages)
108
+ packages.reject(&:gem?)
109
+ end
110
+
111
+ def non_existent_packages
112
+ @package_names ? @package_names - packages.map(&:name) : []
113
+ end
114
+
115
+ def find_tagged_packages
116
+ names = packages.map(&:name)
117
+
118
+ names.select do |package_name|
119
+ package = container.packages_facade.read_package_schema_json(package_name)
120
+ package.tags.include?(@tag_name)
121
+ end.compact
122
+ end
123
+
124
+ def find_children_packages(package_name)
125
+ recursively_find_children_packages(package_name)
126
+ end
127
+
128
+ def find_ancestors_packages(package_name)
129
+ recursively_find_ancestor_packages(package_name)
130
+ end
131
+
132
+ def container
133
+ @container = Ree.container
134
+ end
135
+
136
+ def packages
137
+ @packages ||= project_packages(
138
+ container.packages_facade.load_packages_schema.packages
139
+ )
140
+ end
141
+
142
+ def packages_set
143
+ @packages_set ||= Set.new(packages.map(&:name))
144
+ end
145
+
146
+ def recursively_find_children_packages(package_name, acc = [])
147
+ package = container.load_package(package_name)
148
+
149
+ unless acc.include?(package.name)
150
+ acc << package.name
151
+
152
+ package.deps.map(&:name).each do |pack|
153
+ next if !packages_set.include?(pack)
154
+ recursively_find_children_packages(pack, acc)
155
+ end
156
+ end
157
+
158
+ acc
159
+ end
160
+
161
+ def recursively_find_ancestor_packages(package_name, all_packages: packages, acc: Set.new([package_name]), count: 0)
162
+ parents = package_parents(package_name, all_packages)
163
+
164
+ all_packages = all_packages.reject { |pack| parents.include?(pack.name) }
165
+ return acc.to_a if parents.empty?
166
+
167
+ parents.map { |pa| acc.add(pa) }
168
+
169
+ parents.each do |parent|
170
+ recursively_find_ancestor_packages(parent, all_packages: all_packages, acc: acc.flatten, count: count + 1).map { |e| acc.add(e) }
171
+ end
172
+
173
+ acc.to_a
174
+ end
175
+
176
+ def package_parents(package_name, packages)
177
+ packages.map do |pack|
178
+ package = container.load_package(pack.name)
179
+ pack.name if package.deps.map(&:name).include?(package_name)
180
+ end.compact
181
+ end
182
+ end
183
+ end
184
+ end
data/lib/ree/cli.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal = true
2
+
3
+ module Ree
4
+ module CLI
5
+ autoload :Init, 'ree/cli/init'
6
+ autoload :GeneratePackagesSchema, 'ree/cli/generate_packages_schema'
7
+ autoload :GeneratePackageSchema, 'ree/cli/generate_package_schema'
8
+ autoload :GeneratePackage, 'ree/cli/generate_package'
9
+ autoload :GenerateTemplate, 'ree/cli/generate_template'
10
+ autoload :SpecRunner, 'ree/cli/spec_runner'
11
+ end
12
+ end