pairzone 0.0.1

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.
Files changed (46) hide show
  1. data/.gitignore +26 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +7 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +76 -0
  6. data/README.md +44 -0
  7. data/Rakefile +14 -0
  8. data/bin/pairzone +83 -0
  9. data/config/cucumber.yml +4 -0
  10. data/features/collaborator_joins_pairzone.feature +20 -0
  11. data/features/developer_signs_in.feature +11 -0
  12. data/features/developer_starts_pairzone.feature +35 -0
  13. data/features/keys/bob.key +12 -0
  14. data/features/keys/bob.key.pub +1 -0
  15. data/features/keys/derek.key +27 -0
  16. data/features/keys/derek.key.pub +1 -0
  17. data/features/server/stub-pairzone-server.rb +76 -0
  18. data/features/step_definitions/authorisation_steps.rb +8 -0
  19. data/features/step_definitions/info_steps.rb +5 -0
  20. data/features/step_definitions/repository_steps.rb +6 -0
  21. data/features/step_definitions/running_steps.rb +32 -0
  22. data/features/step_definitions/starting_steps.rb +47 -0
  23. data/features/support/aruba.rb +1 -0
  24. data/features/support/env.rb +5 -0
  25. data/features/support/helpers/server_helper.rb +40 -0
  26. data/features/support/hooks.rb +24 -0
  27. data/features/support/pairzone-config.rb +13 -0
  28. data/lib/pairzone.rb +14 -0
  29. data/lib/pairzone/api/base.rb +27 -0
  30. data/lib/pairzone/api/pairzone.rb +25 -0
  31. data/lib/pairzone/api/pairzone_connection.rb +32 -0
  32. data/lib/pairzone/api/pairzone_lifecycle.rb +34 -0
  33. data/lib/pairzone/api/user.rb +16 -0
  34. data/lib/pairzone/authenticate.rb +51 -0
  35. data/lib/pairzone/commands/info.rb +25 -0
  36. data/lib/pairzone/commands/join.rb +21 -0
  37. data/lib/pairzone/commands/start.rb +29 -0
  38. data/lib/pairzone/logger.rb +33 -0
  39. data/lib/pairzone/shell.rb +38 -0
  40. data/lib/pairzone/version.rb +3 -0
  41. data/pairzone.gemspec +35 -0
  42. data/spec/pairzone/api/pairzone_lifecycle_spec.rb +26 -0
  43. data/spec/pairzone/authentication_spec.rb +44 -0
  44. data/spec/pairzone/logger_spec.rb +41 -0
  45. data/spec/spec_helper.rb +7 -0
  46. metadata +292 -0
