rake_circle_ci 0.10.0.pre.4 → 0.10.0.pre.7

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
  SHA256:
3
- metadata.gz: fa307a2276542c67d73d861a659df253f36618d6c27e5d25be7a3b9b06df3819
4
- data.tar.gz: c2f62ff03caf6a244b7648272bfaacaf041bb216fd8baec44418f9453f7caa5c
3
+ metadata.gz: 799f94557915913f8f49a505d1f36fc022f291bee34ea54982486c4d2ed0c251
4
+ data.tar.gz: eb1d7ade7b37375721bb70b80e7d148fb99a00886f213da1015d26f7a9e40a2d
5
5
  SHA512:
6
- metadata.gz: 3d8cbed1081ee0b81499fa3d75acdcc5266c24662cb3df1db80abc3fb6d23f883787eb4acf2acc4b8597e101f59b5e334fd614cfe00c644b9bb36a37bbed5da5
7
- data.tar.gz: 2f0ad52a3047c16e5d80c4d256de0b6b8fe9d769295d449f5722fd48d855917a7d28ec36d0cfd7398314cb1fef7bb96336406e6ae71423d8495d6904151c09ab
6
+ metadata.gz: 92fcd413f5fc3a5bef72f7a985bf3bc7b97b3180e5061e139c839e0a7411e965b975ed08bb8d75b2f05045461a98b3e4ba2847f07003af0064f8c3653097b848
7
+ data.tar.gz: 0ebd133933c2d83139277317ae9c5810d2f3eb0f0ea98aefb18075543829266b1ca3539ee9b2caf14f2e698dea0c5d4d6b04ec2202e88d943460f76a0cbeaef1
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in rake_docker.gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rake_circle_ci (0.10.0.pre.4)
4
+ rake_circle_ci (0.10.0.pre.7)
5
5
  colored2 (~> 3.1)
6
6
  excon (~> 0.72)
7
7
  rake_factory (~> 0.23)
@@ -17,11 +17,12 @@ GEM
17
17
  tzinfo (~> 2.0)
