carioca 1.4 → 2.0.1

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +18 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +3 -0
  5. data/Gemfile +6 -1
  6. data/Gemfile.lock +49 -0
  7. data/README.md +12 -220
  8. data/Rakefile +5 -66
  9. data/bin/console +15 -0
  10. data/bin/setup +8 -0
  11. data/carioca.gemspec +32 -23
  12. data/config/locales/en.yml +15 -0
  13. data/config/locales/fr.yml +19 -0
  14. data/lib/carioca/configuration.rb +47 -0
  15. data/lib/carioca/constants.rb +45 -0
  16. data/lib/carioca/container.rb +16 -0
  17. data/lib/carioca/dependencies.rb +19 -0
  18. data/lib/carioca/helpers.rb +44 -31
  19. data/lib/carioca/mixin.rb +32 -0
  20. data/lib/carioca/{tasks/rake.rb → rake/manage.rb} +2 -4
  21. data/lib/carioca/rake/tasks/registry.tasks +57 -0
  22. data/lib/carioca/registry.rb +93 -0
  23. data/lib/carioca/registry_file.rb +62 -0
  24. data/lib/carioca/services/config.rb +140 -0
  25. data/lib/carioca/services/i18n.rb +20 -0
  26. data/lib/carioca/services/init.rb +2 -0
  27. data/lib/carioca/validator.rb +49 -0
  28. data/lib/carioca.rb +2 -319
  29. data/samples/Rakefile +2 -0
  30. data/samples/config/carioca.registry +22 -0
  31. data/samples/config/locales/en.yml +2 -0
  32. data/samples/config/locales/es.yml +2 -0
  33. data/samples/config/locales/fr.yml +2 -0
  34. data/samples/config/settings.yml +24 -0
  35. data/samples/test.rb +71 -0
  36. metadata +46 -187
  37. data/AUTHORS +0 -8
  38. data/COPYRIGHT +0 -24
  39. data/ChangeLog +0 -10
  40. data/INSTALL +0 -7
  41. data/doc/manual.rdoc +0 -225
  42. data/lib/carioca/exceptions.rb +0 -9
  43. data/lib/carioca/private.rb +0 -168
  44. data/lib/carioca/services/configuration.rb +0 -203
  45. data/lib/carioca/services/debug.rb +0 -71
  46. data/lib/carioca/services/logger.rb +0 -58
  47. data/lib/carioca/services.rb +0 -143
  48. data/lib/carioca/tasks/registry_init.rake +0 -12
  49. data/spec/carioca_spec.rb +0 -468
  50. data/spec/config/.config +0 -14
  51. data/spec/config/services.registry +0 -55
  52. data/spec/init_spec.rb +0 -2
  53. data/spec/samples/dummy.rb +0 -11
  54. data/spec/samples/otherdummy.rb +0 -11
  55. data/spec/samples/requireddummy.rb +0 -11
  56. data/spec/spec_helper.rb +0 -18
  57. data/ultragreen_roodi_coding_convention.yml +0 -25
@@ -0,0 +1,19 @@
1
+ require 'yaml'
2
+ require 'forwardable'
3
+ require 'singleton'
4
+
5
+ require 'rubygems'
6
+ require 'i18n'
7
+ require 'locale'
8
+ require 'deep_merge'
9
+
10
+ require_relative 'constants'
11
+ require_relative 'validator'
12
+ require_relative 'mixin'
13
+ require_relative 'container'
14
+ require_relative 'helpers'
15
+ require_relative 'configuration'
16
+
17
+ require_relative 'registry_file'
18
+ require_relative 'registry'
19
+ require_relative 'services/init'
@@ -1,35 +1,48 @@
1
- # coding: utf-8
2
- #---
3
- # Author : Romain GEORGES
4
- # type : gem component library
5
- # obj : Carioca Helpers definition Module
6
- #---
1
+ module Carioca
2
+ module Helpers
7
3
 
8
- class Class
9
- # Usage:
10
- # prelaod_service :name => 'service', :params => { :arg => 'value'}
11
- def preload_service(_options = {})
12
- Carioca::Services::Registry.init.start_service _options
13
- end
4
+ def log
5
+ return self.get_service name: :logger
6
+ end
14
7
 
