ci-cache 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 288ef0fe2be849cb4a5d1fbb0f48ecfae5fc62eb
4
+ data.tar.gz: 46f0d3a3f1b403bf6f678e48f9e0cdfbc7b808e9
5
+ SHA512:
6
+ metadata.gz: b5ad74c170005c79dd259ff97441d77bbbb85dcda12ee52bf24675daf9478b9effa8fdb7735053c520be586bb5315fcb146ae34f11cfb36d60088bbfb659db07
7
+ data.tar.gz: 18d7f343646cf8d6bbaa12f239a2690a6ffab84e495d8884812ec24a99b859f982c6587ad0df121b35a60923e49f58796b352da704f4c0cda7c623dc6d85565a
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ Gemfile.lock
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode
6
+ - rbx-19mode
7
+ deploy:
8
+ provider: rubygems
9
+ api_key:
10
+ secure: XMfj0fh0v8byvY67GtTLIeJcxEpmt7WBOTF9fmsEsWv6Wq2ZYeWdlLxgK042FTB7IkFYVF6EsA4zmOFKZkMpypwROj0cwTEeoA/5DjukowVc2KwpRLXMCUBeatRD9U63A8gq3CVrS7t5emo4trxb6lH+x3HIgF5Ef4n8Sj+MWJM=
11
+ gem: ci-cache
12
+ on:
13
+ tags: true
14
+ repo: johanneswuerbach/ci-cache
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Johannes Würbach
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # ci-cache [![Build Status](https://travis-ci.org/johanneswuerbach/ci-cache.png?branch=master)](https://travis-ci.org/johanneswuerbach/ci-cache)
2
+
3
+ Cache files and folders between continues integration builds.
4
+
5
+
6
+ ### Examples
7
+
8
+ #### Bundler
9
+
10
+ ```yaml
11
+ ---
12
+ bundler_args: --without development --path=~/.bundle
13
+ language: ruby
14
+ rvm:
15
+ - 2.0.0
16
+ env:
17
+ global:
18
+ - CI_CACHE_S3_BUCKET="cache-bucket"
19
+ - CI_CACHE_S3_KEY="cache-aws-key"
20
+ - CI_CACHE_S3_SECRET="cache-aws-secret"
21
+ before_install:
22
+ - gem install ci-cache
23
+ - ci-cache get --name bundler-cache --output-path ~
24
+ after_script:
25
+ - bundle clean
26
+ - ci-cache set --name bundler-cache --content ~/.bundle --hash-file Gemfile.lock
27
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ task(:default) { ruby '-S rspec' }
data/bin/ci-cache ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'ci-cache'
5
+ CiCache::CLI.run(ARGV)
data/ci-cache.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require "ci-cache/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "ci-cache"
6
+ s.version = CiCache::VERSION
7
+ s.author = "Johannes Würbach"
8
+ s.email = "johannes.wuerbach@googlemail.com"
9
+ s.homepage = "https://github.com/johanneswuerbach/ci-cache"
10
+ s.summary = %q{ci cache tool}
11
+ s.description = %q{cache files in an ephemeral continuous integration environment}
12
+ s.license = 'MIT'
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_path = 'lib'
17
+ s.required_ruby_version = '>= 1.8.7'
18
+
19
+ s.add_runtime_dependency 'aws-sdk'
20
+
21
+ s.add_development_dependency 'rspec'
22
+ s.add_development_dependency 'rake'
23
+ end
@@ -0,0 +1,160 @@
1
+ require 'ci-cache/error'
2
+ require 'optparse'
3
+ require 'pathname'
4
+
5
+ module CiCache
6
+ class CLI
7
+ def self.run(argv)
8
+ new(argv).run
9
+ end
10
+
11
+ attr_reader :options, :argv
12
+ attr_accessor :fold_count, :command
13
+
14
+ VALID_COMMANDS = ['get', 'set']
15
+
16
+ def initialize(argv = nil)
17
+ @argv = argv || ARGV
18
+ @options = {}
19
+ self.fold_count = 0
20
+ end
21
+
22
+ def run
23
+ parse!
24
+ execute_command
25
+ rescue Error => error
26
+ options[:debug] ? raise(error) : die(error.message)
27
+ end
28
+
29
+ def fold(message)
30
+ self.fold_count += 1
31
+ print "travis_fold:start:ci-cache.#{fold_count}\r" if options[:fold]
32
+ puts "\e[33m#{message}\e[0m"
33
+ yield
34
+ ensure
35
+ print "\ntravis_fold:end:ci-cache.#{fold_count}\r" if options[:fold]
36
+ end
37
+
38
+ def name
39
+ error("No valid name provided") unless options[:name]
40
+ options[:name]
41
+ end
42
+
43
+ def content
44
+ error("No valid content provided") unless options[:content]
45
+ Pathname(options[:content])
46
+ end
47
+
48
+ def hash_file
49
+ error("No hash file provided") unless options[:hash_file]
50
+ Pathname(options[:hash_file]).expand_path
51
+ end
52
+
53
+ def output_path
54
+ error("No output path provided") unless options[:output_path]
55
+ Pathname(options[:output_path]).expand_path
56
+ end
57
+
58
+ def cache_archive_name
59
+ "#{name}.tar.gz"
60
+ end
61
+
62
+ def cache_hash_file_name
63
+ "#{name}.sha2"
64
+ end
65
+
66
+ def tmp_folder
67
+ Pathname("~").expand_path
68
+ end
69
+
70
+ def archive_path
71
+ Pathname("#{tmp_folder}/#{cache_archive_name}")
72
+ end
73
+
74
+ def old_hash_file
75
+ Pathname("#{tmp_folder}/#{cache_hash_file_name}")
76
+ end
77
+
78
+ def log(message)
79
+ $stderr.puts(message)
80
+ end
81
+
82
+ private
83
+
84
+ def execute_command
85
+ if VALID_COMMANDS.include? command
86
+ send(command)
87
+ return 0
88
+ else
89
+ error "Invalid command."
90
+ return 1
91
+ end
92
+ end
93
+
94
+ def get
95
+ fold("Getting #{name}") do
96
+ CiCache::Get.new(self).run
97
+ end
98
+ end
99
+
100
+ def set
101
+ fold("Setting #{name}") do
102
+ CiCache::Set.new(self).run
103
+ end
104
+ end
105
+
106
+ def error(message)
107
+ raise Error, message
108
+ end
109
+
110
+ def die(message)
111
+ $stderr.puts(message)
112
+ exit 1
113
+ end
114
+
115
+ def parse!
116
+ self.command = argv[0]
117
+ parser.parse! argv
118
+ end
119
+
120
+ def parser
121
+ @opt_parser ||= begin
122
+ options = self.options
123
+
124
+ OptionParser.new do |opt|
125
+ opt.banner = 'Usage: ci-cache COMMAND [OPTIONS]'
126
+ opt.separator ''
127
+ opt.separator 'Commands'
128
+ opt.separator ' get: get files from cache'
129
+ opt.separator ' set: cache files'
130
+ opt.separator ''
131
+ opt.separator 'Options'
132
+
133
+ opt.on('--name NAME','archive name') do |name|
134
+ options[:name] = name
135
+ end
136
+
137
+ opt.on('--content CONTENT','path or file to cache') do |content|
138
+ options[:content] = content
139
+ end
140
+
141
+ opt.on('--hash-file HASH_FILE', 'file used to check for updates') do |target_path|
142
+ options[:hash_file] = target_path
143
+ end
144
+
145
+ opt.on('--output-path OUTPUT_PATH', 'path the archive should be extracted to') do |output_path|
146
+ options[:output_path] = output_path
147
+ end
148
+
149
+ opt.on('--fold', 'fold output on travis') do |fold|
150
+ options[:fold] = fold
151
+ end
152
+
153
+ opt.on('-h','--help','help') do
154
+ puts @opt_parser
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,3 @@
1
+ module CiCache
2
+ Error = Class.new(StandardError)
3
+ end
@@ -0,0 +1,50 @@
1
+ module CiCache
2
+ class Get
3
+
4
+ def initialize(context)
5
+ @context = context
6
+ @storage = Storage.new(context)
7
+ end
8
+
9
+ def run
10
+ download_archive
11
+ download_hash_file
12
+ extract_archive
13
+ end
14
+
15
+ private
16
+
17
+ def download_archive
18
+ @storage.download(context.cache_archive_name, tmp_folder)
19
+ end
20
+
21
+ def download_hash_file
22
+ @storage.download(context.cache_hash_file_name, tmp_folder)
23
+ end
24
+
25
+ def extract_archive
26
+ log "Extract: #{archive_path} ~> #{output_path}"
27
+ CiCache.shell("tar -C #{output_path} -xf #{archive_path}")
28
+ end
29
+
30
+ def context
31
+ @context
32
+ end
33
+
34
+ def log(message)
35
+ context.log(message)
36
+ end
37
+
38
+ def tmp_folder
39
+ context.tmp_folder
40
+ end
41
+
42
+ def archive_path
43
+ context.archive_path
44
+ end
45
+
46
+ def output_path
47
+ context.output_path
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,66 @@
1
+ require "digest"
2
+
3
+ module CiCache
4
+ class Set
5
+ def initialize(context)
6
+ @context = context
7
+ @storage = Storage.new(context)
8
+ end
9
+
10
+ def run
11
+ if content_has_changed?
12
+ context.log("Updating cache.")
13
+ archive_files
14
+ upload_archive
15
+ upload_hash_file
16
+ else
17
+ context.log("Nothing changed.")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def context
24
+ @context
25
+ end
26
+
27
+ def archive_files
28
+ dirname, basename = content.split
29
+ log "Archive: #{content} ~> #{archive_path}"
30
+ CiCache.shell("tar -C #{dirname} -cjf #{archive_path} #{basename}")
31
+ end
32
+
33
+ def content_has_changed?
34
+ new_checksum != old_checksum
35
+ end
36
+
37
+ def new_checksum
38
+ @_new_checksum ||= Digest::SHA2.file(context.hash_file).hexdigest
39
+ end
40
+
41
+ def old_checksum
42
+ old_hash_file = context.old_hash_file
43
+ File.exists?(old_hash_file) ? File.read(old_hash_file) : ""
44
+ end
45
+
46
+ def upload_archive
47
+ @storage.upload(context.cache_archive_name, context.archive_path)
48
+ end
49
+
50
+ def upload_hash_file
51
+ @storage.upload(context.cache_hash_file_name, new_checksum)
52
+ end
53
+
54
+ def archive_path
55
+ context.archive_path
56
+ end
57
+
58
+ def content
59
+ context.content
60
+ end
61
+
62
+ def log(message)
63
+ context.log(message)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,54 @@
1
+ module CiCache
2
+ class Storage
3
+
4
+ def initialize(context)
5
+ configure_aws
6
+ @s3 = AWS::S3.new
7
+ @context = context
8
+ end
9
+
10
+ def download(name, tmp_folder)
11
+ target_file = "#{tmp_folder}/#{name}"
12
+ log "Download: #{name} ~> #{target_file}"
13
+ object = bucket_object(name)
14
+ File.open(target_file, 'wb') do |file|
15
+ object.read do |chunk|
16
+ file.write(chunk)
17
+ end
18
+ end
19
+ rescue AWS::S3::Errors::AccessDenied => e
20
+ log "Not found."
21
+ end
22
+
23
+ def upload(name, content)
24
+ log "Upload: #{name}"
25
+ object = bucket_object(name)
26
+ object.write(content)
27
+ end
28
+
29
+ private
30
+
31
+ def log(message)
32
+ @context.log(message)
33
+ end
34
+
35
+ def bucket_name
36
+ ENV["CI_CACHE_S3_BUCKET"]
37
+ end
38
+
39
+ def configure_aws
40
+ AWS.config(
41
+ access_key_id: ENV["CI_CACHE_S3_KEY"],
42
+ secret_access_key: ENV["CI_CACHE_S3_SECRET"]
43
+ )
44
+ end
45
+
46
+ def bucket_object(name)
47
+ bucket.objects[name]
48
+ end
49
+
50
+ def bucket
51
+ @s3.buckets[bucket_name]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module CiCache
2
+ VERSION = '1.0.0'
3
+ end
data/lib/ci-cache.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'aws-sdk'
2
+
3
+ module CiCache
4
+ autoload :CLI, 'ci-cache/cli'
5
+ autoload :Get, 'ci-cache/get'
6
+ autoload :Set, 'ci-cache/set'
7
+ autoload :Error, 'ci-cache/error'
8
+ autoload :Storage, 'ci-cache/storage'
9
+
10
+ def self.shell(command)
11
+ system(command)
12
+ end
13
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe CiCache::CLI do
4
+
5
+ describe "::new" do
6
+ let(:path) { Pathname("~/").expand_path }
7
+ let(:cli) { CiCache::CLI.new([
8
+ "set",
9
+ "--name", "bundle_cache",
10
+ "--hash-file", "Gemfile",
11
+ "--content", "~/.bundle_cache"
12
+ ])}
13
+ subject { cli }
14
+ before do
15
+ cli.send(:parse!)
16
+ end
17
+
18
+ its(:cache_archive_name) { should eq("bundle_cache.tar.gz")}
19
+ its(:cache_hash_file_name) { should eq("bundle_cache.sha2")}
20
+ its(:tmp_folder) { should eq(path) }
21
+ its(:archive_path) { should eq(Pathname("#{path}/bundle_cache.tar.gz"))}
22
+ its(:old_hash_file) { should eq(Pathname("#{path}/bundle_cache.sha2"))}
23
+ its(:hash_file) { should eq(Pathname("Gemfile").expand_path) }
24
+ its(:content) { should eq(Pathname("~/.bundle_cache")) }
25
+ end
26
+
27
+ describe "::run" do
28
+ context "when get is used" do
29
+ let(:get) { double "get" }
30
+ subject { CiCache::CLI.run(["get", "--name", "cached"]) }
31
+
32
+ it "should execute the get command" do
33
+ CiCache::Get.should_receive(:new).with(instance_of(CiCache::CLI)).and_return(get)
34
+ CiCache::CLI.any_instance.should_receive(:fold).and_yield
35
+ get.should_receive(:run)
36
+ subject
37
+ end
38
+ end
39
+
40
+ context "when set is used" do
41
+ let(:set) { double "set" }
42
+ subject { CiCache::CLI.run(["set", "--name", "cached"]) }
43
+
44
+ it "should execute the set command" do
45
+ CiCache::Set.should_receive(:new).with(instance_of(CiCache::CLI)).and_return(set)
46
+ CiCache::CLI.any_instance.should_receive(:fold).and_yield
47
+ set.should_receive(:run)
48
+ subject
49
+ end
50
+ end
51
+ end
52
+ end
data/spec/get_spec.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe CiCache::Get do
4
+ describe :run do
5
+ let(:context) { double "context" }
6
+ let(:get) { CiCache::Get.new(context) }
7
+ let(:storage) { double "storage" }
8
+ subject { get.run }
9
+
10
+ before do
11
+ CiCache.stub(:shell)
12
+ context.stub(:cache_archive_name).and_return("cache.tar.gz")
13
+ context.stub(:cache_hash_file_name).and_return("cache.sha2")
14
+ context.stub(:archive_path).and_return(Pathname("~/cache.tar.gz"))
15
+ context.stub(:tmp_folder).and_return("~")
16
+ context.stub(:output_path).and_return("~")
17
+ context.stub(:log)
18
+
19
+ storage.stub(:download)
20
+ CiCache::Storage.should_receive(:new).and_return(storage)
21
+ end
22
+
23
+ it "downloads the archive" do
24
+ storage.should_receive(:download).with("cache.tar.gz", "~")
25
+ subject
26
+ end
27
+
28
+ it "download the hash file" do
29
+ storage.should_receive(:download).with("cache.sha2", "~")
30
+ subject
31
+ end
32
+
33
+ it "extracts the archive" do
34
+ CiCache.should_receive(:shell).with("tar -C ~ -xf ~/cache.tar.gz")
35
+ subject
36
+ end
37
+ end
38
+ end
data/spec/set_spec.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe CiCache::Set do
4
+ describe :run do
5
+ let(:context) { double "context" }
6
+ let(:set) { CiCache::Set.new(context) }
7
+ let(:storage) { double "storage" }
8
+ subject { set.run }
9
+
10
+ before do
11
+ CiCache.stub(:shell)
12
+ context.stub(:cache_archive_name).and_return("cache.tar.gz")
13
+ context.stub(:cache_hash_file_name).and_return("cache.sha2")
14
+ context.stub(:hash_file).and_return("Gemfile")
15
+ context.stub(:archive_path).and_return("~/archive.tar.gz")
16
+ context.stub(:old_hash_file).and_return("~/cache.sha2")
17
+ context.stub(:content).and_return(Pathname("~/.bundle_cache"))
18
+ context.stub(:log)
19
+
20
+ storage.stub(:upload)
21
+ CiCache::Storage.should_receive(:new).and_return(storage)
22
+ end
23
+
24
+ context "when content has changed" do
25
+ it "archives the folder" do
26
+ CiCache.should_receive(:shell).with("tar -C ~ -cjf ~/archive.tar.gz .bundle_cache")
27
+ subject
28
+ end
29
+
30
+ it "uploads the archive" do
31
+ storage.should_receive(:upload).with("cache.tar.gz", "~/archive.tar.gz")
32
+ subject
33
+ end
34
+
35
+ it "uploads the hash file" do
36
+ storage.should_receive(:upload).with("cache.sha2", Digest::SHA2.file("Gemfile").hexdigest)
37
+ subject
38
+ end
39
+ end
40
+
41
+ context "when content has not changed" do
42
+ it "logs a message" do
43
+ context.should_receive(:log)
44
+ subject
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1 @@
1
+ require 'ci-cache'
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe CiCache::Storage do
4
+ let(:context) { double "context" }
5
+ let(:storage) { CiCache::Storage.new(context) }
6
+ let(:object) { double "object" }
7
+ let(:name) { "file" }
8
+
9
+ before do
10
+ context.stub(:log)
11
+ end
12
+
13
+ describe :download do
14
+ let(:folder) { "~" }
15
+ let(:handle) { double "handle" }
16
+ subject { storage.download(name, folder) }
17
+
18
+ context "when the object exists" do
19
+ it "downloads the object" do
20
+ storage.should_receive(:bucket_object).and_return(object)
21
+ object.should_receive(:read).and_yield("chunk")
22
+ handle.should_receive(:write).with("chunk")
23
+ File.should_receive(:open).with("~/file", "wb").and_yield(handle)
24
+ subject
25
+ end
26
+ end
27
+
28
+ context "when the object doesn't exist" do
29
+ it "logs an error" do
30
+ storage.should_receive(:bucket_object).and_raise(AWS::S3::Errors::AccessDenied.new)
31
+ context.should_receive(:log)
32
+ subject
33
+ end
34
+ end
35
+ end
36
+
37
+ describe :upload do
38
+ subject { storage.upload(name, "content") }
39
+
40
+ it "uploads the content" do
41
+ storage.should_receive(:bucket_object).and_return(object)
42
+ object.should_receive(:write).with("content")
43
+ subject
44
+ end
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ci-cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Johannes Würbach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: cache files in an ephemeral continuous integration environment
56
+ email: johannes.wuerbach@googlemail.com
57
+ executables:
58
+ - ci-cache
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - .travis.yml
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - bin/ci-cache
70
+ - ci-cache.gemspec
71
+ - lib/ci-cache.rb
72
+ - lib/ci-cache/cli.rb
73
+ - lib/ci-cache/error.rb
74
+ - lib/ci-cache/get.rb
75
+ - lib/ci-cache/set.rb
76
+ - lib/ci-cache/storage.rb
77
+ - lib/ci-cache/version.rb
78
+ - spec/cli_spec.rb
79
+ - spec/get_spec.rb
80
+ - spec/set_spec.rb
81
+ - spec/spec_helper.rb
82
+ - spec/storage_spec.rb
83
+ homepage: https://github.com/johanneswuerbach/ci-cache
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: 1.8.7
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.1.3
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: ci cache tool
107
+ test_files:
108
+ - spec/cli_spec.rb
109
+ - spec/get_spec.rb
110
+ - spec/set_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/storage_spec.rb