buildbox 0.2.2 → 0.2.3

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: f440103d7897a20e804e7a4a24b81699cd29e3b3
4
- data.tar.gz: 1c70d6f1809989aba284dd197a9804bf84693e1e
3
+ metadata.gz: 29832c2693fb640f1003b5a010eeb170a792f9c2
4
+ data.tar.gz: dd13bc62a427512418a1bdaa7dabce4098c009dd
5
5
  SHA512:
6
- metadata.gz: 3fe2b5ab4c51c94ccd7efa13d69757decc2f48448ce206ef51f0ae4735090b05a947b257590bf21e1e6647f7a53b0bde114813afdd74abd729b7c7caaebd104c
7
- data.tar.gz: f3a8445fe4b4af7aa8eaf8d16f8935980b051461de31638afbd2509f5e0979dc174cadabe2469d8c53c0fd53671bde7457601f516d80c129a2d3c4b55cb69497
6
+ metadata.gz: bc853759496d74190b5b5edf806325693bace3870809c3e78ef868a2e8bc45f33cadb3f3feab5268ec54f0d76ccbf600d682fea035fa863284b253ee1c6f1ded
7
+ data.tar.gz: 2d728c74a1571837bd7d3c93f85b49574bc65fb393435c8b61b69f2987012c13129de744df72415cf201e5d3520527b4eb1eeb223956305401dd3cb5ff0cbbe0
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- buildbox (0.2.2)
4
+ buildbox (0.2.3)
5
5
  celluloid (~> 0.14)
6
+ childprocess (~> 0.3)
6
7
  faraday (~> 0.8)
7
8
  faraday_middleware (~> 0.9)
8
9
  hashie (~> 2.0)
@@ -12,8 +13,10 @@ GEM
12
13
  remote: https://rubygems.org/
13
14
  specs:
14
15
  addressable (2.3.5)
15
- celluloid (0.14.1)
16
- timers (>= 1.0.0)
16
+ celluloid (0.15.1)
17
+ timers (~> 1.1.0)
18
+ childprocess (0.3.9)
19
+ ffi (~> 1.0, >= 1.0.11)
17
20
  crack (0.4.1)
18
21
  safe_yaml (~> 0.9.0)
19
22
  diff-lcs (1.2.4)
@@ -21,8 +24,9 @@ GEM
21
24
  multipart-post (~> 1.2.0)
22
25
  faraday_middleware (0.9.0)
23
26
  faraday (>= 0.7.4, < 0.9)
27
+ ffi (1.9.0)
24
28
  hashie (2.0.5)
25
- multi_json (1.7.9)
29
+ multi_json (1.8.0)
26
30
  multipart-post (1.2.0)
27
31
  rake (10.1.0)
28
32
  rspec (2.14.1)
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pty'
4
+
5
+ # spawn the process in a pseudo terminal so colors out outputted
6
+ read_io, write_io, pid = PTY.spawn("bash", "-c", ARGV.join(" "))
7
+
8
+ # we don't need to write to the spawned io
9
+ write_io.close
10
+
11
+ loop do
12
+ fds, = IO.select([read_io], nil, nil, 1)
13
+ if fds
14
+ # should have some data to read
15
+ begin
16
+ print read_io.read_nonblock(10240)
17
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
18
+ # do select again
19
+ rescue EOFError, Errno::EIO # EOFError from OSX, EIO is raised by ubuntu
20
+ break
21
+ end
22
+ end
23
+ # if fds are empty, timeout expired - run another iteration
24
+ end
25
+
26
+ # we're done reading, yay!
27
+ read_io.close
28
+
29
+ # just wait until its finally finished closing
30
+ Process.waitpid(pid)
31
+
32
+ # exit with the status code that the process returned
33
+ exit $?.exitstatus
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'hashie', '~> 2.0'
24
24
  spec.add_dependency 'multi_json', '~> 1.7'
25
25
  spec.add_dependency 'celluloid', '~> 0.14'
26
+ spec.add_dependency 'childprocess', '~> 0.3'
26
27
  end
@@ -7,7 +7,6 @@ module Buildbox
7
7
  autoload :Command, "buildbox/command"
8
8
  autoload :CLI, "buildbox/cli"
9
9
  autoload :Configuration, "buildbox/configuration"
10
- autoload :Environment, "buildbox/environment"
11
10
  autoload :Monitor, "buildbox/monitor"
12
11
  autoload :Runner, "buildbox/runner"
13
12
  autoload :Script, "buildbox/script"
@@ -24,6 +23,10 @@ module Buildbox
24
23
  @logger ||= Logger.new(STDOUT).tap { |logger| logger.level = Logger::INFO }
25
24
  end
26
25
 
26
+ def self.gem_root
27
+ path = File.expand_path(File.join(__FILE__, "..", ".."))
28
+ end
29
+
27
30
  def self.root_path
28
31
  path = Pathname.new File.join(ENV['HOME'], ".buildbox")
29
32
  path.mkpath unless path.exist?
@@ -28,10 +28,10 @@ module Buildbox
28
28
  end
29
29
 
30
30
  @commands['agent:setup'] = OptionParser.new do |opts|
31
- opts.banner = "Usage: buildbox setup:add [token]"
31
+ opts.banner = "Usage: buildbox agent:setup [token]"
32
32
 
33
33
  opts.on("--help", "You're looking at it.") do
34
- puts @commands['setup:add']
34
+ puts @commands['agent:setup']
35
35
  exit
36
36
  end
37
37
  end
@@ -61,7 +61,7 @@ module Buildbox
61
61
 
62
62
  if command == "agent:start"
63
63
  Buildbox::Server.new.start
64
- elsif command == "setup:add"
64
+ elsif command == "agent:setup"
65
65
  if @argv.length == 0
66
66
  puts "No token provided"
67
67
  exit 1
@@ -86,7 +86,7 @@ module Buildbox
86
86
  Buildbox.config.update(:api_key => api_key)
87
87
 
88
88
  puts "Successfully added your api_key"
89
- puts "You can now add agents with: buildbox setup:add [agent_token]"
89
+ puts "You can now add agents with: buildbox agent:setup [agent_token]"
90
90
  rescue
91
91
  puts "Could not authenticate your api_key"
92
92
  exit 1
@@ -1,3 +1,4 @@
1
+ require 'childprocess'
1
2
  require 'pty'
2
3
 
3
4
  module Buildbox
@@ -5,63 +6,69 @@ module Buildbox
5
6
  class Result < Struct.new(:output, :exit_status)
6
7
  end
7
8
 
8
- def self.run(command, options = {}, &block)
9
- new(command, options).run(&block)
9
+ def self.command(command, options = {}, &block)
10
+ new(command, options).start(&block)
10
11
  end
11
12
 
12
- def initialize(command, options = {})
13
- @command = command
13
+ def self.script(script, options = {}, &block)
14
+ new(script, options).start(&block)
15
+ end
16
+
17
+ def initialize(arguments, options = {})
18
+ @arguments = arguments
19
+ @environment = options[:environment] || {}
14
20
  @directory = options[:directory] || "."
15
- @read_interval = options[:read_interval] || 5
16
21
  end
17
22
 
18
- def run(&block)
19
- output = ""
20
- read_io, write_io, pid = nil
23
+ def start(&block)
24
+ read_io, write_io = IO.pipe
21
25
 
22
- # spawn the process in a pseudo terminal so colors out outputted
23
- read_io, write_io, pid = PTY.spawn("cd #{expanded_directory} && #{@command}")
26
+ arguments = [ *runner, *@arguments ].compact.map(&:to_s) # all arguments must be a string
27
+ process = ChildProcess.build(*arguments)
28
+ process.cwd = expanded_directory
29
+ process.io.stdout = process.io.stderr = write_io
24
30
 
25
- # we don't need to write to the spawned io
31
+ @environment.each_pair do |key, value|
32
+ process.environment[key] = value
33
+ end
34
+
35
+ process.start
26
36
  write_io.close
27
37
 
28
- loop do
29
- fds, = IO.select([read_io], nil, nil, read_interval)
30
- if fds
31
- # should have some data to read
32
- begin
33
- chunk = read_io.read_nonblock(10240)
34
- cleaned_chunk = UTF8.clean(chunk)
35
-
36
- output << chunk
37
- yield cleaned_chunk if block_given?
38
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK
39
- # do select again
40
- rescue EOFError, Errno::EIO # EOFError from OSX, EIO is raised by ubuntu
41
- break
42
- end
38
+ output = ""
39
+ begin
40
+ loop do
41
+ chunk = read_io.readpartial(10240)
42
+ cleaned_chunk = UTF8.clean(chunk)
43
+
44
+ output << chunk
45
+ yield cleaned_chunk if block_given?
43
46
  end
44
- # if fds are empty, timeout expired - run another iteration
47
+ rescue EOFError
45
48
  end
46
49
 
47
- # we're done reading, yay!
48
- read_io.close
49
-
50
- # just wait until its finally finished closing
51
- Process.waitpid(pid)
50
+ process.wait
52
51
 
53
52
  # the final result!
54
- Result.new(output.chomp, $?.exitstatus)
53
+ Result.new(output.chomp, process.exit_code)
55
54
  end
56
55
 
57
56
  private
58
57
 
59
- def expanded_directory
60
- File.expand_path(@directory)
58
+ # on heroku, tty isn't avaiable. so we result to just running command through
59
+ # bash. the downside to this, is that stuff colors aren't outputted because
60
+ # processes don't think they're being in a terminal.
61
+ def runner
62
+ require 'pty'
63
+ PTY.spawn('whoami')
64
+
65
+ [ File.join(Buildbox.gem_root, "bin", "buildbox-pty") ]
66
+ rescue
67
+ [ "bash", "-c" ]
61
68
  end
62
69
 
63
- def read_interval
64
- @read_interval
70
+ def expanded_directory
71
+ File.expand_path(@directory)
65
72
  end
66
73
  end
67
74
  end
@@ -5,7 +5,7 @@ require 'json'
5
5
  module Buildbox
6
6
  class Configuration < Hashie::Mash
7
7
  def agent_access_tokens
8
- env_agents = ENV['BUILDBOX_WORKERS']
8
+ env_agents = ENV['BUILDBOX_AGENTS']
9
9
 
10
10
  if env_agents.nil?
11
11
  self[:agent_access_tokens] || []
@@ -24,7 +24,7 @@ module Buildbox
24
24
 
25
25
  def check
26
26
  unless api_key
27
- puts "No api_key set. You can set it with\nbuildbox authenticate [api_key]"
27
+ puts "No api_key set. You can set it with\nbuildbox auth:login [api_key]"
28
28
  exit 1
29
29
  end
30
30
  end
@@ -15,13 +15,16 @@ module Buildbox
15
15
 
16
16
  def start
17
17
  info "Starting to build #{namespace}/#{@build.number} starting..."
18
- info "Running command: #{command}"
19
18
 
20
19
  FileUtils.mkdir_p(directory_path)
21
20
  File.open(script_path, 'w+') { |file| file.write(@build.script) }
21
+ File.chmod(0777, script_path)
22
+
23
+ info "Running script: #{script_path}"
22
24
 
23
25
  build.output = ""
24
- result = Command.run(command, :directory => directory_path) do |chunk|
26
+ result = Command.script(script_path, :environment => @build.env,
27
+ :directory => directory_path) do |chunk|
25
28
  build.output << chunk
26
29
  end
27
30
 
@@ -35,12 +38,6 @@ module Buildbox
35
38
 
36
39
  private
37
40
 
38
- def command
39
- export = environment.any? ? "export #{environment};" : ""
40
-
41
- "#{export} chmod +x #{script_path} && #{script_path}"
42
- end
43
-
44
41
  def directory_path
45
42
  @directory_path ||= Buildbox.root_path.join(namespace)
46
43
  end
@@ -52,9 +49,5 @@ module Buildbox
52
49
  def namespace
53
50
  "#{@build.project.team.name}/#{@build.project.name}"
54
51
  end
55
-
56
- def environment
57
- @environment ||= Environment.new(@build.env)
58
- end
59
52
  end
60
53
  end
@@ -1,3 +1,3 @@
1
1
  module Buildbox
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -5,34 +5,34 @@ require "spec_helper"
5
5
  describe Buildbox::Command do
6
6
  describe "#run" do
7
7
  it "is run within a tty" do
8
- result = Buildbox::Command.run(%{ruby -e "puts STDOUT.tty?"})
8
+ result = Buildbox::Command.command(%{ruby -e "puts STDOUT.tty?"})
9
9
 
10
10
  result.output.should == "true"
11
11
  end
12
12
 
13
13
  it "successfully runs and returns the output from a simple comment" do
14
- result = Buildbox::Command.run('echo hello world')
14
+ result = Buildbox::Command.command('echo hello world')
15
15
 
16
16
  result.exit_status.should == 0
17
17
  result.output.should == "hello world"
18
18
  end
19
19
 
20
20
  it "redirects stdout to stderr" do
21
- result = Buildbox::Command.run('echo hello world 1>&2')
21
+ result = Buildbox::Command.command('echo hello world 1>&2')
22
22
 
23
23
  result.exit_status.should == 0
