xway 0.0.1.alpha → 0.0.1.beta
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.
- data/.coveralls.yml +1 -0
- data/.travis.yml +3 -0
- data/README.md +16 -0
- data/Rakefile +6 -1
- data/bin/xway +1 -1
- data/lib/xway.rb +8 -2
- data/lib/xway/api.rb +25 -0
- data/lib/xway/api/endpoints.rb +45 -0
- data/lib/xway/api/http.rb +17 -0
- data/lib/xway/api/request.rb +37 -0
- data/lib/xway/api/request/body.rb +41 -0
- data/lib/xway/cli.rb +19 -0
- data/lib/xway/error.rb +7 -0
- data/lib/xway/parameter.rb +68 -0
- data/lib/xway/version.rb +1 -1
- data/spec/assets/appway-example.json +21 -0
- data/spec/assets/custom.xway +1 -0
- data/spec/integration/bin/xway_binary_spec.rb +18 -0
- data/spec/integration/lib/xway/cli_spec.rb +9 -0
- data/spec/lib/xway/api/endpoints_spec.rb +89 -0
- data/spec/lib/xway/api/http_spec.rb +35 -0
- data/spec/lib/xway/api/request/body_spec.rb +42 -0
- data/spec/lib/xway/api/request_spec.rb +22 -0
- data/spec/lib/xway/api_spec.rb +90 -0
- data/spec/lib/xway/cli_spec.rb +34 -0
- data/spec/lib/xway/error_spec.rb +6 -0
- data/spec/lib/xway/parameter_spec.rb +122 -0
- data/spec/lib/xway_spec.rb +6 -0
- data/spec/spec_helper.rb +11 -0
- data/xway.gemspec +7 -2
- metadata +104 -6
- data/spec/bin/xway_spec.rb +0 -10
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
[appway](http://github.com/threez/appway) client written in ruby
|
4
4
|
|
5
|
+
[](https://rubygems.org/gems/xway)
|
6
|
+
[](https://travis-ci.org/dpree/xway)
|
7
|
+
[](https://coveralls.io/r/dpree/xway)
|
8
|
+
[](https://gemnasium.com/dpree/xway)
|
9
|
+
[](https://codeclimate.com/github/dpree/xway)
|
10
|
+
|
5
11
|
## Installation
|
6
12
|
|
7
13
|
Add this line to your application's Gemfile:
|
@@ -28,6 +34,16 @@ Or install it yourself as:
|
|
28
34
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
35
|
5. Create new Pull Request
|
30
36
|
|
37
|
+
### Coding guide
|
38
|
+
|
39
|
+
* Using global methods like `Xway.parameter`
|
40
|
+
* is allowed for classes / modules defined on the same or a higher level to the `Xway` namespace
|
41
|
+
* is allowed for classes / modules defined excactly one level below the `Xway` namespace
|
42
|
+
* e.g. `Xway::Api`
|
43
|
+
* is not allowed for classes / modules defined more than one level below the `Xway` namespace
|
44
|
+
* e.g. `Xway::Api::Request`
|
45
|
+
* these classes should use dependency injection instead
|
46
|
+
|
31
47
|
# License
|
32
48
|
|
33
49
|
Copyright (c) 2013 Jens Bissinger. See [LICENSE.txt](LICENSE.txt)
|
data/Rakefile
CHANGED
data/bin/xway
CHANGED
data/lib/xway.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'xway/version'
|
2
|
+
require 'xway/error'
|
3
|
+
require 'xway/parameter'
|
4
|
+
require 'xway/api'
|
5
|
+
require 'xway/cli'
|
2
6
|
|
3
7
|
module Xway
|
4
|
-
|
8
|
+
def self.parameter
|
9
|
+
@parameter ||= Parameter.new.reload!
|
10
|
+
end
|
5
11
|
end
|
data/lib/xway/api.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'xway/api/request'
|
2
|
+
require 'xway/api/endpoints'
|
3
|
+
require 'xway/api/http'
|
4
|
+
|
5
|
+
module Xway
|
6
|
+
class Api
|
7
|
+
def request method_name, *args, &block
|
8
|
+
http = Http.new
|
9
|
+
request = build_request method_name
|
10
|
+
parameter[:servers].map do |server|
|
11
|
+
http.request server, request, parameter[:debug]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def parameter
|
18
|
+
Xway.parameter
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_request method_name
|
22
|
+
Endpoints.new.send(method_name, parameter[:app] || {})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Xway
|
2
|
+
class Api
|
3
|
+
class Endpoints
|
4
|
+
def list options={}
|
5
|
+
Request.new 'get', '/applications'
|
6
|
+
end
|
7
|
+
|
8
|
+
def create options={}
|
9
|
+
Request.new 'post', '/applications', options
|
10
|
+
end
|
11
|
+
|
12
|
+
def find options={app: ':name'}
|
13
|
+
Request.new 'get', "/applications/#{options[:app]}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def update options={app: ':name'}
|
17
|
+
Request.new 'put', "/applications/#{options[:app]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete options={app: ':name'}
|
21
|
+
Request.new 'delete', "/applications/#{options[:app]}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def log options={app: ':name'}
|
25
|
+
Request.new 'get', "/applications/#{options[:app]}/log"
|
26
|
+
end
|
27
|
+
|
28
|
+
def start options={app: ':name'}
|
29
|
+
Request.new 'post', "/applications/#{options[:app]}/start"
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop options={app: ':name'}
|
33
|
+
Request.new 'post', "/applications/#{options[:app]}/stop"
|
34
|
+
end
|
35
|
+
|
36
|
+
def restart options={app: ':name'}
|
37
|
+
Request.new 'post', "/applications/#{options[:app]}/restart"
|
38
|
+
end
|
39
|
+
|
40
|
+
def redeploy options={app: ':name'}
|
41
|
+
Request.new 'post', "/applications/#{options[:app]}/redeploy"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Xway
|
4
|
+
class Api
|
5
|
+
class Http
|
6
|
+
def request server, request, debug=false
|
7
|
+
uri = File.join(server, request.path)
|
8
|
+
http_options = request.http_options.tap do |http_options|
|
9
|
+
http_options[:debug_output] = STDOUT if debug
|
10
|
+
end
|
11
|
+
HTTParty.send(request.method_name, uri, http_options)
|
12
|
+
rescue => e
|
13
|
+
raise Error, ["#{server} appears offline", e]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'xway/api/request/body'
|
2
|
+
|
3
|
+
module Xway
|
4
|
+
class Api
|
5
|
+
class Request
|
6
|
+
attr_reader :method_name, :path, :headers, :body
|
7
|
+
|
8
|
+
def initialize method_name, path, options={}
|
9
|
+
@method_name = method_name
|
10
|
+
@path = path
|
11
|
+
@options = options
|
12
|
+
@body = build_body
|
13
|
+
@headers = build_headers
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_headers
|
17
|
+
{'X-App' => 'appway'}.tap do |headers|
|
18
|
+
headers['Content-Type'] = body.mime_type if body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_body
|
23
|
+
if path = @options[:manifest]
|
24
|
+
@body = Body.new path
|
25
|
+
else
|
26
|
+
@body = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def http_options
|
31
|
+
http_options = {headers: headers}.tap do |http_options|
|
32
|
+
http_options[:body] = body.read if body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Xway
|
2
|
+
class Api
|
3
|
+
class Request
|
4
|
+
class Body
|
5
|
+
attr_reader :path
|
6
|
+
|
7
|
+
def initialize path
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
def read
|
12
|
+
check_type do |extname|
|
13
|
+
if File.exists?(path)
|
14
|
+
File.read(path)
|
15
|
+
else
|
16
|
+
raise ManifestFileNotFound, "could not find file #{path}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def mime_type
|
22
|
+
check_type do |extname|
|
23
|
+
'application/json'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def check_type
|
30
|
+
extname = File.extname(path)
|
31
|
+
if extname == '.json'
|
32
|
+
yield extname
|
33
|
+
else
|
34
|
+
raise ManifestFileTypeUnsupported, \
|
35
|
+
"unsupported extension #{extname} for #{path}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/xway/cli.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Xway
|
2
|
+
class Cli
|
3
|
+
def initialize api=Api.new, out=STDOUT
|
4
|
+
@api = api
|
5
|
+
@out = out
|
6
|
+
end
|
7
|
+
|
8
|
+
def start
|
9
|
+
commands = Xway.parameter.rest
|
10
|
+
if Xway.parameter[:version]
|
11
|
+
@out.puts "xway #{VERSION}"
|
12
|
+
elsif commands.empty?
|
13
|
+
Xway.parameter.print_help!
|
14
|
+
else
|
15
|
+
@out.puts @api.request(*commands)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/xway/error.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'configliere'
|
2
|
+
|
3
|
+
module Xway
|
4
|
+
class Parameter
|
5
|
+
def reload!
|
6
|
+
@param = Configliere::Param.new
|
7
|
+
@param.define :servers, type: Array,
|
8
|
+
flag: 's',
|
9
|
+
description: 'all appway servers',
|
10
|
+
default: ['http://localhost:8000']
|
11
|
+
@param.define 'app.name', type: String,
|
12
|
+
flag: 'a',
|
13
|
+
description: 'name of your app'
|
14
|
+
@param.define 'app.manifest', type: String,
|
15
|
+
flag: 'm',
|
16
|
+
description: 'path to your app.way file'
|
17
|
+
@param.define :debug, flag: 'd',
|
18
|
+
description: 'print debug info to stdout',
|
19
|
+
default: false
|
20
|
+
@param.define :version, flag: 'v',
|
21
|
+
description: 'print version info'
|
22
|
+
@param.read global_config if File.exists? global_config
|
23
|
+
@param.read local_config if File.exists? local_config
|
24
|
+
@param.use(:commandline)
|
25
|
+
@param.resolve!
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def print_help!
|
30
|
+
reload!
|
31
|
+
@param[:help] = true
|
32
|
+
@param.resolve!
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def [] key
|
37
|
+
if @param
|
38
|
+
@param[key]
|
39
|
+
else
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def rest
|
45
|
+
if @param
|
46
|
+
@param.rest
|
47
|
+
else
|
48
|
+
[]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_hash
|
53
|
+
if @param
|
54
|
+
@param.to_hash
|
55
|
+
else
|
56
|
+
{}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def global_config
|
61
|
+
ENV['XWAY_CONFIG'] || File.join(ENV['HOME'], '.xway')
|
62
|
+
end
|
63
|
+
|
64
|
+
def local_config
|
65
|
+
File.join(Dir.pwd, '.xway')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/xway/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"name": "example",
|
3
|
+
"repo": {
|
4
|
+
"url": "git://github.com/threez/appway-example.git",
|
5
|
+
"branch": "master"
|
6
|
+
},
|
7
|
+
"packages": {
|
8
|
+
},
|
9
|
+
"user": "www-data",
|
10
|
+
"group": "www-data",
|
11
|
+
"domain": [
|
12
|
+
"^example.*",
|
13
|
+
"^example.local$"
|
14
|
+
],
|
15
|
+
"install": [
|
16
|
+
"npm install"
|
17
|
+
],
|
18
|
+
"scale": {
|
19
|
+
"web": 2
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
foo: bar
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'open3'
|
3
|
+
require 'xway/version'
|
4
|
+
|
5
|
+
class XwayBinary
|
6
|
+
attr_reader :stdin, :stdout, :stderr
|
7
|
+
def run
|
8
|
+
exe = File.expand_path('../../../bin/xway', File.dirname(__FILE__))
|
9
|
+
ENV['RUBYLIB'] = File.join(File.dirname(__FILE__), '../../../lib')
|
10
|
+
@stdin, @stdout, @stderr = Open3.popen3("#{exe} --version")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe XwayBinary do
|
15
|
+
before { subject.run }
|
16
|
+
its('stderr.readlines.to_s') { should_not include('xway') }
|
17
|
+
its('stdout.readlines.to_s') { should include(Xway::VERSION) }
|
18
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/api/endpoints'
|
3
|
+
require 'xway/api/request'
|
4
|
+
|
5
|
+
describe Xway::Api::Endpoints do
|
6
|
+
subject('endpoints') { described_class.new }
|
7
|
+
|
8
|
+
describe 'list' do
|
9
|
+
subject { endpoints.list({}) }
|
10
|
+
its('method_name') { should eq 'get' }
|
11
|
+
its('path') { should eq '/applications' }
|
12
|
+
its('headers') { should eq('X-App' => 'appway') }
|
13
|
+
its('body') { should eq(nil) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'create' do
|
17
|
+
let('manifest') { File.join(ASSETS_PATH, 'appway-example.json') }
|
18
|
+
subject { endpoints.create manifest: manifest }
|
19
|
+
its('method_name') { should eq 'post' }
|
20
|
+
its('path') { should eq '/applications' }
|
21
|
+
its('headers') { should eq('X-App' => 'appway',
|
22
|
+
'Content-Type' => 'application/json') }
|
23
|
+
its('body') { should be_kind_of(Xway::Api::Request::Body) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'find' do
|
27
|
+
subject { endpoints.find app: 'foo' }
|
28
|
+
its('method_name') { should eq 'get' }
|
29
|
+
its('path') { should eq '/applications/foo' }
|
30
|
+
its('headers') { should eq('X-App' => 'appway') }
|
31
|
+
its('body') { should eq(nil) }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'update' do
|
35
|
+
subject { endpoints.update app: 'foo' }
|
36
|
+
its('method_name') { should eq 'put' }
|
37
|
+
its('path') { should eq '/applications/foo' }
|
38
|
+
its('headers') { should eq('X-App' => 'appway') }
|
39
|
+
its('body') { should eq(nil) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'delete' do
|
43
|
+
subject { endpoints.delete app: 'foo' }
|
44
|
+
its('method_name') { should eq 'delete' }
|
45
|
+
its('path') { should eq '/applications/foo' }
|
46
|
+
its('headers') { should eq('X-App' => 'appway') }
|
47
|
+
its('body') { should eq(nil) }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'log' do
|
51
|
+
subject { endpoints.log app: 'foo' }
|
52
|
+
its('method_name') { should eq 'get' }
|
53
|
+
its('path') { should eq '/applications/foo/log' }
|
54
|
+
its('headers') { should eq('X-App' => 'appway') }
|
55
|
+
its('body') { should eq(nil) }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'start' do
|
59
|
+
subject { endpoints.start app: 'foo' }
|
60
|
+
its('method_name') { should eq 'post' }
|
61
|
+
its('path') { should eq '/applications/foo/start' }
|
62
|
+
its('headers') { should eq('X-App' => 'appway') }
|
63
|
+
its('body') { should eq(nil) }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'stop' do
|
67
|
+
subject { endpoints.stop app: 'foo' }
|
68
|
+
its('method_name') { should eq 'post' }
|
69
|
+
its('path') { should eq '/applications/foo/stop' }
|
70
|
+
its('headers') { should eq('X-App' => 'appway') }
|
71
|
+
its('body') { should eq(nil) }
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'restart' do
|
75
|
+
subject { endpoints.restart app: 'foo' }
|
76
|
+
its('method_name') { should eq 'post' }
|
77
|
+
its('path') { should eq '/applications/foo/restart' }
|
78
|
+
its('headers') { should eq('X-App' => 'appway') }
|
79
|
+
its('body') { should eq(nil) }
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'redeploy' do
|
83
|
+
subject { endpoints.redeploy app: 'foo' }
|
84
|
+
its('method_name') { should eq 'post' }
|
85
|
+
its('path') { should eq '/applications/foo/redeploy' }
|
86
|
+
its('headers') { should eq('X-App' => 'appway') }
|
87
|
+
its('body') { should eq(nil) }
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/api/http'
|
3
|
+
require 'xway/error'
|
4
|
+
|
5
|
+
describe Xway::Api::Http do
|
6
|
+
let('headers') { {'X-App' => 'appway'} }
|
7
|
+
let('request') do
|
8
|
+
double('Xway::Api::Request').tap do |mock|
|
9
|
+
mock.stub('method_name').and_return('get')
|
10
|
+
mock.stub('path').and_return('/bar')
|
11
|
+
mock.stub('http_options').and_return(headers: headers)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'wraps errors' do
|
16
|
+
HTTParty.stub('get') { raise StandardError, 'foo' }
|
17
|
+
expect { subject.request 'http://foo', request }.to\
|
18
|
+
raise_error(Xway::Error)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'calls HTTParty' do
|
22
|
+
it do
|
23
|
+
HTTParty.should_receive('get').with('http://foo/bar',
|
24
|
+
headers: headers)
|
25
|
+
subject.request 'http://foo', request
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'includes debug flag' do
|
29
|
+
HTTParty.should_receive('get').with('http://foo/bar',
|
30
|
+
headers: headers,
|
31
|
+
debug_output: STDOUT)
|
32
|
+
subject.request 'http://foo', request, true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/error'
|
3
|
+
require 'xway/api/request/body'
|
4
|
+
|
5
|
+
describe Xway::Api::Request::Body do
|
6
|
+
context 'unknown file type' do
|
7
|
+
let('path') { 'foo/bar' }
|
8
|
+
before do
|
9
|
+
File.stub('exists?').with(path).and_return(true)
|
10
|
+
end
|
11
|
+
subject { described_class.new path }
|
12
|
+
|
13
|
+
its('path') { should eq path }
|
14
|
+
it { expect{subject.mime_type}.to raise_error(Xway::ManifestFileTypeUnsupported) }
|
15
|
+
it { expect{subject.read}.to raise_error(Xway::ManifestFileTypeUnsupported) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'known file type but not existent' do
|
19
|
+
let('path') { 'foo/bar.json' }
|
20
|
+
before do
|
21
|
+
File.stub('exists?').with(path).and_return(false)
|
22
|
+
end
|
23
|
+
subject { described_class.new path }
|
24
|
+
|
25
|
+
its('path') { should eq path }
|
26
|
+
its('mime_type') { should eq 'application/json' }
|
27
|
+
it { expect{subject.read}.to raise_error(Xway::ManifestFileNotFound) }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'correct file' do
|
31
|
+
let('path') { 'foo/bar.json' }
|
32
|
+
before do
|
33
|
+
File.stub('exists?').with(path).and_return(true)
|
34
|
+
File.stub('read').with(path).and_return('example data')
|
35
|
+
end
|
36
|
+
subject { described_class.new path }
|
37
|
+
|
38
|
+
its('path') { should eq path }
|
39
|
+
its('mime_type') { should eq 'application/json' }
|
40
|
+
its('read') { should eq 'example data' }
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/api/request'
|
3
|
+
|
4
|
+
describe Xway::Api::Request do
|
5
|
+
subject { described_class.new 'get', '/foo' }
|
6
|
+
|
7
|
+
its('method_name') { should eq 'get' }
|
8
|
+
its('path') { should eq '/foo' }
|
9
|
+
its('headers') { should eq('X-App' => 'appway') }
|
10
|
+
its('body') { should eq nil }
|
11
|
+
|
12
|
+
context 'with manifest' do
|
13
|
+
let('manifest') { File.join(ASSETS_PATH, 'appway-example.json') }
|
14
|
+
subject { described_class.new 'get', '/foo', manifest: manifest }
|
15
|
+
|
16
|
+
its('method_name') { should eq 'get' }
|
17
|
+
its('path') { should eq '/foo' }
|
18
|
+
its('headers') { should eq('X-App' => 'appway',
|
19
|
+
'Content-Type' => 'application/json') }
|
20
|
+
its('body.read') { should include('github.com/threez/appway-example') }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/api'
|
3
|
+
require 'xway/error'
|
4
|
+
|
5
|
+
describe Xway::Api do
|
6
|
+
let!('parameter') do
|
7
|
+
parameter = double('Xway::Parameter').tap do |p|
|
8
|
+
p.stub('[]').with(:servers).and_return(['http://foo',
|
9
|
+
'http://bar'])
|
10
|
+
p.stub('[]').with(:debug).and_return(false)
|
11
|
+
p.stub('[]').with(:app).and_return(nil)
|
12
|
+
end
|
13
|
+
Xway.stub('parameter').and_return(parameter)
|
14
|
+
end
|
15
|
+
|
16
|
+
subject('api') { described_class.new }
|
17
|
+
|
18
|
+
context 'mock HTTParty' do
|
19
|
+
before do
|
20
|
+
HTTParty.stub('get').and_return('list of apps')
|
21
|
+
end
|
22
|
+
|
23
|
+
subject { api.request 'list' }
|
24
|
+
|
25
|
+
it { should eq ['list of apps', 'list of apps'] }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'mock http + endpoints' do
|
29
|
+
let!('http') do
|
30
|
+
double('Http').tap do |mock|
|
31
|
+
mock.stub('request') do |server, request, debug|
|
32
|
+
Struct\
|
33
|
+
.new(:server, :http_options, :debug)\
|
34
|
+
.new(server, request.http_options, debug)
|
35
|
+
end
|
36
|
+
Xway::Api::Http.stub('new').and_return(mock)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
let!('endpoints') do
|
40
|
+
double('Endpoints').tap do |mock|
|
41
|
+
mock.stub('foo') do |options|
|
42
|
+
Xway::Api::Request.new 'get', '/foo', options
|
43
|
+
end
|
44
|
+
Xway::Api::Endpoints.stub('new').and_return(mock)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'apps' do
|
49
|
+
describe 'builds request for each server' do
|
50
|
+
subject { api.request 'foo' }
|
51
|
+
|
52
|
+
its('first.server') { should eq('http://foo') }
|
53
|
+
its('first.http_options') { should eq(:headers => {
|
54
|
+
"X-App" => "appway"}) }
|
55
|
+
its('first.debug') { should be_false }
|
56
|
+
its('last.server') { should eq('http://bar') }
|
57
|
+
its('last.http_options') { should eq(:headers => {
|
58
|
+
"X-App" => "appway"}) }
|
59
|
+
its('last.debug') { should be_false }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'app name + manifest' do
|
64
|
+
before do
|
65
|
+
manifest = File.join(ASSETS_PATH, 'appway-example.json')
|
66
|
+
File.stub('exists?').with(manifest).and_return(true)
|
67
|
+
File.stub('read').with(manifest).and_return('appway-example.json.data')
|
68
|
+
Xway.parameter.stub('[]').with(:app).and_return(name: 'appway-example',
|
69
|
+
manifest: manifest)
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'builds request for each server' do
|
73
|
+
subject { api.request 'foo' }
|
74
|
+
|
75
|
+
its('first.server') { should eq('http://foo') }
|
76
|
+
its('first.http_options') { should eq(:headers => {
|
77
|
+
"X-App" => "appway",
|
78
|
+
"Content-Type" => "application/json"},
|
79
|
+
:body => "appway-example.json.data") }
|
80
|
+
its('first.debug') { should be_false }
|
81
|
+
its('last.server') { should eq('http://bar') }
|
82
|
+
its('last.http_options') { should eq(:headers => {
|
83
|
+
"X-App" => "appway",
|
84
|
+
"Content-Type" => "application/json"},
|
85
|
+
:body => "appway-example.json.data") }
|
86
|
+
its('last.debug') { should be_false }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/cli'
|
3
|
+
require 'xway/version'
|
4
|
+
|
5
|
+
describe Xway::Cli do
|
6
|
+
let('parameter') do
|
7
|
+
double('Xway::Parameter').tap do |mock|
|
8
|
+
mock.stub('rest').and_return([])
|
9
|
+
mock.stub('[]').with(:version).and_return(nil)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
let('api') { double('api') }
|
13
|
+
let('out') { double('stdout').tap { |o| o.stub('puts') } }
|
14
|
+
before { Xway.stub('parameter').and_return(parameter) }
|
15
|
+
subject { described_class.new api, out }
|
16
|
+
|
17
|
+
it 'prints usage per default' do
|
18
|
+
parameter.should_receive('print_help!')
|
19
|
+
subject.start
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'prints version on :version parameter' do
|
23
|
+
parameter.stub('[]').with(:version).and_return(true)
|
24
|
+
out.should_receive('puts').with("xway #{Xway::VERSION}")
|
25
|
+
subject.start
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'executes commands on api' do
|
29
|
+
api.should_receive('request').with('list').and_return('list result')
|
30
|
+
out.should_receive('puts').with('list result')
|
31
|
+
parameter.stub('rest').and_return(['list'])
|
32
|
+
subject.start
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xway/parameter'
|
3
|
+
|
4
|
+
describe Xway::Parameter do
|
5
|
+
its('global_config') { should eq(File.join(ENV['HOME'], '.xway')) }
|
6
|
+
its('local_config') { should eq(File.join(Dir.pwd, '.xway')) }
|
7
|
+
|
8
|
+
context 'mocked Configliere::Param' do
|
9
|
+
let('param') do
|
10
|
+
double('Configliere::Param').tap do |param|
|
11
|
+
param.stub('define')
|
12
|
+
param.stub('use')
|
13
|
+
param.stub('read')
|
14
|
+
param.stub('resolve!')
|
15
|
+
param.stub('[]')
|
16
|
+
param.stub('to_hash')
|
17
|
+
param.stub('rest')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
before do
|
21
|
+
subject.stub('global_config').and_return('global-xway-conf')
|
22
|
+
subject.stub('local_config').and_return('local-xway-conf')
|
23
|
+
File.stub('exists?').with('global-xway-conf').and_return(false)
|
24
|
+
File.stub('exists?').with('local-xway-conf').and_return(false)
|
25
|
+
Configliere::Param.stub('new').and_return(param)
|
26
|
+
end
|
27
|
+
|
28
|
+
its('to_hash') { should eq({}) }
|
29
|
+
its('rest') { should eq([]) }
|
30
|
+
it { subject[:servers].should eq(nil)}
|
31
|
+
|
32
|
+
describe 'loads!' do
|
33
|
+
it 'reads global config when it exists' do
|
34
|
+
File.stub('exists?').with('global-xway-conf').and_return(true)
|
35
|
+
param.should_receive('read').with('global-xway-conf')
|
36
|
+
subject.reload!
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'reads local config when it exists' do
|
40
|
+
File.stub('exists?').with('local-xway-conf').and_return(true)
|
41
|
+
param.should_receive('read').with('local-xway-conf')
|
42
|
+
subject.reload!
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'uses commandline' do
|
46
|
+
param.should_receive('use').with(:commandline)
|
47
|
+
subject.reload!
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'calls resolve' do
|
51
|
+
param.should_receive('resolve!')
|
52
|
+
subject.reload!
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'defines servers' do
|
56
|
+
param.should_receive('define').with(:servers,
|
57
|
+
type: Array,
|
58
|
+
flag: 's',
|
59
|
+
description: 'all appway servers',
|
60
|
+
default: ['http://localhost:8000'])
|
61
|
+
subject.reload!
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'defines app.name' do
|
65
|
+
param.should_receive('define').with('app.name',
|
66
|
+
type: String,
|
67
|
+
flag: 'a',
|
68
|
+
description: 'name of your app')
|
69
|
+
subject.reload!
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'defines app.manifest' do
|
73
|
+
param.should_receive('define').with('app.manifest',
|
74
|
+
type: String,
|
75
|
+
flag: 'm',
|
76
|
+
description: 'path to your app.way file')
|
77
|
+
subject.reload!
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'defines debug' do
|
81
|
+
param.should_receive('define').with(:debug,
|
82
|
+
flag: 'd',
|
83
|
+
description: 'print debug info to stdout',
|
84
|
+
default: false)
|
85
|
+
subject.reload!
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'defines version' do
|
89
|
+
param.should_receive('define').with(:version,
|
90
|
+
flag: 'v',
|
91
|
+
description: 'print version info')
|
92
|
+
subject.reload!
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'after reload!' do
|
97
|
+
before do
|
98
|
+
param.stub('[]').with(:servers).and_return('http://bar')
|
99
|
+
param.stub('to_hash').and_return(servers: ['http://bar'])
|
100
|
+
param.stub('rest').and_return([1,2,3])
|
101
|
+
subject.reload!
|
102
|
+
end
|
103
|
+
its('rest') { should eq([1,2,3]) }
|
104
|
+
its('to_hash') { should eq(servers: ['http://bar']) }
|
105
|
+
it { subject[:servers].should eq('http://bar') }
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'print_help!' do
|
109
|
+
param.should_receive('[]=').with(:help, true)
|
110
|
+
param.should_receive('resolve!')
|
111
|
+
subject.print_help!
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'custom XWAY_CONFIG' do
|
116
|
+
let('xway_config') { File.join(Dir.pwd, 'spec/assets/custom.xway') }
|
117
|
+
before { ENV.stub('[]').and_return(xway_config) }
|
118
|
+
|
119
|
+
its('global_config') { should eq(xway_config) }
|
120
|
+
its('local_config') { should eq(File.join(Dir.pwd, '.xway')) }
|
121
|
+
end
|
122
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# this must before application code is required
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
|
1
5
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
6
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
7
|
# Require this file using `require "spec_helper"` to ensure that it is only
|
@@ -15,3 +19,10 @@ RSpec.configure do |config|
|
|
15
19
|
# --seed 1234
|
16
20
|
config.order = 'random'
|
17
21
|
end
|
22
|
+
|
23
|
+
# just add the lib folder to the load path
|
24
|
+
# -> actual 'require' calls will be done within each spec (speed + modularity)
|
25
|
+
lib = File.expand_path('../lib', File.dirname(__FILE__))
|
26
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
27
|
+
|
28
|
+
ASSETS_PATH = File.expand_path('assets', File.dirname(__FILE__))
|
data/xway.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Xway::VERSION
|
9
9
|
gem.authors = ["Jens Bissinger"]
|
10
10
|
gem.email = ["mail@jens-bissinger.de"]
|
11
|
-
gem.description = %q{
|
12
|
-
gem.summary = %q{
|
11
|
+
gem.description = %q{Appway client.}
|
12
|
+
gem.summary = %q{Provides the xway command. See github.com/threez/appway.}
|
13
13
|
gem.homepage = ""
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
@@ -17,9 +17,14 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
+
gem.add_dependency 'configliere'
|
21
|
+
gem.add_dependency 'httparty'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rake'
|
20
24
|
gem.add_development_dependency 'rspec'
|
21
25
|
gem.add_development_dependency 'rspec-nc'
|
22
26
|
gem.add_development_dependency 'guard'
|
23
27
|
gem.add_development_dependency 'guard-rspec'
|
24
28
|
gem.add_development_dependency 'terminal-notifier-guard'
|
29
|
+
gem.add_development_dependency 'coveralls'
|
25
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.
|
4
|
+
version: 0.0.1.beta
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,56 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: configliere
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: httparty
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
14
62
|
- !ruby/object:Gem::Dependency
|
15
63
|
name: rspec
|
16
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,7 +139,23 @@ dependencies:
|
|
91
139
|
- - ! '>='
|
92
140
|
- !ruby/object:Gem::Version
|
93
141
|
version: '0'
|
94
|
-
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: coveralls
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: Appway client.
|
95
159
|
email:
|
96
160
|
- mail@jens-bissinger.de
|
97
161
|
executables:
|
@@ -99,8 +163,10 @@ executables:
|
|
99
163
|
extensions: []
|
100
164
|
extra_rdoc_files: []
|
101
165
|
files:
|
166
|
+
- .coveralls.yml
|
102
167
|
- .gitignore
|
103
168
|
- .rspec
|
169
|
+
- .travis.yml
|
104
170
|
- Gemfile
|
105
171
|
- Guardfile
|
106
172
|
- LICENSE.txt
|
@@ -108,8 +174,28 @@ files:
|
|
108
174
|
- Rakefile
|
109
175
|
- bin/xway
|
110
176
|
- lib/xway.rb
|
177
|
+
- lib/xway/api.rb
|
178
|
+
- lib/xway/api/endpoints.rb
|
179
|
+
- lib/xway/api/http.rb
|
180
|
+
- lib/xway/api/request.rb
|
181
|
+
- lib/xway/api/request/body.rb
|
182
|
+
- lib/xway/cli.rb
|
183
|
+
- lib/xway/error.rb
|
184
|
+
- lib/xway/parameter.rb
|
111
185
|
- lib/xway/version.rb
|
112
|
-
- spec/
|
186
|
+
- spec/assets/appway-example.json
|
187
|
+
- spec/assets/custom.xway
|
188
|
+
- spec/integration/bin/xway_binary_spec.rb
|
189
|
+
- spec/integration/lib/xway/cli_spec.rb
|
190
|
+
- spec/lib/xway/api/endpoints_spec.rb
|
191
|
+
- spec/lib/xway/api/http_spec.rb
|
192
|
+
- spec/lib/xway/api/request/body_spec.rb
|
193
|
+
- spec/lib/xway/api/request_spec.rb
|
194
|
+
- spec/lib/xway/api_spec.rb
|
195
|
+
- spec/lib/xway/cli_spec.rb
|
196
|
+
- spec/lib/xway/error_spec.rb
|
197
|
+
- spec/lib/xway/parameter_spec.rb
|
198
|
+
- spec/lib/xway_spec.rb
|
113
199
|
- spec/spec_helper.rb
|
114
200
|
- xway.gemspec
|
115
201
|
homepage: ''
|
@@ -135,8 +221,20 @@ rubyforge_project:
|
|
135
221
|
rubygems_version: 1.8.23
|
136
222
|
signing_key:
|
137
223
|
specification_version: 3
|
138
|
-
summary:
|
224
|
+
summary: Provides the xway command. See github.com/threez/appway.
|
139
225
|
test_files:
|
140
|
-
- spec/
|
226
|
+
- spec/assets/appway-example.json
|
227
|
+
- spec/assets/custom.xway
|
228
|
+
- spec/integration/bin/xway_binary_spec.rb
|
229
|
+
- spec/integration/lib/xway/cli_spec.rb
|
230
|
+
- spec/lib/xway/api/endpoints_spec.rb
|
231
|
+
- spec/lib/xway/api/http_spec.rb
|
232
|
+
- spec/lib/xway/api/request/body_spec.rb
|
233
|
+
- spec/lib/xway/api/request_spec.rb
|
234
|
+
- spec/lib/xway/api_spec.rb
|
235
|
+
- spec/lib/xway/cli_spec.rb
|
236
|
+
- spec/lib/xway/error_spec.rb
|
237
|
+
- spec/lib/xway/parameter_spec.rb
|
238
|
+
- spec/lib/xway_spec.rb
|
141
239
|
- spec/spec_helper.rb
|
142
240
|
has_rdoc:
|
data/spec/bin/xway_spec.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'open3'
|
3
|
-
|
4
|
-
describe 'xway' do
|
5
|
-
it 'returns version string' do
|
6
|
-
exe = File.expand_path('../../bin/xway', File.dirname(__FILE__))
|
7
|
-
stdin, stdout, stderr = Open3.popen3("#{exe}")
|
8
|
-
stdout.readlines.to_s.should include(Xway::VERSION)
|
9
|
-
end
|
10
|
-
end
|