buildbox 0.2.2 → 0.2.3

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