carioca 1.4 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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