tty-config 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +103 -18
  4. data/lib/tty/config.rb +66 -129
  5. data/lib/tty/config/dependency_loader.rb +55 -0
  6. data/lib/tty/config/generator.rb +57 -0
  7. data/lib/tty/config/marshaller.rb +56 -0
  8. data/lib/tty/config/marshaller_registry.rb +43 -0
  9. data/lib/tty/config/marshallers.rb +35 -0
  10. data/lib/tty/config/marshallers/hcl_marshaller.rb +25 -0
  11. data/lib/tty/config/marshallers/ini_marshaller.rb +28 -0
  12. data/lib/tty/config/marshallers/java_props_marshaller.rb +25 -0
  13. data/lib/tty/config/marshallers/json_marshaller.rb +25 -0
  14. data/lib/tty/config/marshallers/toml_marshaller.rb +25 -0
  15. data/lib/tty/config/marshallers/yaml_marshaller.rb +29 -0
  16. data/lib/tty/config/version.rb +1 -1
  17. metadata +54 -32
  18. data/Rakefile +0 -8
  19. data/bin/console +0 -14
  20. data/bin/setup +0 -8
  21. data/spec/spec_helper.rb +0 -54
  22. data/spec/unit/alias_setting_spec.rb +0 -72
  23. data/spec/unit/append_spec.rb +0 -26
  24. data/spec/unit/autoload_env_spec.rb +0 -62
  25. data/spec/unit/delete_spec.rb +0 -22
  26. data/spec/unit/exist_spec.rb +0 -24
  27. data/spec/unit/fetch_spec.rb +0 -45
  28. data/spec/unit/generate_spec.rb +0 -70
  29. data/spec/unit/merge_spec.rb +0 -22
  30. data/spec/unit/new_spec.rb +0 -6
  31. data/spec/unit/normalize_hash_spec.rb +0 -21
  32. data/spec/unit/read_spec.rb +0 -118
  33. data/spec/unit/remove_spec.rb +0 -16
  34. data/spec/unit/set_from_env_spec.rb +0 -78
  35. data/spec/unit/set_if_empty_spec.rb +0 -26
  36. data/spec/unit/set_spec.rb +0 -62
  37. data/spec/unit/validate_spec.rb +0 -76
  38. data/spec/unit/write_spec.rb +0 -197
  39. data/tasks/console.rake +0 -11
  40. data/tasks/coverage.rake +0 -11
  41. data/tasks/spec.rake +0 -29
  42. data/tty-config.gemspec +0 -28
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Config
5
+ module DependencyLoader
6
+ attr_reader :dep_name
7
+
8
+ # Lazy load a dependency
9
+ #
10
+ # @api public
11
+ def dependency(*dep_names, &block)
12
+ self.dep_name = dep_names
13
+ @block = block
14
+ end
15
+
16
+ # Load dependency before object instatiation
17
+ #
18
+ # @api public
19
+ def new(*)
20
+ load
21
+ super
22
+ end
23
+
24
+ # Try loading depedency
25
+ #
26
+ # @api private
27
+ def load
28
+ return if dep_name.nil?
29
+
30
+ dep_name.empty? ? @block.() : dep_name.each { |dep| require(dep) }
31
+ rescue LoadError, NameError => err
32
+ raise DependencyLoadError, "#{raise_error_message} #{err.message}"
33
+ end
34
+
35
+ def inherited(subclass)
36
+ super
37
+ subclass.send(:dep_name=, dep_name)
38
+ end
39
+
40
+ private
41
+
42
+ def raise_error_message
43
+ if dep_name.empty?
44
+ "One or more dependency are missing."
45
+ elsif dep_name.size == 1
46
+ "The dependency `#{dep_name.join}` is missing."
47
+ else
48
+ "The dependencies `#{dep_name.join(", ")}` are missing."
49
+ end
50
+ end
51
+
52
+ attr_writer :dep_name
53
+ end # DependencyLoader
54
+ end # Config
55
+ end # TTY
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Config
5
+ module Generator
6
+ # Generate file content based on the data hash
7
+ #
8
+ # @param [Hash] data
9
+ #
10
+ # @return [String]
11
+ # the file content
12
+ #
13
+ # @api public
14
+ def self.generate(data, separator: '=')
15
+ content = []
16
+ values = {}
17
+ sections = {}
18
+
19
+ data.keys.sort.each do |key|
20
+ val = data[key]
21
+ if val.is_a?(NilClass)
22
+ next
23
+ elsif val.is_a?(Hash) ||
24
+ (val.is_a?(Array) && val.first.is_a?(Hash))
25
+ sections[key] = val
26
+ elsif val.is_a?(Array)
27
+ values[key] = val.join(',')
28
+ else
29
+ values[key] = val
30
+ end
31
+ end
32
+
33
+ # values
34
+ values.each do |key, val|
35
+ content << "#{key} #{separator} #{val}"
36
+ end
37
+ content << '' unless values.empty?
38
+
39
+ # sections
40
+ sections.each do |section, object|
41
+ next if object.empty? # only add section if values present
42
+
43
+ content << "[#{section}]"
44
+ if object.is_a?(Array)
45
+ object = object.reduce({}, :merge!)
46
+ end
47
+ object.each do |key, val|
48
+ val = val.join(',') if val.is_a?(Array)
49
+ content << "#{key} #{separator} #{val}" if val
50
+ end
51
+ content << ''
52
+ end
53
+ content.join("\n")
54
+ end
55
+ end # INIFile
56
+ end # Config
57
+ end # TTY
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "dependency_loader"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshaller
8
+ # @api private
9
+ def self.included(base)
10
+ super
11
+ # Help marshallers to declare their gem dependency
12
+ base.extend DependencyLoader
13
+ # Help marshallers to declare their extension matching
14
+ base.extend ExtensionsStore
15
+ end
16
+
17
+ module ExtensionsStore
18
+ def ext
19
+ @ext ||= []
20
+ end
21
+
22
+ # Set a list of extensions
23
+ #
24
+ # @example
25
+ # extenion "ext1", "ext2", "ext3"
26
+ #
27
+ # @api public
28
+ def extension(*extensions)
29
+ if extensions[0].is_a?(Array)
30
+ @ext = extensions[0]
31
+ else
32
+ @ext = extensions
33
+ end
34
+ end
35
+ end
36
+
37
+ # Marshal object into a given format
38
+ #
39
+ # @param [Object] _object
40
+ #
41
+ # @api public
42
+ def marshal(_object, _options = {})
43
+ raise NotImplementedError
44
+ end
45
+
46
+ # Unmarshal content into a hash object
47
+ #
48
+ # @param [String] _content
49
+ #
50
+ # @api public
51
+ def unmarshal(_content, _options = {})
52
+ raise NotImplementedError
53
+ end
54
+ end # Marshaller
55
+ end # Config
56
+ end # TTY
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Config
5
+ class MarshallerRegistry
6
+
7
+ attr_reader :marshallers
8
+
9
+ # @api private
10
+ def initialize(mappings = {})
11
+ @marshallers = mappings
12
+ end
13
+
14
+ def names
15
+ marshallers.keys
16
+ end
17
+
18
+ def objects
19
+ marshallers.values
20
+ end
21
+
22
+ def exts
23
+ marshallers.values.reduce([]) { |acc, obj| acc + obj.ext }
24
+ end
25
+
26
+ def registered?(name_or_object)
27
+ marshallers.key?(name_or_object) || marshallers.has_value?(name_or_object)
28
+ end
29
+
30
+ def register(name, object)
31
+ marshallers[name] = object
32
+ end
33
+
34
+ def unregister(name)
35
+ marshallers.delete(name)
36
+ end
37
+
38
+ def [](name)
39
+ marshallers.fetch(name)
40
+ end
41
+ end
42
+ end # Config
43
+ end # TTY
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "marshaller_registry"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ NO_EXT = ""
9
+
10
+ def marshaller_registry
11
+ @marshaller_registry ||= MarshallerRegistry.new
12
+ end
13
+
14
+ def marshallers
15
+ marshaller_registry.objects
16
+ end
17
+
18
+ def extensions
19
+ marshaller_registry.exts << NO_EXT
20
+ end
21
+
22
+ def registered_marshaller?(name_or_object)
23
+ marshaller_registry.registered?(name_or_object)
24
+ end
25
+
26
+ def register_marshaller(name, object)
27
+ marshaller_registry.register(name, object)
28
+ end
29
+
30
+ def unregister_marshaller(*names)
31
+ names.map { |name| marshaller_registry.unregister(name) }
32
+ end
33
+ end # Marshallers
34
+ end # Config
35
+ end # TTY
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ class HCLMarshaller
9
+ include TTY::Config::Marshaller
10
+
11
+ dependency "rhcl"
12
+
13
+ extension ".hcl"
14
+
15
+ def marshal(object)
16
+ Rhcl.dump(object)
17
+ end
18
+
19
+ def unmarshal(content)
20
+ Rhcl.parse(content)
21
+ end
22
+ end # HCLMarshaller
23
+ end # Marshallers
24
+ end # Config
25
+ end # TTY
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../generator"
4
+ require_relative "../marshaller"
5
+
6
+ module TTY
7
+ class Config
8
+ module Marshallers
9
+ class INIMarshaller
10
+ include TTY::Config::Marshaller
11
+
12
+ dependency "inifile"
13
+
14
+ extension ".ini", ".cnf", ".conf", ".cfg", ".cf"
15
+
16
+ def marshal(object)
17
+ TTY::Config::Generator.generate(object)
18
+ end
19
+
20
+ def unmarshal(content)
21
+ ini = IniFile.new(content: content).to_h
22
+ global = ini.delete('global')
23
+ ini.merge!(global)
24
+ end
25
+ end # INIMarshaller
26
+ end # Marshallers
27
+ end # Config
28
+ end # TTY
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ class JavaPropsMarshaller
9
+ include TTY::Config::Marshaller
10
+
11
+ dependency "java-properties"
12
+
13
+ extension ".properties", ".props", ".prop"
14
+
15
+ def marshal(object)
16
+ JavaProperties.generate(object)
17
+ end
18
+
19
+ def unmarshal(content)
20
+ JavaProperties.parse(content)
21
+ end
22
+ end # JavapropsMarshaller
23
+ end # Marshallers
24
+ end # Config
25
+ end # TTY
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ class JSONMarshaller
9
+ include TTY::Config::Marshaller
10
+
11
+ dependency "json"
12
+
13
+ extension ".json"
14
+
15
+ def marshal(object)
16
+ JSON.pretty_generate(object)
17
+ end
18
+
19
+ def unmarshal(content)
20
+ JSON.parse(content)
21
+ end
22
+ end # JSONMarshaller
23
+ end # Marshallers
24
+ end # Config
25
+ end # TTY
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ class TOMLMarshaller
9
+ include TTY::Config::Marshaller
10
+
11
+ dependency "toml"
12
+
13
+ extension ".toml"
14
+
15
+ def marshal(data)
16
+ TOML::Generator.new(data).body
17
+ end
18
+
19
+ def unmarshal(content)
20
+ TOML::Parser.new(content).parsed
21
+ end
22
+ end # TOMLMarshaller
23
+ end # Marshallers
24
+ end # Config
25
+ end # TTY
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ class YAMLMarshaller
9
+ include TTY::Config::Marshaller
10
+
11
+ dependency "yaml"
12
+
13
+ extension ".yaml", ".yml"
14
+
15
+ def marshal(object)
16
+ YAML.dump(TTY::Config.normalize_hash(object, :to_s))
17
+ end
18
+
19
+ def unmarshal(content)
20
+ if YAML.respond_to?(:safe_load)
21
+ YAML.safe_load(content)
22
+ else
23
+ YAML.load(content)
24
+ end
25
+ end
26
+ end # YAMLMarshaller
27
+ end # Marshallers
28
+ end # Config
29
+ end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Config
5
- VERSION = "0.3.2"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-18 00:00:00.000000000 Z
11
+ date: 2020-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,49 +80,71 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rhcl
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.1.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.1.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: java-properties
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.0
83
111
  description: Define, read and write any Ruby app configurations with a penchant for
