urn 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +89 -23
  4. data/lib/urn.rb +47 -10
  5. data/spec/urn_spec.rb +129 -26
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f729f3390ecec4c9843f007a1be16632ca7b1516
4
- data.tar.gz: b85858036290b073d73ddca76076f59fe4e9476e
3
+ metadata.gz: 8943094c2abdbd829f57606ac2f651ac1f16944a
4
+ data.tar.gz: 2e7adb38f071f23aa5325509ed77c87dc67c2abd
5
5
  SHA512:
6
- metadata.gz: 69b2624baef7186d9c1f4beea2fe468a01eb3c85134647a8b30761b46d3ce51a27bf2fa8d054744ff206a76010361a3b5eb39e6ba9e2551ef8d442da6aed82cc
7
- data.tar.gz: 3ace937ef1827b479377959d3bba1b7ebf87ff31690b18ad359571a4d59c15c73e3a2edfc09f69690ec548b47fa0458cf0e84c7ecefc54e09e9e166e7cbf5e85
6
+ metadata.gz: f19abc0d935c0e06f933dac8e3aba375c2f841072cdde554539216d2d8b544102934f5df025dcc7276fb5fb389ba5f50cd1310212227ada8ed0ea33c0ae7b729
7
+ data.tar.gz: 9a829c8512031bee7061ff5b7a521c66de6026dfa866dd43ce88937aaed832e00d6e7c14b385a262d285ff4d00971b7f89832cba56be1d772060d8e1f90da24e
@@ -2,6 +2,52 @@
2
2
  All notable changes to this project will be documented in this file. This
3
3
  project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [2.0.0] - 2016-03-22