18
18
  addressable (2.8.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
+ ast (2.4.2)
20
21
  colored2 (3.1.2)
21
22
  concurrent-ruby (1.1.9)
22
23
  diff-lcs (1.5.0)
23
24
  docile (1.4.0)
24
- excon (0.92.0)
25
+ excon (0.92.2)
25
26
  faraday (1.10.0)
26
27
  faraday-em_http (~> 1.0)
27
28
  faraday-em_synchrony (~> 1.0)
@@ -60,7 +61,11 @@ GEM
60
61
  faraday (>= 0.9)
61
62
  sawyer (~> 0.8.0, >= 0.5.3)
62
63
  open4 (1.3.4)
64
+ parallel (1.21.0)
65
+ parser (3.1.1.0)
66
+ ast (~> 2.4.1)
63
67
  public_suffix (4.0.6)
68
+ rainbow (3.1.1)
64
69
  rake (13.0.6)
65
70
  rake_factory (0.29.0)
66
71
  activesupport (>= 4)
@@ -77,6 +82,8 @@ GEM
77
82
  colored2 (~> 3.1)
78
83
  rake_factory (~> 0.23)
79
84
  sshkey (~> 2.0)
85
+ regexp_parser (2.2.1)
86
+ rexml (3.2.5)
80
87
  rspec (3.11.0)
81
88
  rspec-core (~> 3.11.0)
82
89
  rspec-expectations (~> 3.11.0)
@@ -90,6 +97,22 @@ GEM
90
97
  diff-lcs (>= 1.2.0, < 2.0)
91
98
  rspec-support (~> 3.11.0)
92
99
  rspec-support (3.11.0)
100
+ rubocop (1.26.0)
101
+ parallel (~> 1.10)
102
+ parser (>= 3.1.0.0)
103
+ rainbow (>= 2.2.2, < 4.0)
104
+ regexp_parser (>= 1.8, < 3.0)
105
+ rexml
106
+ rubocop-ast (>= 1.16.0, < 2.0)
107
+ ruby-progressbar (~> 1.7)
108
+ unicode-display_width (>= 1.4.0, < 3.0)
109
+ rubocop-ast (1.16.0)
110
+ parser (>= 3.1.1.0)
111
+ rubocop-rake (0.6.0)
112
+ rubocop (~> 1.0)
113
+ rubocop-rspec (2.9.0)
114
+ rubocop (~> 1.19)
115
+ ruby-progressbar (1.11.0)
93
116
  ruby2_keywords (0.0.5)
94
117
  ruby_gpg2 (0.8.0)
95
118
  lino (>= 1.5)
@@ -105,6 +128,7 @@ GEM
105
128
  sshkey (2.0.0)
106
129
  tzinfo (2.0.4)
107
130
  concurrent-ruby (~> 1.0)
131
+ unicode-display_width (2.1.0)
108
132
 
109
133
  PLATFORMS
110
134
  ruby
@@ -120,7 +144,10 @@ DEPENDENCIES
120
144
  rake_gpg
121
145
  rake_ssh
122
146
  rspec
147
+ rubocop
148
+ rubocop-rake
149
+ rubocop-rspec
123
150
  simplecov
124
151
 
125
152
  BUNDLED WITH
126
- 2.3.9
153
+ 2.3.10
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
  require 'rake_circle_ci'
3
5
  require 'rake_github'
@@ -5,17 +7,20 @@ require 'rake_ssh'
5
7
  require 'rake_gpg'
6
8
  require 'securerandom'
7
9
  require 'rspec/core/rake_task'
10
+ require 'rubocop/rake_task'
8
11
 
9
- task :default => :spec
10
-
11
- RSpec::Core::RakeTask.new(:spec)
12
+ task default: %i[
13
+ library:fix
14
+ test:unit
15
+ ]
12
16
 
13
17
  namespace :encryption do
14
18
  namespace :passphrase do
19
+ desc 'Generate encryption passphrase for CI GPG key'
15
20
  task :generate do
16
- File.open('config/secrets/ci/encryption.passphrase', 'w') do |f|
17
- f.write(SecureRandom.base64(36))
18
- end
21
+ FileUtils.mkdir_p('config/secrets/ci/')
22
+ File.write('config/secrets/ci/encryption.passphrase',
23
+ SecureRandom.base64(36))
19
24
  end
20
25
  end
21
26
  end
@@ -23,85 +28,102 @@ end
23
28
  namespace :keys do
24
29
  namespace :deploy do
25
30
  RakeSSH.define_key_tasks(
26
- path: 'config/secrets/ci/',
27
- comment: 'maintainers@infrablocks.io')
31
+ path: 'config/secrets/ci/',
32
+ comment: 'maintainers@infrablocks.io'
33
+ )
28
34
  end
29
35
 
30
36
  namespace :gpg do
31
37
  RakeGPG.define_generate_key_task(
32
- output_directory: 'config/secrets/ci',
33
- name_prefix: 'gpg',
34
- owner_name: 'InfraBlocks Maintainers',
35
- owner_email: 'maintainers@infrablocks.io',
36
- owner_comment: 'rake_circle_ci CI Key')
38
+ output_directory: 'config/secrets/ci',
39
+ name_prefix: 'gpg',
40
+ owner_name: 'InfraBlocks Maintainers',
41
+ owner_email: 'maintainers@infrablocks.io',
42
+ owner_comment: 'rake_circle_ci CI Key'
43
+ )
37
44
  end
38
45
  end
39
46
 
47
+ RuboCop::RakeTask.new
48
+
49
+ namespace :library do
50
+ desc 'Run all checks of the library'
51
+ task check: [:rubocop]
52
+
53
+ desc 'Attempt to automatically fix issues with the library'
54
+ task fix: [:'rubocop:auto_correct']
55
+ end
56
+
57
+ namespace :test do
58
+ RSpec::Core::RakeTask.new(:unit)
59
+ end
60
+
40
61
  RakeCircleCI.define_project_tasks(
41
- namespace: :circle_ci,
42
- project_slug: 'github/infrablocks/rake_circle_ci'
62
+ namespace: :circle_ci,
63
+ project_slug: 'github/infrablocks/rake_circle_ci'
43
64
  ) do |t|
