spitball 0.5.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source :rubygems
2
2
 
3
- gemspec
3
+ gemspec :name => 'spitball-server'
data/README.md CHANGED
@@ -20,7 +20,7 @@ pull packages down from said server.
20
20
  --version
21
21
 
22
22
  environment variables:
23
- SPITBALL_CACHE Specifies the cache dir. Defaults to /tmp/spitball
23
+ SPITBALL_CACHE Specifies the cache dir. Defaults to /tmp/spitball-username
24
24
 
25
25
  ### TODO
26
26
 
data/Rakefile CHANGED
@@ -14,39 +14,24 @@ Spec::Rake::SpecTask.new(:spec) do |t|
14
14
  end
15
15
 
16
16
  require 'bundler'
17
- Bundler::GemHelper.install_tasks
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)
@@ -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
@@ -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 = File.join(ENV['SPITBALL_CACHE'] || File.join(ENV['HOME'], '.spitball'), 'client')
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'] || '/tmp/spitball'
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?
@@ -1,3 +1,3 @@
1
1
  class Spitball
2
- VERSION = '0.5.1'
2
+ VERSION = '0.6.1' unless const_defined?(:VERSION)
3
3
  end
@@ -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
- $:.push File.expand_path("../lib", __FILE__)
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 = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
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: 9
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 5
8
+ - 6
9
9
  - 1
10
- version: 0.5.1
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-04-28 00:00:00 -07:00
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
- requirement: &id001 !ruby/object:Gem::Requirement
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- requirement: &id004 !ruby/object:Gem::Requirement
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: 3
74
+ hash: 49
76
75
  segments:
77
76
  - 0
78
- version: "0"
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
- requirement: &id005 !ruby/object:Gem::Requirement
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