6
+ ### Changed
7
+ - Only return `URN` instances for valid `URN`s at creation. Raise `URN::InvalidURNError` otherwise.
8
+ - `#normalize` returns a normalized `URN` object instead of its `String` representation. You can get the normalized `String` representation with `.normalize.to_s`
9
+ - Do not allow hexadecimal numbers from 0 to 20 and from 7F to FF. See [RFC2141](https://www.ietf.org/rfc/rfc2141.txt) section "2.4 Excluded characters".
10
+
11
+ ### Added
12
+ - Shortcut method (`URN()`) at creation:
13
+ ```ruby
14
+ urn = URN('URN:Name:Spec')
15
+ #=> #<URN:0x007fd97a835558 @urn="URN:Name:Spec">
16
+ ```
17
+ - `REGEX` into the API documentation
18
+ - `#nid` returns the namespace identifier part.
19
+ ```ruby
20
+ URN('URN:Name:Spec').nid
21
+ #=> "Name"
22
+ ```
23
+ - `#nss` returns the namespace specific string part.
24
+ ```ruby
25
+ URN('URN:Name:Spec').nss
26
+ #=> "Spec"
27
+ ```
28
+ - `#to_s` returns the `String` representation.
29
+ ```ruby
30
+ URN('URN:Name:Spec').to_s
31
+ #=> "URN:Name:Spec"
32
+ ```
33
+ - `#===(other)` returns true if the URN objects are equivalent. This method normalizes both URNs before doing the comparison, and allows comparison against Strings.
34
+ - `#==(other)` returns true if the URN objects are equivalent. This method normalizes both URNs before doing the comparison.
35
+ - `#eql?(other)` returns true if the URN objects are equal. This method does NOT normalize either URN before doing the comparison.
36
+ - `.extract(str)` attempts to parse and merge a set of URNs. If no `block` is given, then returns the result as an `Array`. Else it calls `block` for each element in result and returns `nil`.
37
+ - URN initialization accepts a `URN` as argument:
38
+ ```ruby
39
+ URN(URN('urn:foo:bar'))
40
+ #=> #<URN:0x007f85040434c8 @urn="urn:foo:bar">
41
+ ```
42
+
43
+ ### Removed
44
+ - `#valid?`. Validity check is now at object creation time, therefore all instances of `URN` are valid.
45
+
46
+
47
+ ## [1.0.0] - 2016-03-09
48
+ ### Changed
49
+ - The library is now [RFC2141](https://www.ietf.org/rfc/rfc2141.txt) compliant.
50
+
5
51
  ## [0.1.3] - 2016-03-07
6
52
  ### Fixed
7
53
  - Explicitly require CGI standard library
@@ -18,6 +64,8 @@ project adheres to [Semantic Versioning](http://semver.org/).
18
64
  ### Added
19
65
  - First version with basic implementation.
20
66
 
67
+ [2.0.0]: https://github.com/altmetric/urn/releases/tag/v2.0.0
68
+ [1.0.0]: https://github.com/altmetric/urn/releases/tag/v1.0.0
21
69
  [0.1.3]: https://github.com/altmetric/urn/releases/tag/v0.1.3
22
70
  [0.1.2]: https://github.com/altmetric/urn/releases/tag/v0.1.2
23
71
  [0.1.1]: https://github.com/altmetric/urn/releases/tag/v0.1.1
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # URN [![Build Status](https://travis-ci.org/altmetric/urn.svg?branch=master)](https://travis-ci.org/altmetric/urn)
2
2
 
3
- Ruby library to validate and normalize URNs.
3
+ Ruby library to validate and normalize URNs according to [RFC 2141](https://www.ietf.org/rfc/rfc2141.txt).
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/urn.svg)](https://badge.fury.io/rb/urn)
4
6
 
5
- **Current version:** 0.1.3
6
7
  **Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0, 2.1, 2.2, 2.3
7
8
 
8
9
  ## Installation
@@ -10,7 +11,7 @@ Ruby library to validate and normalize URNs.
10
11
  Add this line to your application's `Gemfile`:
11
12
 
12
13
  ```ruby
13
- gem 'urn', '~> 0.1'
14
+ gem 'urn', '~> 2.0'
14
15
  ```
15
16
 
16
17
  And then execute:
@@ -19,62 +20,127 @@ And then execute:
19
20
 
20
21
  Or install it yourself as:
21
22
 
22
- $ gem install urn -v '~> 0.1'
23
+ $ gem install urn -v '~> 2.0'
23
24
 
24
25
  ## Usage
25
26
 
26
27
  ```ruby
27
- urn = URN.new('URN:NameSpace:Identifier')
28
+ urn = URN('URN:NameSpace:Identifier')
28
29
  #=> #<URN:0x007fd97a835558 @urn="URN:NameSpace:Identifier">
29
30
 
30
- urn.valid?
31
- #=> true
31
+ urn = URN.new('URN:NameSpace:Identifier')
32
+ #=> #<URN:0x007fd97a835558 @urn="URN:NameSpace:Identifier">
32
33
 
33
34
  urn.normalize
34
35
  #=> "urn:namespace:Identifier"
36
+
37
+ urn = URN('123')
38
+ #=> URN::InvalidURNError: bad URN(is not URN?): 123
35
39
  ```
36
40
 
37
41
  ## API Documentation
38
42
 
39
43
  ### `URN::PATTERN`
40
-
41
44
  ```ruby
42
45
  text.match(/\?urn=(#{URN::PATTERN})/)
43
46
  ```
47
+ Return a `String` of an unanchored regular expression suitable for matching URNs.
44
48
 
45
- Return a `String` of an unanchored regular expression suitable for matching
46
- URNs.
47
-
48
- ### `URN.new`
49
+ ### `URN::REGEX`
50
+ ```ruby
51
+ URN::REGEX
52
+ #=> /\A(?i:urn:(?!urn:)[a-z0-9][a-z0-9-]{1,31}:(?:[a-z0-9()+,-.:=@;$_!*']|%[0-9a-f]{2})+)\z/
53
+ ```
54
+ Return a `Regexp` object with the anchored regular expression suitable to match a URN.
49
55
 
56
+ ### `URN()` or `URN.new`
50
57
  ```ruby
58
+ urn = URN('urn:nid:nss')
59
+ #=> #<URN:0xdecafbad @urn="urn:nid:nss">
60
+
51
61
  urn = URN.new('urn:nid:nss')
52
62
  #=> #<URN:0xdecafbad @urn="urn:nid:nss">
63
+
64
+ urn = URN('1234')
65
+ #=> URN::InvalidURNError: bad URN(is not URN?): 1234
53
66
  ```
67
+ Return a new `URN` instance when the given string is valid according to [RFC 2141](https://www.ietf.org/rfc/rfc2141.txt). Otherwise, it raises an `URN::InvalidURNError`
54
68
 
55
- Return a new `URN` instance with the given string.
69
+ ### `URN#normalize`
70
+ ```ruby
71
+ URN('URN:FOO:BAR').normalize
72
+ #=> #<URN:0x007fb9a3096848 @urn="urn:foo:BAR">
73
+ ```
74
+ Return the normalized `URN` object, normalizing the case
75
+ of the `urn` token and namespace identifier. Call `#to_s` after `#normalize` if you want the normalized `String` representation.
56
76
 
57
- ### `URN#valid?`
77
+ ### `URN#nid`
78
+ ```ruby
79
+ URN('urn:nid:nss').nid
80
+ #=> "nid"
81
+ ```
82
+ Return the namespace identifier part.
58
83
 
84
+ ### `URN#nss`
59
85
  ```ruby
60
- URN.new('foo').valid?
61
- #=> false
86
+ URN('urn:nid:nss').nss
87
+ #=> "nss"
88
+ ```
89
+ Return the namespace specific string part.
90
+
91
+ ### `URN#to_s`
92
+ ```ruby
93
+ URN('urn:Nid:Nss').to_s
94
+ #=> "urn:Nid:Nss"
95
+ ```
96
+ Return the `String` representation.
97
+
98
+ ### `#===(other)`
99
+ ```ruby
100
+ URN('urn:name:spec') === 'URN:Name:spec'
101
+ #=> true
62
102
 
63
- URN.new('urn:foo:bar').valid?
103
+ URN('urn:name:spec') === URN('URN:Name:spec')
64
104
  #=> true
65
105
  ```
106
+ Return true if the URN objects are equivalent. This method normalizes both URNs before doing the comparison, and allows comparison against Strings.
66
107
 
67
- Returns true if the `URN` is valid according to [RFC 2141](https://www.ietf.org/rfc/rfc2141.txt).
108
+ ### `#==(other)`
109
+ ```ruby
110
+ URN('urn:name:spec') == 'URN:Name:spec'
111
+ #=> false
68
112
 
69
- ### `URN#normalize`
113
+ URN('urn:name:spec') == URN('URN:Name:spec')
114
+ #=> true
115
+ ```
116
+ Returns true if the URN objects are equivalent. This method normalizes both URNs before doing the comparison.
70
117
 
118
+ ### `#eql?(other)`
71
119
  ```ruby
72
- URN.new('URN:FOO:BAR').normalize
73
- #=> "urn:foo:BAR"
120
+ URN('urn:name:spec').eql?('urn:name:spec')
121
+ #=> false
122
+
123
+ URN('urn:name:spec').eql?(URN('urn:NAME:spec'))
124
+ #=> false
125
+
126
+ URN('urn:name:spec').eql?(URN('urn:name:spec'))
127
+ #=> true
74
128
  ```
129
+ Returns true if the URN objects are equal. This method does NOT normalize either URN before doing the comparison.
75
130
 
76
- Return a normalized `String` representation of the `URN`, normalizing the case
77
- of the `urn` token and namespace identifier.
131
+ ### `.extract(str)`
132
+ ```ruby
133
+ URN.extract('text urn:1234:abc more text URN:foo:bar%23.\\')
134
+ #=> ['urn:1234:abc', 'URN:foo:bar%23.']
135
+
136
+ normalized_urns = []
137
+ #=> []
138
+ URN.extract('text urn:1234:abc more text URN:foo:bar%23.\\') { |urn| normalized_urns << URN(urn).normalize.to_s }
139
+ #=> nil
140
+ normalized_urns
141
+ #=> ['urn:1234:abc', 'URN:foo:bar%23.']
142
+ ```
143
+ Extracts URNs from a string. If block given, iterates through all matched URNs. Returns nil if block given or array with matches.
78
144
 
79
145
  ## Contributing
80
146
 
data/lib/urn.rb CHANGED
@@ -1,26 +1,63 @@
1
+ def URN(urn)
2
+ URN.new(urn)
3
+ end
4
+
1
5
  class URN
6
+ InvalidURNError = Class.new(StandardError)
7
+
2
8
  PATTERN = %{(?i:urn:(?!urn:)[a-z0-9][a-z0-9\-]{1,31}:} +
3
- %{(?:[a-z0-9()+,-.:=@;$_!*']|%[0-9a-f]{2})+)}.freeze
9
+ %{(?:[a-z0-9()+,-.:=@;$_!*']|%(?:2[1-9a-f]|[3-6][0-9a-f]|7[0-9a-e]))+)}.freeze
4
10
  REGEX = /\A#{PATTERN}\z/
5
11
 
6
- attr_reader :urn
12
+ attr_reader :urn, :nid, :nss
7
13
  private :urn
8
14
 
9
- def initialize(urn)
10
- @urn = urn
15
+ def self.extract(str, &blk)
16
+ str.scan(/#{PATTERN}/, &blk)
11
17
  end
12
18
 
13
- def valid?
14
- !(urn =~ REGEX).nil?
19
+ def initialize(urn)
20
+ urn = urn.to_s
21
+ fail InvalidURNError, "bad URN(is not URN?): #{urn}" if urn !~ REGEX
22
+
23
+ @urn = urn
24
+ _scheme, @nid, @nss = urn.split(':', 3)
15
25
  end
16
26
 
17
27
  def normalize
18
- return unless valid?
19
-
20
- _scheme, nid, nss = urn.split(':', 3)
21
28
  normalized_nid = nid.downcase
22
29
  normalized_nss = nss.gsub(/%([0-9a-f]{2})/i) { |hex| hex.downcase }
23
30
 
24
- "urn:#{normalized_nid}:#{normalized_nss}"
31
+ URN.new("urn:#{normalized_nid}:#{normalized_nss}")
32
+ end
33
+
34
+ def to_s
35
+ urn
36
+ end
37
+
38
+ def ===(other)
39
+ if other.respond_to?(:normalize)
40
+ urn_string = other.normalize.to_s
41
+ else
42
+ begin
43
+ urn_string = URN.new(other).normalize.to_s
44
+ rescue URN::InvalidURNError
45
+ return false
46
+ end
47
+ end
48
+
49
+ normalize.to_s == urn_string
50
+ end
51
+
52
+ def ==(other)
53
+ return false unless other.is_a?(URN)
54
+
55
+ normalize.to_s == other.normalize.to_s
56
+ end
57
+
58
+ def eql?(other)
59
+ return false unless other.is_a?(URN)
60
+
61
+ to_s == other.to_s
25
62
  end
26
63
  end
@@ -2,65 +2,168 @@
2
2
  require 'urn'
3
3
 
4
4
  RSpec.describe URN do
5
- describe '#valid?' do
6
- it 'returns true if it is valid' do
7
- expect(described_class.new('urn:namespace:specificstring')).to be_valid
5
+ describe 'URN' do
6
+ it 'returns a URN if it is valid' do
7
+ expect(URN('urn:namespace:specificstring')).to be_kind_of(described_class)
8
8
  end
9
9
 
10
- it 'returns true if namespace includes urn' do
11
- expect(described_class.new('urn:urnnamespace:specificstring')).to be_valid
10
+ it 'raise InvalidURNError if it is not valid' do
11
+ expect { URN('urn:urn:1234') }.to raise_error(described_class::InvalidURNError, 'bad URN(is not URN?): urn:urn:1234')
12
12
  end
13
13
 
14
- it 'returns false if it does not start with urn' do
15
- expect(described_class.new('not-urn:namespace:specificstring')).not_to be_valid
14
+ it 'returns the same URN if the argument is a URN' do
15
+ urn = URN.new('urn:foo:bar')
16
+
17
+ expect(URN(urn).to_s).to eq('urn:foo:bar')
18
+ end
19
+ end
20
+
21
+ describe '#initialize' do
22
+ it 'returns the same URN if the argument is a URN' do
23
+ urn = URN.new('urn:foo:bar')
24
+
25
+ expect(URN.new(urn).to_s).to eq('urn:foo:bar')
26
+ end
27
+
28
+ it 'returns a URN if it is valid' do
29
+ expect(described_class.new('urn:namespace:specificstring')).to be_kind_of(described_class)
16
30
  end
17
31
 
18
- it 'returns false if namespace is urn' do
19
- expect(described_class.new('urn:urn:specificstring')).not_to be_valid
32
+ it 'raise InvalidURNError if it is not valid' do
33
+ expect { described_class.new('urn:urn:1234') }.to raise_error(described_class::InvalidURNError, 'bad URN(is not URN?): urn:urn:1234')
20
34
  end
21
35
 
22
- it 'returns false if namespace is URN' do
23
- expect(described_class.new('urn:URN:specificstring')).not_to be_valid
36
+ it 'returns a URN if namespace includes urn' do
37
+ expect(described_class.new('urn:urnnamespace:specificstring')).to be_kind_of(described_class)
38
+ end
39
+
40
+ it 'raises an error if it does not start with urn' do
41
+ expect { described_class.new('not-urn:namespace:specificstring') }.to raise_error(described_class::InvalidURNError)
42
+ end
43
+
44
+ it 'raises an error if namespace is urn' do
45
+ expect { described_class.new('urn:urn:specificstring') }.to raise_error(described_class::InvalidURNError)
46
+ end
47
+
48
+ it 'raises an error if namespace is URN' do
49
+ expect { described_class.new('urn:URN:specificstring') }.to raise_error(described_class::InvalidURNError)
24
50
  end
25
51
 
26
52
  it 'returns true if the namespace identifier is 32 characters long' do
27
53
  nid = 'a' * 32
28
54
 
29
- expect(described_class.new("urn:#{nid}:bar")).to be_valid
55
+ expect(described_class.new("urn:#{nid}:bar")).to be_kind_of(described_class)
30
56
  end
31
57
 
32
- it 'returns false if the namespace identifier begins with a hyphen' do
33
- expect(described_class.new('urn:-foo:bar')).not_to be_valid
58
+ it 'raises an error if the namespace identifier begins with a hyphen' do
59
+ expect { described_class.new('urn:-foo:bar') }.to raise_error(described_class::InvalidURNError)
34
60
  end
35
61
 
36
- it 'returns false if the namespace specific string has invalid escaping' do
37
- expect(described_class.new('urn:foo:bar%2')).not_to be_valid
62
+ it 'raises an error if the namespace specific string has invalid escaping' do
63
+ expect { described_class.new('urn:foo:bar%2') }.to raise_error(described_class::InvalidURNError)
38
64
  end
39
65
 
40
- it 'returns false if the namespace specific string has reserved characters' do
41
- expect(described_class.new('urn:foo:café')).not_to be_valid
66
+ it 'raises an error if the namespace specific string has reserved characters' do
67
+ expect { described_class.new('urn:foo:café') }.to raise_error(described_class::InvalidURNError)
42
68
  end
43
- end
44
69
 
45
- describe '#normalize' do
46
- it 'returns nil if it is not valid' do
47
- expect(described_class.new('urn:').normalize).to be_nil
70
+ it 'raises an error if the namespace specific string has a not allowed hexadecimal value' do
71
+ expect { described_class.new('urn:foo:abc%10') }.to raise_error(described_class::InvalidURNError)
48
72
  end
73
+ end
49
74
 
75
+ describe '#normalize' do
50
76
  it 'lowercases the leading "urn:" token' do
51
- expect(described_class.new('URN:foo:123').normalize).to eq('urn:foo:123')
77
+ expect(described_class.new('URN:foo:123').normalize.to_s).to eq('urn:foo:123')
52
78
  end
53
79
 
54
80
  it 'lowercases the namespace identifier' do
55
- expect(described_class.new('urn:FOO:123').normalize).to eq('urn:foo:123')
81
+ expect(described_class.new('urn:FOO:123').normalize.to_s).to eq('urn:foo:123')
56
82
  end
57
83
 
58
84
  it 'lowercases %-escaping in the namespace specific string' do
59
- expect(described_class.new('urn:foo:123%2C456').normalize).to eq('urn:foo:123%2c456')
85
+ expect(described_class.new('urn:foo:123%2C456').normalize.to_s).to eq('urn:foo:123%2c456')
60
86
  end
61
87
 
62
88
  it 'does not lowercase other characters in the namespace specific string' do
63
- expect(described_class.new('urn:foo:BA%2CR').normalize).to eq('urn:foo:BA%2cR')
89
+ expect(described_class.new('urn:foo:BA%2CR').normalize.to_s).to eq('urn:foo:BA%2cR')
90
+ end
91
+ end
92
+
93
+ describe '#nid' do
94
+ it 'returns the namespace identifier' do
95
+ expect(described_class.new('urn:namespace:specificstring').nid).to eq('namespace')
96
+ end
97
+ end
98
+
99
+ describe '#nss' do
100
+ it 'returns the namespace specific string' do
101
+ expect(described_class.new('urn:namespace:specificstring').nss).to eq('specificstring')
102
+ end
103
+ end
104
+
105
+ describe '#to_s' do
106
+ it 'returns the string representation of the URN' do
107
+ expect(described_class.new('urn:Name:Spec').to_s).to eq('urn:Name:Spec')
108
+ end
109
+ end
110
+
111
+ describe '#===' do
112
+ it 'returns true if the string is an equivalent valid URN' do
113
+ expect(described_class.new('urn:name:spec') === 'URN:Name:spec').to be(true)
114
+ end
115
+
116
+ it 'returns true if the normalized object of the other class is equal' do
117
+ expect(described_class.new('urn:name:spec') === URI('urn:name:spec')).to be(true)
118
+ end
119
+
120
+ it 'returns true if the URN object is an equivalent valid URN' do
121
+ expect(described_class.new('urn:name:spec') === described_class.new('URN:Name:spec')).to be(true)
122
+ end
123
+
124
+ it 'returns false if the URN is not equivalent' do
125
+ expect(described_class.new('urn:name:spec') === described_class.new('URN:Name:SPEC')).to be(false)
126
+ end
127
+
128
+ it 'return false if the URN is not valid' do
129
+ expect(described_class.new('urn:name:spec') === 'urn:urn:urn').to be(false)
130
+ end
131
+ end
132
+
133
+ describe '#==' do
134
+ it 'returns true if the URN object is an equivalent valid URN' do
135
+ expect(described_class.new('urn:name:spec')).to eq(described_class.new('URN:Name:spec'))
136
+ end
137
+
138
+ it 'returns false if the argument is not a URN object' do
139
+ expect(described_class.new('urn:name:spec')).not_to eq('urn:name:spec')
140
+ end
141
+ end
142
+
143
+ describe '#eql?' do
144
+ it 'returns true if both URNs are equal' do
145
+ expect(described_class.new('urn:Name:Spec')).to eql(described_class.new('urn:Name:Spec'))
146
+ end
147
+
148
+ it 'returns false if the URNs are not equal' do
149
+ expect(described_class.new('urn:name:spec')).not_to eql(described_class.new('urn:Name:spec'))
150
+ end
151
+ end
152
+
153
+ describe '.extract' do
154
+ it 'extracts the URNs from a string' do
155
+ str = 'En un pueblo italiano urn:1234:abc al pie de la montaña URN:foo:bar%23.\\'
156
+
157
+ expect(URN.extract(str)).to contain_exactly('urn:1234:abc', 'URN:foo:bar%23.')
158
+ end
159
+
160
+ it 'extracts the URNs from a string using a block' do
161
+ str = 'Llum, foc, destrucció. urn:foo:%10 El món pot ser només una runa, URN:FOO:BA%2cR això no ho consentirem.'
162
+
163
+ normalized_urns = []
164
+ URN.extract(str) { |urn| normalized_urns << URN(urn).normalize.to_s }
165
+
166
+ expect(normalized_urns).to contain_exactly('urn:foo:BA%2cR')
64
167
  end
65
168
  end
66
169
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ana Castro
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2016-03-09 00:00:00.000000000 Z
13
+ date: 2016-03-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler