autoini 0.1.0 → 0.2.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
  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