s3_gem_host 1.0.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.
@@ -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: []