pair 0.0.2 → 0.0.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.
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
6
+ - ree
7
+ - jruby
8
+ - rbx
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pair (0.0.1)
5
- httparty
4
+ pair (0.0.2)
5
+ httparty (~> 0.8.1)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
@@ -13,18 +13,20 @@ GEM
13
13
  multi_xml
14
14
  multi_json (1.0.3)
15
15
  multi_xml (0.4.1)
16
- rspec (2.3.0)
17
- rspec-core (~> 2.3.0)
18
- rspec-expectations (~> 2.3.0)
19
- rspec-mocks (~> 2.3.0)
20
- rspec-core (2.3.1)
21
- rspec-expectations (2.3.0)
16
+ rake (0.9.2.2)
17
+ rspec (2.7.0)
18
+ rspec-core (~> 2.7.0)
19
+ rspec-expectations (~> 2.7.0)
20
+ rspec-mocks (~> 2.7.0)
21
+ rspec-core (2.7.1)
22
+ rspec-expectations (2.7.0)
22
23
  diff-lcs (~> 1.1.2)
23
- rspec-mocks (2.3.0)
24
+ rspec-mocks (2.7.0)
24
25
 
25
26
  PLATFORMS
26
27
  ruby
27
28
 
28
29
  DEPENDENCIES
29
30
  pair!
30
- rspec (~> 2.3.0)
31
+ rake
32
+ rspec (~> 2.7.0)
@@ -11,15 +11,24 @@ Hosting Users:
11
11
  * Must have a variant of unix installed
12
12
  * Must have tmux installed
13
13
 
