bundle_depot 0.0.3 → 0.2.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: a55b38b0f6d97f4ebeaaa598a2a262d0d88b5797
4
- data.tar.gz: f7fb75fd3fd2f272c61817429d0b5ac09ee31202
3
+ metadata.gz: 9be713b4d9ac3679609e14010e93609ba007a147
4
+ data.tar.gz: d7912052a61da3ac04c079d3f8ebd3ae960a47f2
5
5
  SHA512:
6
- metadata.gz: 9d6f9c86dfb3e854adeacc54050733ab626888a9a1d504cf7daf138686674456ac24753bcaecb03b07fdfa96d81ff9652dbe95d3b4655daed6c72a9d56a398fa
7
- data.tar.gz: 746b346998225e6dea7215365e56f797df61187ba2eef2bbed5cf42756dc95c54e3d93eb5e9aa0cdf418df800c441ebfefd80ced575990daec958f46de5d989e
6
+ metadata.gz: 5e4115c9b586fb36382a7cd1a5869c1fb821f916d1d9b2fd37eaf168d382f7d6f19df66bb6426d4a66cf93979c04b18bde72c7c5355a7f7127c6a72ffa8d0c94
7
+ data.tar.gz: 75565c28483a91a1ad04fee040e0c60b152c883462daf051d1388445684002ecf94a61e2989b1e4bec7376ad05465dc45e2edf6c86889b66c5bf391f2c369430
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bundle_depot (0.0.3)
4
+ bundle_depot (0.2.0)
5
+ net-scp
5
6
  thor
6
7
 
7
8
  GEM
@@ -30,6 +31,9 @@ GEM
30
31
  multi_json (~> 1.3)
31
32
  multi_json (1.8.2)
32
33
  multi_test (0.0.2)
34
+ net-scp (1.1.2)
35
+ net-ssh (>= 2.6.5)
36
+ net-ssh (2.7.0)
33
37
  rack (1.5.2)
34
38
  rack-protection (1.5.1)
35
39
  rack
data/README.md CHANGED
@@ -1,24 +1,101 @@
1
1
  # BundleDepot
2
2
 
3
- TODO: Write a gem description
3
+ Utility for caching bundled gems.
4
4
 
5
- ## Installation
5
+ Especially useful for CI servers that rely on clean build directories, or use
6
+ multiple build directories and need to run `bundle install` repeatedly.
6
7
 
7
- Add this line to your application's Gemfile:
8
8
 
9
- gem 'bundle_depot'
9
+ ## How it works
10
10
 
11
- And then execute:
11
+ bundle-depot fetch
12
+ bundle install --path .bundle/depot/current
13
+ bundle-depot store
12
14
 
13
- $ bundle
15
+ This will:
14
16
 
15
- Or install it yourself as:
17
+ 1. Create a SHA2 hash from the project's `Gemfile.lock` (e.g. 314ff159)
18
+ 2. If required, a folder `.bundle/depot/cache/314ff159` is created. This is the local cache.
19
+ 3. A remote location is checked for a file `314ff159.tar.gz`. If available it is downloaded and unpacked.
20
+ 4. A symlink is managed to point from `.bundle/depot/current` to `.bundle/depot/cache/314ff159`
21
+ 5. `bundle install` is installing gems when both caches are cold. Otherwise, does nothing \o/
22
+ 6. Tar and zip `.bundle/depot/cache/314ff159` into `.bundle/depot/cache/314ff159.tar.gz`
23
+ 7. Upload `314ff159.tar.gz` to the remote cache
24
+
25
+ Whenever the Gemfile changes in subsequent runs this process will repeat
26
+ itself. `.bundle/depot/current` will point to the cache entry that contains the
27
+ most recent bundle gems.
28
+
29
+
30
+ ## Shared Cache on the local machine
31
+
32
+ This can be used to setup a shared cache on the same machine by configuring the
33
+ environent variable `BUNDLE_DEPOT_CACHE`.
34
+
35
+ export BUNDLE_DEPOT_CACHE=/var/lib/bundle_depot
36
+ bundle-depot fetch
37
+ bundle install --path .bundle/depot/current
38
+ bundle-depot store
39
+
40
+ Instead of using `.bundle/depot/cache` this will then use `/var/lib/bundle_depot` as
41
+ a shared cache folder.
42
+
43
+ ## Remote Caching
44
+
45
+ When a remote store is configured this sequence will check and update a remote
46
+ cache location:
47
+
48
+ export BUNDLE_DEPOT_SCP_USER=upload
49
+ export BUNDLE_DEPOT_SCP_PASS=upload
50
+ export BUNDLE_DEPOT_SCP_HOST=cache.example.com
51
+
52
+ bundle-depot fetch
53
+ bundle install --path .bundle/depot/current
54
+ bundle-depot store
55
+
56
+ In addition to checking the local cache on the file system, this will check
57
+ the existance of a zipped bundle on a remote location. Currently supported is
58
+ a connection via SCP.
16
59
 
17
- $ gem install bundle_depot
18
60
 
19
- ## Usage
61
+ ## Configuration Options
62
+
63
+ * `BUNDLE_DEPOT_CACHE`
64
+ Point to where you want to keep your local cache. Defaults to `.bundle/depot/cache`
65
+
66
+
67
+ ## Complete Example
68
+
69
+ #!/bin/sh
70
+ set -o errexit # abort after the first command that fails
71
+
72
+ fmt <<'EOF'
73
+ ====================================================================================
74
+ Preparing Build Agent Environment
75
+ ====================================================================================
76
+ EOF
77
+ gem install bundle_depot --install-dir .gems --bindir bin --no-rdoc --no-ri
78
+
79
+
80
+ fmt <<'EOF'
81
+ ====================================================================================
82
+ Bundle it!
83
+ ====================================================================================
84
+ EOF
85
+ export BUNDLE_DEPOT_HOME=/var/lib/bundle_depot
86
+ export BUNDLE_DEPOT_SCP_USER=upload
87
+ export BUNDLE_DEPOT_SCP_PASS=upload
88
+ export BUNDLD_DEPOT_SCP_HOST=cache.example.com
89
+
90
+ bin/bundle-depot fetch
91
+ bundle install --path .bundle/depot/current --frozen
92
+ bin/bundle-depot store
93
+
94
+
95
+ ## Installation
96
+
97
+ $ gem install bundle_depot
20
98
 
21
- TODO: Write usage instructions here
22
99
 
23
100
  ## Contributing
24
101
 
data/bundle_depot.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "thor"
22
+ spec.add_dependency "net-scp"
22
23
 
23
24
  spec.add_development_dependency "cucumber"
24
25
  spec.add_development_dependency "aruba"
data/features/cli.feature CHANGED
@@ -1,5 +1,11 @@
1
1
  @announce
2
2
  Feature: CLI
3
+ Background:
4
+ Given the following environment variables are set:
5
+ | variable | value |
6
+ | BUNDLE_DEPOT_SCP_USER | upload |
7
+ | BUNDLE_DEPOT_SCP_PASS | upload |
8
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
3
9
 
4
10
  Scenario: Help screen
5
11
  When I run `bundle-depot`
@@ -9,8 +9,6 @@ Feature: Fetch remotely stored bundle
9
9
 
10
10
  Scenario: Working directory defaults to ./bundle/depot
11
11
  Given there is the project "json" in the current directory
12
- And the remote cache contains the packed bundle for "json"
13
- And the local cache does not contain the bundle "json"
14
12
  When I run `bundle-depot fetch`
15
13
  Then the following directories should exist:
16
14
  | .bundle/depot/cache |
@@ -18,11 +16,9 @@ Feature: Fetch remotely stored bundle
18
16
 
19
17
  Scenario: Local Cache can be overwritten by environment
20
18
  Given there is the project "json" in the current directory
21
- And the remote cache contains the packed bundle for "json"
22
- And the local cache does not contain the bundle "json"
23
19
  And the following environment variables are set:
24
- | variable | value |
25
- | BUNDLE_DEPOT_CACHE_PATH | special/depot/cache |
20
+ | variable | value |
21
+ | BUNDLE_DEPOT_CACHE | special/depot/cache |
26
22
  When I run `bundle-depot fetch`
27
23
  Then the following directories should exist:
28
24
  | special/depot/cache/bde95daa2ce7dede336b4367b9e3a0690027bd6f071e0fdcb1b3047cf988963c |
@@ -37,27 +33,38 @@ Feature: Fetch remotely stored bundle
37
33
  When I run `bundle-depot fetch`
38
34
  Then the exit status should be 0
39
35
 
40
- Scenario: Does nothing if the remote cache does not contain the bundle
36
+ Scenario: .bundle/depot/current points to
41
37
  Given there is the project "json" in the current directory
42
- And the remote cache does not contain the packed bundle "json"
43
38
  When I run `bundle-depot fetch`
44
- Then the exit status should be 0
39
+ Then the following symlinks should exist:
40
+ | source | target |
41
+ | .bundle/depot/current | .bundle/depot/cache/bde95daa2ce7dede336b4367b9e3a0690027bd6f071e0fdcb1b3047cf988963c |
45
42
 
46
- Scenario: Download the Bundle to local cache
43
+ Scenario: Skip remote check if SCP is not setup
47
44
  Given there is the project "json" in the current directory
48
- And the remote cache contains the packed bundle for "json"
49
- And the local cache does not contain the bundle "json"
50
45
  When I run `bundle-depot fetch`
51
- Then the exit status should be 0
52
- And the following directories should exist:
53
- | .bundle/depot/cache/bde95daa2ce7dede336b4367b9e3a0690027bd6f071e0fdcb1b3047cf988963c |
46
+ Then the output should not contain "=> Bundle is not in remote cache"
54
47
 
55
- Scenario: .bundle/depot/current points to
48
+ Scenario: Check remote cache when SCP is setup
56
49
  Given there is the project "json" in the current directory
50
+ And the following environment variables are set:
51
+ | variable | value |
52
+ | BUNDLE_DEPOT_SCP_USER | upload |
53
+ | BUNDLE_DEPOT_SCP_PASS | upload |
54
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
57
55
  And the remote cache contains the packed bundle for "json"
58
56
  And the local cache does not contain the bundle "json"
59
57
  When I run `bundle-depot fetch`
60
- Then the following symlinks should exist:
61
- | source | target |
62
- | .bundle/depot/current | .bundle/depot/cache/bde95daa2ce7dede336b4367b9e3a0690027bd6f071e0fdcb1b3047cf988963c |
58
+ Then the output should contain "=> Bundle found in remote cache. Downloading!"
63
59
 
60
+ Scenario: Does nothing if the remote cache does not contain the bundle
61
+ Given there is the project "json" in the current directory
62
+ And the following environment variables are set:
63
+ | variable | value |
64
+ | BUNDLE_DEPOT_SCP_USER | upload |
65
+ | BUNDLE_DEPOT_SCP_PASS | upload |
66
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
67
+ And the remote cache does not contain the packed bundle "json"
68
+ And the local cache does not contain the bundle "json"
69
+ When I run `bundle-depot fetch`
70
+ Then the exit status should be 0
@@ -7,7 +7,10 @@ When(/^I run `([^`]*)` in a bundler sandbox$/) do |cmd|
7
7
  set_env(key, nil)
8
8
  end
9
9
  run_simple(unescape(cmd), false)
10
- restore_env
10
+
11
+ %w[RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE GEM_HOME GEM_PATH].each do |key|
12
+ ENV[key] = original_env[key]
13
+ end
11
14
  end
12
15
 
13
16
  Then(/^bundler did not install gems$/) do
@@ -3,19 +3,39 @@ Feature: Store Local Package Remotely
3
3
 
4
4
  Scenario: No Gemfile (store)
5
5
  Given there is no Gemfile.lock in the current directory
6
+ And the following environment variables are set:
7
+ | variable | value |
8
+ | BUNDLE_DEPOT_SCP_USER | upload |
9
+ | BUNDLE_DEPOT_SCP_PASS | upload |
10
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
6
11
  When I run `bundle-depot store`
7
12
  Then the output should contain "Couldn't find Gemfile.lock"
8
13
  And the exit status should not be 0
9
14
 
15
+ Scenario: No SCP environment configured
16
+ Given there is the project "json" in the current directory
17
+ When I run `bundle-depot store`
18
+ Then the output should contain "Remote cache is not configured. Configured the SCP environment variables to run 'bundle-depot store'"
19
+ And the exit status should not be 0
20
+
10
21
  Scenario: Does nothing if remote cache contains the bundle
11
22
  Given there is the project "json" in the current directory
23
+ And the following environment variables are set:
24
+ | variable | value |
25
+ | BUNDLE_DEPOT_SCP_USER | upload |
26
+ | BUNDLE_DEPOT_SCP_PASS | upload |
27
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
12
28
  And the remote cache contains the packed bundle for "json"
13
29
  When I run `bundle-depot store`
14
30
  Then the exit status should be 0
15
31
 
16
32
  Scenario: Fails if local cache does not contain the bundle
17
- Given an empty file named "Gemfile.lock"
18
- And the remote cache does not contain the packed bundle "json"
33
+ Given there is the project "json" in the current directory
34
+ And the following environment variables are set:
35
+ | variable | value |
36
+ | BUNDLE_DEPOT_SCP_USER | upload |
37
+ | BUNDLE_DEPOT_SCP_PASS | upload |
38
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
19
39
  And the local cache does not contain the bundle "json"
20
40
  When I run `bundle-depot store`
21
41
  Then the output should contain "Couldn't find the cached bundle."
@@ -23,6 +43,11 @@ Feature: Store Local Package Remotely
23
43
 
24
44
  Scenario: Uploads the Bundle to remote cache
25
45
  Given there is the project "json" in the current directory
46
+ And the following environment variables are set:
47
+ | variable | value |
48
+ | BUNDLE_DEPOT_SCP_USER | upload |
49
+ | BUNDLE_DEPOT_SCP_PASS | upload |
50
+ | BUNDLE_DEPOT_SCP_HOST | cache.example.com |
26
51
  And the remote cache does not contain the packed bundle "json"
27
52
  And the local cache contains the bundle "json"
28
53
  When I run `bundle-depot store`
@@ -5,12 +5,14 @@ require 'bundle_depot'
5
5
 
6
6
  World(RSpec::Matchers)
7
7
 
8
+ ENV["TEST"] = "true"
9
+
8
10
  def local_cache_path
9
- File.join(BundleDepot::Cache::DEFAULT_BUNDLE_DEPOT_PATH, "cache")
11
+ BundleDepot::Cache.cache_path
10
12
  end
11
13
 
12
14
  def remote_cache_path
13
- File.join(BundleDepot::Cache::DEFAULT_BUNDLE_DEPOT_PATH, "remote")
15
+ File.join(".bundle", "depot","remote")
14
16
  end
15
17
 
16
18
  def fixture_project_path(project)
@@ -40,3 +42,4 @@ end
40
42
  def remote_cache_packed_bundle_path(bundle)
41
43
  File.join(remote_cache_path, fixtures_bundle_name(bundle) + ".tar.gz")
42
44
  end
45
+
@@ -1,143 +1,233 @@
1
1
  require "digest"
2
+ require "delegate"
3
+ require 'net/scp'
2
4
 
3
5
  module BundleDepot
4
6
  class BundleDepotError < StandardError; end
7
+ class GemfileNotFound < BundleDepotError; end
8
+ class RemoteConfigurationMissing < BundleDepotError; end
5
9
  class BundleNotFound < BundleDepotError; end
6
10
  class RemoteBundleNotFound < BundleNotFound; end
7
11
  class LocalBundleNotFound < BundleNotFound; end
8
12
  class ArchivingFailed < BundleDepotError; end
9
13
 
10
- class FileSystemStore
14
+ class Store
15
+ def cached?(file)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def store(file)
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def fetch(file, dest_dir)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def with_packing
28
+ PackingDecorator.new(self)
29
+ end
30
+ end
31
+
32
+ class SCPStore < Store
33
+ attr_reader :host, :user, :password, :path
34
+
35
+ def initialize(host, user, password, path = ".")
36
+ @host = host
37
+ @user = user
38
+ @password = password
39
+ @path = path
40
+ end
41
+
42
+ def cached?(file)
43
+ target = File.join(path, File.basename(file))
44
+ output = "false"
45
+
46
+ Net::SSH.start(host, user, { password: password}) do |session|
47
+ output = session.exec! "test -e #{target} && echo 'true'"
48
+ end
49
+
50
+ output.strip == "true"
51
+ end
52
+
53
+ def store(file)
54
+ Net::SSH.start(host, user, { password: password}) do |session|
55
+ session.exec! "mkdir -p #{path}"
56
+ session.scp.upload! file, File.join(path, File.basename(file))
57
+ end
58
+ end
59
+
60
+ def fetch(file, dest_dir)
61
+ Net::SCP.download!(host, user, File.join(path, file), file, ssh: { password: password })
62
+ rescue Net::SCP::Error
63
+ raise BundleNotFound
64
+ end
65
+
66
+ end
67
+
68
+ class FileSystemStore < Store
11
69
  attr_reader :path
12
70
 
71
+ def cached?(file)
72
+ File.exists? File.join(path, file)
73
+ end
74
+
13
75
  def initialize(path)
14
76
  @path = path
15
77
  FileUtils.mkdir_p(path)
16
78
  end
17
79
 
80
+ def store(file)
81
+ FileUtils.cp_r file, File.join(path, File.basename(file))
82
+ end
83
+
84
+ def fetch(file, dest_dir)
85
+ FileUtils.cp_r File.join(path, file), dest_dir
86
+ end
87
+ end
88
+
89
+ class PackingDecorator < SimpleDelegator
90
+
18
91
  def cached?(file)
19
- File.exists? File.join(path, file)
92
+ super(packed_file(file))
20
93
  end
21
94
 
22
95
  def store(file)
23
- FileUtils.cp_r file, File.join(path, File.basename(file))
96
+ working_dir = File.expand_path(File.dirname(file))
97
+ source = File.basename(file)
98
+ target = packed_file(file)
99
+
100
+ raise BundleNotFound unless File.exists? file
101
+
102
+ unless File.exist?(target)
103
+ puts "=> Packing bundle"
104
+ `tar -C #{working_dir} -czf #{target} #{source}`
105
+ raise ArchivingFailed unless $?.exitstatus == 0
106
+ end
107
+
108
+ super(target)
24
109
  end
25
110
 
26
111
  def fetch(file, dest_dir)
27
- FileUtils.cp_r File.join(path, file), dest_dir
112
+ source = packed_file(file)
113
+ target = File.join(dest_dir, source)
114
+
115
+ super(source, dest_dir)
116
+
117
+ puts "=> Unpacking #{target}"
118
+ `tar -C #{dest_dir} -xf #{target}`
119
+ raise ArchivingFailed unless $?.exitstatus == 0
120
+ end
121
+
122
+ def packed_file(file)
123
+ file + ".tar.gz"
28
124
  end
29
125
  end
30
126
 
31
127
  class Cache
32
- DEFAULT_BUNDLE_DEPOT_PATH = File.join(".bundle", "depot")
128
+ DEFAULT_BUNDLE_DEPOT_CURRENT = File.join(".bundle", "depot", "current")
129
+ DEFAULT_BUNDLE_DEPOT_CACHE = File.join(".bundle", "depot", "cache")
33
130
 
34
131
  attr_reader :local, :remote
35
132
 
36
133
  def initialize(local = FileSystemStore.new(Cache.cache_path),
37
- remote = FileSystemStore.new(File.join(Cache.depot_path, "remote")))
134
+ remote = FileSystemStore.new(File.join(".bundle", "depot", "remote")).with_packing)
135
+
136
+ if remote_configured? && !ENV["TEST"]
137
+ remote = SCPStore.new(ENV["BUNDLE_DEPOT_SCP_HOST"],
138
+ ENV["BUNDLE_DEPOT_SCP_USER"],
139
+ ENV["BUNDLE_DEPOT_SCP_PASS"], "cache").with_packing
140
+ end
38
141
 
39
142
  @local = local
40
143
  @remote = remote
41
144
  end
42
145
 
43
146
  def store
44
- if remote.cached?(digest + ".tar.gz")
45
- puts "=> Bundle is already in remote cache. Skipping upload."
46
- else
47
- raise BundleNotFound unless local.cached?(digest)
48
- pack
49
- upload
50
- end
147
+ setup
148
+ store_remote
51
149
  end
52
150
 
53
151
  def fetch
152
+ setup
153
+ fetch_remote unless fetch_local
154
+ manage_symlink
155
+ end
156
+
157
+ def fetch_local
54
158
  if local.cached?(digest)
55
159
  puts "=> Bundle found in local cache"
160
+ true
56
161
  else
57
162
  puts "=> Bundle is not in local cache"
58
- if remote.cached?(digest + ".tar.gz")
59
- download
60
- unpack
61
- else
62
- puts "=> Bundle is not in remote cache"
63
- FileUtils.mkdir_p(unpacked_bundle)
64
- end
65
163
  end
66
- link
67
164
  end
68
165
 
166
+ def fetch_remote
167
+ return unless remote_configured?
168
+
169
+ if remote.cached?(digest)
170
+ puts "=> Bundle found in remote cache. Downloading!"
171
+ remote.fetch(digest, local.path)
172
+ else
173
+ puts "=> Bundle is not in remote cache"
174
+ end
175
+ end
176
+
177
+ def store_remote
178
+ raise RemoteConfigurationMissing unless remote_configured?
69
179
 
70
- def self.depot_path
71
- ENV["BUNDLE_DEPOT_PATH"] || DEFAULT_BUNDLE_DEPOT_PATH
180
+ if remote.cached?(digest)
181
+ puts "=> Bundle is already in remote cache. Skipping upload."
182
+ else
183
+ puts "=> Uploading bundle to remote cache"
184
+ remote.store(File.join(local.path, digest))
185
+ end
72
186
  end
73
187
 
74
188
  def self.cache_path
75
- ENV["BUNDLE_DEPOT_CACHE_PATH"] || File.join(Cache.depot_path, "cache")
189
+ ENV["BUNDLE_DEPOT_CACHE"] || DEFAULT_BUNDLE_DEPOT_CACHE
76
190
  end
77
191
 
78
192
  def self.current_bundle_path
79
- ENV["BUNDLE_DEPOT_CURRENT_PATH"] || File.join(Cache.depot_path, "current")
193
+ ENV["DEFAULT_BUNDLE_DEPOT_CURRENT"] || DEFAULT_BUNDLE_DEPOT_CURRENT
80
194
  end
81
195
 
82
- private
83
-
84
- def link
85
- source = unpacked_bundle
86
- target = Cache.current_bundle_path
87
-
88
- if File.exist?(target)
89
- if File.symlink?(target)
90
- if File.readlink(File.expand_path(target)) == File.expand_path(source)
91
- return
92
- else
93
- File.unlink(target)
94
- end
95
- else
96
- raise "Shit. #{target} is not a symlink. Aborting to not mess stuff up..."
97
- end
98
- end
99
-
100
- puts "=> Linking #{target} -> #{source}"
101
- File.symlink File.expand_path(source), target
196
+ def remote_configured?
197
+ ENV["BUNDLE_DEPOT_SCP_HOST"]
102
198
  end
103
199
 
104
- def pack
105
- return if File.exist?(packed_file)
106
- puts "=> Packing bundle"
107
-
108
- `tar -C #{File.expand_path(local.path)} -czf #{packed_file} #{digest}`
109
- raise ArchivingFailed unless $?.exitstatus == 0
110
- end
200
+ private
111
201
 