44
65
  circle_ci_config =
45
- YAML.load_file('config/secrets/circle_ci/config.yaml')
66
+ YAML.load_file('config/secrets/circle_ci/config.yaml')
46
67
 
47
- t.api_token = circle_ci_config["circle_ci_api_token"]
68
+ t.api_token = circle_ci_config['circle_ci_api_token']
48
69
  t.environment_variables = {
49
- ENCRYPTION_PASSPHRASE:
50
- File.read('config/secrets/ci/encryption.passphrase')
51
- .chomp
70
+ ENCRYPTION_PASSPHRASE:
71
+ File.read('config/secrets/ci/encryption.passphrase')
72
+ .chomp
52
73
  }
53
74
  t.checkout_keys = []
54
75
  t.ssh_keys = [
55
- {
56
- hostname: "github.com",
57
- private_key: File.read('config/secrets/ci/ssh.private')
58
- }
76
+ {
77
+ hostname: 'github.com',
78
+ private_key: File.read('config/secrets/ci/ssh.private')
79
+ }
59
80
  ]
60
81
  end
61
82
 
62
83
  RakeGithub.define_repository_tasks(
63
- namespace: :github,
64
- repository: 'infrablocks/rake_circle_ci',
84
+ namespace: :github,
85
+ repository: 'infrablocks/rake_circle_ci'
65
86
  ) do |t, args|
66
87
  github_config =
67
- YAML.load_file('config/secrets/github/config.yaml')
88
+ YAML.load_file('config/secrets/github/config.yaml')
68
89
 
69
- t.access_token = github_config["github_personal_access_token"]
90
+ t.access_token = github_config['github_personal_access_token']
70
91
  t.deploy_keys = [
71
- {
72
- title: 'CircleCI',
73
- public_key: File.read('config/secrets/ci/ssh.public')
74
- }
92
+ {
93
+ title: 'CircleCI',
94
+ ssh_key: File.read('config/secrets/ci/ssh.public')
95
+ }
75
96
  ]
76
97
  t.branch_name = args.branch_name
77
98
  t.commit_message = args.commit_message
78
99
  end
79
100
 
80
101
  namespace :pipeline do