14
+ == Installation
15
+ Pair is available on {RubyGems}[http://rubygems.org/gems/pair]; the
16
+ easiest way to install it is
17
+
18
+ gem install pair
19
+
14
20
  == Example
15
21
 
16
- === Interactive hosted session
22
+ === Hosting an interactive session
23
+ In interactive mode, participants can interact with the tmux session.
17
24
 
18
- bin/pairmill host -p<github-user>,<github-user>,<github-user>
25
+ pair host -p<github-user>,<github-user>,<github-user>
19
26
 
20
- === Interactive hosted session
27
+ === Hosting a view-only session
28
+ In view mode, participants can see your tmux session but may not
29
+ interact with it.
21
30
 
22
- bin/pairmill host -v<github-user>,<github-user>,<github-user>
31
+ pair host -v<github-user>,<github-user>,<github-user>
23
32
 
24
33
  == Contributing to pair
25
34
 
data/bin/pair CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
- require "pair/command_line"
6
- Pair::CommandLine.run!(ARGV)
5
+ require "pair/cli"
6
+ Pair::Cli.run!(ARGV)
7
7
 
@@ -1,10 +1,9 @@
1
- require 'httparty'
2
- require 'ruby-debug' if ENV["DEBUGGER"] == "true"
1
+ module Pair
2
+ end
3
3
 
4
4
  require "pair/version"
5
+
6
+ require "pair/os"
7
+ require "pair/config"
5
8
  require "pair/api"
6
9
  require "pair/session"
7
-
8
- module Pair
9
- # Your code goes here...
10
- end
@@ -1,60 +1,39 @@
1
- require 'yaml'
1
+ require 'httparty'
2
+ require 'pair/config'
2
3
 
3
4
  module Pair
4
5
  module Api
5
- def create_session(session)
6
- post("/v1/sessions", {
7
- :body => {
8
- :session => {
9
- :name => session.name,
10
- :viewers => session.viewers,
11
- :participants => session.participants,
12
- :tunnel => {
13
- :host_login => session.host_login
14
- }
15
- }
16
- }
17
- })
18
- end
19
-
20
- def join_session(session)
21
- options = { :query => { :name => session.name, :host => session.host, :format => "json" } }
22
- get("/v1/sessions/search.json", options)
23
- end
6
+ include HTTParty
7
+ extend self
24
8
 
25
- def api_token
26
- config[:api_token]
9
+ def setup
10
+ base_uri ENV['BASE_URI'] || 'api.pairmill.com'
11
+ default_params :api_token => Pair.config.api_token
12
+ yield
27
13
  end
28
14
 
29
- def config
30
- @config ||= if File.exists?(config_file)
31
- YAML.load_file(config_file)[base_uri] || setup_config
32
- else
33
- setup_config
15
+ def create_session(session)
16
+ setup do
17
+ post("/v1/sessions", {
18
+ :body => {
19
+ :session => {
20
+ :name => session.name,
21
+ :viewers => session.viewers,
22
+ :participants => session.participants,
23
+ :tunnel => {
24
+ :host_login => session.host_login
25
+ }
26
+ }
27
+ }
28
+ })
34
29
  end
35
30
  end
36
31
 
37
- def config_file
38
- File.expand_path("~/.pair.yml")
39
- end
40
-
41
- def setup_config
42
- config = YAML.load_file(config_file) rescue {}
43
-
44
- print "Please input your API token for #{base_uri}: "
45
- config[base_uri] = {:api_token => $stdin.gets.chomp}
46
-
47
- File.open(config_file, 'w') do |f|
48
- f.write(YAML.dump(config))
32
+ def join_session(session)
33
+ setup do
34
+ options = { :query => { :name => session.name, :host => session.host, :format => "json" } }
35
+ get("/v1/sessions/search.json", options)
49
36
  end
50
-
51
- config[base_uri]
52
37
  end
53
-
54
- include HTTParty
55
- extend self
56
-
57
- base_uri ENV['BASE_URI'] || 'api.pairmill.com'
58
- default_params :api_token => api_token
59
38
  end
60
39
  end
@@ -1,8 +1,9 @@
1
1
  require "pair"
2
+ require 'pair/cli/custom_errors'
2
3
  require "optparse"
3
4
 
4
5
  module Pair
5
- class CommandLine
6
+ class Cli
6
7
  attr_accessor :arguments, :options
7
8
  private :arguments=, :options=
8
9
 
@@ -18,35 +19,44 @@ module Pair
18
19
  def run!
19
20
  case command = arguments.shift
20
21
  when 'host'
21
- require "pair/command_line/host"
22
+ require "pair/cli/host"
22
23
  Host.run!(arguments)
24
+ when 'config'
25
+ require "pair/cli/config"
26
+ Config.run!(arguments)
23
27
  else
24
28
  unknown_command(command)
25
29
  end
30
+ rescue ApiTokenMissingError, EnableSSHError => error
31
+ handle_error error.message, false
26
32
  rescue SystemExit
27
33
  raise
28
34
  rescue
29
- if $-d
35
+ handle_error " Please contact support@pairmill.com, there\n" +
36
+ " was an issue creating your session.", $-d
37
+ end
38
+
39
+ private
40
+ def handle_error message, reraise = true
41
+ if reraise
42
+ raise
43
+ else
30
44
  STDOUT.puts "\n"
31
- STDOUT.puts " Please contact support@pairmill.com, there"
32
- STDOUT.puts " was an issue creating your session."
45
+ STDOUT.puts message
33
46
  STDOUT.puts "\n"
34
- else
35
- raise
36
47
  end
37
48
  end
38
49
 
39
- private
40
50
  def unknown_command(command)
41
51
  puts "Unknown command: #{command}" if command
42
52
 
43
53
  #{$0} join [options]
44
54
  abort %Q[
45
- Usage: #{$0} host [options]
55
+ Usage: #{$0.split("/").last} host [options]
46
56
 
47
57
  You can pass -h to a subcommand to learn more about it.
48
58
 
49
- e.g. #{$0} join -h
59
+ e.g. #{$0.split("/").last} join -h
50
60
  ].gsub(/^ {0,9}/,'')
51
61
  end
52
62
 
@@ -0,0 +1,28 @@
1
+ module Pair
2
+ class Cli
3
+ class Config < self
4
+ def run!
5
+ parse!
6
+
7
+ Pair.config(options)
8
+ end
9
+
10
+ def parse!
11
+ opts = parse do |opts|
12
+ opts.banner = "Usage: #{$0.split("/").last} config" +
13
+ "\n\n" +
14
+ "Options:" +
15
+ "\n"
16
+
17
+ opts.on("--api-token KEY") do |key|
18
+ options[:api_token] = key
19
+ end
20
+
21
+ # opts.on("--enable-ssh") do
22
+ # options[:enable_ssh] = true
23
+ # end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ module Pair
2
+ class Cli
3
+ class ApiTokenMissingError < StandardError; end
4
+ class EnableSSHError < StandardError; end
5
+ end
6
+ end
@@ -1,16 +1,31 @@
1
- require "pair/command_line"
2
-
3
1
  module Pair
4
- class CommandLine
2
+ class Cli
5
3
  class Host < self
6
4
  def run!
7
5
  parse!
8
- Pair::Session.host(options)
6
+
7
+ with_valid_config do
8
+ Pair::Session.host(options)
9
+ end
10
+ end
11
+
12
+ def with_valid_config
13
+ config = Pair.config
14
+
15
+ unless config.api_token
16
+ raise ApiTokenMissingError.new("api-token is required. try --help to understand how")
17
+ end
18
+
19
+ unless config.ssh_enabled?
20
+ raise EnableSSHError.new("ssh is not enabled, turn on ssh daemon to continue")
21
+ end
22
+
23
+ yield
9
24
  end
10
25
 
11
26
  def parse!
12
27
  opts = parse do |opts|
13
- opts.banner = "Usage: #{$0} host [-s SESSION_NAME] [-v PAIR[,PAIR[,...]] [-p PAIR[,PAIR[,...]]" +
28
+ opts.banner = "Usage: #{$0.split("/").last} host [-s SESSION_NAME] [-v PAIR[,PAIR[,...]] [-p PAIR[,PAIR[,...]]" +
14
29
  "\n\n" +
15
30
  "At least one PAIR (of any type must be defined). A PAIR takes the form of a Github username." +
16
31
  "\n\n"+
@@ -0,0 +1,96 @@
1
+ require 'yaml/store'
2
+
3
+ module Pair
4
+ HOST = ENV['HOST'] || "api.pairmill.com"
5
+
6
+ def self.config(options = nil)
7
+ config = Config.new(HOST, STDIN, STDOUT)
8
+ config.update(options) if options
9
+ config
10
+ end
11
+
12
+ class Config
13
+ attr_accessor :host, :input, :output
14
+
15
+ def initialize(host = HOST, input = STDIN, output = STDOUT)
16
+ self.host = host
17
+ self.input = input
18
+ self.output = output
19
+ end
20
+
21
+ # def api_token
22
+ # self[:api_token] ||= begin
23
+ # print "Please input your API token for Pair: "
24
+ # gets.chomp
25
+ # end
26
+ # end
27
+
28
+ def method_missing(method, *args, &block)
29
+ method = method.to_s
30
+
31
+ if method =~ /=$/ # setter
32
+ self[method.gsub(/=$/,'').to_sym] = [*args].first
33
+ else
34
+ self[method.to_sym] || super
35
+ end
36
+ end
37
+
38
+ def api_token
39
+ self[:api_token]
40
+ end
41
+
42
+ def enable_ssh
43
+ self[:enable_ssh]
44
+ end
45
+
46
+ def ssh_enabled?
47
+ if Pair::OS.x?
48
+ `systemsetup -getremotelogin`.match("Remote Login: On")
49
+ end
50
+ end
51
+
52
+ def update(options = {})
53
+ if options.is_a? Hash
54
+ options.each do |k,v|
55
+ config.transaction do
56
+ host_config[k] = v
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ protected
63
+ def [](key)
64
+ config.transaction do
65
+ host_config[key]
66
+ end
67
+ end
68
+
69
+ def []=(key, value)
70
+ config.transaction do
71
+ host_config[key] = value
72
+ end
73
+ end
74
+
75
+ # Must be called within a config transaction
76
+ def host_config
77
+ config[host] ||= {}
78
+ end
79
+
80
+ def config
81
+ @config ||= YAML::Store.new(config_file)
82
+ end
83
+
84
+ def config_file
85
+ File.join(ENV['HOME'], ".pair.yml")
86
+ end
87
+
88
+ def print(*args)
89
+ output.print(*args)
90
+ end
91
+
92
+ def gets(*args)
93
+ input.gets(*args)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,13 @@
1
+ require 'rbconfig'
2
+
3
+ module Pair
4
+ module OS
5
+ def linux?
6
+ !RbConfig::CONFIG['target_os'].match("linux").nil?
7
+ end
8
+
9
+ def self.x?
10
+ !RbConfig::CONFIG['target_os'].match("darwin").nil?
11
+ end
12
+ end
13
+ end
@@ -9,8 +9,8 @@ module Pair
9
9
  attr_accessor :attach_command
10
10
  attr_accessor :key_file_path
11
11
 
12
- def initialize(member_keys = {}, attach_command)
13
- self.member_keys = member_keys
12
+ def initialize(member_keys, attach_command)
13
+ self.member_keys = member_keys || {}
14
14
  self.attach_command = attach_command
15
15
  self.key_file_path = File.expand_path("~/.ssh/authorized_keys")
16
16
  end
@@ -1,3 +1,3 @@
1
1
  module Pair
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -17,5 +17,6 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency("httparty", "~> 0.8.1")
19
19
 
20
- gem.add_development_dependency("rspec", "~> 2.3.0")
20
+ gem.add_development_dependency("rake")
21
+ gem.add_development_dependency("rspec", "~> 2.7.0")
21
22
  end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'pair/config'
4
+
5
+ describe Pair::Config do
6
+ let(:stdin) { StringIO.new }
7
+ let(:stdout) { StringIO.new }
8
+ let(:host) { "api.domain.com" }
9
+
10
+ let(:config) { described_class.new(host, stdin, stdout) }
11
+
12
+ before do
13
+ config_hash = {}
14
+ YAML::Store.stub!(:new => config_hash)
15
+ def config_hash.transaction
16
+ yield
17
+ end
18
+ end
19
+
20
+ context "for different hosts" do
21
+ it "has a different set of configs for each host" do
22
+ host1, host2 = "api.domain.com", "api.beta.domain.com"
23
+ config1 = described_class.new(host1)
24
+ config2 = described_class.new(host2)
25
+ config3 = described_class.new(host1)
26
+
27
+ config1.a_setting = "setting 1"
28
+ config2.a_setting = "setting 2"
29
+
30
+ config1.a_setting.should == "setting 1"
31
+ config3.a_setting.should == "setting 1"
32
+ config2.a_setting.should == "setting 2"
33
+ end
34
+ end
35
+
36
+ describe '#api_token' do
37
+ # context "when none is saved" do
38
+ # it "prompts for key to be entered" do
39
+ # response = "abc123"
40
+ # stdin << "#{response}\n"
41
+ # stdin.rewind
42
+ #
43
+ # config.api_token.should == response
44
+ #
45
+ # stdout.rewind
46
+ # stdout.read.should == "Please input your API token for Pair: "
47
+ # end
48
+ #
49
+ # it "saves the key" do
50
+ # stdin.should_receive(:gets).once.and_return("abc123\n")
51
+ # config.api_token
52
+ # config.api_token
53
+ # end
54
+ # end
55
+
56
+ context "when one is already saved" do
57
+ it "returns the saved value" do
58
+ api_token = "abc123"
59
+ config.api_token = api_token
60
+ config.api_token.should == api_token
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,5 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
+ require 'pair/session/authorized_keys_file'
3
4
  require 'fileutils'
4
5
 
5
6
  describe Pair::Session::AuthorizedKeysFile do
@@ -2,14 +2,17 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  require 'rspec'
5
- require 'json'
6
5
  require 'fixture_helper'
7
- require 'pair'
6
+
7
+ require 'pair/config'
8
8
 
9
9
  # Requires supporting files with custom matchers and macros, etc,
10
10
  # in ./support/ and its subdirectories.
11
11
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
12
12
 
13
13
  RSpec.configure do |config|
14
-
14
+ config.before do
15
+ # Never ask for API token in tests
16
+ Pair.stub!(:config => stub(:api_token => "xxxx"))
17
+ end
15
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pair
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,12 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-11-27 00:00:00.000000000Z
13
+ date: 2011-12-08 00:00:00.000000000 -06:00
14
+ default_executable:
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: httparty
17
- requirement: &70298620262940 !ruby/object:Gem::Requirement
18
+ requirement: &2157594700 !ruby/object:Gem::Requirement
18
19
  none: false
19
20
  requirements:
20
21
  - - ~>
@@ -22,18 +23,29 @@ dependencies:
22
23
  version: 0.8.1
23
24
  type: :runtime
24
25
  prerelease: false
25
- version_requirements: *70298620262940
26
+ version_requirements: *2157594700
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: &2157594280 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *2157594280
26
38
  - !ruby/object:Gem::Dependency
27
39
  name: rspec
28
- requirement: &70298620258860 !ruby/object:Gem::Requirement
40
+ requirement: &2157593740 !ruby/object:Gem::Requirement
29
41
  none: false
30
42
  requirements:
31
43
  - - ~>
32
44
  - !ruby/object:Gem::Version
33
- version: 2.3.0
45
+ version: 2.7.0
34
46
  type: :development
35
47
  prerelease: false
36
- version_requirements: *70298620258860
48
+ version_requirements: *2157593740
37
49
  description: Effortless remote pairing
38
50
  email:
39
51
  - me@bjeanes.com
@@ -46,6 +58,7 @@ files:
46
58
  - .gitignore
47
59
  - .rspec
48
60
  - .rvmrc
61
+ - .travis.yml
49
62
  - Gemfile
50
63
  - Gemfile.lock
51
64
  - README.rdoc
@@ -53,8 +66,12 @@ files:
53
66
  - bin/pair
54
67
  - lib/pair.rb
55
68
  - lib/pair/api.rb
56
- - lib/pair/command_line.rb
57
- - lib/pair/command_line/host.rb
69
+ - lib/pair/cli.rb
70
+ - lib/pair/cli/config.rb
71
+ - lib/pair/cli/custom_errors.rb
72
+ - lib/pair/cli/host.rb
73
+ - lib/pair/config.rb
74
+ - lib/pair/os.rb
58
75
  - lib/pair/session.rb
59
76
  - lib/pair/session/authorized_keys_file.rb
60
77
  - lib/pair/session/hosted_session.rb
@@ -66,8 +83,10 @@ files:
66
83
  - spec/fixtures/api_hosted_session.yml
67
84
  - spec/fixtures/api_joined_session.yml
68
85
  - spec/fixtures/user_keys.yml
86
+ - spec/pair/config_spec.rb
69
87
  - spec/pair/session/authorized_keys_file_spec.rb
70
88
  - spec/spec_helper.rb
89
+ has_rdoc: true
71
90
  homepage: http://www.pairmill.com
72
91
  licenses: []
73
92
  post_install_message:
@@ -88,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
107
  version: '0'
89
108
  requirements: []
90
109
  rubyforge_project:
91
- rubygems_version: 1.8.10
110
+ rubygems_version: 1.6.2
92
111
  signing_key:
93
112
  specification_version: 3
94
113
  summary: Pair with remote programmers with a single command.
@@ -97,5 +116,6 @@ test_files:
97
116
  - spec/fixtures/api_hosted_session.yml
98
117
  - spec/fixtures/api_joined_session.yml
99
118
  - spec/fixtures/user_keys.yml
119
+ - spec/pair/config_spec.rb
100
120
  - spec/pair/session/authorized_keys_file_spec.rb
101
121
  - spec/spec_helper.rb