tty-config 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 106bc8ef14d41383dee670ba581128d5cb22492357e1a01fa7610cc9fcdf26d1
4
- data.tar.gz: 78e5a75dff911c39eb7355b114bbc7a511123b22050b792c99936e3b337b5d5e
3
+ metadata.gz: caebad5a11c843f7436887a74a9c69bb19bc0303b52078daf9e1504ba3306f79
4
+ data.tar.gz: 61db32809d542344928572cba720baeb132be4b0e0a5ff8f2661d44825bc151b
5
5
  SHA512:
6
- metadata.gz: 7d94ee40e738070bd66ad3371df6ea6dc281fabb26d6b66c6e07988e637a352d01402081d9c6d8dd8979c9c712b3a932b93d0d178cb9e779058bfeb290ee7605
7
- data.tar.gz: '0119ee7f6f3ecdade2606f3df3ebce8d814e3241de3d191ac6ee3cc947691981a3c03dad1f0af29657807c9fda9e08c2c2533614f406dc6511f9c9eb9858a37e'
6
+ metadata.gz: 768fb85c76d3d68a4c29240c8d557c29ffe4482773131b5ce3cf24d6a3e355d2480dfee921781f6a28013f60b5132e2bb30d09751680546691bff9378e9cccaf
7
+ data.tar.gz: 5e59beca53007689060f817cd73bb0684bce1cb3ffc72bcd0b4c8eb10fe1d8fd5a937037378e04f2f0666badb3abfeb22abd97d3e69904022bc489092e0a89b6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.6.0] - 2022-06-18
4
+
5
+ ### Added
6
+ * Add the ability to persist configuration settings in an XML format
7
+
8
+ ### Changed
9
+ * Change the INI file format generator to improve maintainability
10
+ * Change gemspec to update toml version constraint
11
+
3
12
  ## [v0.5.1] - 2022-02-04
4
13
 
5
14
  ### Fixed
@@ -77,6 +86,7 @@
77
86
 
78
87
  * Initial implementation and release
79
88
 
89
+ [v0.6.0]: https://github.com/piotrmurach/tty-config/compare/v0.5.1...v0.6.0
80
90
  [v0.5.1]: https://github.com/piotrmurach/tty-config/compare/v0.5.0...v0.5.1
81
91
  [v0.5.0]: https://github.com/piotrmurach/tty-config/compare/v0.4.0...v0.5.0
82
92
  [v0.4.0]: https://github.com/piotrmurach/tty-config/compare/v0.3.2...v0.4.0
data/README.md CHANGED
@@ -27,7 +27,7 @@
27
27
 
28
28
  This is a one-stop shop for all your configuration needs:
29
29
 
