spitball 0.5.1 → 0.6.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.
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/Rakefile +20 -35
- data/bin/spitball +60 -0
- data/bin/spitball-cache-cleanup +22 -0
- data/bin/spitball-server +100 -0
- data/lib/spitball/remote.rb +1 -1
- data/lib/spitball/repo.rb +1 -1
- data/lib/spitball/version.rb +1 -1
- data/spitball-server.gemspec +27 -0
- data/spitball.gemspec +3 -4
- metadata +30 -24
data/Gemfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -14,39 +14,24 @@ Spec::Rake::SpecTask.new(:spec) do |t|
|
|
14
14
|
end
|
15
15
|
|
16
16
|
require 'bundler'
|
17
|
-
|
18
|
-
|
19
|
-
namespace :version do
|
20
|
-
def update_version
|
21
|
-
source = File.read(VERSION_FILE)
|
22
|
-
new_v = nil
|
23
|
-
File.open(VERSION_FILE, 'w') do |f|
|
24
|
-
f.write source.gsub(/\d+\.\d+\.\d+/) {|v|
|
25
|
-
new_v = yield(*v.split(".").map {|i| i.to_i}).join(".")
|
26
|
-
}
|
27
|
-
end
|
28
|
-
new_v
|
29
|
-
end
|
30
|
-
|
31
|
-
def commit_version(v)
|
32
|
-
system "git add #{VERSION_FILE} && git c -m 'release version #{v}'"
|
33
|
-
end
|
34
|
-
|
35
|
-
desc "Increment the major version and commit"
|
36
|
-
task :incr_major do
|
37
|
-
new_v = update_version {|m,_,_| [m+1, 0, 0] }
|
38
|
-
commit_version(new_v)
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "Increment the minor version and commit"
|
42
|
-
task :incr_minor do
|
43
|
-
new_v = update_version {|ma,mi,_| [ma, mi+1, 0] }
|
44
|
-
commit_version(new_v)
|
45
|
-
end
|
46
|
-
|
47
|
-
desc "Increment the patch version and commit"
|
48
|
-
task :incr_patch do
|
49
|
-
new_v = update_version {|ma,mi,p| [ma, mi, p+1] }
|
50
|
-
commit_version(new_v)
|
51
|
-
end
|
17
|
+
namespace :spitball do
|
18
|
+
Bundler::GemHelper.install_tasks(:name => 'spitball')
|
52
19
|
end
|
20
|
+
|
21
|
+
class NonTaggingGemHelper < Bundler::GemHelper
|
22
|
+
def guard_already_tagged; end
|
23
|
+
def tag_version; yield if block_given?; end
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :spitball_server do
|
27
|
+
NonTaggingGemHelper.install_tasks(:name => 'spitball-server')
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "build spitball/spitball-server"
|
31
|
+
task :build => [:'spitball:build', :'spitball_server:build']
|
32
|
+
|
33
|
+
desc "install spitball/spitball-server"
|
34
|
+
task :install => [:'spitball:install', :'spitball_server:install']
|
35
|
+
|
36
|
+
desc "release spitball/spitball-server"
|
37
|
+
task :release => [:'spitball:release', :'spitball_server:release']
|
data/bin/spitball
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spitball'
|
4
|
+
require 'optparse'
|
5
|
+
require 'net/http'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
STDOUT.sync = true
|
9
|
+
|
10
|
+
args = {}
|
11
|
+
opts = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: spitball [options] GEMFILE ARCHIVE"
|
13
|
+
opts.separator ""
|
14
|
+
opts.separator "options:"
|
15
|
+
|
16
|
+
opts.on('-h', '--host HOST', 'Get the tarball from a remote spitball server') do |host|
|
17
|
+
args[:host] = host
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-p', '--port PORT', 'Specify the remote server port. Default 8080') do |port|
|
21
|
+
args[:port] = port
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-v', '--version', 'Display the version and quit') do
|
25
|
+
puts Spitball::VERSION
|
26
|
+
exit!(0)
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('--without a,b,c', Array, 'Excluded groups in the tarball. Does not apply to remote spitballs') do |without|
|
30
|
+
args[:without] = without
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('-g', '--generate-only', "Only generate, don't download") do
|
34
|
+
args[:generate] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.separator ""
|
38
|
+
opts.separator "environment variables:"
|
39
|
+
opts.separator "\tSPITBALL_CACHE\t\t Specifies the cache dir. Defaults to /tmp/spitball-#{ENV['USER']}"
|
40
|
+
opts.separator ""
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.permute!(ARGV)
|
44
|
+
|
45
|
+
args[:gemfile] = ARGV[0]
|
46
|
+
args[:destination] = ARGV[1]
|
47
|
+
|
48
|
+
unless args[:gemfile] and args[:destination]
|
49
|
+
puts opts.help
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
gemfile = File.read(args[:gemfile])
|
54
|
+
gemfile_lock = File.read("#{args[:gemfile]}.lock")
|
55
|
+
|
56
|
+
ball = args[:host] ?
|
57
|
+
Spitball::Remote.new(gemfile, gemfile_lock, :host => args[:host], :port => (args[:port] || 8080).to_i, :without => args[:without]) :
|
58
|
+
Spitball.new(gemfile, gemfile_lock, :without => args[:without])
|
59
|
+
|
60
|
+
args[:generate] ? ball.cache! : ball.copy_to(args[:destination])
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spitball'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
args = {}
|
7
|
+
|
8
|
+
opts = OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: spitball-cache-cleanup [options]"
|
10
|
+
opts.separator ""
|
11
|
+
opts.separator "options:"
|
12
|
+
|
13
|
+
opts.on('-w', '--access-window SECONDS', 'Access window within which tarballs are kept. Default 30 days') do |access_window|
|
14
|
+
args[:access_window] = access_window
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.permute!(ARGV)
|
19
|
+
|
20
|
+
args[:access_window] ||= 2592000
|
21
|
+
|
22
|
+
Spitball::Repo.clean_up_unused(args[:access_window].to_i)
|
data/bin/spitball-server
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spitball'
|
4
|
+
require 'optparse'
|
5
|
+
require 'sinatra'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
# cargo culting sinatra's option parser, since it has trouble
|
9
|
+
# with rubygem stub files
|
10
|
+
|
11
|
+
OptionParser.new { |op|
|
12
|
+
op.on('-x') { set :lock, true }
|
13
|
+
op.on('-e env') { |val| set :environment, val.to_sym }
|
14
|
+
op.on('-s server') { |val| set :server, val }
|
15
|
+
op.on('-p port') { |val| set :port, val.to_i }
|
16
|
+
op.on('-o addr') { |val| set :bind, val }
|
17
|
+
}.parse!(ARGV.dup)
|
18
|
+
|
19
|
+
# always run
|
20
|
+
set :run, true
|
21
|
+
|
22
|
+
mime_type :gemfile, 'text/plain'
|
23
|
+
mime_type :lock, 'text/plain'
|
24
|
+
mime_type :tgz, 'application/x-compressed'
|
25
|
+
|
26
|
+
# return json array of cached SHAs
|
27
|
+
get '/list' do
|
28
|
+
content_type :json
|
29
|
+
JSON.dump Spitball::Repo.cached_digests
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/env' do
|
33
|
+
content_type :text
|
34
|
+
`#{$:.inspect}\n#{Spitball.gem_cmd} env`
|
35
|
+
end
|
36
|
+
|
37
|
+
# return tgz or gemfile of cached SHA or 404
|
38
|
+
get '/:digest.:format' do |digest, format|
|
39
|
+
error 400 unless ['tgz', 'gemfile'].include? format
|
40
|
+
|
41
|
+
# this returns 404 on Errno::ENOENT
|
42
|
+
send_file Spitball::Repo.bundle_path(digest, format), :type => format
|
43
|
+
end
|
44
|
+
|
45
|
+
class Streamer
|
46
|
+
def initialize(io); @io = io end
|
47
|
+
def each; while buf = @io.read(200); yield buf end end
|
48
|
+
end
|
49
|
+
|
50
|
+
# POST a gemfile. Returns 201 Created if the bundle already exists, or
|
51
|
+
# 202 Accepted if it does not. The body of the response is the URI for
|
52
|
+
# the tarball.
|
53
|
+
post '/create' do
|
54
|
+
request_version = request.env["HTTP_#{Spitball::PROTOCOL_HEADER.gsub(/-/, '_').upcase}"]
|
55
|
+
if request_version != Spitball::PROTOCOL_VERSION
|
56
|
+
status 403
|
57
|
+
"Received version #{request_version} but need version #{Spitball::PROTOCOL_VERSION}"
|
58
|
+
else
|
59
|
+
without = request_version = request.env["HTTP_#{Spitball::WITHOUT_HEADER.gsub(/-/, '_').upcase}"]
|
60
|
+
without &&= without.split(',')
|
61
|
+
ball = Spitball.new(params['gemfile'], params['gemfile_lock'], :without => without)
|
62
|
+
url = "#{request.url.split("/create").first}/#{ball.digest}.tgz"
|
63
|
+
response['Location'] = url
|
64
|
+
|
65
|
+
if ball.cached?
|
66
|
+
status 201
|
67
|
+
"Bundle tarball pre-cached.\n"
|
68
|
+
else
|
69
|
+
status 202
|
70
|
+
|
71
|
+
i,o = IO.pipe
|
72
|
+
o.sync = true
|
73
|
+
|
74
|
+
# fork twice. once so we can have a pid to detach from in order to clean up,
|
75
|
+
# twice in order to properly redirect stdout for underlying shell commands.
|
76
|
+
pid = fork do
|
77
|
+
baller = open("|-")
|
78
|
+
if baller == nil # child
|
79
|
+
$stdout.sync = true
|
80
|
+
begin
|
81
|
+
ball.cache!
|
82
|
+
rescue Object => e
|
83
|
+
puts "#{e.class}: #{e}", e.backtrace.map{|l| "\t#{l}" }
|
84
|
+
end
|
85
|
+
else
|
86
|
+
while buf = baller.read(200)
|
87
|
+
$stdout.print buf
|
88
|
+
o.print buf
|
89
|
+
end
|
90
|
+
end
|
91
|
+
exit!
|
92
|
+
end
|
93
|
+
|
94
|
+
o.close
|
95
|
+
Process.detach(pid)
|
96
|
+
|
97
|
+
Streamer.new(i)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/spitball/remote.rb
CHANGED
@@ -11,7 +11,7 @@ class Spitball::Remote
|
|
11
11
|
@host = opts[:host]
|
12
12
|
@port = opts[:port]
|
13
13
|
@without = (opts[:without] || []).map{|w| w.to_sym}
|
14
|
-
@cache_dir =
|
14
|
+
@cache_dir = ENV['SPITBALL_CACHE'] || "/tmp/spitball-#{ENV['USER']}/client"
|
15
15
|
FileUtils.mkdir_p(@cache_dir)
|
16
16
|
use_cache_file
|
17
17
|
end
|
data/lib/spitball/repo.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spitball::Repo
|
2
2
|
extend self
|
3
3
|
|
4
|
-
WORKING_DIR = ENV['SPITBALL_CACHE'] ||
|
4
|
+
WORKING_DIR = ENV['SPITBALL_CACHE'] || "/tmp/spitball-#{ENV['USER']}"
|
5
5
|
|
6
6
|
def bundle_path(digest, extension = nil)
|
7
7
|
extension = ".#{extension}" unless extension.nil? or extension.empty?
|
data/lib/spitball/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/spitball/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "spitball-server"
|
6
|
+
s.version = Spitball::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Matt Freels", "Brandon Mitchell", "Joshua Hull"]
|
9
|
+
s.email = "freels@twitter.com"
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Use bundler to generate gem tarball packages -- server!}
|
12
|
+
s.description = %q{Use bundler to generate gem tarball packages - server!}
|
13
|
+
|
14
|
+
s.rubyforge_project = "spitball-server"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = ['spitball-server', 'spitball-cache-cleanup']
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'sinatra', '~> 1.2.0'
|
22
|
+
s.add_development_dependency 'rspec', "~> 1.3.0"
|
23
|
+
s.add_development_dependency 'diff-lcs'
|
24
|
+
s.add_development_dependency 'rr'
|
25
|
+
s.add_development_dependency 'rake', '0.8.7'
|
26
|
+
s.add_development_dependency 'phocus'
|
27
|
+
end
|
data/spitball.gemspec
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
require "spitball/version"
|
2
|
+
require File.expand_path("../lib/spitball/version", __FILE__)
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = "spitball"
|
@@ -17,12 +16,12 @@ Gem::Specification.new do |s|
|
|
17
16
|
s.add_development_dependency 'rspec', "~> 1.3.0"
|
18
17
|
s.add_development_dependency 'diff-lcs'
|
19
18
|
s.add_development_dependency 'rr'
|
20
|
-
s.add_development_dependency 'rake'
|
19
|
+
s.add_development_dependency 'rake', '0.8.7'
|
21
20
|
s.add_development_dependency 'phocus'
|
22
21
|
|
23
22
|
s.files = `git ls-files`.split("\n")
|
24
23
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
25
|
-
s.executables =
|
24
|
+
s.executables = ['spitball']
|
26
25
|
s.extra_rdoc_files = [ "README.md" ]
|
27
26
|
s.require_paths = ["lib"]
|
28
27
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spitball
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 1
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Freels
|
@@ -17,13 +17,12 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-
|
20
|
+
date: 2011-07-30 00:00:00 -07:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
24
|
-
name: rspec
|
25
24
|
prerelease: false
|
26
|
-
|
25
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
27
26
|
none: false
|
28
27
|
requirements:
|
29
28
|
- - ~>
|
@@ -34,12 +33,12 @@ dependencies:
|
|
34
33
|
- 3
|
35
34
|
- 0
|
36
35
|
version: 1.3.0
|
36
|
+
requirement: *id001
|
37
|
+
name: rspec
|
37
38
|
type: :development
|
38
|
-
version_requirements: *id001
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
|
-
name: diff-lcs
|
41
40
|
prerelease: false
|
42
|
-
|
41
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
43
42
|
none: false
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
@@ -48,12 +47,12 @@ dependencies:
|
|
48
47
|
segments:
|
49
48
|
- 0
|
50
49
|
version: "0"
|
50
|
+
requirement: *id002
|
51
|
+
name: diff-lcs
|
51
52
|
type: :development
|
52
|
-
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
|
-
name: rr
|
55
54
|
prerelease: false
|
56
|
-
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
57
56
|
none: false
|
58
57
|
requirements:
|
59
58
|
- - ">="
|
@@ -62,26 +61,28 @@ dependencies:
|
|
62
61
|
segments:
|
63
62
|
- 0
|
64
63
|
version: "0"
|
64
|
+
requirement: *id003
|
65
|
+
name: rr
|
65
66
|
type: :development
|
66
|
-
version_requirements: *id003
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
|
-
name: rake
|
69
68
|
prerelease: false
|
70
|
-
|
69
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
71
70
|
none: false
|
72
71
|
requirements:
|
73
|
-
- - "
|
72
|
+
- - "="
|
74
73
|
- !ruby/object:Gem::Version
|
75
|
-
hash:
|
74
|
+
hash: 49
|
76
75
|
segments:
|
77
76
|
- 0
|
78
|
-
|
77
|
+
- 8
|
78
|
+
- 7
|
79
|
+
version: 0.8.7
|
80
|
+
requirement: *id004
|
81
|
+
name: rake
|
79
82
|
type: :development
|
80
|
-
version_requirements: *id004
|
81
83
|
- !ruby/object:Gem::Dependency
|
82
|
-
name: phocus
|
83
84
|
prerelease: false
|
84
|
-
|
85
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
86
|
none: false
|
86
87
|
requirements:
|
87
88
|
- - ">="
|
@@ -90,12 +91,13 @@ dependencies:
|
|
90
91
|
segments:
|
91
92
|
- 0
|
92
93
|
version: "0"
|
94
|
+
requirement: *id005
|
95
|
+
name: phocus
|
93
96
|
type: :development
|
94
|
-
version_requirements: *id005
|
95
97
|
description: Use bundler to generate gem tarball packages.
|
96
98
|
email: freels@twitter.com
|
97
|
-
executables:
|
98
|
-
|
99
|
+
executables:
|
100
|
+
- spitball
|
99
101
|
extensions: []
|
100
102
|
|
101
103
|
extra_rdoc_files:
|
@@ -105,6 +107,9 @@ files:
|
|
105
107
|
- Gemfile
|
106
108
|
- README.md
|
107
109
|
- Rakefile
|
110
|
+
- bin/spitball
|
111
|
+
- bin/spitball-cache-cleanup
|
112
|
+
- bin/spitball-server
|
108
113
|
- lib/ext/bundler_fake_dsl.rb
|
109
114
|
- lib/ext/bundler_lockfile_parser.rb
|
110
115
|
- lib/spitball.rb
|
@@ -117,6 +122,7 @@ files:
|
|
117
122
|
- spec/spec.opts
|
118
123
|
- spec/spec_helper.rb
|
119
124
|
- spec/spitball_spec.rb
|
125
|
+
- spitball-server.gemspec
|
120
126
|
- spitball.gemspec
|
121
127
|
has_rdoc: true
|
122
128
|
homepage: http://rubygems.org/gems/spitball
|