buildbox 0.6.beta2 → 0.6.beta3

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 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