xcskarel 0.7.1 → 0.8.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 +4 -4
- data/bin/xcskarel +50 -0
- data/lib/xcskarel.rb +3 -1
- data/lib/xcskarel/application.rb +52 -0
- data/lib/xcskarel/config.rb +86 -0
- data/lib/xcskarel/filter.rb +3 -1
- data/lib/xcskarel/server.rb +3 -1
- data/lib/xcskarel/version.rb +1 -1
- data/lib/xcskarel/xcsfile.rb +71 -0
- data/spec/filter_spec.rb +19 -0
- metadata +4 -2
- data/lib/xcskarel/bot.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2d2ee90682d97c41330da69045be0e7d247e205
|
4
|
+
data.tar.gz: 64564df685430fb56aa6af4e47a402f9fd2e4022
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0845f1c391fda33d0e758c4ff1cf742ca63aed8ac2d8a311ca7554ed37b99d51ad6852c1875ab82d4099a066367ae5a5ced67b789b472e483ec9ca833bac9501
|
7
|
+
data.tar.gz: df228a2c1a18993371002d6868a8baedac53425c234894a622c1287c53276ac1ba09381d648bb8225063cc9a22baf28aa5299767bc563184e3ce66d5b2d603b3
|
data/bin/xcskarel
CHANGED
@@ -33,6 +33,52 @@ class XCSKarelApplication
|
|
33
33
|
global_option('--no_pretty', 'Disables output JSON prettification')
|
34
34
|
global_option('--no_filter', 'Prints full JSON payload for objects instead of just filtering the important ones')
|
35
35
|
|
36
|
+
# Managing local xcsconfig folder
|
37
|
+
|
38
|
+
command :'config list' do |c|
|
39
|
+
c.syntax = 'xcskarel config list [options]'
|
40
|
+
c.description = 'Lists the Xcode Bot configurations found in this folder'
|
41
|
+
c.example 'lists all configurations stored in this folder', 'xcskarel config list'
|
42
|
+
c.action do |args, options|
|
43
|
+
config_folder = XCSKarel::XCSFile.get_config_folder
|
44
|
+
return unless config_folder
|
45
|
+
XCSKarel::Application.list_configs(config_folder)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
command :'config show' do |c|
|
50
|
+
c.syntax = 'xcskarel config show [options]'
|
51
|
+
c.description = 'Opens the selected config for editing'
|
52
|
+
c.example 'opens a config of choice', 'xcskarel config show'
|
53
|
+
c.action do |args, options|
|
54
|
+
config_folder = XCSKarel::XCSFile.get_config_folder
|
55
|
+
return unless config_folder
|
56
|
+
XCSKarel::Application.show_config(config_folder)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
command :'config new' do |c|
|
61
|
+
c.syntax = 'xcskarel config new [options]'
|
62
|
+
c.description = 'Starts the interactive process of creating a new config from an existing Bot'
|
63
|
+
c.example 'starts creating new config from server at 192.168.1.64', 'xcskarel config new --host 192.168.1.64'
|
64
|
+
add_xcs_options(c)
|
65
|
+
c.action do |args, options|
|
66
|
+
|
67
|
+
# let user chose a bot from the server
|
68
|
+
server = create_server_from_options(options)
|
69
|
+
bot = XCSKarel::Application.choose_bot(server)
|
70
|
+
|
71
|
+
# get our config folder
|
72
|
+
config_folder = XCSKarel::XCSFile.get_config_folder
|
73
|
+
return unless config_folder
|
74
|
+
|
75
|
+
# dump the bot into that config folder under a random name
|
76
|
+
XCSKarel::Application.save_bot(config_folder, bot, server.api_version)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Talking to Xcode Server API
|
81
|
+
|
36
82
|
command :bots do |c|
|
37
83
|
c.syntax = 'xcskarel bots [options]'
|
38
84
|
c.description = 'Fetches all Bots found on the specified server'
|
@@ -87,6 +133,8 @@ class XCSKarelApplication
|
|
87
133
|
end
|
88
134
|
end
|
89
135
|
|
136
|
+
# Managing a local Xcode Server
|
137
|
+
|
90
138
|
command :'server start' do |c|
|
91
139
|
c.syntax = 'xcskarel server start [options]'
|
92
140
|
c.description = 'Start local Xcode Server'
|
@@ -137,6 +185,8 @@ class XCSKarelApplication
|
|
137
185
|
end
|
138
186
|
end
|
139
187
|
|
188
|
+
# Managing Xcode
|
189
|
+
|
140
190
|
command :'xcode select' do |c|
|
141
191
|
c.syntax = 'xcskarel xcode select'
|
142
192
|
c.description = 'Interactive xcode-select'
|
data/lib/xcskarel.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
module XCSKarel
|
2
|
+
module Application
|
3
|
+
def self.choose_bot(server)
|
4
|
+
all_bots = server.get_bots
|
5
|
+
bot_names = all_bots.map { |json| "#{json['name']} (#{json['_id']})" }
|
6
|
+
puts "Which Bot should be used as a template?"
|
7
|
+
choice = choose(*bot_names)
|
8
|
+
bot = all_bots[bot_names.index(choice)]
|
9
|
+
XCSKarel.log.info "Chose Bot \"#{bot['name']}\""
|
10
|
+
return bot
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.save_bot(config_folder, bot, api_version)
|
14
|
+
rand_name = XCSKarel::XCSFile.random_name
|
15
|
+
config_name = ask("Config name (hit Enter to accept generated name \"" + "#{rand_name}".yellow + "\"): ")
|
16
|
+
config_name = rand_name if config_name.length == 0
|
17
|
+
|
18
|
+
# preprocess the config name first
|
19
|
+
require 'uri'
|
20
|
+
config_name = URI::escape(config_name.gsub(" ", "_"))
|
21
|
+
|
22
|
+
real_name = "botconfig_#{config_name}.json"
|
23
|
+
new_config_path = XCSKarel::XCSFile.new_config_name(config_folder, real_name)
|
24
|
+
new_config = XCSKarel::Config.new(bot, api_version, new_config_path)
|
25
|
+
new_config.save
|
26
|
+
|
27
|
+
XCSKarel.log.info "Saved Bot \"#{new_config.name}\" configuration to #{new_config_path}. Check this into your repository.".green
|
28
|
+
system "open \"#{new_config_path}\""
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.list_configs(config_folder)
|
32
|
+
configs = XCSKarel::XCSFile.load_configs(config_folder)
|
33
|
+
if configs.count == 0
|
34
|
+
XCSKarel.log.info "Found no existing configs in #{config_folder}".yellow
|
35
|
+
else
|
36
|
+
out = "\n" + configs.map { |c| "\"#{c.name}\"".yellow + " [#{File.basename(c.path)}]".yellow + " - from Bot " + "#{c.original_bot_name}".yellow }.join("\n")
|
37
|
+
XCSKarel.log.info "Found #{configs.count} configs in \"#{config_folder}\":"
|
38
|
+
XCSKarel.log.info out
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.show_config(config_folder)
|
43
|
+
configs = XCSKarel::XCSFile.load_configs(config_folder)
|
44
|
+
config_names = configs.map { |c| "Config " + "#{c.name}".yellow + " from Bot " + "#{c.original_bot_name}".yellow }
|
45
|
+
puts "Which config?"
|
46
|
+
choice = choose(*config_names)
|
47
|
+
config = configs[config_names.index(choice)]
|
48
|
+
XCSKarel.log.info "Editing config \"#{config.name}\""
|
49
|
+
system "open \"#{config.path}\""
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module XCSKarel
|
2
|
+
class Config
|
3
|
+
attr_reader :json
|
4
|
+
attr_reader :path
|
5
|
+
attr_reader :api_version
|
6
|
+
|
7
|
+
def initialize(json, api_version, path)
|
8
|
+
@json = json
|
9
|
+
@path = path
|
10
|
+
@api_version = api_version || (config_json ? config_json['api_version'] : nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
(config_json['name'] || File.basename(@path).split('.').first).gsub("botconfig_", "")
|
15
|
+
end
|
16
|
+
|
17
|
+
def original_bot_name
|
18
|
+
@json['name'] || config_json['original_bot_name']
|
19
|
+
end
|
20
|
+
|
21
|
+
def config_json
|
22
|
+
@json['xcsconfig'] || {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def key_paths_for_persistance
|
26
|
+
key_paths_for_xcode_server << "xcsconfig"
|
27
|
+
end
|
28
|
+
|
29
|
+
def key_paths_for_xcode_server
|
30
|
+
["configuration"]
|
31
|
+
end
|
32
|
+
|
33
|
+
def format_version
|
34
|
+
1
|
35
|
+
end
|
36
|
+
|
37
|
+
def json_for_persistence
|
38
|
+
filtered = XCSKarel::Filter.filter_key_paths(@json, key_paths_for_persistance)
|
39
|
+
|
40
|
+
# also add xcsconfig metadata
|
41
|
+
unless filtered["xcsconfig"]
|
42
|
+
filtered["xcsconfig"] = {
|
43
|
+
format_version: format_version,
|
44
|
+
app_version: XCSKarel::VERSION,
|
45
|
+
original_bot_name: @json['name'],
|
46
|
+
name: name,
|
47
|
+
api_version: @api_version
|
48
|
+
}
|
49
|
+
end
|
50
|
+
return filtered
|
51
|
+
end
|
52
|
+
|
53
|
+
def json_for_xcode_server
|
54
|
+
XCSKarel::Filter.filter_key_paths(@json, key_paths_for_xcode_server)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.from_file(file_path)
|
58
|
+
abs_path = File.absolute_path(file_path)
|
59
|
+
raise "No file #{abs_path}" unless File.exist?(abs_path)
|
60
|
+
config = self.new(JSON.parse(File.read(abs_path)), nil, abs_path)
|
61
|
+
unless config.validate_loaded
|
62
|
+
XCSKarel.log.warn "Skipping invalid config #{abs_path}".yellow
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
return config
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_loaded
|
69
|
+
return false unless config_json
|
70
|
+
return true
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_file(file_path)
|
74
|
+
abs_path = File.absolute_path(file_path)
|
75
|
+
raise "File #{abs_path} already exists. Choose a different name.".red if File.exist?(abs_path)
|
76
|
+
FileUtils.mkdir_p(File.dirname(abs_path))
|
77
|
+
File.open(abs_path, 'w') do |f|
|
78
|
+
f.puts JSON.pretty_generate(json_for_persistence) + "\n"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def save
|
83
|
+
to_file(@path)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/xcskarel/filter.rb
CHANGED
@@ -24,7 +24,9 @@ module XCSKarel
|
|
24
24
|
key.split('.').first == keys.first
|
25
25
|
end.first
|
26
26
|
if match
|
27
|
-
|
27
|
+
child_key_paths = match.split('.').drop(1)
|
28
|
+
# if there are no more key paths, we just take everything (whitelisted by default)
|
29
|
+
new_hash[keys.first] = child_key_paths.count == 0 ? v : filter_key_paths(v, child_key_paths)
|
28
30
|
end
|
29
31
|
end
|
30
32
|
return new_hash
|
data/lib/xcskarel/server.rb
CHANGED
@@ -11,6 +11,7 @@ module XCSKarel
|
|
11
11
|
attr_reader :user
|
12
12
|
attr_reader :pass
|
13
13
|
attr_reader :port
|
14
|
+
attr_reader :api_version
|
14
15
|
|
15
16
|
def initialize(host, user=nil, pass=nil, allow_self_signed=true)
|
16
17
|
@port = 20343
|
@@ -88,7 +89,8 @@ module XCSKarel
|
|
88
89
|
raise "Failed to validate - #{e}.\nPlease make sure your Xcode Server is up and running at #{host}. Run `xcskarel server start` to start a new local Xcode Server instance.".red
|
89
90
|
else
|
90
91
|
raise "Failed to validate - Endpoint at \"#{url}\" responded with #{response.data[:status_line]}".red if response.status != 204
|
91
|
-
|
92
|
+
@api_version = response.headers['X-XCSAPIVersion'].to_s
|
93
|
+
XCSKarel.log.debug "Validation of host #{@host} (API version #{@api_version}) succeeded.".green
|
92
94
|
end
|
93
95
|
end
|
94
96
|
end
|
data/lib/xcskarel/version.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
module XCSKarel
|
2
|
+
module XCSFile
|
3
|
+
def self.folder_name
|
4
|
+
"xcsconfig"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.file_name
|
8
|
+
"xcsfile.json"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_config_folder_in_current_folder
|
12
|
+
self.find_config_folder_in_folder(Dir.pwd)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.find_config_folder_in_folder(folder)
|
16
|
+
# look for the xcsconfig folder with an xcsfile inside
|
17
|
+
abs_folder = File.absolute_path(folder)
|
18
|
+
found_folder = Dir[File.join(abs_folder, "/", "*")].select do |f|
|
19
|
+
File.basename(f) == self.folder_name
|
20
|
+
end.first
|
21
|
+
return found_folder
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.create_config_folder_in_current_folder
|
25
|
+
self.create_config_folder_in_folder(Dir.pwd)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.create_config_folder_in_folder(folder)
|
29
|
+
abs_folder = File.absolute_path(folder)
|
30
|
+
config_folder = File.join(abs_folder, self.folder_name)
|
31
|
+
FileUtils.mkdir_p(config_folder)
|
32
|
+
return config_folder
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_config_folder
|
36
|
+
config_folder = XCSKarel::XCSFile.find_config_folder_in_current_folder
|
37
|
+
unless config_folder
|
38
|
+
should_create = agree("There is no xcsconfig folder found, should I create one for you? (y/n)".red)
|
39
|
+
if should_create
|
40
|
+
config_folder = XCSKarel::XCSFile.create_config_folder_in_current_folder unless config_folder
|
41
|
+
XCSKarel.log.debug "Folder #{config_folder} created".yellow
|
42
|
+
else
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# we have a config folder
|
47
|
+
XCSKarel.log.debug "Config folder found: #{config_folder}".green
|
48
|
+
return config_folder
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.load_configs(folder)
|
52
|
+
require 'json'
|
53
|
+
Dir[File.join(folder, "/", "botconfig_*.json")].map do |f|
|
54
|
+
XCSKarel::Config.from_file(f)
|
55
|
+
end.select do |c|
|
56
|
+
c != nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.random_name
|
61
|
+
require 'securerandom'
|
62
|
+
"#{SecureRandom.hex(6)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.new_config_name(folder, name)
|
66
|
+
name = name.split('.').first + ".json"
|
67
|
+
File.join(folder, name)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/spec/filter_spec.rb
CHANGED
@@ -43,6 +43,25 @@ describe XCSKarel do
|
|
43
43
|
expect(test(obj, ["oranges.old"])).to eq(exp)
|
44
44
|
end
|
45
45
|
|
46
|
+
it "keeps full values when hashes and key is already whitelisted" do
|
47
|
+
obj = {
|
48
|
+
"apples" => "green",
|
49
|
+
"blackberries" => 12,
|
50
|
+
"oranges" => {
|
51
|
+
"new" => 2,
|
52
|
+
"old" => -2
|
53
|
+
}
|
54
|
+
}
|
55
|
+
exp = {
|
56
|
+
"apples" => "green",
|
57
|
+
"oranges" => {
|
58
|
+
"new" => 2,
|
59
|
+
"old" => -2
|
60
|
+
}
|
61
|
+
}
|
62
|
+
expect(test(obj, ["oranges", "apples"])).to eq(exp)
|
63
|
+
end
|
64
|
+
|
46
65
|
it "handles basic key path with an array without popping the key path" do
|
47
66
|
obj = [
|
48
67
|
"apples",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcskarel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Honza Dvorsky
|
@@ -174,12 +174,14 @@ extra_rdoc_files: []
|
|
174
174
|
files:
|
175
175
|
- bin/xcskarel
|
176
176
|
- lib/xcskarel.rb
|
177
|
-
- lib/xcskarel/
|
177
|
+
- lib/xcskarel/application.rb
|
178
|
+
- lib/xcskarel/config.rb
|
178
179
|
- lib/xcskarel/control.rb
|
179
180
|
- lib/xcskarel/filter.rb
|
180
181
|
- lib/xcskarel/log.rb
|
181
182
|
- lib/xcskarel/server.rb
|
182
183
|
- lib/xcskarel/version.rb
|
184
|
+
- lib/xcskarel/xcsfile.rb
|
183
185
|
- spec/default_spec.rb
|
184
186
|
- spec/filter_spec.rb
|
185
187
|
homepage: http://github.com/czechboy0/xcskarel
|
data/lib/xcskarel/bot.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module XCSKarel
|
2
|
-
class Bot
|
3
|
-
attr_reader :json
|
4
|
-
def initialize(json)
|
5
|
-
@json = json
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.from_file(file_path)
|
9
|
-
abs_path = File.absolute_path(file_path)
|
10
|
-
raise "No file #{abs_path}" unless File.exist?(abs_path)
|
11
|
-
self.new(File.read(abs_path))
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_file(file_path="./xcskarel/bot.json")
|
15
|
-
abs_path = File.absolute_path(file_path)
|
16
|
-
raise "File #{abs_path} already exists." if File.exist?(abs_path)
|
17
|
-
FileUtils.mkdir_p(File.dirname(abs_path))
|
18
|
-
File.open(abs_path, 'w') do |f|
|
19
|
-
f.puts JSON.pretty_generate(@json) + "\n"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|