Module: BundleCache

Extended by:
BundleCache
Included in:
BundleCache
Defined in:
lib/bundle_cache.rb,
lib/bundle_cache/cache.rb,
lib/bundle_cache/install.rb,
lib/bundle_cache/version.rb,
lib/bundle_cache/validation.rb

Constant Summary collapse

VERSION =
"0.2.3"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cacheObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bundle_cache/cache.rb', line 5

def self.cache
  acl_to_use = ENV["KEEP_BUNDLE_PRIVATE"] ? :private : :public_read
  bundle_dir = ENV["BUNDLE_DIR"] || "~/.bundle"
  processing_dir = ENV["PROCESS_DIR"] || ENV["HOME"]

  bucket_name     = ENV["AWS_S3_BUCKET"]
  architecture    = `uname -m`.strip

  file_name       = "#{ENV['BUNDLE_ARCHIVE']}-#{architecture}.tgz"
  file_path       = "#{processing_dir}/#{file_name}"
  lock_file       = File.join(File.expand_path(ENV["TRAVIS_BUILD_DIR"].to_s), "Gemfile.lock")
  digest_filename = "#{file_name}.sha2"
  old_digest      = File.expand_path("#{processing_dir}/remote_#{digest_filename}")

  puts "Checking for changes"
  bundle_digest = Digest::SHA2.file(lock_file).hexdigest
  old_digest    = File.exists?(old_digest) ? File.read(old_digest) : ""

  if bundle_digest == old_digest
    puts "=> There were no changes, doing nothing"
  else
    if old_digest == ""
      puts "=> There was no existing digest, uploading a new version of the archive"
    else
      puts "=> There were changes, uploading a new version of the archive"
      puts "  => Old checksum: #{old_digest}"
      puts "  => New checksum: #{bundle_digest}"
    end

    puts "=> Preparing bundle archive"
    `tar -C #{File.dirname(bundle_dir)} -cjf #{file_path} #{File.basename(bundle_dir)} && split -b 5m -a 3 #{file_path} #{file_path}.`

    if 1 == $?.exitstatus
      puts "=> Archive failed. Please make sure '--path=#{bundle_dir}' is added to bundle_args."
      exit 1
    end


    parts_pattern = File.expand_path(File.join(processing_dir, "#{file_name}.*"))
    parts = Dir.glob(parts_pattern).sort

    s3 = AWS::S3.new
    bucket = s3.buckets[bucket_name]

    puts "=> Uploading the bundle"
    gem_archive = bucket.objects[file_name]

    puts "  => Uploading #{parts.length} parts"
    gem_archive.multipart_upload(:acl => acl_to_use) do |upload|
      parts.each_with_index do |part, index|
        puts "    => Uploading #{part}"
        File.open part do |part_file|
          upload.add_part(part_file)
          puts "      => Uploaded"
        end
      end
    end
    puts "  => Completed multipart upload"

    puts "=> Uploading the digest file"
    hash_object = bucket.objects[digest_filename]
    hash_object.write(bundle_digest, :acl => acl_to_use, :content_type => "text/plain")
  end

  puts "All done now."
end

.installObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/bundle_cache/install.rb', line 5

def self.install
  architecture = `uname -m`.strip
  file_name = "#{ENV['BUNDLE_ARCHIVE']}-#{architecture}.tgz"
  digest_filename = "#{file_name}.sha2"
  bucket_name = ENV["AWS_S3_BUCKET"]
  bundle_dir = ENV["BUNDLE_DIR"] || "~/.bundle"
  processing_dir = ENV['PROCESS_DIR'] || ENV['HOME']

  s3 = AWS::S3.new
  bucket = s3.buckets[bucket_name]

  gem_archive = bucket.objects[file_name]
  hash_object = bucket.objects[digest_filename]

  puts "=> Downloading the bundle"
  File.open("#{processing_dir}/remote_#{file_name}", 'wb') do |file|
    gem_archive.read do |chunk|
      file.write(chunk)
    end
  end
  puts "  => Completed bundle download"

  puts "=> Extract the bundle"
  `cd #{File.dirname(bundle_dir)} && tar -xf "#{processing_dir}/remote_#{file_name}"`

  puts "=> Downloading the digest file"
  File.open("#{processing_dir}/remote_#{file_name}.sha2", 'wb') do |file|
    hash_object.read do |chunk|
      file.write(chunk)
    end
  end
  puts "  => Completed digest download"

  puts "=> All done!"
rescue AWS::S3::Errors::NoSuchKey
  puts "There's no such archive!"
end

Instance Method Details

#access_keys_missing?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/bundle_cache/validation.rb', line 18

def access_keys_missing?
  ENV['AWS_ACCESS_KEY_ID'].nil? || ENV['AWS_SECRET_ACCESS_KEY'].nil?
end

#deprecation_warningObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/bundle_cache/validation.rb', line 22

def deprecation_warning
  if !!ENV['AWS_S3_KEY']
    puts "The 'AWS_S3_KEY' environment variable is deprecated and will be removed in the future."
    puts "Please set 'AWS_ACCESS_KEY_ID' instead"
    ENV['AWS_ACCESS_KEY_ID'] = ENV['AWS_S3_KEY']
  end

  if !!ENV['AWS_S3_SECRET']
    puts "The 'AWS_S3_SECRET' environment variable is deprecated and will be removed in the future."
    puts "Please set 'AWS_SECRET_ACCESS_KEY' instead"
    ENV['AWS_SECRET_ACCESS_KEY'] = ENV['AWS_S3_SECRET']
  end

  if !!ENV['AWS_S3_REGION']
    puts "The 'AWS_S3_REGION' environment variable is deprecated and will be removed in the future."
    puts "Please set 'AWS_DEFAULT_REGION' instead"
    ENV['AWS_DEFAULT_REGION'] = ENV['AWS_S3_REGION']
  end
end

#session_token_missing?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/bundle_cache/validation.rb', line 14

def session_token_missing?
  ENV['AWS_SESSION_TOKEN'].nil?
end

#verify_envObject



4
5
6
7
8
9
10
11
12
# File 'lib/bundle_cache/validation.rb', line 4

def verify_env
  deprecation_warning

  %w(AWS_S3_BUCKET BUNDLE_ARCHIVE).each do |var|
    abort("Missing ENV[#{var}]") unless ENV[var]
  end

  abort("Missing required AWS credentials") if (session_token_missing? && access_keys_missing?)
end