buildbox 0.6.beta2 → 0.6.beta3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d09a24715e1c3a79b74647a1b775b7166cdcf952
4
- data.tar.gz: 124c2dad15dbe1e38273803411e2eb73095cee42
3
+ metadata.gz: 6d0de360c32f22ab29259e472e4ecba54dc326aa
4
+ data.tar.gz: 12631903e7780f9d7fea9ea16964fb09402e30de
5
5
  SHA512:
6
- metadata.gz: 039183e2b691d6f18c4e009ec9468bed4225f3d90d15c200ea72773e86f53646a49c6ab8791ad12dd124f185f7f5b23481e005b1b978a4760b599f9cdf6d43b6
7
- data.tar.gz: e87d1f3ce2c272bee640828402baf01e28eca316b4319bed05598f35de6c89cb7d5f926f1e038329782080ab515c42ed741a5983e3cef81cb7672466ac284daa
6
+ metadata.gz: 211edbd383cb6b699ceef9187c18d12374ada689dbf13210b87117efdccad1bf261a8f4b7e3dcfe3bb2ea8d83c9b936dfc75a4a19a548e996cbceb49cef05f85
7
+ data.tar.gz: 77e43c81f73e764bdcf432b815df5dde9d5acb92ac3c7edea20bb195cd90cb07d3f7900790ae5c03231d0456417cb8e320e06fc8a2b7ad3ddfe93b2ce3e24e38
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- buildbox (0.6.beta2)
4
+ buildbox (0.6.beta3)
5
5
  celluloid (~> 0.14)
6
6
  childprocess (~> 0.3)
7
7
  faraday (~> 0.8)
data/lib/buildbox.rb CHANGED
@@ -16,7 +16,6 @@ module Buildbox
16
16
  autoload :Server, "buildbox/server"
17
17
  autoload :UTF8, "buildbox/utf8"
18
18
  autoload :Agent, "buildbox/agent"
19
- autoload :Uploader, "buildbox/uploader"
20
19
  autoload :VERSION, "buildbox/version"
21
20
 
22
21
  def self.config
@@ -42,13 +42,12 @@ module Buildbox
42
42
  end
43
43
 
44
44
  def upload_artifacts_from(build_directory, artifact_path)
45
- files = Artifact.files_to_upload(build_directory, artifact_path)
45
+ artifacts = Artifact::Collector.collect_and_copy(build_directory, artifact_path)
46
46
 
47
- files.each_pair do |relative_path, absolute_path|
48
- Celluloid::Actor[:uploader_pool].async.upload(@api, @access_token, @current_build, relative_path, absolute_path)
49
- end
47
+ Artifact::Uploader.new(@api, @access_token, @current_build, artifacts).async.prepare_and_upload
50
48
  rescue => e
51
49
  error "There was an error uploading artifacts for path: #{artifact_path} (#{e.class.name}: #{e.message})"
50
+
52
51
  e.backtrace[0..3].each { |line| error(line) }
53
52
  end
54
53
  end
data/lib/buildbox/api.rb CHANGED
@@ -54,8 +54,8 @@ module Buildbox
54
54
  put("#{access_token}/builds/#{build.id}", options)
55
55
  end
56
56
 
57
- def create_artifact(access_token, build, options)
58
- post("#{access_token}/builds/#{build.id}/artifacts", options)
57
+ def create_artifacts(access_token, build, artifacts)
58
+ post("#{access_token}/builds/#{build.id}/artifacts", :artifacts => artifacts.map(&:as_json))
59
59
  end
60
60
 
61
61
  def update_artifact(access_token, build, artifact_id, options)
@@ -1,62 +1,30 @@
1
- require 'fileutils'
2
- require 'tempfile'
1
+ require 'securerandom'
3
2
 
4
3
  module Buildbox
5
4
  class Artifact