84
112
  terminal clients.
85
113
  email:
86
- - me@piotrmurach.com
114
+ - piotr@piotrmurach.com
87
115
  executables: []
88
116
  extensions: []
89
- extra_rdoc_files: []
117
+ extra_rdoc_files:
118
+ - README.md
119
+ - CHANGELOG.md
90
120
  files:
91
121
  - CHANGELOG.md
92
122
  - LICENSE.txt
93
123
  - README.md
94
- - Rakefile
95
- - bin/console
96
- - bin/setup
97
124
  - lib/tty-config.rb
98
125
  - lib/tty/config.rb
126
+ - lib/tty/config/dependency_loader.rb
127
+ - lib/tty/config/generator.rb
128
+ - lib/tty/config/marshaller.rb
129
+ - lib/tty/config/marshaller_registry.rb
130
+ - lib/tty/config/marshallers.rb
131
+ - lib/tty/config/marshallers/hcl_marshaller.rb
132
+ - lib/tty/config/marshallers/ini_marshaller.rb
133
+ - lib/tty/config/marshallers/java_props_marshaller.rb
134
+ - lib/tty/config/marshallers/json_marshaller.rb
135
+ - lib/tty/config/marshallers/toml_marshaller.rb
136
+ - lib/tty/config/marshallers/yaml_marshaller.rb
99
137
  - lib/tty/config/version.rb
