mona 0.2.3
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/.ruby-version +1 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +193 -0
- data/Rakefile +8 -0
- data/example/Gemfile +1 -0
- data/example/Gemfile.lock +51 -0
- data/example/Monafile.rb +16 -0
- data/example/bounded_contexts/cart/cart_app/Package.rb +11 -0
- data/example/bounded_contexts/cart/cart_app/bin/console +11 -0
- data/example/bounded_contexts/cart/cart_app/package/cart_app.rb +2 -0
- data/example/bounded_contexts/cart/cart_core/Package.rb +12 -0
- data/example/bounded_contexts/cart/cart_core/bin/console +9 -0
- data/example/bounded_contexts/cart/cart_core/package/cart_core.rb +2 -0
- data/example/bounded_contexts/cart/cart_datasets/Package.rb +10 -0
- data/example/bounded_contexts/cart/cart_datasets/bin/console +9 -0
- data/example/bounded_contexts/cart/cart_datasets/package/cart_datasets.rb +2 -0
- data/example/bounded_contexts/orders/orders_app/Package.rb +12 -0
- data/example/bounded_contexts/orders/orders_app/bin/console +9 -0
- data/example/bounded_contexts/orders/orders_app/package/orders_app.rb +2 -0
- data/example/bounded_contexts/orders/orders_core/Package.rb +13 -0
- data/example/bounded_contexts/orders/orders_core/bin/console +9 -0
- data/example/bounded_contexts/orders/orders_core/package/orders_core.rb +2 -0
- data/example/bounded_contexts/orders/orders_datasets/Package.rb +11 -0
- data/example/bounded_contexts/orders/orders_datasets/bin/console +9 -0
- data/example/bounded_contexts/orders/orders_datasets/package/orders_datasets.rb +2 -0
- data/example/bounded_contexts/orders/orders_query_api/Package.rb +13 -0
- data/example/bounded_contexts/orders/orders_query_api/bin/console +9 -0
- data/example/bounded_contexts/orders/orders_query_api/package/cart_query_api.rb +2 -0
- data/example/bounded_contexts/orders/paypal_client/Package.rb +9 -0
- data/example/bounded_contexts/orders/paypal_client/bin/console +9 -0
- data/example/bounded_contexts/orders/paypal_client/package/paypal_client.rb +2 -0
- data/example/bounded_contexts/shared/db_connection/Package.rb +10 -0
- data/example/bounded_contexts/shared/db_connection/bin/console +9 -0
- data/example/bounded_contexts/shared/db_connection/package/db_connection.rb +2 -0
- data/example/bounded_contexts/shared/test_utils/Package.rb +9 -0
- data/example/bounded_contexts/shared/test_utils/bin/console +9 -0
- data/example/bounded_contexts/shared/test_utils/package/test_utils.rb +2 -0
- data/example/bounded_contexts/storefront/storefront_app/Package.rb +11 -0
- data/example/bounded_contexts/storefront/storefront_app/bin/console +9 -0
- data/example/bounded_contexts/storefront/storefront_app/package/storefront_app.rb +2 -0
- data/example/bounded_contexts/storefront/storefront_core/Package.rb +11 -0
- data/example/bounded_contexts/storefront/storefront_core/bin/console +9 -0
- data/example/bounded_contexts/storefront/storefront_core/package/storefront_core.rb +2 -0
- data/example/bounded_contexts/storefront/storefront_datasets/Package.rb +11 -0
- data/example/bounded_contexts/storefront/storefront_datasets/bin/console +9 -0
- data/example/bounded_contexts/storefront/storefront_datasets/package/storefront_datasets.rb +2 -0
- data/example/configs/cart_app/default.yml +4 -0
- data/example/configs/cart_app/test.yml +3 -0
- data/example/configs/orders_app/default.yml +4 -0
- data/example/configs/orders_app/test.yml +2 -0
- data/exe/mona +15 -0
- data/lib/mona/config/loader.rb +74 -0
- data/lib/mona/config/manager.rb +20 -0
- data/lib/mona/config.rb +23 -0
- data/lib/mona/loaders/base.rb +63 -0
- data/lib/mona/loaders/zeitwerk.rb +77 -0
- data/lib/mona/package/builder.rb +27 -0
- data/lib/mona/package/dependency_bypasser.rb +43 -0
- data/lib/mona/package/factory.rb +95 -0
- data/lib/mona/package/find_root.rb +33 -0
- data/lib/mona/package/indexer.rb +30 -0
- data/lib/mona/package/initializer.rb +46 -0
- data/lib/mona/package/list.rb +10 -0
- data/lib/mona/package/repo.rb +63 -0
- data/lib/mona/package.rb +51 -0
- data/lib/mona/project/builder.rb +20 -0
- data/lib/mona/project/factory.rb +115 -0
- data/lib/mona/project/find_root.rb +31 -0
- data/lib/mona/project/initializer.rb +26 -0
- data/lib/mona/project.rb +43 -0
- data/lib/mona/task/manager.rb +36 -0
- data/lib/mona/task.rb +21 -0
- data/lib/mona/version.rb +5 -0
- data/lib/mona.rb +110 -0
- data/mona.gemspec +54 -0
- data/sig/mona.rbs +4 -0
- metadata +296 -0
data/exe/mona
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "mona"
|
6
|
+
require "thor"
|
7
|
+
|
8
|
+
class MonaCli < Thor
|
9
|
+
desc "mona cd PACKAGE", "go to PACKAGE"
|
10
|
+
def cd(package)
|
11
|
+
puts "cd #{Mona.packages(File.expand_path(".")).find(package.to_sym).root_path}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
MonaCli.start(ARGV)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
class Mona::Config::Loader
|
6
|
+
include Mona::Mixins
|
7
|
+
|
8
|
+
DEFAULT_CONFIG_FILENAME = 'default.yml'
|
9
|
+
|
10
|
+
sig do
|
11
|
+
params(
|
12
|
+
config_name: T.any(String, Symbol),
|
13
|
+
)
|
14
|
+
.returns(Mona::Config)
|
15
|
+
end
|
16
|
+
def call(config_name)
|
17
|
+
config_name = config_name.to_s
|
18
|
+
config = Mona::Config.new
|
19
|
+
|
20
|
+
default_config_filename = File.join(
|
21
|
+
Mona.current_project.root_path,
|
22
|
+
Mona.current_project.configs_dir,
|
23
|
+
config_name,
|
24
|
+
DEFAULT_CONFIG_FILENAME
|
25
|
+
)
|
26
|
+
|
27
|
+
unless File.exist?(default_config_filename)
|
28
|
+
raise StandardError.new("Config '#{config_name}' was not found. Add it to '#{default_config_filename}'")
|
29
|
+
end
|
30
|
+
|
31
|
+
hash =
|
32
|
+
begin
|
33
|
+
YAML.load( ERB.new(File.read(default_config_filename)).result )
|
34
|
+
rescue => e
|
35
|
+
puts ERB.new(File.read(default_config_filename)).result.inspect
|
36
|
+
end
|
37
|
+
|
38
|
+
hash_to_config(
|
39
|
+
hash: hash,
|
40
|
+
config: config
|
41
|
+
)
|
42
|
+
|
43
|
+
env_config_filename = File.join(
|
44
|
+
Mona.current_project.root_path,
|
45
|
+
Mona.current_project.configs_dir,
|
46
|
+
config_name,
|
47
|
+
"#{Mona.current_project.env}.yml"
|
48
|
+
)
|
49
|
+
|
50
|
+
hash_to_config(
|
51
|
+
hash: YAML.load( ERB.new(File.read(env_config_filename)).result ),
|
52
|
+
config: config
|
53
|
+
) if File.exist?(env_config_filename)
|
54
|
+
|
55
|
+
config.send(config_name)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def hash_to_config(hash:, config:)
|
61
|
+
hash.each do |key, value|
|
62
|
+
if value.is_a?(Hash)
|
63
|
+
nested_config = config.read_attribute(key)
|
64
|
+
if nested_config.nil? || !nested_config.is_a?(Mona::Config)
|
65
|
+
nested_config = Mona::Config.new
|
66
|
+
end
|
67
|
+
hash_to_config(hash: value, config: nested_config)
|
68
|
+
config.write_attribute(key, nested_config)
|
69
|
+
else
|
70
|
+
config.write_attribute(key, value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Mona::Config::Manager
|
2
|
+
include Mona::Mixins
|
3
|
+
|
4
|
+
Inject = Mona::Deps[
|
5
|
+
config_loader: "config.loader"
|
6
|
+
]
|
7
|
+
|
8
|
+
include Inject
|
9
|
+
|
10
|
+
sig do
|
11
|
+
params(
|
12
|
+
method_name: Symbol,
|
13
|
+
args: T.anything
|
14
|
+
)
|
15
|
+
.returns(Mona::Config)
|
16
|
+
end
|
17
|
+
def method_missing(method_name, *args)
|
18
|
+
config_loader.call(method_name)
|
19
|
+
end
|
20
|
+
end
|
data/lib/mona/config.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Mona::Config
|
2
|
+
def initialize(attributes = {})
|
3
|
+
@attributes = attributes
|
4
|
+
end
|
5
|
+
|
6
|
+
def read_attribute(key)
|
7
|
+
@attributes[key.to_s]
|
8
|
+
end
|
9
|
+
|
10
|
+
def write_attribute(key, value)
|
11
|
+
@attributes[key.to_s] = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method_name, *_args)
|
15
|
+
read_attribute(method_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_h
|
19
|
+
@attributes.each_with_object({}) do |(k, v), h|
|
20
|
+
h[k] = self.class === v ? v.to_h : v
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Mona::Loaders::Base
|
2
|
+
include Mona::Mixins
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def registry
|
6
|
+
@registry ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def inherited(subclass)
|
10
|
+
name = subclass.to_s.split("::").last.downcase.to_sym
|
11
|
+
|
12
|
+
registry[name] = subclass
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :overwriters, :inflections, :ignore_dirs, :autoload_dirs, :loader, :root_path
|
17
|
+
|
18
|
+
def initialize(root_path, &block)
|
19
|
+
@root_path = root_path
|
20
|
+
@overwriters = []
|
21
|
+
@inflections = {}
|
22
|
+
@ignore_dirs = []
|
23
|
+
@autoload_dirs = []
|
24
|
+
|
25
|
+
instance_exec(&block) if block_given?
|
26
|
+
end
|
27
|
+
|
28
|
+
def push_dir(dir)
|
29
|
+
@autoload_dirs.push(dir)
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup
|
33
|
+
raise StandardError.new('not implemented')
|
34
|
+
end
|
35
|
+
|
36
|
+
def reload
|
37
|
+
raise StandardError.new('not implemented')
|
38
|
+
end
|
39
|
+
|
40
|
+
def eager_load
|
41
|
+
raise StandardError.new('not implemented')
|
42
|
+
end
|
43
|
+
|
44
|
+
def check_classes
|
45
|
+
raise StandardError.new('not implemented')
|
46
|
+
end
|
47
|
+
|
48
|
+
module SetupDsl
|
49
|
+
def inflect(hash)
|
50
|
+
@inflections.merge!(hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def overwrite(proc)
|
54
|
+
overwriters.push(proc)
|
55
|
+
end
|
56
|
+
|
57
|
+
def ignore(glob)
|
58
|
+
@ignore_dirs.push(glob)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
include SetupDsl
|
63
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'zeitwerk'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
class Mona::Loaders::Zeitwerk < Mona::Loaders::Base
|
5
|
+
include Mona::Mixins
|
6
|
+
|
7
|
+
ERROR_MESSAGE_REGEX = /expected file (?<path>[\w\/]+.rb) to define constant (?<klass>[\w:]+)/
|
8
|
+
|
9
|
+
def initialize(...)
|
10
|
+
@loader = Zeitwerk::Loader.new
|
11
|
+
@loader.inflector = Class.new(Zeitwerk::Inflector).new
|
12
|
+
|
13
|
+
super(...)
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
apply_rules_for(@loader)
|
18
|
+
@loader.setup
|
19
|
+
end
|
20
|
+
|
21
|
+
def eager_load
|
22
|
+
time = Benchmark.realtime do
|
23
|
+
@loader.eager_load
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "eager_load dependencies in #{'%.2f' % time} seconds"
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_classes
|
30
|
+
check_classes_loader = @loader.dup
|
31
|
+
check_classes_loader.on_load { |cpath, value, abspath| puts value }
|
32
|
+
|
33
|
+
errors = []
|
34
|
+
|
35
|
+
begin
|
36
|
+
check_classes_loader.eager_load
|
37
|
+
rescue Zeitwerk::NameError => e
|
38
|
+
match = e.message.match(ERROR_MESSAGE_REGEX)
|
39
|
+
|
40
|
+
raise e if match.nil?
|
41
|
+
|
42
|
+
# TODO: use logger
|
43
|
+
errors << "#{match[:path]} => #{match[:klass]}"
|
44
|
+
check_classes_loader.ignore(match[:path])
|
45
|
+
retry
|
46
|
+
end
|
47
|
+
|
48
|
+
puts errors
|
49
|
+
raise StandardError.new("loader fails with #{errors.count} errors") if errors.any?
|
50
|
+
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def apply_rules_for(entity)
|
55
|
+
@autoload_dirs.uniq.each { entity.push_dir(_1) }
|
56
|
+
@ignore_dirs.uniq
|
57
|
+
.map { File.join(Mona.current_project.root_path, _1) }
|
58
|
+
.each { entity.ignore( _1 ) }
|
59
|
+
|
60
|
+
entity.inflector.inflect(@inflections)
|
61
|
+
|
62
|
+
result_overwriter = ->(kname) { @overwriters.each { |o| kname = o.call(kname) }; kname }
|
63
|
+
entity.inflector.define_singleton_method(:camelize) do |basename, abspath|
|
64
|
+
result_overwriter.call( super(basename, abspath) )
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ignore(glob)
|
69
|
+
super(glob)
|
70
|
+
|
71
|
+
# TODO: if loader.setup is true => push dir directly to the @loader
|
72
|
+
@ignore_dirs
|
73
|
+
.uniq
|
74
|
+
.map { File.join(root_path, _1) }
|
75
|
+
.each { @loader.ignore( _1 ) }
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Mona::Package::Builder
|
2
|
+
include Mona::Mixins
|
3
|
+
|
4
|
+
Inject = Mona::Deps[
|
5
|
+
"package.find_root",
|
6
|
+
"package.factory"
|
7
|
+
]
|
8
|
+
|
9
|
+
include Inject
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
package_path: String,
|
14
|
+
project_root: String,
|
15
|
+
package_dirname: String
|
16
|
+
)
|
17
|
+
.returns(Mona::Package)
|
18
|
+
end
|
19
|
+
def call(package_path, project_root, package_dirname)
|
20
|
+
package_root_path = find_root.call(package_path, project_root)
|
21
|
+
package_file_path = "#{package_root_path}/#{Mona::PACKAGE_FILENAME}"
|
22
|
+
|
23
|
+
package_init_proc = proc { instance_eval(File.read(package_file_path)) }
|
24
|
+
|
25
|
+
package = factory.call(package_root_path, package_dirname, init_proc: package_init_proc)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
class Mona::Package::DependencyBypasser
|
4
|
+
include Mona::Mixins
|
5
|
+
|
6
|
+
Inject = Mona::Deps[
|
7
|
+
packages_repo: "package.repo"
|
8
|
+
]
|
9
|
+
|
10
|
+
include Inject
|
11
|
+
|
12
|
+
sig do
|
13
|
+
params(
|
14
|
+
package_name: Symbol,
|
15
|
+
env: Symbol,
|
16
|
+
)
|
17
|
+
.returns(T::Array[Symbol])
|
18
|
+
end
|
19
|
+
def call(package_name:, env:)
|
20
|
+
walk(package_name: package_name, env: env, imported: Set.new)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def walk(package_name:, env:, imported:, packages_order: [])
|
26
|
+
package = packages_repo.find!(package_name)
|
27
|
+
|
28
|
+
return if !imported.add?(package_name)
|
29
|
+
|
30
|
+
package_dependencies = package.get_dependencies(env)
|
31
|
+
|
32
|
+
package_dependencies.each do |name|
|
33
|
+
walk(
|
34
|
+
package_name: name,
|
35
|
+
imported: imported,
|
36
|
+
packages_order: packages_order,
|
37
|
+
env: Mona::Package::DEFAULT_ENV,
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
packages_order.push(package_name)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class Mona::Package::Factory
|
3
|
+
include Mona::Mixins
|
4
|
+
|
5
|
+
sig do
|
6
|
+
params(
|
7
|
+
package_root: String,
|
8
|
+
package_dirname: String,
|
9
|
+
init_proc: T.proc.params(args: T.anything).returns(T.anything)
|
10
|
+
)
|
11
|
+
.returns(Mona::Package)
|
12
|
+
end
|
13
|
+
def call(package_root, package_dirname, init_proc:)
|
14
|
+
@dependencies = Hash.new { |h, k| h[k] = [] }
|
15
|
+
@current_env = Mona::Package::DEFAULT_ENV
|
16
|
+
|
17
|
+
instance_exec(&init_proc)
|
18
|
+
|
19
|
+
package = Mona::Package.new(
|
20
|
+
name: @name,
|
21
|
+
root_path: package_root,
|
22
|
+
package_dirname: package_dirname,
|
23
|
+
dependencies: @dependencies
|
24
|
+
).tap { check_duplicate_dependencies(_1) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def check_duplicate_dependencies(package)
|
30
|
+
package.get_dependency_envs.each do |env|
|
31
|
+
already_imported = package
|
32
|
+
.get_dependencies(env)
|
33
|
+
.group_by{ |e| e }
|
34
|
+
.select { |k, v| v.size > 1 }
|
35
|
+
.keys
|
36
|
+
|
37
|
+
if already_imported.any?
|
38
|
+
puts "WARNING: duplicated import for following packages #{already_imported.inspect} was already added for package '#{package.name}' for env '#{env}'"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
sig do
|
44
|
+
params(
|
45
|
+
env: Symbol,
|
46
|
+
block: T.proc.params(args: T.anything).returns(T.anything)
|
47
|
+
)
|
48
|
+
.void
|
49
|
+
end
|
50
|
+
def dependency(env = Mona::Package::DEFAULT_ENV, &block)
|
51
|
+
@current_env = env
|
52
|
+
instance_eval(&block)
|
53
|
+
@current_env = Mona::Package::DEFAULT_ENV
|
54
|
+
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
sig do
|
59
|
+
params(
|
60
|
+
package_name: T.any(Symbol, String),
|
61
|
+
)
|
62
|
+
.void
|
63
|
+
end
|
64
|
+
def import(package_name)
|
65
|
+
package_name = package_name.to_sym
|
66
|
+
|
67
|
+
@dependencies[@current_env] << package_name
|
68
|
+
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
sig do
|
73
|
+
params(
|
74
|
+
block: T.proc.params(args: T.anything).returns(T.anything)
|
75
|
+
)
|
76
|
+
.void
|
77
|
+
end
|
78
|
+
def package(&block)
|
79
|
+
instance_exec(&block)
|
80
|
+
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
sig do
|
85
|
+
params(
|
86
|
+
value: T.any(String, Symbol)
|
87
|
+
)
|
88
|
+
.void
|
89
|
+
end
|
90
|
+
def name(value)
|
91
|
+
@name = value.to_sym
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Mona::Package::FindRoot
|
2
|
+
include Mona::Mixins
|
3
|
+
|
4
|
+
SYSTEM_ROOT = '/'
|
5
|
+
|
6
|
+
sig do
|
7
|
+
params(
|
8
|
+
dir: String,
|
9
|
+
project_root: T.nilable(String),
|
10
|
+
)
|
11
|
+
.returns(String)
|
12
|
+
end
|
13
|
+
def call(dir, project_root)
|
14
|
+
init_dir = dir = File.expand_path(dir)
|
15
|
+
project_root = File.expand_path(project_root || SYSTEM_ROOT)
|
16
|
+
|
17
|
+
unless File.exist?(init_dir)
|
18
|
+
raise StandardError.new("path '#{init_dir}' does not exist")
|
19
|
+
end
|
20
|
+
|
21
|
+
loop do
|
22
|
+
project_file_path = File.expand_path(File.join(dir, Mona::PACKAGE_FILENAME))
|
23
|
+
|
24
|
+
if File.exist?(project_file_path)
|
25
|
+
return dir
|
26
|
+
elsif dir == project_root
|
27
|
+
raise StandardError.new("Package.rb for path '#{init_dir}' not found")
|
28
|
+
else
|
29
|
+
dir = File.expand_path("../", dir)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Mona::Package::Indexer
|
2
|
+
include Mona::Mixins
|
3
|
+
|
4
|
+
Inject = Mona::Deps[
|
5
|
+
"package.builder",
|
6
|
+
]
|
7
|
+
|
8
|
+
include Inject
|
9
|
+
|
10
|
+
sig do
|
11
|
+
params(
|
12
|
+
packages_lookup_subdir: String,
|
13
|
+
project_root: String,
|
14
|
+
package_dirname: String
|
15
|
+
)
|
16
|
+
.returns(T::Array[Mona::Package])
|
17
|
+
end
|
18
|
+
def call(packages_lookup_subdir, project_root, package_dirname)
|
19
|
+
packages_path = File.join(
|
20
|
+
project_root,
|
21
|
+
packages_lookup_subdir,
|
22
|
+
"**",
|
23
|
+
Mona::PACKAGE_FILENAME
|
24
|
+
)
|
25
|
+
|
26
|
+
Dir[packages_path].map do |package_file_path|
|
27
|
+
builder.call(package_file_path, project_root, package_dirname)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
class Mona::Package::Initializer
|
4
|
+
include Mona::Mixins
|
5
|
+
|
6
|
+
Inject = Mona::Deps[
|
7
|
+
"package.dependency_bypasser",
|
8
|
+
"package.repo"
|
9
|
+
]
|
10
|
+
|
11
|
+
include Inject
|
12
|
+
|
13
|
+
sig do
|
14
|
+
params(
|
15
|
+
package_name: T.any(Symbol, String),
|
16
|
+
env: Symbol,
|
17
|
+
prevent_eager_load: T::Boolean
|
18
|
+
)
|
19
|
+
.void
|
20
|
+
end
|
21
|
+
def call(package_name, env:, prevent_eager_load: false)
|
22
|
+
package = repo.find!(package_name.to_sym)
|
23
|
+
sorted_packages = nil
|
24
|
+
|
25
|
+
time = Benchmark.realtime do
|
26
|
+
sorted_packages = dependency_bypasser
|
27
|
+
.call(package_name: package.name, env: env)
|
28
|
+
.map { |name| repo.find(name) }
|
29
|
+
|
30
|
+
sorted_packages.each do |sorted_package|
|
31
|
+
Mona.current_project.loader.push_dir(sorted_package.workdir_path)
|
32
|
+
Mona.current_project.loader.loader.do_not_eager_load(sorted_package.workdir_path) if prevent_eager_load
|
33
|
+
end
|
34
|
+
|
35
|
+
Mona.current_project.loader.setup
|
36
|
+
|
37
|
+
sorted_packages.each do |package|
|
38
|
+
require package.entrypoint_file if File.exist?(package.entrypoint_file)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "imported package '#{package_name}' with #{sorted_packages.size} dependencies in #{'%.2f' % time} seconds for env: #{env}"
|
43
|
+
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|