6
- include Celluloid::Logger
5
+ autoload :Poster, "buildbox/artifact/poster"
6
+ autoload :Collector, "buildbox/artifact/collector"
7
+ autoload :Uploader, "buildbox/artifact/uploader"
7
8
 
8
- def self.files_to_upload(build_directory, glob)
9
- new(build_directory, glob).files_to_upload
10
- end
9
+ attr_reader :id, :name, :path
10
+ attr_accessor :remote_id, :upload_instructions
11
11
 
12
- def initialize(build_directory, glob)
13
- @build_directory = build_directory
14
- @glob = glob
12
+ def self.create(name, path)
13
+ new(SecureRandom.uuid, name, path)
15
14
  end
16
15
 
17
- def files_to_upload
18
- tmpdir = Dir.mktmpdir
19
- path_to_absolute = {}
20
-
21
- copy_files_to_upload(tmpdir).each do |file|
22
- path_to_absolute[relativize_to_dir(file, tmpdir)] = file
23
- end
24
-
25
- path_to_absolute
16
+ def initialize(id, name, path)
17
+ @id = id
18
+ @name = name
19
+ @path = path
26
20
  end
27
21
 
28
- private
29
-
30
- def copy_files_to_upload(dir)
31
- expanded_directory = File.expand_path(@build_directory)
32
- absolute_glob = File.expand_path(@glob, expanded_directory)
33
-
34
- target_files = Dir.glob(absolute_glob)
35
-
36
- target_files.each do |file|
37
- relative_path = relativize_to_dir(file, expanded_directory)
38
- copy_to = File.join(dir, relative_path)
39
-
40
- if File.file?(file)
41
- FileUtils.mkdir_p(File.dirname(copy_to))
42
- FileUtils.cp(file, copy_to)
43
- end
44
- end
45
-
46
- # Grab all the files we're going to upload.
47
- Dir.glob(File.join(dir, "**", "*")).reject { |file| File.directory?(file) }
22
+ def basename
23
+ File.basename(@path)
48
24
  end
49
25
 
50
- # /foo/build-directory/something.txt => /something.txt
51
- # /var/random/something.txt => /var/random/something.txt
52
- def relativize_to_dir(path, directory)
53
- if path.to_s.index(directory.to_s) == 0
54
- parts = path.to_s.split(directory.to_s)
55
- parts.shift
56
- parts.join(directory.to_s)
57
- else
58
- path
59
- end
26
+ def as_json
27
+ { :id => @id, :name => @name, :path => @path, :file_size => File.size(@path) }
60
28
  end
61
29
  end
62
30
  end
