s3_gem_host 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 891bc2b41619f6bb1cf73f340cf9eca5dff70759a4e42301ef98020d88edfd55
4
+ data.tar.gz: 84e48dd50ffb92dfba5afb80dfad1f5921e36dcb4385482a65aebc38a8843f7a
5
+ SHA512:
6
+ metadata.gz: 8ba0db102ee30a2ffdd295bf9db7ca66a0aa719c0b51091d92df20253c78da002600c08532dbea328d1515f0ae5c6c4cbeeb2cf1b2172b2ae89d43365306acb2
7
+ data.tar.gz: 0dc809cfa40d2e202cea884cea96e459e2200e6d1fb5d7496e2051cd4e8596b06b1b5ec0dd99280c7c96f6492f9382ef2b1f5c415bf0a9a0f56e1383bd07ca0a
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ .rakeTasks
13
+
14
+ /.idea/
15
+ tags
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,235 @@
1
+ # Run rubocop --auto-gen-config to generate .rubocop_todo.yml
2
+ # Run rubocop --auto-correct to have rubocop auto fix all offenses (Use this feature carefully!)
3
+ # Enable rubocop todos to go through them one by one
4
+ # For how to get started with rubocop, see: https://buildtoship.com/integrate-rubocop-in-your-workflow/
5
+
6
+ require:
7
+ - rubocop-rspec
8
+
9
+ inherit_from: .rubocop_todo.yml
10
+
11
+ AllCops:
12
+ TargetRubyVersion: 2.6
13
+ # Cop names are not displayed in offense messages by default. Change behavior
14
+ # by overriding DisplayCopNames, or by giving the -D/--display-cop-names
15
+ # option.
16
+ DisplayCopNames: true
17
+ # Style guide URLs are not displayed in offense messages by default. Change
18
+ # behavior by overriding DisplayStyleGuide, or by giving the
19
+ # -S/--display-style-guide option.
20
+ DisplayStyleGuide: true
21
+ # Exclude certain files
22
+ Exclude:
23
+ - 'vendor/**/*'
24
+ - 'db/**/*'
25
+ - 'tmp/**/*'
26
+ - 'bin/**/*'
27
+ - 'log/**/*'
28
+ - 'client/**/*'
29
+ - 'node_modules/**/*'
30
+
31
+ ################################## Style ##################################
32
+
33
+ # Enable, Disable, and Edit styles below
34
+ # Default rubocop styles can be found at https://github.com/bbatsov/rubocop/blob/master/config/default.yml
35
+ # Copy styles from above url or .rubocop_todo.yml and only change specific rules (suggest using comments from both)
36
+
37
+ Style/AccessModifierDeclarations:
38
+ Enabled: false
39
+
40
+ Style/BlockDelimiters:
41
+ Exclude:
42
+ - '**/*.rb'
43
+
44
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
45
+ # SupportedStyles: nested, compact
46
+ Style/ClassAndModuleChildren:
47
+ Enabled: false
48
+
49
+ # Document classes and non-namespace modules.
50
+ Style/Documentation:
51
+ Exclude:
52
+ - 'spec/**/*'
53
+ - 'config/*'
54
+ - 'config/locales/*'
55
+
56
+ Style/FrozenStringLiteralComment:
57
+ Exclude:
58
+ - 'app/views/*'
59
+
60
+ Style/GuardClause:
61
+ Exclude:
62
+ - '**/*.rb'
63
+
64
+ Style/NumericPredicate:
65
+ Exclude:
66
+ - '**/*.rb'
67
+
68
+ # Cop supports --auto-correct.
69
+ Style/RedundantSelf:
70
+ Enabled: false
71
+
72
+ # Cop supports --auto-correct.
73
+ # Configuration parameters: AllowIfMethodIsEmpty.
74
+ Style/SingleLineMethods:
75
+ Enabled: false
76
+
77
+ Style/TrailingCommaInArguments:
78
+ Exclude:
79
+ - 'spec/**/*'
80
+ - 'app/**/*'
81
+
82
+ Style/TrailingCommaInArrayLiteral:
83
+ Exclude:
84
+ - 'spec/**/*'
85
+ - 'app/**/*'
86
+
87
+ Style/TrailingCommaInHashLiteral:
88
+ Exclude:
89
+ - 'spec/**/*'
90
+ - 'app/**/*'
91
+
92
+ ################################## Layout #################################
93
+
94
+ Layout/EmptyLinesAroundAccessModifier:
95
+ Enabled: false
96
+
97
+ Layout/IndentationConsistency:
98
+ EnforcedStyle: indented_internal_methods
99
+
100
+ # Checks the indentation of the first element in an array literal.
101
+ Layout/FirstArrayElementIndentation:
102
+ Enabled: false
103
+
104
+ Layout/FirstHashElementIndentation:
105
+ Exclude:
106
+ - '**/*.rb'
107
+
108
+ Layout/MultilineMethodCallIndentation:
109
+ Exclude:
110
+ - 'spec/**/*'
111
+
112
+ # Cop supports --auto-correct.
113
+ # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
114
+ # SupportedStyles: aligned, indented
115
+ Layout/MultilineOperationIndentation:
116
+ EnforcedStyle: indented
117
+
118
+ ################################## Lint ###################################
119
+
120
+ # Cop supports --auto-correct.
121
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
122
+ Lint/UnusedMethodArgument:
123
+ Exclude:
124
+ - 'config/initializers/sidekiq.rb'
125
+ - 'app/controllers/application_controller.rb'
126
+
127
+ ################################## Metrics ################################
128
+
129
+ Metrics/AbcSize:
130
+ Max: 30
131
+
132
+ Metrics/BlockLength:
133
+ Max: 30
134
+ Exclude:
135
+ - 'spec/**/*.rb'
136
+ - 'config/**/*.rb'
137
+ - 'app/controllers/api/**/*'
138
+
139
+ Metrics/ClassLength:
140
+ Enabled: false
141
+
142
+ Metrics/CyclomaticComplexity:
143
+ Max: 9
144
+
145
+ Layout/LineLength:
146
+ Max: 120
147
+ Exclude:
148
+ - 'Gemfile'
149
+
150
+ # Configuration parameters: CountComments.
151
+ Metrics/MethodLength:
152
+ Max: 50
153
+
154
+ Metrics/ModuleLength:
155
+ Max: 250
156
+
157
+ Metrics/ParameterLists:
158
+ Enabled: false
159
+
160
+ Metrics/PerceivedComplexity:
161
+ Max: 10
162
+
163
+ ################################## Naming #################################
164
+
165
+ Naming/HeredocDelimiterNaming:
166
+ Enabled: false
167
+
168
+ Naming/MethodParameterName:
169
+ Enabled: false
170
+
171
+ ################################## RSpec ##################################
172
+
173
+ # Check that instances are not being stubbed globally
174
+ RSpec/AnyInstance:
175
+ Enabled: false
176
+
177
+ RSpec/ContextWording:
178
+ Enabled: false
179
+
180
+ RSpec/DescribeClass:
181
+ Exclude:
182
+ - 'spec/lib/tasks/**/*'
183
+ - 'spec/integration/*.rb'
184
+
185
+ # Configuration parameters: Max.
186
+ RSpec/ExampleLength:
187
+ Max: 25
188
+
189
+ RSpec/ExpectActual:
190
+ Exclude:
191
+ - 'spec/**/*.rb'
192
+
193
+ RSpec/FilePath:
194
+ Exclude:
195
+ - 'spec/karafka/**/*'
196
+
197
+ RSpec/MultipleExpectations:
198
+ Exclude:
199
+ - '**/*.rb'
200
+
201
+ Layout/SpaceAroundMethodCallOperator:
202
+ Enabled: true
203
+
204
+ Lint/RaiseException:
205
+ Enabled: true
206
+
207
+ Lint/StructNewOverride:
208
+ Enabled: true
209
+
210
+ Style/ExponentialNotation:
211
+ Enabled: true
212
+
213
+ Style/HashEachMethods:
214
+ Enabled: true
215
+
216
+ Style/HashTransformKeys:
217
+ Enabled: true
218
+
219
+ Style/HashTransformValues:
220
+ Enabled: true
221
+
222
+ RSpec/NestedGroups:
223
+ Max: 7
224
+
225
+ Lint/UnderscorePrefixedVariableName:
226
+ Enabled: false
227
+
228
+ RSpec/RepeatedExampleGroupBody:
229
+ Enabled: false
230
+
231
+ Layout/EmptyLinesAroundAttributeAccessor:
232
+ Enabled: true
233
+
234
+ Style/SlicingWithRange:
235
+ Enabled: true
@@ -0,0 +1,7 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-05-09 13:29:52 -0700 using RuboCop version 0.82.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
@@ -0,0 +1 @@
1
+ s3_gem_host
@@ -0,0 +1 @@
1
+ ruby-2.6.6
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6
4
+ script:
5
+ - bundle install
6
+ - bundle exec rubocop
7
+ - bundle exec rake spec
@@ -0,0 +1,2 @@
1
+ ## 1.0.0
2
+ * First version
@@ -0,0 +1,18 @@
1
+ # Contributing
2
+ 1. Create a feature branch for your change.
3
+ 2. Push up your proposed changes to your feature branch.
4
+ * Ensure you have full test coverage. Untested code will not be merged in and code coverage is reported on all builds.
5
+ * Bump the version of the gem according to [Versioning](#versioning) below
6
+ * Breaking changes resulting in a major version bump will require more discussion, so please try to keep changes
7
+ fully backward-compatible unless you have a good reason not to.
8
+ * Update documentation in README.md and CHANGES.mb
9
+ 2. Create a Pull Request with your change.
10
+
11
+ ### Versioning
12
+ This gem follows Semantic Versioning (2.0):
13
+
14
+ Given a version number MAJOR.MINOR.PATCH, increment the:
15
+
16
+ MAJOR version when you make incompatible API changes,
17
+ MINOR version when you add functionality in a backwards compatible manner, and
18
+ PATCH version when you make backwards compatible bug fixes.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in s3_gem_host.gemspec
6
+ gemspec
7
+
8
+ group :development, :test do
9
+ gem 'rspec'
10
+ gem 'rubocop', require: false
11
+ gem 'rubocop-rspec', require: false
12
+ gem 'simplecov', require: false
13
+ end
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ s3_gem_host (1.0.0)
5
+ aws-sdk-s3 (~> 1.64)
6
+ builder
7
+ bundler
8
+ rake
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ ast (2.4.0)
14
+ aws-eventstream (1.1.0)
15
+ aws-partitions (1.316.0)
16
+ aws-sdk-core (3.96.0)
17
+ aws-eventstream (~> 1, >= 1.0.2)
18
+ aws-partitions (~> 1, >= 1.239.0)
19
+ aws-sigv4 (~> 1.1)
20
+ jmespath (~> 1.0)
21
+ aws-sdk-kms (1.31.0)
22
+ aws-sdk-core (~> 3, >= 3.71.0)
23
+ aws-sigv4 (~> 1.1)
24
+ aws-sdk-s3 (1.64.0)
25
+ aws-sdk-core (~> 3, >= 3.83.0)
26
+ aws-sdk-kms (~> 1)
27
+ aws-sigv4 (~> 1.1)
28
+ aws-sigv4 (1.1.3)
29
+ aws-eventstream (~> 1.0, >= 1.0.2)
30
+ builder (3.2.4)
31
+ diff-lcs (1.3)
32
+ docile (1.3.2)
33
+ jmespath (1.4.0)
34
+ parallel (1.19.1)
35
+ parser (2.7.1.2)
36
+ ast (~> 2.4.0)
37
+ rainbow (3.0.0)
38
+ rake (13.0.1)
39
+ rexml (3.2.4)
40
+ rspec (3.9.0)
41
+ rspec-core (~> 3.9.0)
42
+ rspec-expectations (~> 3.9.0)
43
+ rspec-mocks (~> 3.9.0)
44
+ rspec-core (3.9.2)
45
+ rspec-support (~> 3.9.3)
46
+ rspec-expectations (3.9.2)
47
+ diff-lcs (>= 1.2.0, < 2.0)
48
+ rspec-support (~> 3.9.0)
49
+ rspec-mocks (3.9.1)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.9.0)
52
+ rspec-support (3.9.3)
53
+ rubocop (0.83.0)
54
+ parallel (~> 1.10)
55
+ parser (>= 2.7.0.1)
56
+ rainbow (>= 2.2.2, < 4.0)
57
+ rexml
58
+ ruby-progressbar (~> 1.7)
59
+ unicode-display_width (>= 1.4.0, < 2.0)
60
+ rubocop-rspec (1.39.0)
61
+ rubocop (>= 0.68.1)
62
+ ruby-progressbar (1.10.1)
63
+ simplecov (0.18.5)
64
+ docile (~> 1.1)
65
+ simplecov-html (~> 0.11)
66
+ simplecov-html (0.12.2)
67
+ unicode-display_width (1.7.0)
68
+
69
+ PLATFORMS
70
+ ruby
71
+
72
+ DEPENDENCIES
73
+ rspec
74
+ rubocop
75
+ rubocop-rspec
76
+ s3_gem_host!
77
+ simplecov
78
+
79
+ BUNDLED WITH
80
+ 2.1.4
@@ -0,0 +1,18 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining
2
+ a copy of this software and associated documentation files (the
3
+ "Software"), to deal in the Software without restriction, including
4
+ without limitation the rights to use, copy, modify, merge, publish,
5
+ distribute, sublicense, and/or sell copies of the Software, and to
6
+ permit persons to whom the Software is furnished to do so, subject to
7
+ the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be
10
+ included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,81 @@
1
+ # S3 Gem Host [![Build Status](https://travis-ci.org/webandtech/s3_gem_host.svg?branch=master)](https://travis-ci.org/webandtech/s3_gem_host)
2
+ This gem provides rake tasks for publishing and managing Ruby gems hosted on Amazon S3.
3
+
4
+ ## Installation
5
+
6
+ Add this gem to your gem's Gemfile:
7
+ ```ruby
8
+ # Gemfile
9
+ gem 's3_gem_host'
10
+ ```
11
+
12
+ Require this bundler/gem_tasks (recommended) and this gem in your Rakefile
13
+ ```ruby
14
+ # Rakefile
15
+
16
+ require 'bundler/gem_tasks' # Recommended
17
+ require 's3_gem_host'
18
+ ```
19
+
20
+ Run `rake -T` and you should see this Gem's tasks available for use.
21
+ ```
22
+ ➜ rake -T
23
+ rake build # Build your-gem-x.x.x.gem into the pkg directory
24
+ rake clean # Remove any temporary products
25
+ rake clobber # Remove any generated files
26
+ rake install # Build and install your-gem-x.x.x.gem into system gems
27
+ rake install:local # Build and install your-gem-x.x.x.gem into system gems without network access
28
+ rake release[remote] # Create tag vx.x.x and build and push s3_gem_host-1.0.0.gem to rubygems.org
29
+ rake s3_gem_host:push # Publish a newly built gem version to S3
30
+ rake s3_gem_host:yank[version] # Remove a previously published gem version from S3
31
+ rake spec # Run RSpec code examples
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ Set the following environment variables (such as when using this gem in your CI/CD pipeline):
37
+ * `S3_GEM_HOST_AWS_ACCESS_KEY_ID`: The AWS Access Key ID to use to write to your S3 bucket
38
+ * `S3_GEM_HOST_AWS_SECRET_ACCESS_KEY`: The AWS Secret Access Key to use to write to your S3 bucket
39
+ * `S3_GEM_HOST_BUCKET`: The S3 bucket where you want to host your gems. This must be an existing S3 bucket. You
40
+ should create a new S3 bucket for hosting your gems. Multiple gems may be hosted in the same bucket.
41
+ * `S3_GEM_HOST_AWS_REGION`: The AWS region where your S3 bucket is hosted; defaults to 'us-east-1'
42
+
43
+ ## Usage
44
+
45
+ 1. Create an S3 bucket to be your "gem server".
46
+ * Each gem you publish will maintain its own source via a root directory in this bucket.
47
+
48
+ 2. You will need to provide https access to your S3 bucket to use it as a Bundler gem source as Bundler does not
49
+ support S3 sources natively. An easy way is to use a CloudFront distribution, which you can secure via http basic auth
50
+ using a Lambda Function. See [Wiki](https://github.com/webandtech/s3_gem_host/wiki) for instructions.
51
+
52
+ 3. Your gem publishing pipleline should look something like this:
53
+ 1. `bundle exec rake release:guard_clean` # from bundler/gem_tasks: check for any uncommitted files
54
+ 2. `bundle exec rake build` # from bundler/gem_tasks: build your new gem file
55
+ 3. `bundle exec rake release:source_control_push` # from bundler/gem_tasks: tag and push the new version to source control
56
+ 4. `bundle exec rake s3_gem_host:push` # from this gem: push your gem to S3
57
+ * You will receive an error if you are missing any of the required ENV variables - see [Configuration](#configuration)
58
+
59
+ 4. Use your gem via the `source` option. The root directory of the source is your gem name, i.e.
60
+ ```ruby
61
+ # Gemfile
62
+
63
+ gem 'your-private-gem', source: 'https://username:password@yours3bucket/your-private-gem'
64
+ ```
65
+
66
+ ### Yanking a Gem
67
+ You can unpublish a gem from S3 using the `s3_gem_host:yank` Rake task. For example:
68
+ * `bundle exec rake s3_gem_host:yank[2.10.1]` will remove your gem version 2.10.1 from the S3 bucket and associated
69
+ index.
70
+
71
+ ## How it works
72
+
73
+ 1. The rake task `s3_gem_host:push` pulls down the current contents of your S3 bucket into a cache dir,
74
+ starting at `/{gem_name}`
75
+ 2. Your newly built gem is copied into the cache dir
76
+ 3. An index is created using the `gem generate_index` command
77
+ 4. All files are pushed back up to S3
78
+
79
+ ## Using your S3 Gem Host
80
+
81
+ See the [Wiki](https://github.com/webandtech/s3_gem_host/wiki).
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/core/rake_task'
4
+ require 'bundler/gem_tasks'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-s3'
4
+ require 's3_gem_host/version'
5
+ require 's3_gem_host/task_helper'
6
+
7
+ S3GemHost::TaskHelper.install
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+
5
+ module S3GemHost
6
+ # Service used for S3 Gem Host rake tasks
7
+ class TaskHelper
8
+ include Rake::DSL
9
+ extend Rake::DSL
10
+
11
+ attr_accessor :aws_access_key_id, :aws_secret_access_key, :bucket_name, :aws_region
12
+
13
+ CACHE_DIR = './s3_gem_host_cache'
14
+ PACKAGE_DIR = './pkg'
15
+
16
+ def initialize(aws_access_key_id:, aws_secret_access_key:, bucket_name:, aws_region:)
17
+ self.aws_access_key_id = aws_access_key_id
18
+ self.aws_secret_access_key = aws_secret_access_key
19
+ self.bucket_name = bucket_name
20
+ self.aws_region = aws_region
21
+ end
22
+
23
+ # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/BlockLength
24
+ def self.install
25
+ namespace :s3_gem_host do
26
+ desc 'Publish a newly built gem version to S3. Run `rake build` first.'
27
+ task :push do
28
+ unless ENV['S3_GEM_HOST_BUCKET'] && ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'] &&
29
+ ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY']
30
+ raise 'S3_GEM_HOST_BUCKET, S3_GEM_HOST_AWS_ACCESS_KEY_ID, and S3_GEM_HOST_AWS_SECRET_ACCESS_KEY '\
31
+ 'are required to be set in ENV'
32
+ end
33
+
34
+ helper = S3GemHost::TaskHelper.new(
35
+ aws_access_key_id: ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'],
36
+ aws_secret_access_key: ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY'],
37
+ bucket_name: ENV['S3_GEM_HOST_BUCKET'],
38
+ aws_region: ENV['S3_GEM_HOST_AWS_REGION'] || 'us-east-1'
39
+ )
40
+
41
+ begin
42
+ helper.bootstrap_directories!
43
+ helper.clone_from_s3
44
+ helper.copy_in_gem
45
+ helper.create_index
46
+ helper.upload_to_s3
47
+ ensure
48
+ helper.cleanup!
49
+ end
50
+
51
+ rake_output_message "#{helper.built_gem_file} pushed to S3 successfully."
52
+ end
53
+
54
+ desc 'Remove a previously published gem version from S3'
55
+ task :yank, [:version] do |_t, args|
56
+ raise ArgumentError, 'version is required' unless (version = args[:version])
57
+
58
+ unless ENV['S3_GEM_HOST_BUCKET'] && ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'] &&
59
+ ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY']
60
+ raise 'S3_GEM_HOST_BUCKET, S3_GEM_HOST_AWS_ACCESS_KEY_ID, and S3_GEM_HOST_AWS_SECRET_ACCESS_KEY '\
61
+ 'are required to be set in ENV'
62
+ end
63
+
64
+ helper = S3GemHost::TaskHelper.new(
65
+ aws_access_key_id: ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'],
66
+ aws_secret_access_key: ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY'],
67
+ bucket_name: ENV['S3_GEM_HOST_BUCKET'],
68
+ aws_region: ENV['S3_GEM_HOST_AWS_REGION'] || 'us-east-1'
69
+ )
70
+
71
+ begin
72
+ helper.bootstrap_directories!
73
+ helper.clone_from_s3
74
+ helper.delete_version!(version)
75
+ helper.create_index
76
+ helper.upload_to_s3
77
+ ensure
78
+ helper.cleanup!
79
+ end
80
+
81
+ rake_output_message "Yanked version #{version} from S3 successfully."
82
+ end
83
+ end
84
+ end
85
+ # rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/BlockLength
86
+
87
+ def bootstrap_directories!
88
+ cleanup!
89
+
90
+ mkdir CACHE_DIR
91
+ rake_output_message "created #{CACHE_DIR}"
92
+
93
+ gem_base_dir = "#{CACHE_DIR}/#{gem_name}"
94
+ mkdir gem_base_dir
95
+ rake_output_message "created #{gem_base_dir}"
96
+
97
+ gems_dir = "#{CACHE_DIR}/#{gem_name}/gems"
98
+ mkdir gems_dir
99
+ rake_output_message "created #{gems_dir}"
100
+
101
+ true
102
+ end
103
+
104
+ def built_gem_file
105
+ return @built_gem_file if @built_gem_file
106
+
107
+ built_gem_file = File.join('./pkg', "#{gem_name}-#{gem_version}.gem")
108
+ raise "Cannot find #{built_gem_file}" unless File.exist?(built_gem_file)
109
+
110
+ @built_gem_file = File.basename(built_gem_file)
111
+ end
112
+
113
+ def clone_from_s3
114
+ prefix = "#{gem_name}/gems/"
115
+ bucket.objects(prefix: prefix, delimiter: '/').each do |s3_obj|
116
+ next if s3_obj.key == prefix # skip the directory S3 object itself
117
+
118
+ new_file = File.join(CACHE_DIR, s3_obj.key)
119
+ s3_obj.download_file(new_file)
120
+ rake_output_message "copied #{s3_obj.key} to #{new_file}"
121
+ end
122
+
123
+ true
124
+ end
125
+
126
+ def copy_in_gem
127
+ # If the same gem file / version already exists in S3, stop release
128
+ if File.exist?("#{CACHE_DIR}/#{gem_name}/gems/#{built_gem_file}")
129
+ raise "This gem version already exists in the S3 bucket: #{self.bucket_name}"
130
+ end
131
+
132
+ # Copy the built gem into the s3 cache dir
133
+ cp "./pkg/#{built_gem_file}", "#{CACHE_DIR}/#{gem_name}/gems"
134
+ rake_output_message "copied #{built_gem_file} to #{CACHE_DIR}/#{gem_name}/gems"
135
+
136
+ true
137
+ end
138
+
139
+ def delete_version!(version)
140
+ file = "#{CACHE_DIR}/#{gem_name}/gems/#{gem_name}-#{version}.gem"
141
+ raise "Gem #{File.basename(file)} could not be found" unless File.exist?(file)
142
+
143
+ rm_f file
144
+ obj = bucket.object(file.sub(%r{^#{CACHE_DIR}/}, ''))
145
+ obj.delete
146
+
147
+ true
148
+ end
149
+
150
+ def create_index
151
+ sh "cd #{CACHE_DIR}/#{gem_name} && gem generate_index ."
152
+ rake_output_message 'created gem version index'
153
+
154
+ true
155
+ end
156
+
157
+ def upload_to_s3
158
+ # Sync the local cache dir up to S3
159
+ files_to_upload = Dir["#{CACHE_DIR}/**/*"]
160
+ files_to_upload.each do |f|
161
+ next if File.directory?(f)
162
+
163
+ obj = bucket.object(f.sub(%r{^#{CACHE_DIR}/}, ''))
164
+
165
+ # Don't re-upload existing gem versions
166
+ next if File.extname(f) == '.gem' && obj.exists?
167
+
168
+ obj.upload_file(f)
169
+ rake_output_message "uploaded #{f} to S3"
170
+ end
171
+
172
+ true
173
+ end
174
+
175
+ def bucket
176
+ @bucket ||= Aws::S3::Resource.new(
177
+ credentials: Aws::Credentials.new(self.aws_access_key_id, self.aws_secret_access_key),
178
+ region: self.aws_region
179
+ ).bucket(self.bucket_name)
180
+ end
181
+
182
+ def gem_name
183
+ gemspec.name
184
+ end
185
+
186
+ def gem_version
187
+ gemspec.version
188
+ end
189
+
190
+ def cleanup!
191
+ rm_rf(CACHE_DIR)
192
+ rake_output_message "deleted #{CACHE_DIR}"
193
+
194
+ true
195
+ end
196
+
197
+ def gemspec
198
+ return @gemspec if @gemspec
199
+
200
+ gemspecs = Dir[File.join(Dir.getwd, '{,*}.gemspec')]
201
+ raise 'Unable to find gemspec' unless gemspecs.any?
202
+
203
+ @gemspec = Bundler.load_gemspec(gemspecs.first)
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module S3GemHost
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 's3_gem_host/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 's3_gem_host'
9
+ spec.version = S3GemHost::VERSION
10
+ spec.authors = ['Aaron Severs']
11
+ spec.license = 'MIT'
12
+
13
+ spec.summary = 'Rake tasks to enable using Amazon S3 as a Ruby gem server'
14
+ spec.description = 'Provides Rake tasks to manage gem hosting on AWS S3 without the need for a separate gem '\
15
+ 'server. This is especially useful for hosting private gems.'
16
+ spec.homepage = 'https://github.com/WebAndTech/s3_gem_host'
17
+ spec.require_paths = ['lib']
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+
22
+ spec.add_dependency 'aws-sdk-s3', '~> 1.64'
23
+ spec.add_dependency 'builder'
24
+ spec.add_dependency 'bundler'
25
+ spec.add_dependency 'rake'
26
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3_gem_host
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Severs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.64'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.64'
27
+ - !ruby/object:Gem::Dependency
28
+ name: builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Provides Rake tasks to manage gem hosting on AWS S3 without the need
70
+ for a separate gem server. This is especially useful for hosting private gems.
71
+ email:
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".rubocop.yml"
79
+ - ".rubocop_todo.yml"
80
+ - ".ruby-gemset"
81
+ - ".ruby-version"
82
+ - ".travis.yml"
83
+ - CHANGES.md
84
+ - CONTRIBUTING.md
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - MIT-LICENSE
88
+ - README.md
89
+ - Rakefile
90
+ - lib/s3_gem_host.rb
91
+ - lib/s3_gem_host/task_helper.rb
92
+ - lib/s3_gem_host/version.rb
93
+ - s3_gem_host.gemspec
94
+ homepage: https://github.com/WebAndTech/s3_gem_host
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.0.8
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Rake tasks to enable using Amazon S3 as a Ruby gem server
117
+ test_files: []