rox-client-rspec 0.3.0
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.
- checksums.yaml +15 -0
- data/Gemfile +21 -0
- data/LICENSE.txt +20 -0
- data/README.md +148 -0
- data/VERSION +1 -0
- data/lib/rox-client-rspec.rb +14 -0
- data/lib/rox-client-rspec/cache.rb +60 -0
- data/lib/rox-client-rspec/client.rb +119 -0
- data/lib/rox-client-rspec/config.rb +178 -0
- data/lib/rox-client-rspec/formatter.rb +86 -0
- data/lib/rox-client-rspec/project.rb +32 -0
- data/lib/rox-client-rspec/server.rb +97 -0
- data/lib/rox-client-rspec/tasks.rb +62 -0
- data/lib/rox-client-rspec/test_payload.rb +23 -0
- data/lib/rox-client-rspec/test_result.rb +114 -0
- data/lib/rox-client-rspec/test_run.rb +104 -0
- data/lib/rox-client-rspec/uid.rb +60 -0
- metadata +215 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTNlNmE4ZTM2MjhmZDg1M2VlMWI3NDM1NTE2NzhhYTgzYmZjYTNkNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjlmNTViYTI1OWMzOTQ1M2QyNzcwOTRiNThhNTM2ZGVhOTdjMTQ2Yg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
N2FjYWE5ZTI3NjRkODM0NGFmNDc5Mjk5OGM5Yjg0MzkyMzY2NTEzMmExYWFm
|
10
|
+
ZmY4ZDk4ZTRjMzBkZDg0YzQ0NjUyZjlkMmYzNWJjYTBkMDFmYzFmNmU3MzQ1
|
11
|
+
NzZmMWIwZGUxMWIwYTg4NWIyZDRmNDhmNTljZWRiMGE5N2RjMDc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Y2U2OTQ0M2Y2YTE5ODBlYjI3NmM2MDUxMTA3M2RiZTM2M2VhMzhiOTcxZjVh
|
14
|
+
YjQ5YjFjN2EyYjA0MjliZWQ3M2ZlMzQ0YzcwYTZlZjE2OGU4ZDBhYzY1MWNm
|
15
|
+
NzJiY2IzZGM5NTEwZTU0NTQ1YWZlYjZiZmIwMTkxYzFiODRhMGU=
|
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem 'rspec', '~> 2.14'
|
7
|
+
gem 'oj', '~> 2.1'
|
8
|
+
gem 'httparty', '~> 0.11.0'
|
9
|
+
gem 'paint', '~> 0.8.6'
|
10
|
+
gem 'rake', '~> 10.1'
|
11
|
+
|
12
|
+
# Add dependencies to develop your gem here.
|
13
|
+
# Include everything needed to run rake, tests, features, etc.
|
14
|
+
group :development do
|
15
|
+
gem 'bundler'
|
16
|
+
gem 'jeweler'
|
17
|
+
gem 'geminabox'
|
18
|
+
gem 'rake-version'
|
19
|
+
gem 'simplecov'
|
20
|
+
gem 'fakefs', require: 'fakefs/safe'
|
21
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012-2013 Lotaris SA
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# RSpec ROX Client
|
2
|
+
|
3
|
+
**RSpec client for [ROX Center](https://github.com/lotaris/rox-center).**
|
4
|
+
|
5
|
+
[](http://badge.fury.io/rb/rox-client-rspec)
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* RSpec 2.14
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
In your Gemfile:
|
14
|
+
|
15
|
+
```rb
|
16
|
+
gem 'rox-client-rspec', '~> 0.3.0'
|
17
|
+
```
|
18
|
+
|
19
|
+
Manually:
|
20
|
+
|
21
|
+
gem install rox-client-rspec
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
If you haven't done it already, follow the [setup procedure](#setup) below.
|
26
|
+
|
27
|
+
To track a test, you must assign it a ROX test key generated from your ROX Center server.
|
28
|
+
|
29
|
+
**NOTE: currently, all the tests in your test suite must be assigned a test key for the client to work.**
|
30
|
+
|
31
|
+
Test keys are assigned to test using RSpec metadata:
|
32
|
+
|
33
|
+
```rb
|
34
|
+
it "should work", rox: { key: 'abcdefghijkl' } do
|
35
|
+
expect(true).to be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it(nil, rox: { key: 'bcdefghijklm' }){ should validate_presence_of(:name) }
|
39
|
+
```
|
40
|
+
|
41
|
+
<a name="setup"></a>
|
42
|
+
## Setup
|
43
|
+
|
44
|
+
ROX clients use [YAML](http://yaml.org) files for configuration.
|
45
|
+
To use the RSpec ROX Client, you need two configuration files and you must set up the client in your spec helper file.
|
46
|
+
|
47
|
+
In your home folder, you must create the `~/.rox/config.yml` configuration file.
|
48
|
+
|
49
|
+
```yml
|
50
|
+
# List of ROX Center servers you can submit test results to.
|
51
|
+
servers:
|
52
|
+
- name: rox.example.com # A custom name for your ROX Center server.
|
53
|
+
# You will use this in the client configuration file.
|
54
|
+
# We recommend using the domain name where you deployed it.
|
55
|
+
|
56
|
+
apiUrl: https://rox.example.com/api # The URL of your ROX Center server's API.
|
57
|
+
# This is the domain where you deployed it with /api.
|
58
|
+
|
59
|
+
apiKeyId: 39fuc7x85lsoy9c0ek2d # Your user credentials on this server.
|
60
|
+
apiKeySecret: mwpqvvmagzoegxnqptxdaxkxonjmvrlctwcrfmowibqcpnsdqd
|
61
|
+
|
62
|
+
# If true, test results will be uploaded to ROX Center.
|
63
|
+
# Set to false to temporarily disable publishing.
|
64
|
+
# You can change this at runtime from the command line by setting the
|
65
|
+
# ROX_PUBLISH environment variable to 0 (false) or 1 (true).
|
66
|
+
publish: true
|
67
|
+
```
|
68
|
+
|
69
|
+
In the project directory where you run RSpec, you must add the `rox.yml` client configuration file:
|
70
|
+
|
71
|
+
```yml
|
72
|
+
# Configuration specific to your project.
|
73
|
+
project:
|
74
|
+
name: My Project
|
75
|
+
version: 1.2.3
|
76
|
+
apiId: 154sic93pxs0 # The API key of your project in the ROX Center server.
|
77
|
+
|
78
|
+
# Where the client should store its temporary files.
|
79
|
+
# The client will work without it but it is required for some advanced features.
|
80
|
+
workspace: tmp/rox
|
81
|
+
|
82
|
+
# Client advanced features.
|
83
|
+
payload:
|
84
|
+
|
85
|
+
# Saves a copy of the test payload sent to the ROX Center server for debugging.
|
86
|
+
# The file will be saved in rspec/servers/<SERVER_NAME>/payload.json.
|
87
|
+
save: false
|
88
|
+
|
89
|
+
# If you track a large number of tests (more than a thousand), enabling this
|
90
|
+
# will reduce the size of the test payloads sent to ROX Center server by caching
|
91
|
+
# test information that doesn't change often such as the name.
|
92
|
+
cache: false
|
93
|
+
|
94
|
+
# Prints a copy of the test payload sent to the ROX Center server for debugging.
|
95
|
+
# Temporarily enable at runtime by setting the ROX_PRINT_PAYLOAD environment variable to 1.
|
96
|
+
print: false
|
97
|
+
|
98
|
+
# The name of the ROX Center server to upload test results to.
|
99
|
+
# This name must be one of the server names in the ~/.rox/config.yml file.
|
100
|
+
# You can change this at runtime from the command line by setting the
|
101
|
+
# ROX_SERVER environment variable.
|
102
|
+
server: rox.example.com
|
103
|
+
```
|
104
|
+
|
105
|
+
Finally, you must enable the client in your spec helper file (usually `spec/spec_helper.rb`).
|
106
|
+
|
107
|
+
```yml
|
108
|
+
RoxClient::RSpec.configure do |config|
|
109
|
+
|
110
|
+
# Optional ROX Center category to add to all the tests sent with this client.
|
111
|
+
config.project.category = 'RSpec'
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
The next time you run your test suite, the RSpec ROX Client will send the results to your ROX Center server.
|
116
|
+
|
117
|
+
## Contributing
|
118
|
+
|
119
|
+
* [Fork](https://help.github.com/articles/fork-a-repo)
|
120
|
+
* Create a topic branch - `git checkout -b my_feature`
|
121
|
+
* Push to your branch - `git push origin my_feature`
|
122
|
+
* Create a [pull request](http://help.github.com/pull-requests/) from your branch
|
123
|
+
|
124
|
+
Please add a changelog entry with your name for new features and bug fixes.
|
125
|
+
|
126
|
+
## License
|
127
|
+
|
128
|
+
The RSpec ROX Client is licensed under the [MIT License](http://opensource.org/licenses/MIT).
|
129
|
+
|
130
|
+
Copyright (c) 2012-2013 Lotaris SA
|
131
|
+
|
132
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
133
|
+
of this software and associated documentation files (the "Software"), to deal
|
134
|
+
in the Software without restriction, including without limitation the rights
|
135
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
136
|
+
copies of the Software, and to permit persons to whom the Software is
|
137
|
+
furnished to do so, subject to the following conditions:
|
138
|
+
|
139
|
+
The above copyright notice and this permission notice shall be included in
|
140
|
+
all copies or substantial portions of the Software.
|
141
|
+
|
142
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
143
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
144
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
145
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
146
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
147
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
148
|
+
THE SOFTWARE.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
module RoxClient
|
5
|
+
|
6
|
+
module RSpec
|
7
|
+
VERSION = '0.3.0'
|
8
|
+
|
9
|
+
class Error < StandardError; end
|
10
|
+
class PayloadError < Error; end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module RoxClient::RSpec
|
3
|
+
|
4
|
+
class Cache
|
5
|
+
|
6
|
+
class Error < RoxClient::RSpec::Error; end
|
7
|
+
|
8
|
+
def initialize options = {}
|
9
|
+
@tests = {}
|
10
|
+
@workspace, @server_name, @project_api_id = options[:workspace], options[:server_name], options[:project_api_id]
|
11
|
+
end
|
12
|
+
|
13
|
+
def save test_run
|
14
|
+
validate!
|
15
|
+
|
16
|
+
@tests = { @project_api_id => @tests[@project_api_id] || {} }
|
17
|
+
test_run.results.each{ |r| @tests[@project_api_id][r.key] = test_result_hash(r) }
|
18
|
+
|
19
|
+
FileUtils.mkdir_p File.dirname(cache_file)
|
20
|
+
File.open(cache_file, 'w'){ |f| f.write Oj.dump(@tests, mode: :strict) }
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def load
|
26
|
+
validate!
|
27
|
+
|
28
|
+
@tests = if File.exists? cache_file
|
29
|
+
Oj.load(File.read(cache_file), mode: :strict) rescue {}
|
30
|
+
else
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def known? test_result
|
37
|
+
@tests[@project_api_id] && !!@tests[@project_api_id][test_result.key]
|
38
|
+
end
|
39
|
+
|
40
|
+
def stale? test_result
|
41
|
+
@tests[@project_api_id] && test_result_hash(test_result) != @tests[@project_api_id][test_result.key]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate!
|
47
|
+
required = { "workspace" => @workspace, "server name" => @server_name, "project API identifier" => @project_api_id }
|
48
|
+
missing = required.keys.select{ |k| !required[k] }
|
49
|
+
raise Error.new("Missing cache options: #{missing.join ', '}") if missing.any?
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_result_hash r
|
53
|
+
Digest::SHA2.hexdigest "#{r.name} || #{r.category} || #{r.tags.collect(&:to_s).sort.join(' ')} || #{r.tickets.collect(&:to_s).sort.join(' ')}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def cache_file
|
57
|
+
@cache_file ||= File.join(@workspace, 'rspec', 'servers', @server_name, 'cache.json')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
module RoxClient::RSpec
|
3
|
+
|
4
|
+
class Client
|
5
|
+
|
6
|
+
def initialize server, options = {}
|
7
|
+
|
8
|
+
@server = server
|
9
|
+
@publish, @local_mode, @workspace = options[:publish], options[:local_mode], options[:workspace]
|
10
|
+
@cache_payload, @print_payload, @save_payload = options[:cache_payload], options[:print_payload], options[:save_payload]
|
11
|
+
|
12
|
+
cache_options = { workspace: @workspace }
|
13
|
+
cache_options.merge! server_name: @server.name, project_api_id: @server.project_api_id if @server
|
14
|
+
@cache = Cache.new cache_options
|
15
|
+
|
16
|
+
@uid = UID.new workspace: @workspace
|
17
|
+
end
|
18
|
+
|
19
|
+
def process test_run
|
20
|
+
|
21
|
+
puts
|
22
|
+
return fail "No server to publish results to" if !@server
|
23
|
+
|
24
|
+
test_run.uid = @uid.load_uid
|
25
|
+
|
26
|
+
payload_options = @server.payload_options
|
27
|
+
|
28
|
+
cache_enabled = @cache_payload && load_cache
|
29
|
+
payload_options[:cache] = @cache if cache_enabled
|
30
|
+
|
31
|
+
return false unless payload = build_payload(test_run, payload_options)
|
32
|
+
|
33
|
+
published = if !@publish
|
34
|
+
puts Paint["ROX - Publishing disabled", :yellow]
|
35
|
+
false
|
36
|
+
elsif publish_payload payload
|
37
|
+
@cache.save test_run if cache_enabled
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
save_payload payload if @save_payload
|
44
|
+
print_payload payload if @print_payload
|
45
|
+
|
46
|
+
published
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_payload test_run, options = {}
|
52
|
+
begin
|
53
|
+
TestPayload.new(test_run).to_h options
|
54
|
+
rescue PayloadError => e
|
55
|
+
fail e.message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def fail msg, type = :error
|
60
|
+
styles = { warning: [ :yellow ], error: [ :bold, :red ] }
|
61
|
+
warn Paint["ROX - #{msg}", *styles[type]]
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def load_cache
|
66
|
+
begin
|
67
|
+
@cache.load
|
68
|
+
rescue Cache::Error => e
|
69
|
+
warn Paint["ROX - #{e.message}", :yellow]
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def print_payload payload
|
75
|
+
puts Paint['ROX - Printing payload...', :yellow]
|
76
|
+
begin
|
77
|
+
puts JSON.pretty_generate(payload)
|
78
|
+
rescue
|
79
|
+
puts payload.inspect
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def save_payload payload
|
84
|
+
|
85
|
+
missing = { "workspace" => @workspace, "server" => @server }.inject([]){ |memo,(k,v)| !v ? memo << k : memo }
|
86
|
+
return fail "Cannot save payload without a #{missing.join ' and '}" if missing.any?
|
87
|
+
|
88
|
+
FileUtils.mkdir_p File.dirname(payload_file)
|
89
|
+
File.open(payload_file, 'w'){ |f| f.write Oj.dump(payload, mode: :strict) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def payload_file
|
93
|
+
@payload_file ||= File.join(@workspace, 'rspec', 'servers', @server.name, 'payload.json')
|
94
|
+
end
|
95
|
+
|
96
|
+
def publish_payload payload
|
97
|
+
|
98
|
+
puts Paint["ROX - Sending payload to #{@server.api_url}...", :magenta]
|
99
|
+
|
100
|
+
begin
|
101
|
+
if @local_mode
|
102
|
+
puts Paint['ROX - LOCAL MODE: not actually sending payload.', :yellow]
|
103
|
+
else
|
104
|
+
@server.upload payload
|
105
|
+
end
|
106
|
+
puts Paint["ROX - Done!", :green]
|
107
|
+
true
|
108
|
+
rescue Server::Error => e
|
109
|
+
warn Paint["ROX - Upload failed!", :red, :bold]
|
110
|
+
warn Paint["ROX - #{e.message}", :red, :bold]
|
111
|
+
if e.response
|
112
|
+
warn Paint["ROX - Dumping response body...", :red, :bold]
|
113
|
+
warn e.response.body
|
114
|
+
end
|
115
|
+
false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# Utilities to send test results to ROX Center.
|
4
|
+
module RoxClient::RSpec
|
5
|
+
|
6
|
+
def self.config
|
7
|
+
@config ||= Config.new.tap(&:load)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configure options = {}
|
11
|
+
yield config if block_given?
|
12
|
+
config.load_warnings.each{ |w| warn Paint["ROX - #{w}", :yellow] }
|
13
|
+
config.setup! if options[:setup] != false
|
14
|
+
config
|
15
|
+
end
|
16
|
+
|
17
|
+
class Config
|
18
|
+
# TODO: add silent/verbose option(s)
|
19
|
+
class Error < RoxClient::RSpec::Error; end
|
20
|
+
attr_writer :publish, :local_mode, :cache_payload, :print_payload, :save_payload
|
21
|
+
attr_reader :project, :server, :workspace, :load_warnings
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@servers = []
|
25
|
+
@project = Project.new
|
26
|
+
@publish, @local_mode, @cache_payload, @print_payload, @save_payload = false, false, false, false, false
|
27
|
+
@load_warnings = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def workspace= dir
|
31
|
+
@workspace = dir ? File.expand_path(dir) : nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def servers
|
35
|
+
@servers.dup
|
36
|
+
end
|
37
|
+
|
38
|
+
# Plugs ROX utilities into RSpec.
|
39
|
+
def setup!
|
40
|
+
::RSpec.configure do |c|
|
41
|
+
c.add_formatter Formatter
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
%w(publish local_mode cache_payload print_payload save_payload).each do |name|
|
46
|
+
define_method("#{name}?"){ instance_variable_get("@#{name}") }
|
47
|
+
end
|
48
|
+
|
49
|
+
def client_options
|
50
|
+
{
|
51
|
+
publish: @publish,
|
52
|
+
local_mode: @local_mode,
|
53
|
+
workspace: @workspace,
|
54
|
+
cache_payload: @cache_payload,
|
55
|
+
print_payload: @print_payload,
|
56
|
+
save_payload: @save_payload
|
57
|
+
}.select{ |k,v| !v.nil? }
|
58
|
+
end
|
59
|
+
|
60
|
+
def load
|
61
|
+
|
62
|
+
@load_warnings = []
|
63
|
+
return unless config = load_config_files
|
64
|
+
|
65
|
+
@publish = parse_env_flag :publish, !!config[:publish]
|
66
|
+
@server_name = parse_env_option(:server) || config[:server]
|
67
|
+
@local_mode = parse_env_flag(:local) || !!config[:local]
|
68
|
+
|
69
|
+
self.workspace = parse_env_option(:workspace) || config[:workspace]
|
70
|
+
@cache_payload = parse_env_flag :cache_payload, !!config[:payload][:cache]
|
71
|
+
@print_payload = parse_env_flag :print_payload, !!config[:payload][:print]
|
72
|
+
@save_payload = parse_env_flag :save_payload, !!config[:payload][:save]
|
73
|
+
|
74
|
+
@servers, @server = build_servers config
|
75
|
+
|
76
|
+
if @servers.empty?
|
77
|
+
@load_warnings << "No server defined"
|
78
|
+
elsif !@server_name
|
79
|
+
@load_warnings << "No server name given"
|
80
|
+
elsif !@server
|
81
|
+
@load_warnings << "Unknown server '#{@server_name}'"
|
82
|
+
end
|
83
|
+
|
84
|
+
project_options = config[:project]
|
85
|
+
project_options.merge! api_id: @server.project_api_id if @server and @server.project_api_id
|
86
|
+
@project.update project_options
|
87
|
+
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def build_servers config
|
94
|
+
|
95
|
+
servers = {}
|
96
|
+
|
97
|
+
default_server_options = { project_api_id: config[:project][:api_id] }
|
98
|
+
config[:servers].each do |server_options|
|
99
|
+
|
100
|
+
name = server_options[:name].to_s.strip
|
101
|
+
if name.empty?
|
102
|
+
@load_warnings << "Ignoring unnamed server"
|
103
|
+
next
|
104
|
+
elsif servers[name]
|
105
|
+
servers[name].merge! server_options
|
106
|
+
next
|
107
|
+
end
|
108
|
+
|
109
|
+
servers[name] = server_options
|
110
|
+
end
|
111
|
+
|
112
|
+
servers.each_key{ |name| servers[name] = Server.new default_server_options.merge(servers[name]) }
|
113
|
+
|
114
|
+
[ servers.values, servers[@server_name.to_s.strip] ]
|
115
|
+
end
|
116
|
+
|
117
|
+
def load_config_files
|
118
|
+
|
119
|
+
configs = [ home_config_file, working_config_file ]
|
120
|
+
actual_configs = configs.select{ |f| File.exists? f }
|
121
|
+
|
122
|
+
if actual_configs.empty?
|
123
|
+
@load_warnings << %|no config file found, looking for:\n #{configs.join "\n "}|
|
124
|
+
return false
|
125
|
+
end
|
126
|
+
|
127
|
+
actual_configs.collect!{ |f| YAML.load_file f }
|
128
|
+
|
129
|
+
actual_configs.inject({}) do |memo,yml|
|
130
|
+
memo.merge! parse_general_options(yml)
|
131
|
+
memo[:servers] = (memo[:servers] || []) + (yml['servers'].kind_of?(Array) ? yml['servers'].collect{ |s| parse_server_options s } : [])
|
132
|
+
memo[:payload] = (memo[:payload] || {}).merge parse_payload_options(yml['payload'])
|
133
|
+
memo[:project] = (memo[:project] || {}).merge parse_project_options(yml['project'])
|
134
|
+
memo
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def home_config_file
|
139
|
+
File.join File.expand_path('~'), '.rox', 'config.yml'
|
140
|
+
end
|
141
|
+
|
142
|
+
def working_config_file
|
143
|
+
File.expand_path ENV['ROX_CONFIG'] || 'rox.yml', Dir.pwd
|
144
|
+
end
|
145
|
+
|
146
|
+
def parse_env_flag name, default = false
|
147
|
+
val = parse_env_option name
|
148
|
+
val ? !!val.to_s.strip.match(/\A(1|t|true)\Z/i) : default
|
149
|
+
end
|
150
|
+
|
151
|
+
def parse_env_option name
|
152
|
+
var = "ROX_#{name.upcase}"
|
153
|
+
ENV.key?(var) ? ENV[var] : nil
|
154
|
+
end
|
155
|
+
|
156
|
+
def parse_general_options h
|
157
|
+
parse_options h, %w(publish server local workspace)
|
158
|
+
end
|
159
|
+
|
160
|
+
def parse_server_options h
|
161
|
+
parse_options h, %w(name apiUrl apiKeyId apiKeySecret apiVersion projectApiId)
|
162
|
+
end
|
163
|
+
|
164
|
+
def parse_payload_options h
|
165
|
+
parse_options h, %w(save cache print)
|
166
|
+
end
|
167
|
+
|
168
|
+
def parse_project_options h
|
169
|
+
# TODO: remove project name once API v0 is dead
|
170
|
+
parse_options h, %w(name version apiId category tags tickets)
|
171
|
+
end
|
172
|
+
|
173
|
+
def parse_options h, keys
|
174
|
+
return {} unless h.kind_of? Hash
|
175
|
+
keys.inject({}){ |memo,k| memo[k.gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym] = h[k] if h.key?(k); memo }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|