@@ -0,0 +1,63 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+
4
+ module Buildbox
5
+ class Artifact::Collector
6
+ include Celluloid::Logger
7
+
8
+ MAX_ARTIFACT_LIMIT = 500
9
+
10
+ class TooManyArtifactsError < RuntimeError; end
11
+
12
+ def self.collect_and_copy(build_directory, glob)
13
+ new(build_directory, glob).collect_and_copy
14
+ end
15
+
16
+ def initialize(build_directory, glob)
17
+ @build_directory = build_directory
18
+ @glob = glob
19
+ end
20
+
21
+ def collect_and_copy
22
+ index = 0
23
+ artifacts = []
24
+ tmpdir = Dir.mktmpdir
25
+
26
+ globbed_files.each do |file|
27
+ raise TooManyArtifactsError if index > MAX_ARTIFACT_LIMIT
28
+
29
+ absolute_path = File.expand_path(file, @build_directory)
30
+ copy_to_path = File.join(tmpdir, file)
31
+
32
+ if File.file?(absolute_path)
33
+ artifacts << Artifact.create(file, copy_to_path)
34
+
35
+ FileUtils.mkdir_p(File.dirname(copy_to_path))
36
+ FileUtils.cp(absolute_path, copy_to_path)
37
+ end
38
+
39
+ index += 1
40
+ end
41
+
42
+ artifacts
43
+ end
44
+
45
+ private
46
+
47
+ def glob_path
48
+ Pathname.new(@glob)
49
+ end
50
+
51
+ def build_directory_path
52
+ Pathname.new(@build_directory)
53
+ end
54
+
55
+ def globbed_files
56
+ if glob_path.relative?
57
+ Dir.chdir(build_directory_path.expand_path) { Dir.glob(glob_path) }
58
+ else
59
+ Dir.glob(glob_path)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ require 'celluloid'
2
+ require 'mime/types'
3
+
4
+ module Buildbox
5
+ class Artifact::Poster
6
+ include Celluloid
7
+ include Celluloid::Logger
8
+
9
+ def post(api, access_token, build, artifact)
10
+ upload_action = artifact.upload_instructions['action']
11
+ form_data = artifact.upload_instructions['data'].to_hash.dup
12
+
13
+ connection = Faraday.new(:url => upload_action['url']) do |faraday|
14
+ faraday.request :multipart
15
+
16
+ faraday.response :raise_error
17
+
18
+ faraday.options[:timeout] = 60
19
+ faraday.options[:open_timeout] = 60
20
+
21
+ faraday.adapter Faraday.default_adapter
22
+ end
23
+
24
+ mime_type = MIME::Types.type_for(artifact.path)[0].to_s
25
+
26
+ file_input_key = upload_action['file_input']
27
+ form_data[file_input_key] = Faraday::UploadIO.new(artifact.path, mime_type)
28
+
29
+ api.update_artifact(access_token, build, artifact.remote_id, :state => 'uploading')
30
+
31
+ upload_exception = nil
32
+ response = nil
33
+
34
+ begin
35
+ response = connection.post(upload_action['path'], form_data)
36
+ rescue => e
37
+ upload_exception = e
38
+ end
39
+
40
+ if upload_exception
41
+ error "Error uploading #{artifact.basename} with a status of (#{upload_exception.class.name}: #{upload_exception.message})"
42
+ finished_state = 'error'
43
+ else
44
+ info "Finished uploading #{artifact.basename} with a status of #{response.status}"
45
+ finished_state = 'finished'
46
+ end
47
+
48
+ api.update_artifact(access_token, build, artifact.remote_id, :state => finished_state)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ require 'celluloid'
2
+ require 'mime/types'
3
+
4
+ module Buildbox
5
+ class Artifact::Uploader
6
+ include Celluloid
7
+ include Celluloid::Logger
8
+
9
+ def initialize(api, access_token, build, artifacts)
10
+ @api = api
11
+ @access_token = access_token
12
+ @build = build
13
+ @artifacts = artifacts
14
+ end
15
+
16
+ def prepare_and_upload
17
+ info "Preparing #{@artifacts.count} artifacts for upload"
18
+
19
+ responses = @api.create_artifacts(@access_token, @build, @artifacts)
20
+ responses.each do |response|
21
+ artifact = @artifacts.find { |artifact| artifact.id == response['id'] }
22
+
23
+ artifact.remote_id = response['artifact']['id']
24
+ artifact.upload_instructions = response['artifact']['uploader']
25
+ end
26
+
27
+ @artifacts.each do |artifact|
28
+ Celluloid::Actor[:artifact_poster_pool].async.post(@api, @access_token, @build, artifact)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -12,7 +12,7 @@ module Buildbox
12
12
 
13
13
  def start
14
14
  Celluloid.logger = @logger
15
- Celluloid::Actor[:uploader_pool] = Uploader.pool
15
+ Celluloid::Actor[:artifact_poster_pool] = Artifact::Poster.pool
16
16
 
17
17
  agent_access_tokens.each do |access_token|
18
18
  @supervisors << Buildbox::Agent.supervise(access_token)
@@ -1,3 +1,3 @@
1
1
  module Buildbox
