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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +21 -0
- data/README.md +474 -0
- data/Rakefile +8 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/exe/ree +264 -0
- data/lib/ree/args.rb +34 -0
- data/lib/ree/bean_dsl.rb +24 -0
- data/lib/ree/cli/generate_package.rb +18 -0
- data/lib/ree/cli/generate_package_schema.rb +54 -0
- data/lib/ree/cli/generate_packages_schema.rb +17 -0
- data/lib/ree/cli/generate_template.rb +20 -0
- data/lib/ree/cli/init.rb +22 -0
- data/lib/ree/cli/spec_runner.rb +184 -0
- data/lib/ree/cli.rb +12 -0
- data/lib/ree/container.rb +67 -0
- data/lib/ree/contracts/arg_contracts/any.rb +15 -0
- data/lib/ree/contracts/arg_contracts/array_of.rb +52 -0
- data/lib/ree/contracts/arg_contracts/block.rb +15 -0
- data/lib/ree/contracts/arg_contracts/bool.rb +21 -0
- data/lib/ree/contracts/arg_contracts/eq.rb +28 -0
- data/lib/ree/contracts/arg_contracts/exactly.rb +28 -0
- data/lib/ree/contracts/arg_contracts/hash_of.rb +59 -0
- data/lib/ree/contracts/arg_contracts/ksplat.rb +141 -0
- data/lib/ree/contracts/arg_contracts/kwargs.rb +22 -0
- data/lib/ree/contracts/arg_contracts/nilor.rb +16 -0
- data/lib/ree/contracts/arg_contracts/none.rb +15 -0
- data/lib/ree/contracts/arg_contracts/optblock.rb +11 -0
- data/lib/ree/contracts/arg_contracts/or.rb +30 -0
- data/lib/ree/contracts/arg_contracts/range_of.rb +51 -0
- data/lib/ree/contracts/arg_contracts/set_of.rb +54 -0
- data/lib/ree/contracts/arg_contracts/splat.rb +297 -0
- data/lib/ree/contracts/arg_contracts/splat_of.rb +64 -0
- data/lib/ree/contracts/arg_contracts/squarable.rb +11 -0
- data/lib/ree/contracts/arg_contracts/subclass_of.rb +28 -0
- data/lib/ree/contracts/arg_contracts.rb +29 -0
- data/lib/ree/contracts/called_args_validator.rb +291 -0
- data/lib/ree/contracts/contract_definition.rb +142 -0
- data/lib/ree/contracts/contractable.rb +34 -0
- data/lib/ree/contracts/core.rb +17 -0
- data/lib/ree/contracts/engine.rb +71 -0
- data/lib/ree/contracts/engine_proxy.rb +13 -0
- data/lib/ree/contracts/errors/bad_contract_error.rb +4 -0
- data/lib/ree/contracts/errors/contract_error.rb +4 -0
- data/lib/ree/contracts/errors/error.rb +4 -0
- data/lib/ree/contracts/errors/return_contract_error.rb +4 -0
- data/lib/ree/contracts/method_decorator.rb +158 -0
- data/lib/ree/contracts/truncatable.rb +9 -0
- data/lib/ree/contracts/utils.rb +9 -0
- data/lib/ree/contracts/validators/array_validator.rb +51 -0
- data/lib/ree/contracts/validators/base_validator.rb +27 -0
- data/lib/ree/contracts/validators/class_validator.rb +17 -0
- data/lib/ree/contracts/validators/default_validator.rb +20 -0
- data/lib/ree/contracts/validators/hash_validator.rb +100 -0
- data/lib/ree/contracts/validators/proc_validator.rb +17 -0
- data/lib/ree/contracts/validators/range_validator.rb +17 -0
- data/lib/ree/contracts/validators/regexp_validator.rb +17 -0
- data/lib/ree/contracts/validators/valid_validator.rb +28 -0
- data/lib/ree/contracts/validators.rb +42 -0
- data/lib/ree/contracts.rb +45 -0
- data/lib/ree/core/link_validator.rb +42 -0
- data/lib/ree/core/object.rb +132 -0
- data/lib/ree/core/object_error.rb +9 -0
- data/lib/ree/core/object_link.rb +21 -0
- data/lib/ree/core/object_schema.rb +47 -0
- data/lib/ree/core/object_schema_builder.rb +110 -0
- data/lib/ree/core/package.rb +177 -0
- data/lib/ree/core/package_dep.rb +9 -0
- data/lib/ree/core/package_env_var.rb +12 -0
- data/lib/ree/core/package_loader.rb +95 -0
- data/lib/ree/core/package_schema.rb +27 -0
- data/lib/ree/core/package_schema_builder.rb +53 -0
- data/lib/ree/core/package_schema_loader.rb +170 -0
- data/lib/ree/core/packages_detector.rb +43 -0
- data/lib/ree/core/packages_schema.rb +19 -0
- data/lib/ree/core/packages_schema_builder.rb +50 -0
- data/lib/ree/core/packages_schema_loader.rb +95 -0
- data/lib/ree/core/packages_schema_locator.rb +27 -0
- data/lib/ree/core/packages_store.rb +32 -0
- data/lib/ree/core/path_helper.rb +104 -0
- data/lib/ree/dsl/build_package_dsl.rb +155 -0
- data/lib/ree/dsl/domain_error.rb +4 -0
- data/lib/ree/dsl/error_builder.rb +39 -0
- data/lib/ree/dsl/error_dsl.rb +27 -0
- data/lib/ree/dsl/import_dsl.rb +106 -0
- data/lib/ree/dsl/link_import_builder.rb +66 -0
- data/lib/ree/dsl/object_dsl.rb +319 -0
- data/lib/ree/dsl/object_hooks.rb +6 -0
- data/lib/ree/dsl/package_require.rb +44 -0
- data/lib/ree/error.rb +11 -0
- data/lib/ree/facades/packages_facade.rb +197 -0
- data/lib/ree/fn_dsl.rb +24 -0
- data/lib/ree/gen/init.rb +64 -0
- data/lib/ree/gen/package.rb +56 -0
- data/lib/ree/gen.rb +8 -0
- data/lib/ree/handlers/template_handler.rb +118 -0
- data/lib/ree/link_dsl.rb +175 -0
- data/lib/ree/object_compiler.rb +149 -0
- data/lib/ree/package_dsl.rb +34 -0
- data/lib/ree/rspec_link_dsl.rb +19 -0
- data/lib/ree/spec_runner/command_generator.rb +49 -0
- data/lib/ree/spec_runner/command_params.rb +9 -0
- data/lib/ree/spec_runner/runner.rb +200 -0
- data/lib/ree/spec_runner/spec_filename_matcher.rb +27 -0
- data/lib/ree/spec_runner/view.rb +30 -0
- data/lib/ree/spec_runner.rb +11 -0
- data/lib/ree/templates/init/.gitignore +1 -0
- data/lib/ree/templates/init/.irbrc +13 -0
- data/lib/ree/templates/init/.rspec +3 -0
- data/lib/ree/templates/init/.ruby-version +1 -0
- data/lib/ree/templates/init/Gemfile +7 -0
- data/lib/ree/templates/init/Packages.schema.json +1 -0
- data/lib/ree/templates/init/bin/console +5 -0
- data/lib/ree/templates/init/readme.md +2 -0
- data/lib/ree/templates/init/ree.setup.rb +21 -0
- data/lib/ree/templates/init/spec.init.rb +7 -0
- data/lib/ree/templates/package/.gitignore +0 -0
- data/lib/ree/templates/package/.rspec +2 -0
- data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>/.gitkeep +0 -0
- data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>.rb +15 -0
- data/lib/ree/templates/package/Package.schema.json +0 -0
- data/lib/ree/templates/package/bin/console +5 -0
- data/lib/ree/templates/package/spec/package_schema_spec.rb +14 -0
- data/lib/ree/templates/package/spec/spec_helper.rb +3 -0
- data/lib/ree/templates/template_detector.rb +35 -0
- data/lib/ree/templates/template_renderer.rb +55 -0
- data/lib/ree/utils/render_utils.rb +20 -0
- data/lib/ree/utils/string_utils.rb +29 -0
- data/lib/ree/version.rb +5 -0
- data/lib/ree.rb +279 -0
- data/sig/ree.rbs +4 -0
- metadata +199 -0
data/bin/setup
ADDED
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
|
data/lib/ree/bean_dsl.rb
ADDED
|
@@ -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
|
data/lib/ree/cli/init.rb
ADDED
|
@@ -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
|