112
- def unpack
113
- `tar -C #{File.expand_path(local.path)} -xf #{packed_file}`
114
- raise ArchivingFailed unless $?.exitstatus == 0
202
+ def setup
203
+ FileUtils.mkdir_p(File.dirname(Cache.current_bundle_path))
115
204
  end
116
205
 
117
- def upload
118
- puts "=> Uploading bundle to remote cache"
119
- remote.store(packed_file)
120
- end
206
+ def manage_symlink
207
+ source = File.join(local.path, digest)
208
+ target = Cache.current_bundle_path
121
209
 
122
- def download
123
- puts "=> Bundle found in remote cache. Downloading!"
124
- remote.fetch(digest + ".tar.gz", local.path)
210
+ FileUtils.mkdir_p(source) unless File.exists?(source)
211
+
212
+ if remove_outdated_symlink(source, target)
213
+ puts "=> Linking #{target} -> #{source}"
214
+ File.symlink File.expand_path(source), target
215
+ else
216
+ puts "=> #{target} is pointing to the right bundle"
217
+ end
125
218
  end
126
219
 
127
- def packed_file
128
- File.expand_path(File.join(local.path, digest + ".tar.gz"))
129
- end
220
+ def remove_outdated_symlink(source, target)
221
+ return true unless File.exist?(target)
222
+ raise "#{target} is not a symlink. Aborting to not mess stuff up..." unless File.symlink?(target)
223
+ return false if File.symlink?(target) && File.readlink(File.expand_path(target)) == File.expand_path(source)
130
224
 
131
- def unpacked_bundle
132
- File.join(local.path, digest)
225
+ File.unlink(target)
133
226
  end
134
227
 
135
228
  def digest
136
- Digest::SHA2.file(lock_file).hexdigest
137
- end
138
-
139
- def lock_file
140
- File.expand_path("Gemfile.lock")
229
+ raise GemfileNotFound unless File.exist?("Gemfile.lock")
230
+ Digest::SHA2.file("Gemfile.lock").hexdigest
141
231
  end
142
232
  end
143
233
 
@@ -15,12 +15,10 @@ module BundleDepot
15
15
  tenderloin bresaola rump pastrami turkey kevin flank.
16
16
  D
17
17
  def fetch
18
- unless File.exist?("Gemfile.lock")
19
- say "Couldn't find Gemfile.lock"
20
- exit 1
21
- end
22
-
23
18
  BundleDepot::Cache.new.fetch
19
+ rescue GemfileNotFound
20
+ say "Couldn't find Gemfile.lock"
21
+ exit 1
24
22
  end
25
23
 
26
24
  desc "store", "Store bundle to remote location"
@@ -30,22 +28,16 @@ module BundleDepot
30
28
  tenderloin bresaola rump pastrami turkey kevin flank.
31
29
  D
32
30
  def store
33
- unless File.exist?("Gemfile.lock")
34
- say "Couldn't find Gemfile.lock"
35
- exit 1
36
- end
37
-
38
31
  BundleDepot::Cache.new.store
39
-
32
+ rescue GemfileNotFound
33
+ say "Couldn't find Gemfile.lock"
34
+ exit 1
40
35
  rescue BundleNotFound
41
36
  say "Couldn't find the cached bundle. Please run 'bundle-depot fetch' before calling this command..."
42
37
  exit 2
43
-
44
- # Calculate Checksum
45
- # Check local cache
46
- # Check remote cache
47
- # Pack
48
- # Upload
38
+ rescue RemoteConfigurationMissing
39
+ say "Remote cache is not configured. Configured the SCP environment variables to run 'bundle-depot store'"
40
+ exit 3
49
41
  end
50
42
  end
51
43
  end
@@ -1,3 +1,3 @@
1
1
  module BundleDepot
2
- VERSION = "0.0.3"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundle_depot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Schmidt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-06 00:00:00.000000000 Z
11
+ date: 2013-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: net-scp
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'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: cucumber
29
43
  requirement: !ruby/object:Gem::Requirement