2
- VERSION = "0.6.beta2"
2
+ VERSION = "0.6.beta3"
3
3
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Buildbox::Artifact::Collector do
4
+ let(:directory) { File.join(FIXTURES_PATH, "artifact-globber") }
5
+
6
+ def test_for_files(files, expected)
7
+ expected.each do |path|
8
+ expect(files.map(&:name)).to include(path)
9
+ expect(File.exist?(files.find{ |f| f.name == path }.path)).to be_true
10
+ end
11
+ end
12
+
13
+ describe "#collect_and_copy" do
14
+ it "handles specific files" do
15
+ files = Buildbox::Artifact::Collector.collect_and_copy(directory, "foo.txt")
16
+
17
+ expect(files.length).to eql(1)
18
+ test_for_files(files, %w(foo.txt))
19
+ end
20
+
21
+ it "handles globs" do
22
+ files = Buildbox::Artifact::Collector.collect_and_copy(directory, "bar/**/*.txt")
23
+
24
+ expect(files.length).to eql(4)
25
+ test_for_files(files, %w(bar/bang.txt bar/bang1.txt bar/bang2.txt bar/inside-bar/bang3.txt))
26
+ end
27
+
28
+ it "handles absolute globs" do
29
+ files = Buildbox::Artifact::Collector.collect_and_copy(directory, File.join(File.expand_path(directory), "**/*.txt"))
30
+ expected_files = %w(foo.txt bar/bang.txt bar/bang1.txt bar/bang2.txt bar/inside-bar/bang3.txt).map do |file|
31
+ File.join(directory, file)
32
+ end
33
+
34
+ expect(files.length).to eql(5)
35
+ test_for_files(files, expected_files)
36
+ end
37
+
38
+ it "handles specifying everything under a folder" do
39
+ files = Buildbox::Artifact::Collector.collect_and_copy(directory, "coverage/**/*")
40
+
41
+ expect(files.length).to eql(25)
42
+ test_for_files(files, %w(coverage/index.html coverage/assets/0.8.0/application.js))
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.beta2
4
+ version: 0.6.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Pitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-12 00:00:00.000000000 Z
11
+ date: 2013-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -185,6 +185,9 @@ files:
185
185
  - lib/buildbox/agent.rb
186
186
  - lib/buildbox/api.rb
187
187
  - lib/buildbox/artifact.rb
188
+ - lib/buildbox/artifact/collector.rb
189
+ - lib/buildbox/artifact/poster.rb
190
+ - lib/buildbox/artifact/uploader.rb
188
191
  - lib/buildbox/build.rb
189
192
  - lib/buildbox/canceler.rb
190
193
  - lib/buildbox/cli.rb
@@ -194,13 +197,12 @@ files:
194
197
  - lib/buildbox/platform.rb
195
198
  - lib/buildbox/runner.rb
196
199
  - lib/buildbox/server.rb
197
- - lib/buildbox/uploader.rb
198
200
  - lib/buildbox/utf8.rb
199
201
  - lib/buildbox/version.rb
200
202
  - lib/certs/cacert.pem
201
203
  - spec/buildbox/buildbox/agent_spec.rb
202
204
  - spec/buildbox/buildbox/api_spec.rb
203
- - spec/buildbox/buildbox/artifact_spec.rb
205
+ - spec/buildbox/buildbox/artifact/collector_spec.rb
204
206
  - spec/buildbox/buildbox/build_spec.rb
205
207
  - spec/buildbox/buildbox/cli_spec.rb
206
208
  - spec/buildbox/buildbox/command_spec.rb
@@ -297,7 +299,7 @@ summary: Ruby agent for buildbox
297
299
  test_files:
298
300
  - spec/buildbox/buildbox/agent_spec.rb
299
301
  - spec/buildbox/buildbox/api_spec.rb
300
- - spec/buildbox/buildbox/artifact_spec.rb
302
+ - spec/buildbox/buildbox/artifact/collector_spec.rb
301
303
  - spec/buildbox/buildbox/build_spec.rb
