aws_config 0.0.4 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50d2a27d4fa0613f456f1b3da9fa72c8ea6bc9e7
4
- data.tar.gz: 5e755930909eae2434eda5290724278d4e6a82bb
3
+ metadata.gz: 88a82fbb7b9a68a42fdcc7f1cc9139ddd5d4b8bd
4
+ data.tar.gz: 6d0a314b119d49b0f52fd72b6660130daa63ad32
5
5
  SHA512:
6
- metadata.gz: 0ad003aa7df45d64bfd53c66a7df78aeaa8332596290432b30b28280ff215f63bc9dfa1a731b685dabd61661798d3aba277ce2b0aededcd66d96e18ee2d29cfc
7
- data.tar.gz: 17824affad770dbe373da8528a7648b947278dea200224cff19b1b1fd2a2864f783d05556f3d0e74a8b1dae8c4ccd49f9f3536f71a3231d7f8d113227d8a3585
6
+ metadata.gz: 823e225fc21dfe091ac67fd1cd2f3c0dd807fa464768e5d27b31cca99aac1219b828dd34592960a99f17216c60daaf9d0e0e433caef0f22da348b8f9181efced
7
+ data.tar.gz: b64deea1c8c374456d36e826776a3e737d45f04fd7d7b7a48dff26860d98ad373af3e75cf8651866cbd8a94b12445a9a6ee29f192b7de090054309d8768e95c4
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ vendor
@@ -6,70 +6,58 @@ module AWSConfig
6
6
  attr_accessor :credential_file_mode
7
7
 
8
8
  def self.parse(string, credential_file_mode = false)
9
- parser = new
10
- parser.credential_file_mode = credential_file_mode
11
- parser.parse(string)
9
+ from_hash(new.tokenize(string))
12
10
  end
13
11
 