15
- def use_configuration(_options = {})
16
- options = Methodic.get_options(_options)
17
- options.specify_classes_of :with_file => String
18
- options.specify_default_value_for :with_file => 'services/registry.yml'
19
- options.merge
20
- options.validate!
21
- Carioca::Services::Registry.init.start_service :name => 'configuration', :params => { :config_file => options[:with_file]}
22
- end
23
- end
8
+ def i18n
9
+ return self.get_service name: :i18n
10
+ end
24
11
 
12
+ def debug(message: )
13
+ log.debug(self.config.name) { "#{message}" }
14
+ end
25
15
 
26
- Module.class_eval do
27
- def init_registry _options={}
28
- options = Methodic.get_options(_options)
29
- options.specify_classes_of :with_file => String
30
- options.specify_default_value_for :with_file => 'services/registry.yml'
31
- options.merge
32
- options.validate!
33
- Carioca::Services::Registry.init :file => options[:with_file]
34
- end
35
- end
16
+ # facility to find a file in gem path
17
+ # @param [String] _gem a Gem name
18
+ # @param [String] _file a file relative path in the gem
19
+ # @return [String] the path of the file, if found.
20
+ # @return [False] if not found
21
+ def search_file_in_gem(_gem,_file)
22
+ if Gem::Specification.respond_to?(:find_by_name)
23
+ begin
24
+ spec = Gem::Specification.find_by_name(_gem)
25
+ rescue LoadError
26
+ spec = nil
27
+ end
28
+ else
29
+ spec = Gem.searcher.find(_gem)
30
+ end
31
+ if spec then
32
+ if Gem::Specification.respond_to?(:find_by_name)
33
+ res = spec.lib_dirs_glob.split('/')
34
+ else
35
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
36
+ end
37
+ res.pop
38
+ services_path = res.join('/').concat("/#{_file}")
39
+ return services_path if File::exist?(services_path)
40
+ return false
41
+ else
42
+ return false
43
+ end
44
+ end
45
+
46
+
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ module Carioca
2
+ module Injector
3
+ def inject(service: )
4
+ self.create_methods(service){return Carioca::Registry.get.get_service name: service }
5
+ end
6
+
7
+ def register(service: , definition:)
8
+ Carioca::Registry.get.add service: service, definition: definition
9
+ end
10
+
11
+ def services
12
+ Carioca::Registry.get.services
13
+ end
14
+
15
+ def active_services
16
+ Carioca::Registry.get.active_services
17
+ end
18
+
19
+ def create_methods(name, &block)
20
+ self.define_method name, &block
21
+ self.class.send(:define_method, name, &block)
22
+ end
23
+
24
+ def self.extended(base)
25
+ base.include self
26
+ end
27
+
28
+
29
+
30
+ end
31
+
32
+ end
@@ -17,7 +17,5 @@ else
17
17
  end
18
18
 
19
19
  res.pop
20
- tasks_path = res.join('/').concat('/lib/carioca/tasks/')
21
-
22
-
23
- Dir["#{tasks_path}/*.rake"].each { |ext| load ext }
20
+ tasks_path = res.join('/').concat('/lib/carioca/rake/tasks/')
21
+ Dir["#{tasks_path}/*.task*"].each { |ext| load ext }
@@ -0,0 +1,57 @@
1
+ require "tty-prompt"
2
+ require "pastel"
3
+
4
+ namespace :carioca do
5
+ namespace :registry do
6
+ desc "Adding service to Carioca Registry file"
7
+ task :add_service do
8
+ begin
9
+ puts "Carioca : registering service :"
10
+ config = Carioca::Configuration::new
11
+ prompt = TTY::Prompt.new
12
+ pastel = Pastel.new
13
+ filename = prompt.ask("Registry File path ?", default: config.filename)
14
+ registry_file = Carioca::RegistryFile::new filename: filename
15
+ name = prompt.ask("Service name ?") { |q| q.required true }.to_sym
16
+ if config.builtins.include? name or registry_file.validated.include? name then
17
+ puts 'Carioca : service already defined or Builtins'
18
+ exit 1
19
+ end
20
+ definition = {
21
+ :type => prompt.select("Choose the service type ?", [:gem, :stdlib, :file, :internal]),
22
+ :description => prompt.ask("Description ?", default: "The #{name} service"),
23
+ :service => prompt.ask("Service [#{name}] inline Proc Ruby code ?", default: name.to_s.capitalize)
24
+ }
25
+ map = {:gem => "Rubygem name", :stdlib => "StdLib name", :file => "absolut path of the Ruby file"}
26
+ definition[:resource] = prompt.ask("Give the #{map[definition[:type]]} ? ", default: name.to_s ) if map.keys.include? definition[:type]
27
+ have_depends = prompt.yes?("Did this service have dependencies ? ")
28
+ if have_depends then
29
+ potentials = config.builtins.merge(registry_file.validated).keys
30
+ definition[:depends] = prompt.multi_select("Choose your depends ?", potentials, min: 1)
31
+ end
32
+ puts "\n => Service : #{name}"
33
+ puts "Definition "
34
+ definition.each do |key,value|
35
+ puts " * #{key}: #{value}"
36
+ end
37
+ is_correct = prompt.yes?("Is it correct ? ")
38
+ rescue TTY::Reader::InputInterrupt
39
+ puts 'Carioca : interrupted'
40
+ exit 5
41
+ end
42
+ if is_correct then
43
+ begin
44
+ registry_file.add service: name, definition: definition
45
+ registry_file.save!
46
+ rescue => e
47
+ puts "Carioca: Can't save : #{e}"
48
+ exit 10
49
+ end
50
+
51
+ puts "Carioca : Registry saved"
52
+ else
53
+ puts 'Carioca : Nothing saved'
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,93 @@
1
+ module Carioca
2
+ class Registry
3
+ include Carioca::Helpers
4
+ include Singleton
5
+ @@config = Configuration::new
6
+
7
+ def Registry.config
8
+ return @@config
9
+ end
10
+
11
+ def Registry.configure(&block)
12
+ yield(@@config)
13
+ end
14
+
15
+ class << self
16
+ alias_method :get, :instance
17
+ alias_method :init, :instance
18
+
19
+ end
20
+
21
+ attr_accessor :services
22
+ attr_accessor :active_services
23
+
24
+ def get_service(name: )
25
+
26
+ raise "Service not found: #{name}" unless @services.include? name
27
+ if @active_services.include? name then
28
+ debug message: i18n.t('service.getting', name: name) if @active_services.include? :logger and ![:logger, :i18n].include? name and @@config.debug?
29
+ else
30
+ service = @services[name]
31
+ service[:depends].each do|dep|
32
+ debug message: i18n.t('service.depends', name: dep) if @active_services.include? :logger and ![:logger, :i18n].include? dep and @@config.debug?
33
+ get_service(name: dep) unless @active_services.include? dep
34
+ end if service.include? :depends
35
+ debug message: i18n.t('service.starting', name: name) if @active_services.include? :logger and ![:logger, :i18n].include? name and @@config.debug?
36
+ require service[:resource] if [:gem, :file, :stdlib].include? service[:type]
37
+ @active_services[name] ||= eval("lambda { #{service[:service]} }").call
38
+ end
39
+ return @active_services[name]
40
+ end
41
+
42
+ def config
43
+ return @@config
44
+ end
45
+
46
+ def add(service: , definition:, skip_validation: false )
47
+ mess =
48
+ raise "Service #{service} already exist." if @services.include? service and skip_validation == false
49
+ debug message: i18n.t('service.adding', name: service) if @active_services.include? :logger and @@config.debug?
50
+ checker = Carioca::Services::Validator::new service: service , definition: definition
51
+ checker.validate! unless skip_validation
52
+ @services[service] = checker.definition
53
+ end
54
+
55
+ private
56
+ def prepare_logger
57
+ conf_i18n = @@config.builtins[:i18n]
58
+ add service: :i18n, definition: @@config.builtins[:i18n], skip_validation: true
59
+ conf_logger = @@config.builtins[:logger]
60
+ conf_logger[:service] = @@config.log_target
61
+ add service: :logger, definition: @@config.builtins[:logger], skip_validation: true
62
+ get_service name: :logger
63
+ end
64
+
65
+ def initialize
66
+ @services = Hash::new
67
+ @active_services = Hash::new
68
+ prepare_logger
69
+ locale = @@config.default_locale
70
+ target = (@@config.log_file?)? @@config.log_file : "STDOUT"
71
+ debug message: i18n.t('notify.locale', loc: locale) if @@config.debug?
72
+ debug message: i18n.t('notify.logger', target: target) if @@config.debug?
73
+ debug message: i18n.t('init.carioca') if @@config.debug?
74
+ debug message: i18n.t('init.builtins') if @@config.debug?
75
+ @@config.builtins.each do |service, spec|
76
+ add service: service, definition: spec, skip_validation: true unless service == :logger
77
+ end
78
+ open_registry_file if File::exist? @@config.filename and @@config.init_from_file?
79
+ end
80
+
81
+ def open_registry_file
82
+ debug message: i18n.t('init.registry.processing', filename: @@config.filename) if @@config.debug?
83
+ registry_file = Carioca::RegistryFile::new filename: @@config.filename
84
+ debug message: i18n.t('notify.useless_entry', altered: registry_file.altered.to_s, filename: @@config.filename ) if registry_file.altered? and @@config.debug?
85
+ registry_file.validated.each do |service,spec|
86
+ add service: service, definition: spec
87
+ end
88
+ debug message: i18n.t('init.registry.processing') if @@config.debug?
89
+ end
90
+
91
+
92
+ end
93
+ end
@@ -0,0 +1,62 @@
1
+ module Carioca
2
+
3
+
4
+
5
+
6
+ class RegistryFile
7
+
8
+ attr_accessor :validated, :altered
9
+ include Carioca::Constants
10
+
11
+ def initialize(filename:)
12
+ @filename = filename
13
+ @candidates = Hash::new
14
+ @validated = Hash::new
15
+ @altered = []
16
+ open
17
+ end
18
+
19
+ def altered?
20
+ return !@altered.empty?
21
+ end
22
+
23
+ def create!(force: false)
24
+ write_ok = true
25
+ write_ok = force if File::exist? @filename
26
+ File.open(@filename, 'w') { |file| file.write(@validated.to_yaml) } if write_ok
27
+ end
28
+
29
+ def save!
30
+ create! force: true
31
+ end
32
+
33
+ def add(service:, definition: )
34
+ checker = Carioca::Services::Validator::new service: service , definition: definition
35
+ checker.validate!
36
+ @validated[service] = checker.definition
37
+ end
38
+
39
+ def open
40
+ if File::exist?(@filename) then
41
+ @candidates = YAML.load_file(@filename)
42
+ else
43
+ create!
44
+ end
45
+ prepare!
46
+ end
47
+
48
+ private
49
+ def prepare!
50
+ save = @candidates.dup
51
+ @candidates.delete_if {|key, value| BUILTINS.keys.include? key }
52
+ @altered = save.keys - @candidates.keys
53
+ @candidates.each do |service, definition|
54
+ checker = Carioca::Services::Validator::new service: service , definition: definition
55
+ checker.validate!
56
+ @validated[service] = checker.definition
57
+ end
58
+ end
59
+
60
+
61
+ end
62
+ end
@@ -0,0 +1,140 @@
1
+ class Hash
2
+ # monkey patching
3
+ def deep_symbolize
4
+ target = dup
5
+ target.inject({}) do |memo, (key, value)|
6
+ value = value.deep_symbolize if value.is_a?(Hash)
7
+ memo[key.to_sym] = value
8
+ memo
9
+ end
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ if name.to_s =~ /(.+)=$/
14
+ self[$1.to_sym] = args.first
15
+ else
16
+ self[name.to_sym]
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+
23
+
24
+ module Carioca
25
+ module Services
26
+ module Config
27
+
28
+ class ConfigFile
29
+ include Carioca::Constants
30
+ attr_accessor :filename, :data
31
+ attr_reader :error
32
+
33
+ def initialize(filename:)
34
+ @filename = filename
35
+ @data = {}
36
+ @error = ""
37
+ open
38
+
39
+ end
40
+
41
+ def error?
42
+ return !@error.empty?
43
+ end
44
+
45
+ def create!(force: false)
46
+ write_ok = true
47
+ write_ok = force if File::exist? @filename
48
+ File.open(@filename, 'w') { |file| file.write(@data.to_yaml) } if write_ok
49
+ end
50
+
51
+ def open
52
+ if File::exist?(@filename) then
53
+ begin
54
+ @data = YAML.load_file(@filename)
55
+ rescue Exception => e
56
+ @error = e.message
57
+ @data = {}
58
+ end
59
+ end
60
+ prepare!
61
+ end
62
+
63
+ private
64
+ def prepare!
65
+ config = Carioca::Registry.config
66
+ @data = {} unless @data.class == Hash
67
+ @data.delete_if {|key,value| config.config_root != key }
68
+ @data[config.config_root] = {} unless @data.include? config.config_root
69
+ config.supported_environment.each do |evt|
70
+ @data[config.config_root][evt] = {} unless @data[config.config_root].include? evt
71
+ end
72
+ @data[config.config_root][:default] = {} unless @data[config.config_root].include? :default
73
+ create!
74
+ end
75
+
76
+ end
77
+ class Settings < Hash
78
+
79
+ attr_accessor :config_file
80
+ attr_accessor :stage
81
+
82
+ include Carioca::Helpers
83
+
84
+ def initialize(config_filename: , stage:, root:)
85
+ registry = Carioca::Registry.get
86
+ @logger = registry.get_service name: :logger
87
+ @i18n = registry.get_service name: :i18n
88
+
89
+ @stage = stage
90
+ @root = root
91
+ @config_file = Carioca::Services::Config::ConfigFile::new filename: config_filename
92
+ initconf
93
+ end
94
+
95
+ def refresh
96
+ initconf
97
+ end
98
+
99
+
100
+
101
+ private
102
+ def initconf
103
+ newsets = {}
104
+ @logger.debug("Carioca->Config") { @i18n.t('config.load.error', message: @config_file.error) } if @config_file.error?
105
+ @content = @config_file.data
106
+
107
+ unless @stage then
108
+ newsets = @content
109
+ else
110
+ self.merge! @content[@root][:default]
111
+ data = @content[@root][@stage]
112
+ self.deep_merge! data
113
+
114
+ end
115
+
116
+
117
+ end
118
+
119
+
120
+ end
121
+
122
+
123
+
124
+ class Factory
125
+ extend Forwardable
126
+
127
+ attr_accessor :settings
128
+ def_delegators :@settings, :refresh
129
+
130
+
131
+ def initialize(**keywords)
132
+ @settings = Carioca::Services::Config::Settings.new(**keywords)
133
+ end
134
+
135
+ end
136
+ end
137
+
138
+ end
139
+ end
140
+
@@ -0,0 +1,20 @@
1
+ module Carioca
2
+ module Services
3
+ class I18n
4
+
5
+ def I18n.get(default_locale: , load_path:, locales_availables: )
6
+ ::I18n::Backend::Simple.include(::I18n::Backend::Fallbacks)
7
+ ::I18n.load_path << load_path
8
+ ::I18n.default_locale = default_locale
9
+ ::I18n.fallbacks = locales_availables
10
+ return ::I18n
11
+ end
12
+
13
+ def I18n.get_system_locale
14
+ return ::Locale.candidates.to_s.split('_').first.to_sym
15
+ end
16
+
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: UTF-8
2
+ Dir[File.dirname(__FILE__) + '/*.rb'].sort.each {|file| require file unless File.basename(file) == 'init.rb'}
@@ -0,0 +1,49 @@
1
+ module Carioca
2
+ module Services
3
+ class Validator
4
+
5
+ attr_reader :definition
6
+
7
+ include Carioca::Constants
8
+
9
+ def initialize(definition: , service: )
10
+ @definition = definition
11
+ @service = service
12
+ end
13
+
14
+ def validate!
15
+ validate_mandatories
16
+ validate_full_and_type
17
+ validate_not_builtins
18
+ fill_content
19
+ end
20
+
21
+ private
22
+ def validate_not_builtins
23
+
24
+ raise "Builtins reserved name #{@service.to_s}" if BUILTINS.keys.include? @service
25
+ end
26
+
27
+ def validate_mandatories
28
+ SERVICES_MANDATORY_SPECS.keys.each do |spec|
29
+ raise "Key : :#{spec} is mandatory in a service definition" unless @definition.include? spec
30
+ end
31
+ end
32
+
33
+ def validate_full_and_type
34
+ @definition.each do |spec,value|
35
+ raise "Key : :#{spec} is not allowed in a service definition" unless SERVICES_FULL_LIST_SPECS.include? spec
36
+ raise "key : #{spec} must be a : #{SERVICES_FULL_LIST_SPECS[spec].to_s}" unless value.class == SERVICES_FULL_LIST_SPECS[spec]
37
+ if SERVICES_SPECS_DETAIL.include? spec then
38
+ raise "key : #{spec} must be in : #{SERVICES_SPECS_DETAIL[spec].to_s}" unless SERVICES_SPECS_DETAIL[spec].include? value
39
+ end
40
+ end
41
+ end
42
+
43
+ def fill_content
44
+ @definition[:description] = @service.to_s unless @definition.include? :description
45
+ end
46
+
47
+ end
48
+ end
49
+ end