24
24
  result.output.should == "hello world"
25
25
  end
26
26
 
27
27
  it "handles commands that fail and returns the correct status" do
28
- result = Buildbox::Command.run('(exit 1)')
28
+ result = Buildbox::Command.command('(exit 1)')
29
29
 
30
30
  result.exit_status.should_not == 0
31
31
  result.output.should == ''
32
32
  end
33
33
 
34
34
  it "handles running malformed commands" do
35
- result = Buildbox::Command.run('if (')
35
+ result = Buildbox::Command.command('if (')
36
36
 
37
37
  result.exit_status.should_not == 0
38
38
  # bash 3.2.48 prints "syntax error" in lowercase.
@@ -45,7 +45,7 @@ describe Buildbox::Command do
45
45
 
46
46
  it "can collect output in chunks" do
47
47
  chunked_output = ''
48
- result = Buildbox::Command.run('echo hello world') do |chunk|
48
+ result = Buildbox::Command.command('echo hello world') do |chunk|
49
49
  unless chunk.nil?
50
50
  chunked_output += chunk
51
51
  end
@@ -56,51 +56,12 @@ describe Buildbox::Command do
56
56
  chunked_output.should == "hello world\r\n"
57
57
  end
58
58
 
59
- it "can collect chunks at paticular intervals" do
60
- command = Buildbox::Command.new(nil, :read_interval => 0.1)
61
-
62
- chunked_output = ''
63
- result = Buildbox::Command.run('sleep 0.5; echo hello world') do |chunk|
64
- unless chunk.nil?
65
- chunked_output += chunk
66
- end
67
- end
68
-
69
- result.exit_status.should == 0
70
- result.output.should == "hello world"
71
- chunked_output.should == "hello world\r\n"
72
- end
73
-
74
- it "can collect chunks from within a thread" do
75
- chunked_output = ''
76
- result = nil
77
- worker_thread = Thread.new do
78
- result = Buildbox::Command.run('echo before sleep; sleep 1; echo after sleep') do |chunk|
79
- unless chunk.nil?
80
- chunked_output += chunk
81
- end
82
- end
83
- end
84
-
85
- worker_thread.run
86
- sleep(0.5)
87
- result.should be_nil
88
- chunked_output.should == "before sleep\r\n"
89
-
90
- worker_thread.join
91
-
92
- result.should_not be_nil
93
- result.exit_status.should == 0
94
- result.output.should == "before sleep\r\nafter sleep"
95
- chunked_output.should == "before sleep\r\nafter sleep\r\n"
96
- end
97
-
98
59
  it 'returns a result when running an invalid command in a thread' do
99
60
  result = nil
100
61
  second_result = nil
101
62
  thread = Thread.new do
102
- result = Buildbox::Command.run('sillycommandlololol')
103
- second_result = Buildbox::Command.run('export FOO=bar; doesntexist.rb')
63
+ result = Buildbox::Command.command('sillycommandlololol')
64
+ second_result = Buildbox::Command.command('export FOO=bar; doesntexist.rb')
104
65
  end
105
66
  thread.join
106
67
 
@@ -113,9 +74,9 @@ describe Buildbox::Command do
113
74
  second_result.output.should =~ /doesntexist.rb:.+not found/
114
75
  end
115
76
 
116
- it "captures color'd output" do
77
+ it "captures color'd output from a command" do
117
78
  chunked_output = ''
118
- result = Buildbox::Command.run("rspec #{FIXTURES_PATH.join('rspec', 'test_spec.rb')} --color") do |chunk|
79
+ result = Buildbox::Command.command("rspec #{FIXTURES_PATH.join('rspec', 'test_spec.rb')}") do |chunk|
119
80
  chunked_output += chunk unless chunk.nil?
120
81
  end
121
82
 
@@ -124,8 +85,26 @@ describe Buildbox::Command do
124
85
  chunked_output.should include("32m")
125
86
  end
126
87
 
88
+ it "runs scripts in a tty" do
89
+ chunked_output = ''
90
+ result = Buildbox::Command.script(FIXTURES_PATH.join('tty_script')) do |chunk|
91
+ chunked_output += chunk unless chunk.nil?
92
+ end
93
+
94
+ result.output.should == "true"
95
+ result.exit_status.should == 123
96
+ end
97
+
98
+ it "still runs even if pty isn't available" do
99
+ PTY.should_receive(:spawn).and_raise(RuntimeError.new)
100
+ result = Buildbox::Command.command('echo hello world')
101
+
102
+ result.exit_status.should == 0
103
+ result.output.should == "hello world"
104
+ end
105
+
127
106
  it "supports utf8 characters" do