81
- task :prepare => [
82
- :'circle_ci:project:follow',
83
- :'circle_ci:env_vars:ensure',
84
- :'circle_ci:checkout_keys:ensure',
85
- :'circle_ci:ssh_keys:ensure',
86
- :'github:deploy_keys:ensure'
102
+ desc 'Prepare CircleCI Pipeline'
103
+ task prepare: %i[
104
+ circle_ci:project:follow
105
+ circle_ci:env_vars:ensure
106
+ circle_ci:checkout_keys:ensure
107
+ circle_ci:ssh_keys:ensure
108
+ github:deploy_keys:ensure
87
109
  ]
88
110
  end
89
111
 
90
112
  namespace :version do
91
- desc "Bump version for specified type (pre, major, minor, patch)"
113
+ desc 'Bump version for specified type (pre, major, minor, patch)'
92
114
  task :bump, [:type] do |_, args|
93
115
  bump_version_for(args.type)
94
116
  end
95
117
  end
96
118
 
97
- desc "Release gem"
119
+ desc 'Release gem'
98
120
  task :release do
99
- sh "gem release --tag --push"
121
+ sh 'gem release --tag --push'
100
122
  end
101
123
 
102
124
  def bump_version_for(version_type)
103
- sh "gem bump --version #{version_type} " +
104
- "&& bundle install " +
105
- "&& export LAST_MESSAGE=\"$(git log -1 --pretty=%B)\" " +
106
- "&& git commit -a --amend -m \"${LAST_MESSAGE} [ci skip]\""
125
+ sh "gem bump --version #{version_type} " \
126
+ '&& bundle install ' \
127
+ '&& export LAST_MESSAGE="$(git log -1 --pretty=%B)" ' \
128
+ '&& git commit -a --amend -m "${LAST_MESSAGE} [ci skip]"'
107
129
  end
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "rake_circle_ci"
4
+ require 'bundler/setup'
5
+ require 'rake_circle_ci'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "rake_circle_ci"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,35 +1,100 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'excon'
3
5
  require 'sshkey'
4
6
 
5
7
  module RakeCircleCI
6
- class Client
8
+ class URLs
7
9
  def initialize(opts)
8
10
  @base_url = opts[:base_url]
9
11
  @api_token = opts[:api_token]
10
12
  @project_slug = opts[:project_slug]
11
13
  end
12
14
 
15
+ def follow_url
16
+ "#{@base_url}/v1.1/project/#{@project_slug}/follow?" \
17
+ "circle-token=#{@api_token}"
18
+ end
19
+
20
+ def env_vars_url
21
+ "#{@base_url}/v2/project/#{@project_slug}/envvar"
22
+ end
23
+
24
+ def env_var_url(name)
25
+ "#{@base_url}/v2/project/#{@project_slug}/envvar/#{name}"
26
+ end
27
+
28
+ def settings_url
29
+ "#{@base_url}/v1.1/project/#{@project_slug}/settings?" \
30
+ "circle-token=#{@api_token}"
31
+ end
32
+
33
+ def ssh_keys_url
34
+ "#{@base_url}/v1.1/project/#{@project_slug}/ssh-key?" \
35
+ "circle-token=#{@api_token}"
36
+ end
37
+
38
+ def checkout_keys_url
39
+ "#{@base_url}/v1.1/project/#{@project_slug}/checkout-key"
40
+ end
41
+
42
+ def checkout_key_url(fingerprint)
43
+ "#{@base_url}/v1.1/project/#{@project_slug}/checkout-key/#{fingerprint}"
44
+ end
45
+ end
46
+
47
+ class HTTPClient
48
+ def get(url, opts)
49
+ assert_successful(Excon.get(url, opts))
50
+ end
51
+
52
+ def post(url, opts)
53
+ assert_successful(Excon.post(url, opts))
54
+ end
55
+
56
+ def delete(url, opts)
57
+ assert_successful(Excon.delete(url, opts))
58
+ end
59
+
60
+ private
61
+
62
+ def assert_successful(response)
63
+ unless response.status >= 200 && response.status < 300
64
+ host = response.data[:host]
65
+ path = response.data[:path]
66
+ status = response.status
67
+ reason = response.data[:reason_phrase]
68
+ raise "Unsuccessful request: #{host}#{path} #{status} #{reason}"
69
+ end
70
+ response
71
+ end
72
+ end
73
+
74
+ class Client
75
+ def initialize(opts)
76
+ @urls = URLs.new(opts)
77
+ @api_token = opts[:api_token]
78
+ @http = HTTPClient.new
79
+ end
80
+
13
81
  def follow_project
14
- assert_successful(Excon.post(follow_url, headers: headers))
82
+ @http.post(@urls.follow_url, headers: headers)
15
83
  end
16
84
 
17
85
  def find_env_vars
18
- response = assert_successful(Excon.get(env_vars_url, headers: headers))
86
+ response = @http.get(@urls.env_vars_url, headers: headers)
19
87
  body = JSON.parse(response.body)
20
- env_vars = body["items"].map { |item| item["name"] }
21
-
22
- env_vars
88
+ body['items'].map { |item| item['name'] }
23
89
  end
24
90
 
25
91
  def create_env_var(name, value)
26
92
  body = JSON.dump(name: name, value: value)
27
- assert_successful(
28
- Excon.post(env_vars_url, body: body, headers: headers))
93
+ @http.post(@urls.env_vars_url, body: body, headers: headers)
29
94
  end
30
95
 
31
96
  def delete_env_var(name)
32
- assert_successful(Excon.delete(env_var_url(name), headers: headers))
97
+ @http.delete(@urls.env_var_url(name), headers: headers)
33
98
  end
34
99
 
35
100
  def delete_env_vars
@@ -40,32 +105,28 @@ module RakeCircleCI
40
105
  end
41
106
 
42
107
  def find_ssh_keys
43
- response = assert_successful(Excon.get(settings_url, headers: headers))
108
+ response = @http.get(@urls.settings_url, headers: headers)
44
109
  body = JSON.parse(response.body, symbolize_names: true)
45
- ssh_keys = body[:ssh_keys]
46
-
47
- ssh_keys
110
+ body[:ssh_keys]
48
111
  end
49
112
 
50
113
  def create_ssh_key(private_key, opts = {})
51
114
  body = {
52
- fingerprint: SSHKey.new(private_key).sha1_fingerprint,
53
- private_key: private_key,
115
+ fingerprint: SSHKey.new(private_key).sha1_fingerprint,
116
+ private_key: private_key
54
117
  }
55
118
  body = body.merge(hostname: opts[:hostname]) if opts[:hostname]
56
119
  body = JSON.dump(body)
57
- assert_successful(
58
- Excon.post(ssh_keys_url, body: body, headers: headers))
120
+ @http.post(@urls.ssh_keys_url, body: body, headers: headers)
59
121
  end
60
122
 
61
123
  def delete_ssh_key(fingerprint, opts = {})
62
124
  body = {
63
- fingerprint: fingerprint
125
+ fingerprint: fingerprint
64
126
  }
65
127
  body = body.merge(hostname: opts[:hostname]) if opts[:hostname]
66
128
  body = JSON.dump(body)
67
- assert_successful(
68
- Excon.delete(ssh_keys_url, body: body, headers: headers))
129
+ @http.delete(@urls.ssh_keys_url, body: body, headers: headers)
69
130
  end
70
131
 
71
132
  def delete_ssh_keys
@@ -73,33 +134,28 @@ module RakeCircleCI
73
134
  ssh_keys.each do |ssh_key|
74
135
  fingerprint = ssh_key[:fingerprint]
75
136
  hostname = ssh_key[:hostname]
76
- options = hostname && {hostname: hostname}
137
+ options = hostname && { hostname: hostname }
77
138
  args = [fingerprint, options].compact
78
139
  delete_ssh_key(*args)
79
140
  end
80
141
  end
81
142
 
82
143
  def find_checkout_keys
83
- response = assert_successful(
84
- Excon.get(checkout_keys_url, headers: headers))
85
- checkout_keys = JSON.parse(response.body, symbolize_names: true)
86
-
87
- checkout_keys
144
+ response = @http.get(@urls.checkout_keys_url, headers: headers)
145
+ JSON.parse(response.body, symbolize_names: true)
88
146
  end
89
147
 
90
148
  def create_checkout_key(type)
91
149
  type_strings = {
92
- deploy_key: 'deploy-key',
93
- github_user_key: 'github-user-key'
150
+ deploy_key: 'deploy-key',
151
+ github_user_key: 'github-user-key'
94
152
  }
95
153
  body = JSON.dump(type: type_strings[type.to_sym] || type.to_s)
96
- assert_successful(
97
- Excon.post(checkout_keys_url, body: body, headers: headers))
154
+ @http.post(@urls.checkout_keys_url, body: body, headers: headers)
98
155
  end
99
156
 
100
157
  def delete_checkout_key(fingerprint)
101
- assert_successful(
102
- Excon.delete(checkout_key_url(fingerprint), headers: headers))
158
+ @http.delete(@urls.checkout_key_url(fingerprint), headers: headers)
103
159
  end
104
160
 
105
161
  def delete_checkout_keys
@@ -113,52 +169,10 @@ module RakeCircleCI
113
169
 
114
170
  def headers
115
171
  {
116
- "Circle-Token": @api_token,
117
- "Content-Type": "application/json",
118
- "Accept": "application/json"
172
+ 'Circle-Token': @api_token,
173
+ 'Content-Type': 'application/json',
174
+ Accept: 'application/json'
119
175
  }
120
176
  end
121
-
122
- def assert_successful(response)
123
- unless response.status >= 200 && response.status < 300
124
- host = response.data[:host]
125
- path = response.data[:path]
126
- status = response.status
127
- reason = response.data[:reason_phrase]
128
- raise "Unsuccessful request: #{host}#{path} #{status} #{reason}"
129
- end
130
- response
131
- end
132
-
133
- def follow_url
134
- "#{@base_url}/v1.1/project/#{@project_slug}/follow?" +
135
- "circle-token=#{@api_token}"
136
- end
137
-
138
- def env_vars_url
139
- "#{@base_url}/v2/project/#{@project_slug}/envvar"
140
- end
141
-
142
- def env_var_url(name)
143
- "#{@base_url}/v2/project/#{@project_slug}/envvar/#{name}"
144
- end
145
-
146
- def settings_url
147
- "#{@base_url}/v1.1/project/#{@project_slug}/settings?" +
148
- "circle-token=#{@api_token}"
149
- end
150
-
151
- def ssh_keys_url
152
- "#{@base_url}/v1.1/project/#{@project_slug}/ssh-key?" +
153
- "circle-token=#{@api_token}"
154
- end
155
-
156
- def checkout_keys_url
157
- "#{@base_url}/v1.1/project/#{@project_slug}/checkout-key"
158
- end
159
-
160
- def checkout_key_url(fingerprint)
161
- "#{@base_url}/v1.1/project/#{@project_slug}/checkout-key/#{fingerprint}"
162
- end
163
177
  end
164
178
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake_factory'
2
4
 
3
5
  require_relative '../tasks'
@@ -17,17 +19,17 @@ module RakeCircleCI
17
19
  parameter :ensure_task_name, default: :ensure
18
20
 
19
21
  task Tasks::CheckoutKeys::Provision,
20
- name: RakeFactory::DynamicValue.new { |ts|
21
- ts.provision_task_name
22
- }
22
+ name: RakeFactory::DynamicValue.new { |ts|
23
+ ts.provision_task_name
24
+ }
23
25
  task Tasks::CheckoutKeys::Destroy,
24
- name: RakeFactory::DynamicValue.new { |ts|
25
- ts.destroy_task_name
26
- }
26
+ name: RakeFactory::DynamicValue.new { |ts|
27
+ ts.destroy_task_name
28
+ }
27
29
  task Tasks::CheckoutKeys::Ensure,
28
- name: RakeFactory::DynamicValue.new { |ts|
29
- ts.ensure_task_name
30
- }
30
+ name: RakeFactory::DynamicValue.new { |ts|
31
+ ts.ensure_task_name
32
+ }
31
33
  end
32
34
  end
33
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake_factory'
2
4
 
3
5
  require_relative '../tasks'
@@ -17,17 +19,17 @@ module RakeCircleCI
17
19
  parameter :ensure_task_name, default: :ensure
18
20
 
19
21
  task Tasks::EnvironmentVariables::Provision,
20
- name: RakeFactory::DynamicValue.new { |ts|
21
- ts.provision_task_name
22
- }
22
+ name: RakeFactory::DynamicValue.new { |ts|
23
+ ts.provision_task_name
24
+ }
23
25
  task Tasks::EnvironmentVariables::Destroy,
24
- name: RakeFactory::DynamicValue.new { |ts|
25
- ts.destroy_task_name
26
- }
26
+ name: RakeFactory::DynamicValue.new { |ts|
27
+ ts.destroy_task_name
28
+ }
27
29
  task Tasks::EnvironmentVariables::Ensure,
28
- name: RakeFactory::DynamicValue.new { |ts|
29
- ts.ensure_task_name
30
- }
30
+ name: RakeFactory::DynamicValue.new { |ts|
31
+ ts.ensure_task_name
32
+ }
31
33
  end
32
34
  end
33
35
  end