phabulous 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 123536e2fdd3c7a7156dce6239e71b960076bffa
4
+ data.tar.gz: ea46d1c50117920babc2d73607131a071eb78b2e
5
+ SHA512:
6
+ metadata.gz: 85b60c0231cd49ffef2b6017dea747bbfeecf06d8cfbefba47794a0c8c3cb05d5939f58d63b2d7f21a4cadc05a444b1ee00785de542762b59c758a7fc033dfd5
7
+ data.tar.gz: 1a6bb16d43b57a3f378f8305510eef25f1996ddc90f97501c2b077309163428c9af6fc6c3b952e5c235fe77d09c58460878fdac0c3190862618009d651d6fd44
@@ -0,0 +1,20 @@
1
+ class String
2
+ def constantize
3
+ names = self.split('::')
4
+ names.shift if names.empty? || names.first.empty?
5
+
6
+ constant = Object
7
+ names.each do |name|
8
+ constant = constant.const_get(name, false) || constant.const_missing(name)
9
+ end
10
+ constant
11
+ end
12
+
13
+ def demodulize
14
+ if i = self.rindex('::')
15
+ self[(i+2)..-1]
16
+ else
17
+ self
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ require 'phabulous/version'
2
+ require 'phabulous/conduit'
3
+ require 'phabulous/configuration'
4
+
5
+ require 'phabulous/entity'
6
+ require 'phabulous/revision'
7
+ require 'phabulous/user'
8
+ require 'phabulous/feed'
9
+ require 'phabulous/paste'
10
+
11
+ require 'ext/string'
12
+
13
+ module Phabulous
14
+ def self.connect!
15
+ conduit.connect
16
+ end
17
+
18
+ def self.revisions
19
+ Revision
20
+ end
21
+
22
+ def self.users
23
+ User
24
+ end
25
+
26
+ def self.conduit
27
+ @conduit ||= Conduit::Client.new
28
+ end
29
+
30
+ def self.configure
31
+ yield configuration
32
+ end
33
+
34
+ def self.configuration
35
+ @configuration ||= Configuration.new
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ require 'phabulous/conduit/session'
2
+ require 'phabulous/conduit/client'
3
+
4
+ module Phabulous
5
+ module Conduit
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ require 'digest'
2
+ require 'httparty'
3
+
4
+ module Phabulous
5
+ module Conduit
6
+ class Client
7
+ include ::HTTParty
8
+
9
+ Error = Class.new(RuntimeError)
10
+
11
+ attr_accessor :host, :user, :cert, :token, :session
12
+
13
+ def initialize(_host = Phabulous.configuration.host,
14
+ _user = Phabulous.configuration.user, _cert = Phabulous.configuration.cert)
15
+ self.host = _host
16
+ self.user = _user
17
+ self.cert = _cert
18
+ self.session = nil
19
+ end
20
+
21
+ def ping
22
+ request('conduit.ping')
23
+ end
24
+
25
+ def connect
26
+ self.token = Time.now.to_i
27
+
28
+ if result = request('conduit.connect', connection_payload)
29
+ self.session = Conduit::Session.new(result['connectionID'], result['sessionKey'])
30
+ end
31
+
32
+ self.session
33
+ end
34
+
35
+ def request(method, data = {})
36
+ post_body = post_body(data)
37
+ response = self.class.post("#{self.host}/api/#{method}", body: post_body,
38
+ :headers => { 'Content-Type' => 'application/json' } )
39
+
40
+ if response.parsed_response['result']
41
+ response.parsed_response['result']
42
+ else
43
+ raise Error, "Conduit error: #{response.parsed_response['error_info']}"
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def post_body(data)
50
+ if session
51
+ data.merge!(__conduit__: self.session.to_hash)
52
+ end
53
+
54
+ { params: data.to_json, output: 'json' }
55
+ end
56
+
57
+ def connection_payload
58
+ {
59
+ 'client' => "phabulous gem",
60
+ 'clientVersion' => Phabulous::VERSION,
61
+ 'user' => self.user,
62
+ 'host' => self.host,
63
+ 'authToken' => self.token,
64
+ 'authSignature' => auth_signature,
65
+ }
66
+ end
67
+
68
+ def auth_signature
69
+ Digest::SHA1.hexdigest("#{self.token}#{self.cert}")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,16 @@
1
+ module Phabulous
2
+ module Conduit
3
+ class Session
4
+ attr_accessor :connection_id, :session_key
5
+
6
+ def initialize(_connection_id, _session_key)
7
+ self.connection_id = _connection_id
8
+ self.session_key = _session_key
9
+ end
10
+
11
+ def to_hash
12
+ { 'sessionKey' => self.session_key, 'connectionID' => self.connection_id }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Phabulous
2
+ class Configuration
3
+ attr_accessor :user, :host, :cert
4
+ end
5
+ end
@@ -0,0 +1,67 @@
1
+ module Phabulous
2
+ class Entity
3
+ def self.attr_accessor(*args)
4
+ @attributes ||= []
5
+ @attributes |= args
6
+ super(*args)
7
+ end
8
+
9
+ def self.attributes
10
+ @attributes
11
+ end
12
+
13
+ def self.all
14
+ @all ||= Phabulous.conduit.request("#{conduit_name}.query").collect do |attributes|
15
+ # Some conduit.query calls come back as plain arrays like
16
+ # [
17
+ # {
18
+ # attr: 1
19
+ # },
20
+ # {
21
+ # }
22
+ # ]
23
+ # as
24
+ # {
25
+ # phid => {
26
+ # attr1: x,
27
+ # ...
28
+ # },
29
+ # phid-2 => {
30
+ # attr2: y
31
+ # }
32
+ # }
33
+ #
34
+ # This code attempts to handle both cases
35
+ if attributes.length == 2 &&
36
+ attributes.first.is_a?(String) && attributes.first =~ /^PHID.*$/
37
+ new(attributes.last)
38
+ else
39
+ new(attributes)
40
+ end
41
+ end
42
+ end
43
+
44
+ def self.find(id)
45
+ all.select { |entity| entity.phid == id }.first
46
+ end
47
+
48
+ def initialize(attributes = {})
49
+ attributes.each do |attr, value|
50
+ send("#{attr}=", value) if respond_to?("#{attr}=")
51
+ end unless attributes.nil?
52
+ end
53
+
54
+ def attributes
55
+ self.class.attributes.inject({}) do |memo, attr|
56
+ memo[attr] = send(attr) if respond_to?(attr)
57
+ memo
58
+ end if self.class.attributes
59
+ end
60
+
61
+ attr_accessor :phid
62
+
63
+ def self.conduit_name
64
+ name.demodulize.downcase
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Phabulous
3
+ class Feed < Entity
4
+ attr_accessor :authorPHID, :data, :storyType, :storyText
5
+
6
+ alias :storyAuthorPHID= :authorPHID=
7
+ alias :storyData= :data=
8
+ alias :text= :storyText=
9
+
10
+ alias :text :storyText
11
+ alias :type :storyType
12
+
13
+ def author
14
+ User.find(self.authorPHID)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require 'uri'
2
+
3
+ module Phabulous
4
+ class Paste < Entity
5
+ attr_accessor :id, :content, :authorPHID, :uri
6
+
7
+ def author
8
+ User.find(@authorPHID)
9
+ end
10
+
11
+ def uri
12
+ URI.parse(@uri)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ require 'uri'
2
+
3
+ module Phabulous
4
+ class Revision < Entity
5
+ attr_accessor :id, :title, :uri, :dateModified, :authorPHID,
6
+ :reviewers, :statusName, :lineCount, :summary, :statusName
7
+
8
+ def status
9
+ @statusName
10
+ end
11
+
12
+ def uri
13
+ URI.parse(@uri)
14
+ end
15
+
16
+ def dateModified
17
+ Time.at(@dateModified.to_i)
18
+ end
19
+
20
+ def author
21
+ User.find(@authorPHID)
22
+ end
23
+
24
+ def differential_id
25
+ "D#{id}"
26
+ end
27
+
28
+ def reviewers
29
+ @reviewers.collect { |reviewier| User.find(reviewier) }
30
+ end
31
+
32
+ protected
33
+
34
+ def self.conduit_name
35
+ 'differential'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ require 'uri'
2
+
3
+ module Phabulous
4
+ class User < Entity
5
+ attr_accessor :title, :uri, :dateModified,
6
+ :authorPHID, :image, :roles, :userName, :realName
7
+
8
+ def id
9
+ @phid
10
+ end
11
+
12
+ def name
13
+ @userName
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Phabulous
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ describe 'demodulize' do
5
+ it 'removes the module names from a string' do
6
+ expect('Test::Test'.demodulize).to eq('Test')
7
+ end
8
+ end
9
+
10
+ describe 'constantize' do
11
+ it 'creates a constant from a string' do
12
+ expect('Object'.constantize).to be_a(Object)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,163 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ module Conduit
5
+ describe Client do
6
+ describe 'auth_signature' do
7
+ before do
8
+ @client = Conduit::Client.new
9
+ end
10
+
11
+ it 'is the sha1 digest of the conduit token and cert' do
12
+ expect(@client).to receive(:token).and_return('token')
13
+ expect(@client).to receive(:cert).and_return('cert')
14
+
15
+ # sha1(tokencert)
16
+ # => 29ee2e11163771d305e17e3b3bbde765673f7fd8
17
+ expect(@client.send(:auth_signature)).to eq('29ee2e11163771d305e17e3b3bbde765673f7fd8')
18
+ end
19
+ end
20
+
21
+ describe 'connection_payload' do
22
+ before do
23
+ @client = Conduit::Client.new
24
+ end
25
+
26
+ it 'has a conduit name' do
27
+ expect(@client.send(:connection_payload)['client']).to be
28
+ end
29
+
30
+ it 'has a conduit version' do
31
+ expect(@client.send(:connection_payload)['clientVersion']).to be
32
+ end
33
+
34
+ it 'has a user' do
35
+ expect(@client.send(:connection_payload)['user']).to be
36
+ end
37
+
38
+ it 'has a host' do
39
+ expect(@client.send(:connection_payload)['host']).to be
40
+ end
41
+
42
+ it 'has a authToken' do
43
+ expect(@client).to receive(:token).twice.and_return('token')
44
+
45
+ expect(@client.send(:connection_payload)['authToken']).to be
46
+ end
47
+
48
+ it 'has a authSignature' do
49
+ expect(@client.send(:connection_payload)['authSignature']).to be
50
+ end
51
+ end
52
+
53
+ describe 'ping' do
54
+ it 'raises an error on an unsucessful ping' do
55
+ client = Conduit::Client.new(test_phabricator_host, 'fake', 'fake')
56
+
57
+ expect {
58
+ VCR.use_cassette('raises_conduit_errors_on_ping') do
59
+ client.connect
60
+ client.ping
61
+ end
62
+ }.to raise_exception(Client::Error)
63
+ end
64
+
65
+ it 'pings conduit' do
66
+ client = Conduit::Client.new
67
+
68
+ result = VCR.use_cassette('should_ping_conduit') do
69
+ client.connect
70
+ client.ping
71
+ end
72
+
73
+ expect(result).to be_a(String)
74
+ end
75
+ end
76
+
77
+ describe '#connect' do
78
+ before do
79
+ @client = Conduit::Client.new
80
+ end
81
+
82
+ it 'should set the session' do
83
+ VCR.use_cassette('should_set_the_session') do
84
+ @client.connect
85
+ end
86
+
87
+ expect(@client.session).to be_a(Session)
88
+ end
89
+
90
+ it 'sets the token' do
91
+ # not tested here, stub it
92
+ expect(@client).to receive(:request)
93
+
94
+ @client.connect
95
+
96
+ expect(@client.token).to be
97
+ end
98
+
99
+ it 'connects with the connection payload' do
100
+ fake_connection_payload = double
101
+
102
+ expect(@client).to receive(:connection_payload).and_return(fake_connection_payload)
103
+
104
+ expect(@client).to receive(:request).with('conduit.connect',
105
+ fake_connection_payload)
106
+
107
+ @client.connect
108
+ end
109
+ end
110
+
111
+ describe 'post_body' do
112
+ it 'does not include session if session is nil' do
113
+ client = Conduit::Client.new('url', test_phabricator_user, 'key')
114
+ data_to_sign = {a: 1}
115
+
116
+ session = nil
117
+ expect(client).to receive(:session).and_return(session)
118
+
119
+ signed_data = client.send(:post_body, data_to_sign)
120
+
121
+ expect(signed_data).to eq({:params=>"{\"a\":1}", :output=>"json"})
122
+ end
123
+
124
+ it 'signs the request data with the session if the session exists' do
125
+ client = Conduit::Client.new('url', test_phabricator_user, 'key')
126
+ data_to_sign = {a: 1}
127
+
128
+ session = double('session',
129
+ to_hash: {sessionKey: 'x', connectionID: 1})
130
+
131
+ expect(client).to receive(:session).twice.and_return(session)
132
+
133
+ signed_data = client.send(:post_body, data_to_sign)
134
+
135
+ expect(signed_data).to eq({:params=>"{\"a\":1,\"__conduit__\":{\"sessionKey\":\"x\",\"connectionID\":1}}", :output=>"json"})
136
+ end
137
+ end
138
+
139
+ describe '#request' do
140
+ it 'raises errors when conduit erorrs' do
141
+ client = Conduit::Client.new(test_phabricator_host, 'fake', 'fake_cert')
142
+
143
+ expect {
144
+ VCR.use_cassette('raises_conduit_errors') do
145
+ client.request('conduit.connect')
146
+ end
147
+ }.to raise_exception(Client::Error)
148
+ end
149
+
150
+ it 'can make authorized requests' do
151
+ client = Conduit::Client.new
152
+
153
+ VCR.use_cassette('can_make_authorized_requests') do
154
+ client.connect
155
+
156
+ results = client.request('differential.query', ids: [1])
157
+ expect(results).to eq([])
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ module Conduit
5
+ describe Session do
6
+ before do
7
+ @connection_id = 1
8
+ @session_key = SecureRandom.uuid
9
+ @session = Session.new(@connection_id, @session_key)
10
+ end
11
+
12
+ it 'creates a session from a connection id and session key' do
13
+ expect(@session.session_key).to eq(@session_key)
14
+ expect(@session.connection_id).to eq(@connection_id)
15
+ end
16
+
17
+ it 'can be represented as a hash' do
18
+ expect(@session.to_hash).to eq({
19
+ 'sessionKey' => @session_key,
20
+ 'connectionID' => @connection_id
21
+ })
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ describe Configuration do
5
+ before do
6
+ @config = Configuration.new
7
+ end
8
+
9
+ it 'allows user configuration' do
10
+ @config.user = 'user'
11
+ expect(@config.user).to eq('user')
12
+ end
13
+
14
+ it 'allows host configuration' do
15
+ @config.host = 'host'
16
+ expect(@config.host).to eq('host')
17
+ end
18
+
19
+ it 'allows cert configuration' do
20
+ @config.cert = 'cert'
21
+ expect(@config.cert).to eq('cert')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ describe Revision do
5
+
6
+ describe 'uri' do
7
+ before do
8
+ @diff = Revision.new(uri: 'http://google.com')
9
+ end
10
+
11
+ it 'returns a uri object' do
12
+ expect(@diff.uri).to be_a(URI)
13
+ end
14
+ end
15
+
16
+ describe 'dateModified' do
17
+ before do
18
+ @time = Time.now.to_i
19
+ @diff = Revision.new(dateModified: @time.to_s)
20
+ end
21
+
22
+ it 'returns a time object' do
23
+ expect(@diff.dateModified).to be_a(Time)
24
+ end
25
+
26
+ end
27
+
28
+ describe 'author' do
29
+ it 'returns a user object' do
30
+ id = 'id'
31
+ diff = Revision.new(authorPHID: id)
32
+
33
+ user = double
34
+ expect(User).to receive(:find).with(id).and_return(user)
35
+
36
+ expect(diff.author).to equal(user)
37
+ end
38
+ end
39
+
40
+ describe 'differential_id' do
41
+ it 'returns the full differential id' do
42
+ @diff = Revision.new(id: 1)
43
+
44
+ expect(@diff.differential_id).to eq('D1')
45
+ end
46
+ end
47
+
48
+ describe 'reviewers' do
49
+ before do
50
+ @reviewer_id = 1
51
+
52
+ @diff = Revision.new(reviewers: [
53
+ @reviewer_id
54
+ ])
55
+ end
56
+
57
+ it 'returns an array of user objects' do
58
+ user = double
59
+ expect(User).to receive(:find).with(@reviewer_id).and_return(user)
60
+
61
+ expect(@diff.reviewers.first).to equal(user)
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ describe Entity do
5
+
6
+ before do
7
+ class FakeEntity < Entity
8
+ attr_accessor :hi, :x
9
+ end
10
+ end
11
+
12
+ it 'sets attributes on instantiation' do
13
+ fake_model = FakeEntity.new(hi: 'hi')
14
+
15
+ expect(fake_model.hi).to eq('hi')
16
+ end
17
+
18
+ it 'tracks class attribute names' do
19
+ expect(FakeEntity.attributes).to eq([:hi, :x])
20
+ end
21
+
22
+ it 'has an attribues hash of attribute names and their values' do
23
+ fake_model = FakeEntity.new(hi: 'test')
24
+
25
+ expect(fake_model.attributes).to eq({hi: 'test', x: nil})
26
+ end
27
+
28
+ describe 'conduit_name' do
29
+ it 'defaults to the class name' do
30
+ expect(Entity.conduit_name).to eq('entity')
31
+ end
32
+ end
33
+
34
+ describe 'find' do
35
+ it 'finds an entity by id' do
36
+ model = FakeEntity.new(phid: 1)
37
+ expect(FakeEntity).to receive(:all).and_return([model])
38
+
39
+ expect(FakeEntity.find(1)).to eq(model)
40
+ end
41
+ end
42
+
43
+ describe 'all' do
44
+ before do
45
+ FakeEntity.instance_variable_set(:@all, nil)
46
+ end
47
+
48
+ it 'queries conduit and returns all found entities' do
49
+ attributes = [
50
+ {
51
+ x: 1,
52
+ hi: 1
53
+ },
54
+ {
55
+ x: 2,
56
+ hi: 2
57
+ }
58
+ ]
59
+
60
+ expect(Phabulous.conduit).to receive(:request).and_return(attributes)
61
+
62
+ expect(FakeEntity.all.collect(&:attributes)).to eq([{
63
+ x: 1,
64
+ hi: 1
65
+ },{
66
+ x: 2,
67
+ hi: 2
68
+ }])
69
+ end
70
+
71
+ it 'supports both response types from conduit' do
72
+ attributes = {
73
+ "PHID-1" => {
74
+ x: 1,
75
+ hi: 1
76
+ },
77
+ "PHID-2" => {
78
+ x: 2,
79
+ hi: 2
80
+ }
81
+ }
82
+
83
+ expect(Phabulous.conduit).to receive(:request).and_return(attributes)
84
+
85
+ expect(FakeEntity.all.collect(&:attributes)).to eq([{
86
+ x: 1,
87
+ hi: 1
88
+ },{
89
+ x: 2,
90
+ hi: 2
91
+ }])
92
+ end
93
+ end
94
+ end
95
+ end
96
+
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ describe Feed do
5
+
6
+ describe 'author' do
7
+ it 'returns an author object' do
8
+
9
+ end
10
+ end
11
+
12
+ describe 'entity' do
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ module Phabulous
4
+ describe User do
5
+ it 'uses the phid as the id' do
6
+ user = User.new(phid: 123)
7
+
8
+ expect(user.id).to eq(123)
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Phabulous do
4
+ it 'has a version number' do
5
+ expect(Phabulous::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'is configurable' do
9
+ Phabulous.configure do |config|
10
+ config.host = 'config_host_test'
11
+ config.user = 'config_user_test'
12
+ config.cert = 'config_cert_test'
13
+ end
14
+
15
+ expect(Phabulous.configuration.host).to eq('config_host_test')
16
+ expect(Phabulous.configuration.user).to eq('config_user_test')
17
+ expect(Phabulous.configuration.cert).to eq('config_cert_test')
18
+ end
19
+
20
+ it 'has a conduit client instance' do
21
+ expect(Phabulous.conduit).to be_a(Phabulous::Conduit::Client)
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phabulous
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Taylor Finnell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: httparty
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.13'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.13'
111
+ description: Provides access to Phabricator
112
+ email:
113
+ - tmfinnell@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - lib/ext/string.rb
119
+ - lib/phabulous.rb
120
+ - lib/phabulous/conduit.rb
121
+ - lib/phabulous/conduit/client.rb
122
+ - lib/phabulous/conduit/session.rb
123
+ - lib/phabulous/configuration.rb
124
+ - lib/phabulous/entity.rb
125
+ - lib/phabulous/feed.rb
126
+ - lib/phabulous/paste.rb
127
+ - lib/phabulous/revision.rb
128
+ - lib/phabulous/user.rb
129
+ - lib/phabulous/version.rb
130
+ - spec/ext/string_spec.rb
131
+ - spec/lib/phabulous/conduit/client_spec.rb
132
+ - spec/lib/phabulous/conduit/session_spec.rb
133
+ - spec/lib/phabulous/configuration_spec.rb
134
+ - spec/lib/phabulous/differential_spec.rb
135
+ - spec/lib/phabulous/entity_spec.rb
136
+ - spec/lib/phabulous/feed_spec.rb
137
+ - spec/lib/phabulous/user_spec.rb
138
+ - spec/lib/phabulous_spec.rb
139
+ homepage: http://github.com/taylorfinnell/phabulous
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.4.5
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Provides access to Phabricator
163
+ test_files:
164
+ - spec/ext/string_spec.rb
165
+ - spec/lib/phabulous/conduit/client_spec.rb
166
+ - spec/lib/phabulous/conduit/session_spec.rb
167
+ - spec/lib/phabulous/configuration_spec.rb
168
+ - spec/lib/phabulous/differential_spec.rb
169
+ - spec/lib/phabulous/entity_spec.rb
170
+ - spec/lib/phabulous/feed_spec.rb
171
+ - spec/lib/phabulous/user_spec.rb
172
+ - spec/lib/phabulous_spec.rb
173
+ has_rdoc: