dot-properties 0.1.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.
- data/.gitignore +17 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +14 -0
- data/README.md +66 -0
- data/Rakefile +19 -0
- data/dot-properties.gemspec +26 -0
- data/lib/dot-properties.rb +1 -0
- data/lib/dot_properties.rb +144 -0
- data/lib/dot_properties/version.rb +3 -0
- data/spec/dot_properties_spec.rb +127 -0
- data/spec/fixtures/sample.properties +42 -0
- metadata +147 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
##########################################################################
|
2
|
+
# Copyright 2013 Michael B. Klein
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# DotProperties [](http://travis-ci.org/mbklein/dot-properties)
|
2
|
+
|
3
|
+
Reads and writes [Java .properties files](http://en.wikipedia.org/wiki/.properties) like a champ.
|
4
|
+
|
5
|
+
* Intuitive, Hash-like access. Anywhere it makes sense to act like a Hash, it acts like a Hash.
|
6
|
+
* Won't clobber comments and blank lines (unless you want to).
|
7
|
+
* Will preserve original delimiters for each value (unless you normalize them).
|
8
|
+
* Supports all the delimiters (whitespace, `=`, `:`).
|
9
|
+
* Supports both comment prefixes (`#`, `!`).
|
10
|
+
* Supports expansion of inline `${property}` references.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'dot_properties'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install dot_properties
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
require 'dot_properties'
|
29
|
+
|
30
|
+
# Load a .properties file
|
31
|
+
props = DotProperties.new('sample.properties')
|
32
|
+
|
33
|
+
# Get a value
|
34
|
+
props['foo']
|
35
|
+
|
36
|
+
# Set a value
|
37
|
+
props['foo'] = 'bar'
|
38
|
+
|
39
|
+
# Convert key/value pairs to a hash
|
40
|
+
props.to_h
|
41
|
+
|
42
|
+
# Or just let it act like a hash
|
43
|
+
props.each_pair { |key,value| puts "#{key} :: #{value}" }
|
44
|
+
|
45
|
+
# Remove all comments/blanks/both
|
46
|
+
props.strip_comments!
|
47
|
+
props.strip_blanks!
|
48
|
+
props.compact!
|
49
|
+
|
50
|
+
# Write a .properties file
|
51
|
+
File.open('output.properties','w') { |out| out.write(props.to_s) }
|
52
|
+
|
53
|
+
See the spec tests and fixture data for more examples.
|
54
|
+
|
55
|
+
## Known Issues
|
56
|
+
|
57
|
+
* Multiline values will be converted to single line on output
|
58
|
+
|
59
|
+
## History
|
60
|
+
|
61
|
+
- <b>0.1.0</b> - Initial release
|
62
|
+
|
63
|
+
## Copyright
|
64
|
+
|
65
|
+
Copyright (c) 2013 Michael B. Klein. See LICENSE.txt for further details.
|
66
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rdoc/task'
|
3
|
+
require 'dot_properties/version'
|
4
|
+
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
RSpec::Core::RakeTask.new do |t|
|
7
|
+
t.pattern = FileList['./spec/**/*_spec.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
RDoc::Task.new do |rdoc|
|
13
|
+
version = DotProperties::VERSION
|
14
|
+
|
15
|
+
rdoc.rdoc_dir = 'rdoc'
|
16
|
+
rdoc.title = "dot-properties #{version}"
|
17
|
+
rdoc.rdoc_files.include('README*')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dot_properties/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dot-properties"
|
8
|
+
spec.version = DotProperties::VERSION
|
9
|
+
spec.authors = ["Michael B. Klein"]
|
10
|
+
spec.email = ["mbklein@gmail.com"]
|
11
|
+
spec.description = %q{Java-style .properties file manipulation with a light touch}
|
12
|
+
spec.summary = %q{Read/write .properties files, respecting comments and existing formatting as much as possible}
|
13
|
+
spec.homepage = "https://github.com/mbklein/dot-properties"
|
14
|
+
spec.license = "APACHE2"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "rdoc", ">= 2.4.2"
|
25
|
+
spec.add_development_dependency "simplecov"
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'dot_properties'
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require "dot_properties/version"
|
2
|
+
|
3
|
+
class DotProperties
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :to_h, :each, :each_key, :each_pair, :each_value, :empty?,
|
7
|
+
:fetch, :has_key?, :has_value?, :include?, :inspect, :invert,
|
8
|
+
:key, :key?, :keys, :length, :member?, :merge, :reject,
|
9
|
+
:select, :size, :value?, :values, :values_at
|
10
|
+
|
11
|
+
|
12
|
+
# @!attribute [rw] auto_expand
|
13
|
+
# @return [Boolean] Whether to expand resolvable variables within values on retrieval (default: +true+)
|
14
|
+
# @!attribute [rw] default_delimiter
|
15
|
+
# @return [String] The delimiter to use when adding new properties or when calling +normalize_delimiters!+ (default: '=')
|
16
|
+
attr_accessor :auto_expand, :default_delimiter
|
17
|
+
|
18
|
+
def initialize(lines=[])
|
19
|
+
@content = lines.collect { |item| tokenize(item) }
|
20
|
+
@auto_expand = true
|
21
|
+
@default_delimiter = '='
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.load(file)
|
25
|
+
self.parse(File.read(file))
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.parse(str)
|
29
|
+
self.new(str.split(/(?<!\\)\n/))
|
30
|
+
end
|
31
|
+
|
32
|
+
def get(key, expand=@auto_expand)
|
33
|
+
item = find_key(key)
|
34
|
+
value = (item && item[:value]) || nil
|
35
|
+
if value and expand
|
36
|
+
value = value.gsub(/\$\{(.+?)\}/) { |v| has_key?($1) ? get($1,true) : v }
|
37
|
+
end
|
38
|
+
return value
|
39
|
+
end
|
40
|
+
|
41
|
+
def set(key, value)
|
42
|
+
item = find_key(key)
|
43
|
+
if item
|
44
|
+
item[:value] = value
|
45
|
+
else
|
46
|
+
@content << { type: :value, key: key, delimiter: default_delimiter, value: value }
|
47
|
+
end
|
48
|
+
return value
|
49
|
+
end
|
50
|
+
|
51
|
+
def [](key)
|
52
|
+
get(key)
|
53
|
+
end
|
54
|
+
|
55
|
+
def []=(key,value)
|
56
|
+
set(key, value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def <<(item)
|
60
|
+
@content << tokenize(item)
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(key)
|
64
|
+
value = get(key)
|
65
|
+
@content.reject! { |item| item[:type] == :value and item[:key] == key }
|
66
|
+
return value
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
to_h.inspect
|
71
|
+
end
|
72
|
+
|
73
|
+
# Strip all comments and blank lines, leaving only values
|
74
|
+
def compact!
|
75
|
+
@content.reject! { |item| item[:type] != :value }
|
76
|
+
end
|
77
|
+
|
78
|
+
# Replace all delimiters with +default_delimiter+
|
79
|
+
def normalize_delimiters!
|
80
|
+
@content.each { |item| item[:delimiter] = default_delimiter if item[:type] == :value }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Strip all blank lines, leaving only comments and values
|
84
|
+
def strip_blanks!
|
85
|
+
@content.reject! { |item| item[:type] == :blank }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Strip all comments, leaving only blank lines and values
|
89
|
+
def strip_comments!
|
90
|
+
@content.reject! { |item| item[:type] == :comment }
|
91
|
+
end
|
92
|
+
|
93
|
+
# The assembled .properties file as an array of lines
|
94
|
+
def to_a
|
95
|
+
@content.collect { |item| assemble(item) }
|
96
|
+
end
|
97
|
+
|
98
|
+
# All properties as a hash
|
99
|
+
def to_h
|
100
|
+
Hash[@content.select { |item| item[:type] == :value }.collect { |item| item.values_at(:key,:value) }]
|
101
|
+
end
|
102
|
+
|
103
|
+
# The assembled .properties file as a string
|
104
|
+
def to_s
|
105
|
+
to_a.join("\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
def assemble(item)
|
110
|
+
if item[:type] == :value
|
111
|
+
if item[:value].nil? or item[:value].empty?
|
112
|
+
escape(item[:key])
|
113
|
+
else
|
114
|
+
"#{escape(item[:key])}#{item[:delimiter]}#{item[:value]}"
|
115
|
+
end
|
116
|
+
else
|
117
|
+
item[:value]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def tokenize(item)
|
122
|
+
if item =~ /^\s*[#!]/
|
123
|
+
{ type: :comment, value: item }
|
124
|
+
elsif item =~ /^\s*$/
|
125
|
+
{ type: :blank, value: item }
|
126
|
+
else
|
127
|
+
key, delimiter, value = item.split /(\s*(?<!\\)[\s:=]\s*)/, 2
|
128
|
+
{ type: :value, key: unescape(key), delimiter: delimiter, value: value.to_s.gsub(/\\\n\s*/,'') }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def find_key(key)
|
133
|
+
@content.find { |item| item[:type] == :value and item[:key] == key }
|
134
|
+
end
|
135
|
+
|
136
|
+
def escape(key)
|
137
|
+
key.gsub(/[\s:=]/) { |m| "\\#{m}" }
|
138
|
+
end
|
139
|
+
|
140
|
+
def unescape(key)
|
141
|
+
key.gsub(/\\/,'')
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
if defined?(RUBY_ENGINE) and (RUBY_ENGINE == 'ruby') and (RUBY_VERSION >= '1.9')
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
end
|
5
|
+
$:.push(File.join(File.dirname(__FILE__),'..','lib'))
|
6
|
+
|
7
|
+
require 'dot_properties'
|
8
|
+
|
9
|
+
describe DotProperties do
|
10
|
+
let(:propfile) { File.expand_path('../fixtures/sample.properties', __FILE__) }
|
11
|
+
subject { DotProperties.load(propfile) }
|
12
|
+
|
13
|
+
let(:properties) { 16 }
|
14
|
+
let(:comments) { 14 }
|
15
|
+
let(:blanks) { 8 }
|
16
|
+
|
17
|
+
it { should be_an_instance_of(DotProperties) }
|
18
|
+
|
19
|
+
describe "values" do
|
20
|
+
it "should have the right number of properties" do
|
21
|
+
expect(subject.keys.length).to eq(16)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have the right values" do
|
25
|
+
expect(subject['foo.normal']).to eq('bar.normal.value')
|
26
|
+
expect(subject['bar.normal']).to eq('baz.normal.value')
|
27
|
+
expect(subject['foo.whitespace']).to eq('bar.whitespace.value')
|
28
|
+
expect(subject['foo.extraspace']).to eq('bar.extraspace.value')
|
29
|
+
expect(subject['bar.extraspace']).to eq('baz.extraspace.value')
|
30
|
+
expect(subject['foo bar']).to eq('bar baz')
|
31
|
+
expect(subject['bar:baz']).to eq('baz quux')
|
32
|
+
expect(subject['foo bar:baz= quux']).to eq('this is getting ridiculous')
|
33
|
+
expect(subject['lots of fruit']).to eq('apple, peach, kiwi, mango, banana, strawberry, raspberry')
|
34
|
+
expect(subject['some.veggies']).to eq('carrot, potato, broccoli')
|
35
|
+
expect(subject['foo.empty']).to be_empty
|
36
|
+
expect(subject['bar.empty']).to be_empty
|
37
|
+
expect(subject['baz.empty']).to be_empty
|
38
|
+
expect(subject['quux.empty']).to be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it "#auto_expand" do
|
42
|
+
expect(subject['present']).to eq('This value contains two resolvable references, bar.normal.value and baz.extraspace.value')
|
43
|
+
expect(subject['missing']).to eq('This value contains one resolvable reference, bar.normal.value, and one unresolvable reference, ${quux.missing}')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "#auto_expand=false" do
|
47
|
+
subject.auto_expand = false
|
48
|
+
expect(subject['present']).to eq('This value contains two resolvable references, ${foo.normal} and ${bar.extraspace}')
|
49
|
+
expect(subject['missing']).to eq('This value contains one resolvable reference, ${foo.normal}, and one unresolvable reference, ${quux.missing}')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "delimiters" do
|
54
|
+
it "should retain original delimiters and spacing" do
|
55
|
+
expect(subject.to_a.find { |l| l =~ /^foo\.extraspace/ }).to eq('foo.extraspace = bar.extraspace.value')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should retain delimiters even after #set" do
|
59
|
+
subject['bar.extraspace'] = 'new value'
|
60
|
+
expect(subject.to_a.find { |l| l =~ /^bar\.extraspace/ }).to eq('bar.extraspace : new value')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should #normalize delimiters!" do
|
64
|
+
subject.normalize_delimiters!
|
65
|
+
expect(subject.to_a.find { |l| l =~ /^foo\.extraspace/ }).to eq('foo.extraspace=bar.extraspace.value')
|
66
|
+
end
|
67
|
+
|
68
|
+
it "#default_delimiter" do
|
69
|
+
subject.default_delimiter = ' : '
|
70
|
+
subject['new key'] = 'new value'
|
71
|
+
expect(subject.to_a.last).to eq('new\\ key : new value')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "comments and blanks" do
|
76
|
+
it "should leave comments and blanks alone" do
|
77
|
+
expect(subject.to_a.length).to eq(properties + comments + blanks)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should strip comments" do
|
81
|
+
subject.strip_comments!
|
82
|
+
expect(subject.to_a.length).to eq(properties + blanks)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should strip blanks" do
|
86
|
+
subject.strip_blanks!
|
87
|
+
expect(subject.to_a.length).to eq(properties + comments)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should strip comments and blanks" do
|
91
|
+
subject.compact!
|
92
|
+
expect(subject.to_a.length).to eq(properties)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "serialization" do
|
97
|
+
it "#inspect" do
|
98
|
+
expect(subject.inspect).to match(/\{.+\}/)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should round-trip" do
|
102
|
+
hash = subject.to_h.dup
|
103
|
+
array = subject.to_a
|
104
|
+
duplicate = DotProperties.parse(subject.to_s)
|
105
|
+
expect(duplicate.to_h).to eq(hash)
|
106
|
+
expect(duplicate.to_a).to eq(array)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "additional methods" do
|
111
|
+
it "#<<" do
|
112
|
+
subject << ""
|
113
|
+
subject << "# This is a comment on some.new.property"
|
114
|
+
subject << "some.new.property = some.new.value"
|
115
|
+
expect(subject['some.new.property']).to eq('some.new.value')
|
116
|
+
expect(subject.to_h.length).to eq(properties + 1)
|
117
|
+
expect(subject.to_a.length).to eq(properties + comments + blanks + 3)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "#delete" do
|
121
|
+
expect(subject.delete('foo bar')).to eq('bar baz')
|
122
|
+
expect(subject).not_to have_key('foo bar')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Sample .properties file for dot-properties specs
|
2
|
+
# It has 16 properties, 14 comments, and 8 blank lines
|
3
|
+
# It starts with some comments
|
4
|
+
|
5
|
+
# And then has a blank line
|
6
|
+
! followed by some other comments
|
7
|
+
# using various comment markers and
|
8
|
+
! spacing
|
9
|
+
|
10
|
+
# Normal properties
|
11
|
+
foo.normal=bar.normal.value
|
12
|
+
bar.normal:baz.normal.value
|
13
|
+
|
14
|
+
# Whitespace-delimited properties
|
15
|
+
foo.whitespace bar.whitespace.value
|
16
|
+
|
17
|
+
# Whitespace surrounding delimiters
|
18
|
+
foo.extraspace = bar.extraspace.value
|
19
|
+
bar.extraspace : baz.extraspace.value
|
20
|
+
|
21
|
+
# Escaped characters in keys
|
22
|
+
foo\ bar=bar baz
|
23
|
+
bar\:baz : baz quux
|
24
|
+
foo\ bar\:baz\=\ quux this is getting ridiculous
|
25
|
+
|
26
|
+
# Multiline values
|
27
|
+
lots\ of\ fruit apple, peach, kiwi, \
|
28
|
+
mango, banana, strawberry, \
|
29
|
+
raspberry
|
30
|
+
some.veggies=carrot, \
|
31
|
+
potato, \
|
32
|
+
broccoli
|
33
|
+
|
34
|
+
# Empty values
|
35
|
+
foo.empty
|
36
|
+
bar.empty=
|
37
|
+
baz.empty:
|
38
|
+
quux.empty =
|
39
|
+
|
40
|
+
# References
|
41
|
+
present = This value contains two resolvable references, ${foo.normal} and ${bar.extraspace}
|
42
|
+
missing = This value contains one resolvable reference, ${foo.normal}, and one unresolvable reference, ${quux.missing}
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dot-properties
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael B. Klein
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rdoc
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.4.2
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.4.2
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Java-style .properties file manipulation with a light touch
|
95
|
+
email:
|
96
|
+
- mbklein@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .travis.yml
|
103
|
+
- Gemfile
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- dot-properties.gemspec
|
108
|
+
- lib/dot-properties.rb
|
109
|
+
- lib/dot_properties.rb
|
110
|
+
- lib/dot_properties/version.rb
|
111
|
+
- spec/dot_properties_spec.rb
|
112
|
+
- spec/fixtures/sample.properties
|
113
|
+
homepage: https://github.com/mbklein/dot-properties
|
114
|
+
licenses:
|
115
|
+
- APACHE2
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
hash: -1306251061274732022
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: -1306251061274732022
|
138
|
+
requirements: []
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.8.23
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: Read/write .properties files, respecting comments and existing formatting
|
144
|
+
as much as possible
|
145
|
+
test_files:
|
146
|
+
- spec/dot_properties_spec.rb
|
147
|
+
- spec/fixtures/sample.properties
|