128
- result = Buildbox::Command.run('echo "hello"; echo "\xE2\x98\xA0"')
107
+ result = Buildbox::Command.command('echo "hello"; echo "\xE2\x98\xA0"')
129
108
 
130
109
  result.exit_status.should == 0
131
110
  # just trying to interact with the string that has utf8 in it to make sure that it
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ puts STDOUT.tty?
4
+
5
+ exit 123
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.2.2
4
+ version: 0.2.3
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-09-06 00:00:00.000000000 Z
11
+ date: 2013-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -80,11 +80,26 @@ dependencies:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.14'
83
+ - !ruby/object:Gem::Dependency
84
+ name: childprocess
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0.3'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0.3'
83
97
  description: Ruby client for buildbox
84
98
  email:
85
99
  - me@keithpitt.com
86
100
  executables:
87
101
  - buildbox
102
+ - buildbox-pty
88
103
  extensions: []
89
104
  extra_rdoc_files: []
90
105
  files:
@@ -96,6 +111,7 @@ files:
96
111
  - README.md
97
112
  - Rakefile
98
113
  - bin/buildbox
114
+ - bin/buildbox-pty
99
115
  - buildbox-ruby.gemspec
100
116
  - lib/buildbox.rb
101
117
  - lib/buildbox/agent.rb
@@ -104,7 +120,6 @@ files:
104
120
  - lib/buildbox/cli.rb
105
121
  - lib/buildbox/command.rb
106
122
  - lib/buildbox/configuration.rb
107
- - lib/buildbox/environment.rb
108
123
  - lib/buildbox/monitor.rb
109
124
  - lib/buildbox/runner.rb
110
125
  - lib/buildbox/server.rb
@@ -116,7 +131,6 @@ files:
116
131
  - spec/buildbox/buildbox/cli_spec.rb
117
132
  - spec/buildbox/buildbox/command_spec.rb
118
133
  - spec/buildbox/buildbox/configuration_spec.rb
119
- - spec/buildbox/buildbox/environment_spec.rb
120
134
  - spec/buildbox/buildbox/monitor_spec.rb
121
135
  - spec/buildbox/buildbox/runner_spec.rb
122
136
  - spec/buildbox/buildbox/server_spec.rb
@@ -143,6 +157,7 @@ files:
143
157
  - spec/fixtures/repo.git/objects/e9/8d8a9be514ef53609a52c9e1b820dbcc8e6603
144
158
  - spec/fixtures/repo.git/refs/heads/master
145
159
  - spec/fixtures/rspec/test_spec.rb
160
+ - spec/fixtures/tty_script
146
161
  - spec/integration/running_a_build_spec.rb
147
162
  - spec/spec_helper.rb
148
163
  - spec/support/silence_logger.rb
@@ -178,7 +193,6 @@ test_files:
178
193
  - spec/buildbox/buildbox/cli_spec.rb
179
194
  - spec/buildbox/buildbox/command_spec.rb
180
195
  - spec/buildbox/buildbox/configuration_spec.rb
181
- - spec/buildbox/buildbox/environment_spec.rb
182
196
  - spec/buildbox/buildbox/monitor_spec.rb
183
197
  - spec/buildbox/buildbox/runner_spec.rb
184
198
  - spec/buildbox/buildbox/server_spec.rb
@@ -205,6 +219,7 @@ test_files:
205
219
  - spec/fixtures/repo.git/objects/e9/8d8a9be514ef53609a52c9e1b820dbcc8e6603
206
220
  - spec/fixtures/repo.git/refs/heads/master
207
221
  - spec/fixtures/rspec/test_spec.rb
222
+ - spec/fixtures/tty_script
208
223
  - spec/integration/running_a_build_spec.rb
209
224
  - spec/spec_helper.rb
210
225
  - spec/support/silence_logger.rb
@@ -1,17 +0,0 @@
1
- module Buildbox
2
- class Environment
3
- def initialize(environment)
4
- @environment = environment
5
- end
6
-
7
- def any?
8
- @environment && @environment.keys.length > 0
9
- end
10
-
11
- def to_s
12
- @environment.to_a.map do |key, value|
13
- %{#{key}=#{value.inspect}}
14
- end.join(" ")
15
- end
16
- end
17
- end
@@ -1,4 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Buildbox::Environment do
4
- end