@@ -0,0 +1,29 @@
1
+ require 'net/ssh'
2
+ require 'tempfile'
3
+
4
+ module Pairzone
5
+ module Commands
6
+ class Start
7
+ def initialize(project_name, identity, options)
8
+ @project_name = project_name
9
+ @identity = File.expand_path(identity)
10
+ @options = options
11
+ end
12
+
13
+ def execute
14
+ @pairzone = Pairzone::Api::Pairzone.start(:project_name => @project_name, :collaborators => collaborators)
15
+ @pairzone.push_code(@identity)
16
+ unless @options[:background]
17
+ @pairzone.connect(@identity)
18
+ @pairzone.fetch_code(@identity)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def collaborators
25
+ return (@options[:c] || "").split(',')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ module Pairzone
2
+ class Logger
3
+ class << self
4
+ def configure_from(globals)
5
+ @level = globals[:d]
6
+ end
7
+
8
+ def stdout
9
+ @stdout ||= HighLine.new($stdin, $stdout)
10
+ end
11
+
12
+ def stderr
13
+ @stderr ||= HighLine.new($stdin, $stderr)
14
+ end
15
+
16
+ def info(msg)
17
+ stdout.say(msg)
18
+ end
19
+
20
+ def debug(msg)
21
+ stderr.say("<%= color('debug:', YELLOW + BOLD) %> #{msg}") if @level
22
+ end
23
+
24
+ def error(msg)
25
+ stdout.say("<%= color('Pairzone error:', RED + BOLD) %> #{msg}")
26
+ end
27
+
28
+ def ask(msg, &block)
29
+ stdout.ask(msg, &block)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ module Pairzone
2
+ class Shell
3
+ def initialize(identity)
4
+ @identity = identity
5
+ end
6
+
7
+ def run(cmd)
8
+ Logger.debug(cmd)
9
+ output = `#{cmd}`
10
+ Logger.debug("#=> #{output}")
11
+ output
12
+ end
13
+
14
+ def git(cmd)
15
+ git_ssh = Tempfile.new('git_ssh')
16
+ git_ssh.puts %{#!/bin/bash\nexec ssh -i #{@identity} $1 "bash --login -c '$2'"}
17
+ git_ssh.close
18
+ `chmod +x #{git_ssh.path}`
19
+ run "GIT_SSH='#{git_ssh.path}' #{cmd}"
20
+ end
21
+
22
+ def remote(ip, command)
23
+ output = ''
24
+ remote_log(ip, command)
25
+ Net::SSH.start(ip, 'pairzone', :auth_methods => ['publickey'], :keys => [@identity]) do |ssh|
26
+ output = (ssh.exec!("bash --login -c '#{command}'") || "").strip
27
+ end
28
+ remote_log(ip, "#=> #{output}")
29
+ return output
30
+ end
31
+
32
+ def remote_log(ip, msg)
33
+ Logger.debug("<%= color('[pairzone@#{ip}]:', CYAN + BOLD) %> #{msg}")
34
+ end
35
+
36
+
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Pairzone
2
+ VERSION = '0.0.1'
3
+ end
data/pairzone.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'pairzone/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'pairzone'
9
+ s.version = Pairzone::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ["Chris Parsons"]
12
+ s.email = ["chrismdp@gmail.com"]
13
+ s.summary = "Pair with anyone, on any git repository, right now."
14
+ s.description = "" # FIXME
15
+ s.homepage = "https://github.com/chrismdp/pairzone"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'gli'
23
+ s.add_dependency 'net-ssh'
24
+ s.add_dependency 'party_resource'
25
+ s.add_dependency 'highline'
26
+
27
+ s.add_development_dependency 'rspec', '~> 2.10.0'
28
+ s.add_development_dependency 'rake', '~> 0.9.2.2'
29
+ s.add_development_dependency 'cucumber', '~> 1.2'
30
+ s.add_development_dependency 'aruba', '~> 0.4'
31
+ s.add_development_dependency 'sinatra'
32
+ s.add_development_dependency 'background_process'
33
+ s.add_development_dependency 'rack-contrib'
34
+ s.add_development_dependency 'json'
35
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pairzone::Api::PairzoneLifecycle do
4
+ subject { stub(:lifecycle, create: unstarted, find_by_project_name: started).extend(Pairzone::Api::PairzoneLifecycle) }
5
+ let(:unstarted) { mock(:pairzone, name: 'pairzone', collaborators: [], ip: '', status: 'unstarted') }
6
+ let(:started) { mock(:pairzone, name: 'pairzone', collaborators: [], ip: '', status: 'started') }
7
+
8
+ before do
9
+ subject.start_wait_interval = 0
10
+ end
11
+
12
+ context "starting" do
13
+ it "calls create" do
14
+ subject.should_receive(:create) { unstarted }
15
+ subject.start({})
16
+ end
17
+
18
+ it "blocks, calling find_by_project_name until the state is started" do
19
+ subject.should_receive(:find_by_project_name).with(unstarted.name).
20
+ exactly(5).times.
21
+ and_return(unstarted, unstarted, unstarted, unstarted, started)
22
+ subject.start({})
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pairzone::Authenticate do
4
+ describe "key retrieval" do
5
+ let(:config) { "config-file-location" }
6
+ let(:auth_server) { mock }
7
+ let(:key) { 'key' }
8
+
9
+ it "retrieves the key from a file if it already exists" do
10
+ File.stub(exist?: true)
11
+ File.should_receive(:read).and_return(key)
12
+ Pairzone::Authenticate.retrieve_key(config, auth_server).should == key
13
+ end
14
+
15
+ context "connecting to server" do
16
+
17
+ let(:username) { 'username' }
18
+ let(:password) { 'password' }
19
+ let(:user) { mock(:user, authentication_token: key) }
20
+
21
+ before do
22
+ File.stub(exist?: false)
23
+ Pairzone::Logger.stub(:ask).and_return(username, password)
24
+ Pairzone::Api::Base.stub(:connect_to).with(auth_server, username: username, password: password, default: false)
25
+ Pairzone::Api::User.stub(:current_user).and_return(user)
26
+ # Collaborators
27
+ FileUtils.stub(:mkdir_p)
28
+ File.should_receive(:open)
29
+ end
30
+
31
+ it "asks the user if the file does not exist" do
32
+ Pairzone::Authenticate.retrieve_key(config, auth_server).should == key
33
+ end
34
+
35
+ it "asks for username and password again if it fails the first time" do
36
+ Pairzone::Api::Base.stub(:connect_to).exactly(2).times
37
+ Pairzone::Logger.should_receive(:ask).exactly(4).times.and_return("wrong", "wrong", username, password)
38
+ Pairzone::Api::User.stub(:current_user).and_return(nil, user)
39
+
40
+ Pairzone::Authenticate.retrieve_key(config, auth_server).should == key
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pairzone::Logger do
4
+ let(:stdout) { mock }
5
+ let(:stderr) { mock }
6
+
7
+ it "works without first configuring" do
8
+ ->{ Pairzone::Logger.info("foo") }.should_not raise_error
9
+ end
10
+
11
+ context "after configuration" do
12
+ before do
13
+ Pairzone::Logger.instance_variable_set(:@stdout, stdout)
14
+ Pairzone::Logger.instance_variable_set(:@stderr, stderr)
15
+ end
16
+
17
+ it 'prints output to standard output' do
18
+ msg = 'foo'
19
+ stdout.should_receive(:say).with(msg)
20
+ Pairzone::Logger.info(msg)
21
+ end
22
+
23
+ it 'prints debug messages to std error with a prefix' do
24
+ Pairzone::Logger.instance_variable_set(:@level, true)
25
+ stderr.should_receive(:say).with(/debug.*foo/)
26
+ Pairzone::Logger.debug('foo')
27
+ end
28
+
29
+ it 'does not print debug messages if they are not turned on' do
30
+ Pairzone::Logger.instance_variable_set(:@level, false)
31
+ stderr.should_not_receive(:say).with(/debug.*foo/)
32
+ Pairzone::Logger.debug('foo')
33
+ end
34
+
35
+ it 'prints error messages to std output' do
36
+ msg = 'foo'
37
+ stdout.should_receive(:say).with(/error.*foo/)
38
+ Pairzone::Logger.error(msg)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+ require 'pairzone'
7
+ require 'rspec'
metadata ADDED
@@ -0,0 +1,292 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pairzone
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Chris Parsons
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-07-19 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: gli
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: net-ssh
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: party_resource
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: highline
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :runtime
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 2
82
+ - 10
83
+ - 0
84
+ version: 2.10.0
85
+ type: :development
86
+ version_requirements: *id005
87
+ - !ruby/object:Gem::Dependency
88
+ name: rake
89
+ prerelease: false
90
+ requirement: &id006 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ - 9
98
+ - 2
99
+ - 2
100
+ version: 0.9.2.2
101
+ type: :development
102
+ version_requirements: *id006
103
+ - !ruby/object:Gem::Dependency
104
+ name: cucumber
105
+ prerelease: false
106
+ requirement: &id007 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ segments:
112
+ - 1
113
+ - 2
114
+ version: "1.2"
115
+ type: :development
116
+ version_requirements: *id007
117
+ - !ruby/object:Gem::Dependency
118
+ name: aruba
119
+ prerelease: false
120
+ requirement: &id008 !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ - 4
128
+ version: "0.4"
129
+ type: :development
130
+ version_requirements: *id008
131
+ - !ruby/object:Gem::Dependency
132
+ name: sinatra
133
+ prerelease: false
134
+ requirement: &id009 !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ type: :development
143
+ version_requirements: *id009
144
+ - !ruby/object:Gem::Dependency
145
+ name: background_process
146
+ prerelease: false
147
+ requirement: &id010 !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ type: :development
156
+ version_requirements: *id010
157
+ - !ruby/object:Gem::Dependency
158
+ name: rack-contrib
159
+ prerelease: false
160
+ requirement: &id011 !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ type: :development
169
+ version_requirements: *id011
170
+ - !ruby/object:Gem::Dependency
171
+ name: json
172
+ prerelease: false
173
+ requirement: &id012 !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ segments:
179
+ - 0
180
+ version: "0"
181
+ type: :development
182
+ version_requirements: *id012
183
+ description: ""
184
+ email:
185
+ - chrismdp@gmail.com
186
+ executables:
187
+ - pairzone
188
+ extensions: []
189
+
190
+ extra_rdoc_files: []
191
+
192
+ files:
193
+ - .gitignore
194
+ - .rspec
195
+ - .rvmrc
196
+ - Gemfile
197
+ - Gemfile.lock
198
+ - README.md
199
+ - Rakefile
200
+ - bin/pairzone
201
+ - config/cucumber.yml
202
+ - features/collaborator_joins_pairzone.feature
203
+ - features/developer_signs_in.feature
204
+ - features/developer_starts_pairzone.feature
205
+ - features/keys/bob.key
206
+ - features/keys/bob.key.pub
207
+ - features/keys/derek.key
208
+ - features/keys/derek.key.pub
209
+ - features/server/stub-pairzone-server.rb
210
+ - features/step_definitions/authorisation_steps.rb
211
+ - features/step_definitions/info_steps.rb
212
+ - features/step_definitions/repository_steps.rb
213
+ - features/step_definitions/running_steps.rb
214
+ - features/step_definitions/starting_steps.rb
215
+ - features/support/aruba.rb
216
+ - features/support/env.rb
217
+ - features/support/helpers/server_helper.rb
218
+ - features/support/hooks.rb
219
+ - features/support/pairzone-config.rb
220
+ - lib/pairzone.rb
221
+ - lib/pairzone/api/base.rb
222
+ - lib/pairzone/api/pairzone.rb
223
+ - lib/pairzone/api/pairzone_connection.rb
224
+ - lib/pairzone/api/pairzone_lifecycle.rb
225
+ - lib/pairzone/api/user.rb
226
+ - lib/pairzone/authenticate.rb
227
+ - lib/pairzone/commands/info.rb
228
+ - lib/pairzone/commands/join.rb
229
+ - lib/pairzone/commands/start.rb
230
+ - lib/pairzone/logger.rb
231
+ - lib/pairzone/shell.rb
232
+ - lib/pairzone/version.rb
233
+ - pairzone.gemspec
234
+ - spec/pairzone/api/pairzone_lifecycle_spec.rb
235
+ - spec/pairzone/authentication_spec.rb
236
+ - spec/pairzone/logger_spec.rb
237
+ - spec/spec_helper.rb
238
+ has_rdoc: true
239
+ homepage: https://github.com/chrismdp/pairzone
240
+ licenses: []
241
+
242
+ post_install_message:
243
+ rdoc_options: []
244
+
245
+ require_paths:
246
+ - lib
247
+ required_ruby_version: !ruby/object:Gem::Requirement
248
+ none: false
249
+ requirements:
250
+ - - ">="
251
+ - !ruby/object:Gem::Version
252
+ segments:
253
+ - 0
254
+ version: "0"
255
+ required_rubygems_version: !ruby/object:Gem::Requirement
256
+ none: false
257
+ requirements:
258
+ - - ">="
259
+ - !ruby/object:Gem::Version
260
+ segments:
261
+ - 0
262
+ version: "0"
263
+ requirements: []
264
+
265
+ rubyforge_project:
266
+ rubygems_version: 1.3.7
267
+ signing_key:
268
+ specification_version: 3
269
+ summary: Pair with anyone, on any git repository, right now.
270
+ test_files:
271
+ - features/collaborator_joins_pairzone.feature
272
+ - features/developer_signs_in.feature
273
+ - features/developer_starts_pairzone.feature
274
+ - features/keys/bob.key
275
+ - features/keys/bob.key.pub
276
+ - features/keys/derek.key
277
+ - features/keys/derek.key.pub
278
+ - features/server/stub-pairzone-server.rb
279
+ - features/step_definitions/authorisation_steps.rb
280
+ - features/step_definitions/info_steps.rb
281
+ - features/step_definitions/repository_steps.rb
282
+ - features/step_definitions/running_steps.rb
283
+ - features/step_definitions/starting_steps.rb
284
+ - features/support/aruba.rb
285
+ - features/support/env.rb
286
+ - features/support/helpers/server_helper.rb
287
+ - features/support/hooks.rb
288
+ - features/support/pairzone-config.rb
289
+ - spec/pairzone/api/pairzone_lifecycle_spec.rb
290
+ - spec/pairzone/authentication_spec.rb
291
+ - spec/pairzone/logger_spec.rb
292
+ - spec/spec_helper.rb