14
- def parse(string)
15
- wrap(build(tokenize(string)))
16
- end
17
-
18
- private
19
-
20
- def tokenize(string)
21
- s = StringScanner.new(string)
22
- tokens = []
23
-
24
- until s.eos?
25
- if s.scan(/\[\s*([^\]]+)\s*\]/)
26
- if s[1] == "default"
27
- tokens << [:profile, "default"]
28
- elsif m = s[1].match(/profile\s+([^\s]+)$/)
29
- tokens << [:profile, m[1]]
30
- elsif credential_file_mode
31
- tokens << [:profile, s[1]]
32
- end
33
- elsif s.scan(/([^\s=#]+)\s*=\s*([^\s#]+)/)
34
- tokens << [:key_value, s[1], s[2]]
35
- elsif s.scan(/#[^\n]*/)
36
- elsif s.scan(/\s+/)
37
- elsif s.scan(/\n+/)
38
- else
39
- s.scan(/./)
40
- raise "Invalid token `#{s[0]}` as #{s.pos}"
41
- end
12
+ def self.from_hash(hash)
13
+ hash.inject({}) do |memo, (k,v)|
14
+ if v.is_a?(Hash)
15
+ memo[k]=Profile.new(k,v)
16
+ else
17
+ memo[k] = v
42
18
  end
43
19
 
44
- tokens
20
+ memo
45
21
  end
22
+ end
46
23
 
47
- def build(tokens)
48
- tokens = tokens.dup
49
- profiles = {}
50
- profile = nil
51
-
52
- while values = tokens.shift
53
- head = values.shift
24
+ def tokenize(string)
25
+ tokens = { }
26
+ current_profile = nil
27
+ current_nesting = nil
28
+
29
+ string.lines.each do |line|
30
+ comment = line.match(/^\s*#.*/)
31
+ blank = line.match(/^\s*$/)
32
+ next if comment || blank
33
+
34
+ profile_match = line.match(/\[\s*(profile)?\s*(?<profile>[^\]]+)\s*\]/)
35
+ if profile_match
36
+ current_profile = profile_match[:profile]
37
+ tokens[current_profile] ||= {}
38
+ next
39
+ end
54
40
 
55
- case head
56
- when :profile
57
- profile = profiles[values[0]] ||= {}
58
- when :key_value
59
- if profile
60
- profile[values[0]] = values[1]
61
- end
41
+ nest_key_value = line.match(/(?<nest>^\s+)?(?<key>[^\s=#]+)\s*=\s*(?<value>[^\s#]+)/)
42
+ if nest_key_value
43
+ nest, key, value = !!nest_key_value[:nest], nest_key_value[:key], nest_key_value[:value]
44
+ if nest
45
+ fail("Nesting without a parent error") if current_nesting.nil?
46
+ tokens[current_profile][current_nesting][key] = value
47
+ else
48
+ current_nesting = nil
49
+ tokens[current_profile][key] = value
62
50
  end
51
+ next
63
52
  end
64
53
 
65
- profiles
66
- end
67
-
68
- def wrap(profiles)
69
- profiles.inject({}) do |s, (name, properties)|
70
- s[name] = Profile.new(name, properties)
71
- s
54
+ nesting = line.match(/(?<name>[^\s=#]+)\s*=.*/)
55
+ if nesting
56
+ current_nesting = nesting[:name]
57
+ tokens[current_profile][current_nesting] ||= {}
72
58
  end
73
59
  end
60
+ tokens
61
+ end
74
62
  end
75
63
  end
@@ -58,15 +58,8 @@ module AWSConfig
58
58
  }
59
59
  end
60
60
 
61
- # Returns a new profile from the two merged profiles
62
- def merge(profile)
63
- merged = entries.dup
64
- merged.merge! profile.entries
65
- new name, merged
66
- end
67
-
68
- def merge!(profile)
69
- entries.merge! profile.entries
61
+ def merge!(other)
62
+ @entries = Parser.from_hash(entries.merge(other.entries))
70
63
  self
71
64
  end
72
65
  end
@@ -1,3 +1,3 @@
1
1
  module AWSConfig
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -11,12 +11,93 @@ aws_access_key_id=DefaultAccessKey01
11
11
  aws_secret_access_key=Default/Secret/Access/Key/02
12
12
  region=us-west-1
13
13
  EOC
14
- it { should eq [
15
- [:profile, "default"],
16
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
17
- [:key_value, "aws_secret_access_key", "Default/Secret/Access/Key/02"],
18
- [:key_value, "region", "us-west-1"]
19
- ] }
14
+ it { should eq(
15
+ "default" => {
16
+ "aws_access_key_id" => "DefaultAccessKey01",
17
+ "aws_secret_access_key" => "Default/Secret/Access/Key/02",
18
+ "region" => "us-west-1" }
19
+ ) }
20
+ end
21
+
22
+ context "with nesting" do
23
+ let(:string) { <<-EOC }
24
+ [default]
25
+ region=us-east-1
26
+ s3=
27
+ max_concurrent_requests=100101
28
+ max_queue_size=20
29
+ output=json
30
+ EOC
31
+ it { should eq(
32
+ "default" => {
33
+ "region" => "us-east-1",
34
+ "s3" => {
35
+ "max_concurrent_requests" => "100101",
36
+ "max_queue_size" => "20"
37
+ },
38
+ "output" => "json" }
39
+ ) }
40
+ end
41
+
42
+ context "invalid nesting" do
43
+ let(:string) { <<-EOC }
44
+ [default]
45
+ region=us-east-1
46
+ s3=
47
+ max_concurrent_requests=100101
48
+ output=json
49
+ max_queue_size=20
50
+ EOC
51
+ it "raises an exception" do
52
+ expect { subject }.to raise_error(RuntimeError, "Nesting without a parent error")
53
+ end
54
+ end
55
+
56
+ context "multiple nesting" do
57
+ let(:string) { <<-EOC }
58
+ [default]
59
+ region=us-east-1
60
+ s3=
61
+ max_concurrent_requests=100101
62
+ max_queue_size=20
63
+ output=json
64
+ api_versions =
65
+ ec2 = 2015-03-01
66
+ cloudfront = 2015-09-17
67
+ EOC
68
+ it { should eq(
69
+ "default" => {
70
+ "region" => "us-east-1",
71
+ "s3" => {
72
+ "max_concurrent_requests" => "100101",
73
+ "max_queue_size" => "20"
74
+ },
75
+ "output" => "json",
76
+ "api_versions" => {
77
+ "ec2" => "2015-03-01",
78
+ "cloudfront" => "2015-09-17"
79
+ }
80
+ }
81
+ ) }
82
+ end
83
+
84
+ context "with comments" do
85
+ let(:string) { <<-EOC }
86
+ [default] # inline comment in a profile
87
+ region=us-east-1 # inline comment in top level element
88
+ s3= # inline comment in nesting openning
89
+ max_concurrent_requests=100101 # inline comment in a nested element
90
+ # comment prefixed with spaces
91
+ # comment in a new line
92
+ EOC
93
+ it { should eq(
94
+ "default" => {
95
+ "region" => "us-east-1",
96
+ "s3" => {
97
+ "max_concurrent_requests" => "100101",
98
+ }
99
+ }
100
+ ) }
20
101
  end
21
102
 
22
103
  context "default and named profiles" do
@@ -27,12 +108,10 @@ aws_access_key_id=DefaultAccessKey01
27
108
  [profile testing]
28
109
  aws_access_key_id=TestingAccessKey03
29
110
  EOC
30
- it { should eq [
31
- [:profile, "default"],
32
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
33
- [:profile, "testing"],
34
- [:key_value, "aws_access_key_id", "TestingAccessKey03"],
35
- ] }
111
+ it { should eq(
112
+ "default" => { "aws_access_key_id" => "DefaultAccessKey01" },
113
+ "testing" => { "aws_access_key_id" => "TestingAccessKey03" }
114
+ ) }
36
115
 
37
116
  context "Comment line" do
38
117
  let(:string) { <<-EOC }
@@ -40,10 +119,9 @@ aws_access_key_id=TestingAccessKey03
40
119
  # THIS IS COMMENT #
41
120
  aws_access_key_id=DefaultAccessKey01
42
121
  EOC
43
- it { should eq [
44
- [:profile, "default"],
45
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"]
46
- ] }
122
+ it { should eq(
123
+ "default" => { "aws_access_key_id" => "DefaultAccessKey01" }
124
+ ) }
47
125
  end
48
126
 
49
127
  context "Blank line" do
@@ -53,10 +131,9 @@ aws_access_key_id=DefaultAccessKey01
53
131
 
54
132
  aws_access_key_id=DefaultAccessKey01
55
133
  EOC
56
- it { should eq [
57
- [:profile, "default"],
58
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"]
59
- ] }
134
+ it { should eq(
135
+ "default" => { "aws_access_key_id" => "DefaultAccessKey01" }
136
+ ) }
60
137
  end
61
138
  end
62
139
 
@@ -67,108 +144,31 @@ aws_access_key_id=DefaultAccessKey01
67
144
  sut.send(:tokenize, string)
68
145
  end
69
146
  context "with only the default profile" do
70
- let(:string) do
71
- <<-EOC
72
- [default]
73
- aws_access_key_id=DefaultAccessKey01
74
- aws_secret_access_key=Default/Secret/Access/Key/02
75
- EOC
76
- end
77
- it { should eq [
78
- [:profile, "default"],
79
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
80
- [:key_value, "aws_secret_access_key", "Default/Secret/Access/Key/02"],
81
- ] }
147
+ let(:string) { <<-EOC }
148
+ [default]
149
+ aws_access_key_id=DefaultAccessKey01
150
+ aws_secret_access_key=Default/Secret/Access/Key/02
151
+ EOC
152
+ it { should eq(
153
+ "default" => {
154
+ "aws_access_key_id" => "DefaultAccessKey01",
155
+ "aws_secret_access_key" => "Default/Secret/Access/Key/02"
156
+ }
157
+ ) }
82
158
  end
83
159
 
84
160
  context "with the default and named profiles" do
85
- let(:string) do
86
- <<-EOC
87
- [default]
88
- aws_access_key_id=DefaultAccessKey01
89
-
90
- [testing]
91
- aws_access_key_id=TestingAccessKey03
92
- EOC
93
- end
94
- it { should eq [
95
- [:profile, "default"],
96
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
97
- [:profile, "testing"],
98
- [:key_value, "aws_access_key_id", "TestingAccessKey03"],
99
- ] }
100
- end
101
- end
102
- end
103
-
104
- describe "#build" do
105
- subject { described_class.new.send(:build, tokens) }
106
-
107
- context "Single profile" do
108
- let(:tokens) { [
109
- [:profile, "default"],
110
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
111
- [:key_value, "aws_secret_access_key", "Default/Secret/Access/Key/02"],
112
- [:key_value, "region", "us-west-1"]
113
- ] }
114
- it { should eq({
115
- "default" => {
116
- "aws_access_key_id" => "DefaultAccessKey01",
117
- "aws_secret_access_key" => "Default/Secret/Access/Key/02",
118
- "region" => "us-west-1"
119
- }
120
- }) }
121
- end
122
-
123
- context "Multi profiles" do
124
- let(:tokens) { [
125
- [:profile, "default"],
126
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
127
- [:profile, "testing"],
128
- [:key_value, "aws_access_key_id", "TestingAccessKey02"],
129
- ] }
130
- it { should eq({
131
- "default" => { "aws_access_key_id" => "DefaultAccessKey01" },
132
- "testing" => { "aws_access_key_id" => "TestingAccessKey02" }
133
- }) }
134
- end
135
-
136
- context "Twice-defined single profile" do
137
- let(:tokens) { [
138
- [:profile, "default"],
139
- [:key_value, "aws_access_key_id", "DefaultAccessKey01"],
140
- [:key_value, "region", "us-west-1"],
141
- [:profile, "default"],
142
- [:key_value, "aws_access_key_id", "DefaultAccessKey01_ANOTHER"],
143
- [:key_value, "aws_secret_access_key", "Default/Secret/Access/Key/01"],
144
- ] }
145
- it { should eq({
146
- "default" => {
147
- "aws_access_key_id" => "DefaultAccessKey01_ANOTHER",
148
- "aws_secret_access_key" => "Default/Secret/Access/Key/01",
149
- "region" => "us-west-1"
150
- }
151
- }) }
152
- end
153
- end
154
-
155
- describe "#wrap" do
156
- subject { described_class.new.send(:wrap, profiles) }
161
+ let(:string) { <<-EOC }
162
+ [default]
163
+ aws_access_key_id=DefaultAccessKey01
157
164
 
158
- context "Single profile" do
159
- let(:profiles) {
160
- {
161
- "default" => {
162
- "aws_access_key_id" => "DefaultAccessKey01",
163
- "aws_secret_access_key" => "Default/Secret/Access/Key/02",
164
- "region" => "us-west-1"
165
- }
166
- }
167
- }
168
- it { should be_a Hash }
169
- it { should have_key "default" }
170
- it "should have AWSConfig::Profile as value" do
171
- expect(subject["default"]).to be_a AWSConfig::Profile
165
+ [testing]
166
+ aws_access_key_id=TestingAccessKey03
167
+ EOC
168
+ it { should eq(
169
+ "default" => { "aws_access_key_id" => "DefaultAccessKey01" },
170
+ "testing" => { "aws_access_key_id" => "TestingAccessKey03" }
171
+ ) }
172
172
  end
173
173
  end
174
174
  end
@@ -11,10 +11,17 @@ describe AWSConfig do
11
11
  it "should return an entry in a profile via method" do
12
12
  expect(described_class.default.aws_access_key_id).to eq "DefaultAccessKey01"
13
13
  expect(described_class.default.region).to eq "us-west-1"
14
+ expect(described_class.default.output).to eq "json"
15
+ expect(described_class.default.s3.max_concurrent_requests).to eq "100101"
16
+ expect(described_class.default.s3.max_queue_size).to eq "20"
14
17
  end
15
18
 
16
19
  it "should return an entry in a profile like hashes" do
17
20
  expect(described_class["default"]["aws_access_key_id"]).to eq "DefaultAccessKey01"
18
21
  expect(described_class["default"]["region"]).to eq "us-west-1"
22
+ expect(described_class["default"]["output"]).to eq "json"
23
+ expect(described_class["default"]["s3"]["max_concurrent_requests"]).
24
+ to eq "100101"
25
+ expect(described_class["default"]["s3"]["max_queue_size"]).to eq "20"
19
26
  end
20
27
  end
@@ -2,7 +2,13 @@
2
2
  # Optional, to define default region for this profile.
3
3
  region=us-west-1
4
4
  source_profile=default
5
+ # Nested
6
+ s3=
7
+ max_concurrent_requests=100101
8
+ max_queue_size=20
9
+ output=json
5
10
 
6
11
  [profile testing]
7
12
  region=us-west-2
8
13
  source_profile=testing
14
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masato Ikeda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-05 00:00:00.000000000 Z
11
+ date: 2017-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
100
  version: '0'
101
101
  requirements: []
102
102
  rubyforge_project:
103
- rubygems_version: 2.5.1
103
+ rubygems_version: 2.6.8
104
104
  signing_key:
105
105
  specification_version: 4
106
106
  summary: AWSConfig is a parser for AWS_CONFIG_FILE used in aws-cli.