302
304
  - spec/buildbox/buildbox/cli_spec.rb
303
305
  - spec/buildbox/buildbox/command_spec.rb
@@ -1,58 +0,0 @@
1
- require 'celluloid'
2
- require 'mime/types'
3
-
4
- module Buildbox
5
- class Uploader
6
- include Celluloid
7
- include Celluloid::Logger
8
-
9
- def upload(api, access_token, current_build, relative_path, absolute_path)
10
- info "Uploading #{absolute_path}"
11
-
12
- artifact = api.create_artifact(access_token, current_build,
13
- :path => relative_path,
14
- :file_size => File.size(absolute_path))
15
-
16
-
17
- upload_action = artifact[:uploader][:action]
18
- form_data = artifact[:uploader][:data].to_hash.dup
19
-
20
- connection = Faraday.new(:url => upload_action[:url]) do |faraday|
21
- faraday.request :multipart
22
-
23
- faraday.response :raise_error
24
-
25
- faraday.options[:timeout] = 60
26
- faraday.options[:open_timeout] = 60
27
-
28
- faraday.adapter Faraday.default_adapter
29
- end
30
-
31
- mime_type = MIME::Types.type_for(absolute_path)[0].to_s
32
-
33
- file_input_key = upload_action[:file_input]
34
- form_data[file_input_key] = Faraday::UploadIO.new(absolute_path, mime_type)
35
-
36
- api.update_artifact(access_token, current_build, artifact[:id], :state => 'uploading')
37
-
38
- upload_exception = nil
39
- response = nil
40
-
41
- begin
42
- response = connection.post(upload_action[:path], form_data)
43
- rescue => e
44
- upload_exception = e
45
- end
46
-
47
- if upload_exception
48
- error "Error uploading #{File.basename(absolute_path)} with a status of (#{upload_exception.class.name}: #{upload_exception.message})"
49
- finished_state = 'error'
50
- else
51
- info "Finished uploading #{File.basename(absolute_path)} with a status of #{response.status}"
52
- finished_state = 'finished'
53
- end
54
-
55
- api.update_artifact(access_token, current_build, artifact[:id], :state => finished_state)
56
- end
57
- end
58
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Buildbox::Artifact do
4
- let(:directory) { File.join(FIXTURES_PATH, "artifact-globber") }
5
-
6
- def test_for_files(files, expected)
7
- expected.each do |path|
8
- expect(files.keys).to include(path)
9
- expect(File.exist?(files[path])).to be_true
10
- end
11
- end
12
-
13
- describe "#files_to_upload" do
14
- it "handles specific files" do
15
- files = Buildbox::Artifact.files_to_upload(directory, "foo.txt")
16
-
17
- expect(files.length).to eql(1)
18
- test_for_files(files, %w(/foo.txt))
19
- end
20
-
21
- it "handles globs" do
22
- files = Buildbox::Artifact.files_to_upload(directory, "bar/**/*.txt")
23
-
24
- expect(files.length).to eql(4)
25
- test_for_files(files, %w(/bar/bang.txt /bar/bang1.txt /bar/bang2.txt /bar/inside-bar/bang3.txt))
26
- end
27
-
28
- it "handles absolute globs" do
29
- files = Buildbox::Artifact.files_to_upload(directory, File.join(File.expand_path(directory), "**/*.txt"))
30
-
31
- expect(files.length).to eql(5)
32
- test_for_files(files, %w(/foo.txt /bar/bang.txt /bar/bang1.txt /bar/bang2.txt /bar/inside-bar/bang3.txt))
33
- end
34
-
35
- it "handles specifying everything under a folder" do
36
- files = Buildbox::Artifact.files_to_upload(directory, "coverage/**/*")
37
-
38
- expect(files.length).to eql(25)
39
- test_for_files(files, %w(/coverage/index.html /coverage/assets/0.8.0/application.js))
40
- end
41
- end
42
- end