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