30
- * [Read](#216-read) and [write](#217-write) config files in YAML, JSON, TOML, INI, HCL and Java Properties formats
30
+ * [Read](#216-read) and [write](#217-write) config files in YAML, JSON, TOML, INI, XML, HCL and Java Properties formats
31
31
  * Add [custom marshallers](#222-register_marshaller) or override the built-in ones
32
32
  * [Set](#21-set) and [read](#24-fetch) settings for deeply nested keys
33
33
  * [Set](#21-set) defaults for undefined settings
@@ -514,6 +514,7 @@ Currently the supported file formats are:
514
514
  * `toml` for `.toml` extension
515
515
  * `ini` for `.ini`, `.cnf`, `.conf`, `.cfg`, `.cf extensions`
516
516
  * `hcl` for `.hcl` extensions
517
+ * `xml` for `.xml` extension
517
518
  * `jprops` for `.properties`, `.props`, `.prop` extensions
518
519
 
519
520
  Calling `read` without any arguments searches through provided locations to find configuration file and reads it. Therefore, you need to specify at least one search path that contains the configuration file together with actual filename. When filename is specified then all known extensions will be tried.
@@ -700,7 +701,7 @@ config.fetch(:host)
700
701
 
701
702
  There are number of built-in marshallers that handle the process of serializing internal configuration from and back into a desired format, for example, a `JSON` string.
702
703
 
703
- Currently supported formats out-of-the-box are: `YAML`, `JSON`, `TOML`, `INI` & `HCL`.
704
+ Currently supported formats out-of-the-box are: `YAML`, `JSON`, `TOML`, `INI`, `XML`, `HCL` & `Java Properties`.
704
705
 
705
706
  To create your own marshaller use the `TTY::Config::Marshaller` interface. You need to provide the implementation for the following marshalling methods:
706
707
 
@@ -770,7 +771,7 @@ By default, the **TTY::Config** is ready to recognize various extensions. See [2
770
771
  For example, to remove all the built-in marshallers do:
771
772
 
772
773
  ```ruby
773
- config.unregister_marshaller :yaml, :json, :toml, :ini, :hcl
774
+ config.unregister_marshaller :yaml, :json, :toml, :ini, :xml, :hcl, :jprops
774
775
  ```
775
776
 
776
777
  ## 3. Examples
@@ -2,56 +2,129 @@
2
2
 
3
3
  module TTY
4
4
  class Config
5
+ # Responsible for converting a data object into content in INI format
6
+ #
7
+ # @api private
5
8
  module Generator
6
9
  # Generate file content based on the data hash
7
10
  #
8
- # @param [Hash] data
11
+ # @example
12
+ # generate({"foo" => {"bar" => "baz"}})
13
+ # # => "[foo]\nbar = baz\n"
14
+ #
15
+ # @param [Hash{String => Object}] data
16
+ # the data to convert to INI file format
17
+ # @param [String] separator
18
+ # the separator for the key and value pairs
9
19
  #
10
20
  # @return [String]
11
- # the file content
21
+ # the INI file content
12
22
  #
13
23
  # @api public
14
24
  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
25
+ sections_and_values = group_into_sections_and_values(data)
26
+
27
+ values = generate_values(sections_and_values[:values], separator)
28
+ values << "" unless values.empty?
29
+ sections = generate_sections(sections_and_values[:sections], separator)
30
+
31
+ content = values + sections
32
+ content.join("\n")
33
+ end
34
+
35
+ # Group data into sections and values
36
+ #
37
+ # @param [Hash{String => Object}] data
38
+ # the data to group
39
+ #
40
+ # @return [Hash{Symbol => Hash}]
41
+ # the sections and values
42
+ #
43
+ # @api private
44
+ def self.group_into_sections_and_values(data)
45
+ sections_and_values = {sections: {}, values: {}}
46
+ data.sort.each_with_object(sections_and_values) do |(key, val), group|
47
+ group[section?(val) ? :sections : :values][key] = val
31
48
  end
49
+ end
50
+ private_class_method :group_into_sections_and_values
51
+
52
+ # Check whether or not a value is a section
53
+ #
54
+ # @param [Object] value
55
+ # the value to check
56
+ #
57
+ # @return [Boolean]
58
+ # return true if value is a section, false otherwise
59
+ #
60
+ # @api private
61
+ def self.section?(value)
62
+ value.is_a?(Hash) ||
63
+ (value.is_a?(Array) && value.all? { |val| val.is_a?(Hash) })
64
+ end
65
+ private_class_method :section?
32
66
 
33
- # values
34
- values.each do |key, val|
35
- content << "#{key} #{separator} #{val}"
67
+ # Generate key and value pairs
68
+ #
69
+ # @param [Hash{String => Object}] values
70
+ # the values to convert to INI format
71
+ # @param [String] separator
72
+ # the separator for the key and value pairs
73
+ #
74
+ # @return [Array<String>]
75
+ # the formatted key and value pairs
76
+ #
77
+ # @api private
78
+ def self.generate_values(values, separator)
79
+ values.each_with_object([]) do |(key, val), content|
80
+ next if val.nil?
81
+
82
+ content << generate_pair(key, val, separator)
36
83
  end
37
- content << "" unless values.empty?
84
+ end
85
+ private_class_method :generate_values
38
86
 
39
- # sections
40
- sections.each do |section, object|
41
- next if object.empty? # only add section if values present
87
+ # Generate key and value pair
88
+ #
89
+ # @param [String] key
90
+ # the key to convert to INI format
91
+ # @param [Object] value
92
+ # the value to convert to INI format
93
+ # @param [String] separator
94
+ # the separator for the key and value pair
95
+ #
96
+ # @return [String]
97
+ # the formatted key and value pair
98
+ #
99
+ # @api private
100
+ def self.generate_pair(key, value, separator)
101
+ value = value.join(",") if value.is_a?(Array)
102
+ "#{key} #{separator} #{value}"
103
+ end
104
+ private_class_method :generate_pair
105
+
106
+ # Generate sections with key and value pairs
107
+ #
108
+ # @param [Hash{String => Object}] sections
109
+ # the sections to convert to INI format
110
+ # @param [String] separator
111
+ # the separator for the key and value pairs
112
+ #
113
+ # @return [Array<String>]
114
+ # the formatted sections with key and value pairs
115
+ #
116
+ # @api private
117
+ def self.generate_sections(sections, separator)
118
+ sections.each_with_object([]) do |(section, object), content|
119
+ next if object.empty? # skip section with no values
42
120
 
43
121
  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
122
+ object = object.reduce({}, :merge) if object.is_a?(Array)
123
+ content.concat(generate_values(object, separator))
51
124
  content << ""
52
125
  end
53
- content.join("\n")
54
126
  end
55
- end # INIFile
127
+ private_class_method :generate_sections
128
+ end # Generator
56
129
  end # Config
57
130
  end # TTY
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../marshaller"
4
+
5
+ module TTY
6
+ class Config
7
+ module Marshallers
8
+ # Responsible for marshalling content from and into XML format
9
+ #
10
+ # @api public
11
+ class XMLMarshaller
12
+ include TTY::Config::Marshaller
13
+
14
+ dependency "xmlsimple"
15
+
16
+ extension ".xml"
17
+
18
+ def marshal(object)
19
+ XmlSimple.xml_out(object, {rootname: "config"})
20
+ end
21
+
22
+ def unmarshal(content)
23
+ return {} if content.empty?
24
+
25
+ XmlSimple.xml_in(content, {force_array: false})
26
+ end
27
+ end # XMLMarshaller
28
+ end # Marshallers
29
+ end # Config
30
+ end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Config
5
- VERSION = "0.5.1"
5
+ VERSION = "0.6.0"
6
6
  end # Config
7
7
  end # TTY
data/lib/tty/config.rb CHANGED
@@ -10,6 +10,7 @@ require_relative "config/marshallers/yaml_marshaller"
10
10
  require_relative "config/marshallers/toml_marshaller"
11
11
  require_relative "config/marshallers/hcl_marshaller"
12
12
  require_relative "config/marshallers/java_props_marshaller"
13
+ require_relative "config/marshallers/xml_marshaller"
13
14
 
14
15
  module TTY
15
16
  # Responsible for managing application configuration
@@ -104,6 +105,7 @@ module TTY
104
105
  register_marshaller :json, Marshallers::JSONMarshaller
105
106
  register_marshaller :toml, Marshallers::TOMLMarshaller
106
107
  register_marshaller :ini, Marshallers::INIMarshaller
108
+ register_marshaller :xml, Marshallers::XMLMarshaller
107
109
  register_marshaller :hcl, Marshallers::HCLMarshaller
108
110
  register_marshaller :jprops, Marshallers::JavaPropsMarshaller
109
111
 
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.5.1
4
+ version: 0.6.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: 2022-02-04 00:00:00.000000000 Z
11
+ date: 2022-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inifile
@@ -86,14 +86,28 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.2'
89
+ version: '0.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: xml-simple
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.1'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0.2'
110
+ version: '1.1'
97
111
  description: A highly customisable application configuration interface for building
98
112
  terminal tools. It supports many file formats such as YAML, JSON, TOML, INI, HCL
99
113
  and Java Properties.
@@ -121,6 +135,7 @@ files:
121
135
  - lib/tty/config/marshallers/java_props_marshaller.rb
122
136
  - lib/tty/config/marshallers/json_marshaller.rb
123
137
  - lib/tty/config/marshallers/toml_marshaller.rb
138
+ - lib/tty/config/marshallers/xml_marshaller.rb
124
139
  - lib/tty/config/marshallers/yaml_marshaller.rb
125
140
  - lib/tty/config/version.rb
126
141
  homepage: https://ttytoolkit.org