100
- - spec/spec_helper.rb
101
- - spec/unit/alias_setting_spec.rb
102
- - spec/unit/append_spec.rb
103
- - spec/unit/autoload_env_spec.rb
104
- - spec/unit/delete_spec.rb
105
- - spec/unit/exist_spec.rb
106
- - spec/unit/fetch_spec.rb
107
- - spec/unit/generate_spec.rb
108
- - spec/unit/merge_spec.rb
109
- - spec/unit/new_spec.rb
110
- - spec/unit/normalize_hash_spec.rb
111
- - spec/unit/read_spec.rb
112
- - spec/unit/remove_spec.rb
113
- - spec/unit/set_from_env_spec.rb
114
- - spec/unit/set_if_empty_spec.rb
115
- - spec/unit/set_spec.rb
116
- - spec/unit/validate_spec.rb
117
- - spec/unit/write_spec.rb
118
- - tasks/console.rake
119
- - tasks/coverage.rake
120
- - tasks/spec.rake
121
- - tty-config.gemspec
122
- homepage: https://piotrmurach.github.io/tty
138
+ homepage: https://ttytoolkit.org
123
139
  licenses:
124
140
  - MIT
125
- metadata: {}
141
+ metadata:
142
+ allowed_push_host: https://rubygems.org
143
+ bug_tracker_uri: https://github.com/piotrmurach/tty-config/issues
144
+ changelog_uri: https://github.com/piotrmurach/tty-config/blob/master/CHANGELOG.md
145
+ documentation_uri: https://www.rubydoc.info/gems/tty-config
146
+ homepage_uri: https://ttytoolkit.org
147
+ source_code_uri: https://github.com/piotrmurach/tty-config
126
148
  post_install_message:
127
149
  rdoc_options: []
128
150
  require_paths:
@@ -138,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
160
  - !ruby/object:Gem::Version
139
161
  version: '0'
140
162
  requirements: []
141
- rubygems_version: 3.0.3
163
+ rubygems_version: 3.1.2
142
164
  signing_key:
143
165
  specification_version: 4
144
166
  summary: Define, read and write any Ruby app configurations with a penchant for terminal