autoini 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd90d5011121b5b00414dc5da6ab3deaf07eeb8e
4
- data.tar.gz: d4cc5d55c16b7ede2eda4d5f5dc857538479d1da
3
+ metadata.gz: fba73e42029d7494a3259f14d218356f197146a9
4
+ data.tar.gz: 5ad14b10e7d3167801798c48f3b9d70887e5b445
5
5
  SHA512:
6
- metadata.gz: 7665669b4bdeea08c253c598c459705fdb51ee6ac977938d8941c2d25cdddcf49461f96a82ad73df9348a0155fdb36f4af514dda526ff2a852b462ab0c971810
7
- data.tar.gz: 5cbcb038d714bc5b182bf593a20e6de9405f407c6f52972a55e245b3e32e197ece6db096ed7e72530cb2dc8064a7038b48d5082625564a7ebda0032e6bc18cdc
6
+ metadata.gz: b5f615d3dc551ff4dcde7105dbbe19caccf47f1323fc9992a067a600d8b8f98248d84e7f65cd24071475a4b513bd711fab3db5d794c2e480320a30231335deb8
7
+ data.tar.gz: 83511d105f93a7891248eb2a559d0fc1f44cc6fe72919f26e652421cc5fb1b1b999904f0c1863f61aa8ee329e44d51e825dab8fcf94accc4d2e3ff49aa215e52
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /test/fixtures/*
data/README.md CHANGED
@@ -22,6 +22,29 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
+ ### Reading / writing to files
26
+
27
+ If you just want to read/write data to files, these 3 methods are all you need:
28
+
29
+ To read an INI file into a hash object:
30
+ ```ruby
31
+ hash = Autoini.read('data.ini')
32
+ ```
33
+
34
+ To write INI data to a file:
35
+ ```ruby
36
+ Autoini.write('data.ini', section: { foo: :bar })
37
+ ```
38
+
39
+ To merge INI data into a file:
40
+ ```ruby
41
+ Autoini.merge('data.ini', section: { another: :value })
42
+ ```
43
+
44
+ ### Advanced manipulation
45
+
46
+ If you need to read/write comments and blank lines, or alter INI data without writing to a file, you can use the following classes
47
+
25
48
  To parse INI data:
26
49
  ```ruby
27
50
  ini = Autoini::Contents.parse(File.open('data.ini', 'rb', &:read))
@@ -62,7 +85,7 @@ foo2=bar # a comment
62
85
 
63
86
  ## Config
64
87
 
65
- Autoini will always parse lines in a string by \n, but you can choose the new line string using:
88
+ Autoini will always parse lines in a string/file by \n, but you can choose how Autoini writes a new line using:
66
89
  ```ruby
67
90
  Autoini.newline = "\r\n"
68
91
  ```
@@ -72,15 +95,9 @@ Autoini will parse comments as begining with a ; or a #. You can choose which it
72
95
  Autoini.comment = ";"
73
96
  ```
74
97
 
75
- ## Development
76
-
77
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
78
-
79
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
80
-
81
98
  ## Contributing
82
99
 
83
- Bug reports and pull requests are welcome on GitHub at https://github.com/automeow/autoini. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
100
+ Bug reports and pull requests are welcome on GitHub at https://github.com/automeow/autoini.
84
101
 
85
102
 
86
103
  ## License
@@ -20,9 +20,22 @@ module Autoini
20
20
  class << self
21
21
  attr_accessor :newline, :comment
22
22
 
23
+ def read(file)
24
+ Contents.hash(File.open(file, 'rb', &:read))
25
+ end
26
+
27
+ def write(file, data)
28
+ File.write(file, Contents[data].to_s)
29
+ end
30
+
31
+ def merge(file, data)
32
+ Contents.parse((File.open(file, 'rb', &:read) rescue nil))
33
+ .merge!(Contents[data]).tap{ |c| File.write(file, c.to_s) }.to_h
34
+ end
35
+
23
36
  def escape(text)
24
37
  ''.tap do |b|
25
- text.each_char do |c|
38
+ text.to_s.each_char do |c|
26
39
  b << MAP_CHARS[c] and next if MAP_CHARS[c]
27
40
  b << '\\' if SPECIAL.include?(c)
28
41
  b << c
@@ -8,6 +8,10 @@ module Autoini
8
8
  e.is_a?(BlankLine)
9
9
  end
10
10
 
11
+ def to_a
12
+ []
13
+ end
14
+
11
15
  def self.parse_with_comment(line)
12
16
  parse(line)
13
17
  end
@@ -10,6 +10,10 @@ module Autoini
10
10
  "#{Autoini.comment} #{@comment}"
11
11
  end
12
12
 
13
+ def to_a
14
+ []
15
+ end
16
+
13
17
  def ==(e)
14
18
  e.is_a?(Comment) && comment == e.comment
15
19
  end
@@ -5,6 +5,7 @@ module Autoini
5
5
  attr_reader :lines
6
6
 
7
7
  def self.parse(contents)
8
+ return new if contents.nil? || contents.empty?
8
9
  elements = []
9
10
  section = nil
10
11
  contents.split("\n").each do |l|
@@ -21,6 +22,23 @@ module Autoini
21
22
  new(*elements)
22
23
  end
23
24
 
25
+ def self.hash(contents)
26
+ parse(contents).to_h
27
+ end
28
+
29
+ def self.[](hash)
30
+ raise ArgumentError, "must pass a hash" unless hash.is_a?(Hash)
31
+ new(
32
+ *hash.map do |k, v|
33
+ if v.is_a?(Hash)
34
+ Section[k, v]
35
+ else
36
+ Pair.new(k, v)
37
+ end
38
+ end
39
+ )
40
+ end
41
+
24
42
  def initialize(*contents)
25
43
  @lines = []
26
44
  self << contents
@@ -32,16 +50,52 @@ module Autoini
32
50
  raise ArgumentError, "#{c.class.name} must extend Autoini::Element"
33
51
  end
34
52
  if !c.is_a?(Section) && lines.last.is_a?(Section)
35
- raise ArgumentError, "Error on line #{c.inspect}: all elements after a section must be in a section"
53
+ raise ArgumentError, "Error on line #{c.inspect}: all elements " \
54
+ "after a section must be in a section"
36
55
  end
37
56
  lines << c
38
57
  end
39
58
  end
40
59
 
60
+ def section(key)
61
+ lines.select{ |l| l.is_a?(Section) && l.title.to_s == key.to_s }.first
62
+ end
63
+
64
+ def pair(key)
65
+ lines.select{ |l| l.is_a?(Pair) && l.key.to_s == key.to_s }.first
66
+ end
67
+
68
+ def merge!(other_contents)
69
+ unless other_contents.is_a?(Contents)
70
+ raise ArgumentError, "must pass a Autoini::Contents"
71
+ end
72
+ other_contents.lines.each do |l|
73
+ case l
74
+ when Section
75
+ if s = section(l.title)
76
+ s.merge!(l)
77
+ else
78
+ self << l
79
+ end
80
+ when Pair
81
+ if p = pair(l.key)
82
+ p.value = l.value
83
+ else
84
+ self << l
85
+ end
86
+ end
87
+ end
88
+ self
89
+ end
90
+
41
91
  def to_s
42
92
  lines.map(&:to_s).join(Autoini.newline)
43
93
  end
44
94
 
95
+ def to_h
96
+ lines.map(&:to_a).reject(&:empty?).to_h
97
+ end
98
+
45
99
  def ==(c)
46
100
  c.is_a?(Contents) && c.lines.length == lines.length &&
47
101
  lines.map.with_index{ |l, i| c.lines[i] == l }.all?
@@ -3,5 +3,9 @@ module Autoini
3
3
  def ==(element)
4
4
  raise ArgumentError, "== must be overriden in the subclass"
5
5
  end
6
+
7
+ def to_a(element)
8
+ raise ArgumentError, "to_a must be overriden in the subclass"
9
+ end
6
10
  end
7
11
  end
@@ -13,6 +13,10 @@ module Autoini
13
13
  line_comment("#{Autoini.escape(key)}=#{Autoini.escape(value)}")
14
14
  end
15
15
 
16
+ def to_a
17
+ [key.to_sym, value]
18
+ end
19
+
16
20
  def ==(e)
17
21
  e.is_a?(Pair) && e.key == key && e.value == value && e.comment == comment
18
22
  end
@@ -11,6 +11,11 @@ module Autoini
11
11
  self << contents
12
12
  end
13
13
 
14
+ def self.[](title, hash)
15
+ raise ArgumentError, "must pass a hash" unless hash.is_a?(Hash)
16
+ new title, *hash.map{ |k, v| Pair.new(k, v) }
17
+ end
18
+
14
19
  def <<(contents)
15
20
  Autoini.wrap(contents).each do |c|
16
21
  unless c.is_a?(AbstractLine)
@@ -24,12 +29,35 @@ module Autoini
24
29
  [line_comment("[#{title}]"), lines.map(&:to_s)].flatten.join(Autoini.newline)
25
30
  end
26
31
 
32
+ def to_a
33
+ [title.to_sym, lines.map(&:to_a).reject(&:empty?).to_h]
34
+ end
35
+
27
36
  def ==(e)
28
37
  e.is_a?(Section) && e.title == title && e.comment == comment &&
29
38
  e.lines.length == lines.length &&
30
39
  lines.map.with_index{ |l, i| e.lines[i] == l }.all?
31
40
  end
32
41
 
42
+ def pair(key)
43
+ lines.select{ |l| l.is_a?(Pair) && l.key.to_s == key.to_s }.first
44
+ end
45
+
46
+ def merge!(other_section)
47
+ unless other_section.is_a?(Section)
48
+ raise ArgumentError, "must pass a Autoini::Section"
49
+ end
50
+ other_section.lines.each do |l|
51
+ next unless l.is_a?(Pair)
52
+ if p = pair(l.key)
53
+ p.value = l.value
54
+ else
55
+ self << l
56
+ end
57
+ end
58
+ self
59
+ end
60
+
33
61
  def self.parse(line)
34
62
  Section.new(line[1]) if line.length == 3 && line[0] == '[' && line[2] == ']'
35
63
  end
@@ -1,3 +1,3 @@
1
1
  module Autoini
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoini
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Boylett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-08 00:00:00.000000000 Z
11
+ date: 2016-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler