bundler-source-aws-s3 0.2.1

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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +87 -0
  3. data/plugins.rb +146 -0
  4. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a4d5919d913b511b4bd0cc2bbc5cb08bed308eb5ccc10d8790d094c107eb88e1
4
+ data.tar.gz: 120ca809b0c776de957420b09c6ce851d3cd1b02f67ab0fd66c0ca8f122c9c81
5
+ SHA512:
6
+ metadata.gz: 458a8571991308cc317c652a6aabeebf37eaaa58572ee2e6829135dd369ca653419fb6138574258cdf9da47f272996750c714d8301915a68c625ef421a044b5a
7
+ data.tar.gz: ff95b41d255ce9e9a8e691c0778f15e2b32c5bda6daa6829ab5bdaf47f1159e4753cd8f2956233ab329d687ad0ab6f5cc2dbc297bc1ca96248a89a72bdf1de9a
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Bundler-Source-Aws-S3
2
+
3
+ This is a bundler plugin which adds support for s3 as a source for gems.
4
+
5
+ ## Installation
6
+
7
+ ### Setup the aws cli
8
+
9
+ There are multiple ways to [install the aws
10
+ cli](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
11
+ (including [homebrew](https://formulae.brew.sh/formula/awscli)). This plugin
12
+ will use the aws cli to pull gems from your s3 source. There is an expectation
13
+ that if you want to use s3 as a gem source, you'll probably already have this
14
+ installed.
15
+
16
+ ### Setup s3 as a gem source
17
+
18
+ First, you should already have gems in s3 and you should be able to install
19
+ them with Rubygems. Follow the [guide for using s3 as a gem
20
+ source](https://guides.rubygems.org/using-s3-source/).
21
+
22
+ For this plugin to work the aws cli should be able to fetch your gems. The
23
+ plugin will run a command like `aws s3 sync s3://your-source <local path>` and
24
+ you may want to verify that you have aws cli setup correctly (permissions,
25
+ etc) to be able to run that command.
26
+
27
+ ### Add aws-s3 source to your Gemfile
28
+
29
+ In your Gemfile, add a source like this:
30
+
31
+ ```ruby
32
+ source('s3://my-bucket/gems', type: 'aws-s3') do
33
+ gem 'my-cool-gem'
34
+ end
35
+ ```
36
+
37
+ When Bundler sees the `type: 'aws-s3'` it will automatically install and use
38
+ this plugin to install gems from your s3 source.
39
+
40
+ ## Development
41
+
42
+ We don't have a very good development story (there are no tests, yay!). You'll
43
+ want to fork this repository and use your own fork by adding this to a
44
+ `Gemfile` that you plan to use to test your fork:
45
+
46
+ ```ruby
47
+ plugin 'bundler-source-aws-s3', git: 'https://github.com/<you>/bundler-source-aws-s3.git'
48
+ ```
49
+
50
+ You may also want to wipe a few directories out as you test:
51
+
52
+ ```
53
+ rm -rf ./.bundle/plugin
54
+ rm -rf ~/.bundle/bundler-source-aws-s3
55
+ ```
56
+
57
+ You may also want to wipe out the `install_path` for the s3 uri you're testing
58
+ against. You can find that in irb by instantiating your plugin like:
59
+
60
+ ```ruby
61
+ >> BundlerSourceAwsS3::S3Source.new(uri: 's3://vying-gems').send(:install_path)
62
+ ```
63
+
64
+ Although this will only work if you're running irb in a directory with a
65
+ Gemfile and a `.bundle/` directory. These can be empty as of this writing.
66
+
67
+ It can also help to poke at the plugin in irb:
68
+
69
+ ```
70
+ irb -I . -r bundler -r plugins.rb
71
+ ```
72
+
73
+ ## Other s3 source plugins
74
+
75
+ As of this writing there is another gem called
76
+ [bundler-source-s3](https://rubygems.org/gems/bundler-source-s3) that doesn't
77
+ work and you probably don't want to confuse with this gem. If you use type 's3'
78
+ (instead of 'aws-s3') in your Gemfile you'll get that plugin, not this one.
79
+
80
+ ## Contributing
81
+
82
+ Bug reports and pull requests are welcome on GitHub at
83
+ https://github.com/eki/bundler-source-aws-s3.
84
+
85
+ ## License
86
+
87
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/plugins.rb ADDED
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+ require 'rubygems/package'
6
+
7
+ class BundlerSourceAwsS3 < Bundler::Plugin::API
8
+ class S3Source < Bundler::Source
9
+ # Bundler plugin api, we need to install the gem for the given spec and
10
+ # then call post_install.
11
+ def install(spec, opts)
12
+ print_using_message "Using #{spec.name} #{spec.version} from #{self}"
13
+
14
+ validate!(spec)
15
+
16
+ package = package_for(spec)
17
+ destination = install_path.join(spec.full_name)
18
+
19
+ Bundler.mkdir_p(destination)
20
+ package.extract_files(destination)
21
+ File.open(spec.loaded_from, 'wb') { |f| f.write spec.to_ruby }
22
+
23
+ post_install(spec)
24
+ end
25
+
26
+ # Bundler plugin api, we need to return a Bundler::Index
27
+ def specs
28
+ # Only pull gems if bundler tells us to check remote
29
+ pull if remote?
30
+
31
+ # We haven't pulled any s3 gems if the directory doesn't exist, so we'll
32
+ # give bundler an empty index.
33
+ return Bundler::Index.new unless File.directory?(s3_gems_path)
34
+
35
+ Bundler::Index.build do |index|
36
+ packages.map(&:spec).each do |spec|
37
+ spec.source = self
38
+ spec.loaded_from = loaded_from_for(spec)
39
+
40
+ Bundler.rubygems.validate(spec)
41
+ index << spec
42
+ end
43
+ end
44
+ end
45
+
46
+ # Bundler calls this to tell us fetching remote gems is okay.
47
+ def remote!
48
+ @remote = true
49
+ end
50
+
51
+ def remote?
52
+ @remote
53
+ end
54
+
55
+ # TODO What is bundler telling us if unlock! is called?
56
+ def unlock!
57
+ puts "[aws-s3] DEBUG: unlock! called"
58
+ end
59
+
60
+ # TODO What is bundler telling us if cached! is called?
61
+ def cached!
62
+ puts "[aws-s3] DEBUG: cached! called"
63
+ end
64
+
65
+ def to_s
66
+ "aws-s3 plugin with uri #{uri}"
67
+ end
68
+
69
+ private
70
+
71
+ # This is a guard against attempting to install a spec that doesn't match
72
+ # our requirements / expectations.
73
+ #
74
+ # If we want to be more trusting, we could probably safely remove this
75
+ # method.
76
+ def validate!(spec)
77
+ unless spec.source == self && spec.loaded_from == loaded_from_for(spec)
78
+ raise "[aws-s3] Error #{spec.full_name} spec is not valid"
79
+ end
80
+ end
81
+
82
+ # We will use this value as the given spec's loaded_from. It should be the
83
+ # path fo the installed gem's gemspec.
84
+ def loaded_from_for(spec)
85
+ destination = install_path.join(spec.full_name)
86
+ destination.join("#{spec.full_name}.gemspec").to_s
87
+ end
88
+
89
+ # This path is going to be under bundler's gem_install_dir and we'll then
90
+ # mirror the bucket/path directory structure from the source. This is where
91
+ # we want to place our gems. This directory can hold multiple installed
92
+ # gems.
93
+ def install_path
94
+ @install_path ||= gem_install_dir.join(bucket).join(path)
95
+ end
96
+
97
+ # This is the path to the s3 gems for our source uri. We will pull the s3
98
+ # gems into this directory.
99
+ def s3_gems_path
100
+ Bundler.user_bundle_path.
101
+ join('bundler-source-aws-s3').join(bucket).join(path)
102
+ end
103
+
104
+ # Pull s3 gems from the source and store them in
105
+ # .bundle/bundler-source-aws-s3/<bucket>/<path>. We will install, etc, from
106
+ # this directory.
107
+ def pull
108
+ # We only want to pull once in a single bundler run.
109
+ return @pull if defined?(@pull)
110
+
111
+ Bundler.mkdir_p(s3_gems_path)
112
+
113
+ output, status = Open3.capture2e(sync_cmd)
114
+
115
+ @pull = status.success?
116
+ end
117
+
118
+ # Produces a list of Gem::Package for the s3 gems.
119
+ def packages
120
+ @packages ||= Dir.entries(s3_gems_path.join('gems')).
121
+ map { |entry| s3_gems_path.join('gems').join(entry) }.
122
+ select { |gem_path| File.file?(gem_path) }.
123
+ map { |gem_path| Gem::Package.new(gem_path.to_s) }
124
+ end
125
+
126
+ # Find the Gem::Package for a given spec.
127
+ def package_for(spec)
128
+ packages.find { |package| package.spec.full_name == spec.full_name }
129
+ end
130
+
131
+ def sync_cmd
132
+ "aws s3 sync --delete #{uri} #{s3_gems_path}"
133
+ end
134
+
135
+ def bucket
136
+ URI.parse(uri).normalize.host
137
+ end
138
+
139
+ def path
140
+ # Remove the leading slash from the path.
141
+ URI.parse(uri).normalize.path[1..-1]
142
+ end
143
+ end
144
+
145
+ source 'aws-s3', S3Source
146
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bundler-source-aws-s3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Eric K Idema
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Add aws-s3 source to bundler via plugin.
14
+ email:
15
+ - eki@vying.org
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - plugins.rb
22
+ homepage: https://github.com/eki/bundler-source-aws-s3
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Add aws-s3 source to bundler via plugin.
45
+ test_files: []