xcskarel 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9989b96aa6ff52cf3fc52a82ec381ba4410d62f4
4
- data.tar.gz: cd7fff217976a40c5405f96daf2ff3f043f5a77e
3
+ metadata.gz: b2d2ee90682d97c41330da69045be0e7d247e205
4
+ data.tar.gz: 64564df685430fb56aa6af4e47a402f9fd2e4022
5
5
  SHA512:
6
- metadata.gz: d32ad6a22b710bd163c14a188b4ff804bba907808204efe46fba78867979f86f9918c86307bb2831c9e82504d2f065848645d869fe4fcb256c9d76cf22b12bd9
7
- data.tar.gz: 35443b16521422e86b5f183a22c6ba1689385bf265e3dc13c0e4e096f72de0f20779cacf89e14e4b53b52f280b3cb1dfde6d155ad6d353de2761f42af1ad3aa5
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
@@ -4,4 +4,6 @@ require 'xcskarel/version'
4
4
  require 'xcskarel/log'
5
5
  require 'xcskarel/filter'
6
6
  require 'xcskarel/control'
7
- require 'xcskarel/bot'
7
+ require 'xcskarel/config'
8
+ require 'xcskarel/xcsfile'
9
+ require 'xcskarel/application'
@@ -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
@@ -24,7 +24,9 @@ module XCSKarel
24
24
  key.split('.').first == keys.first
25
25
  end.first
26
26
  if match
27
- new_hash[keys.first] = filter_key_paths(v, match.split('.').drop(1))
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
@@ -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
- XCSKarel.log.debug "Validation of host #{@host} succeeded.".green
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
@@ -1,3 +1,3 @@
1
1
  module XCSKarel
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -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.7.1
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/bot.rb
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