flow-cli 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21fd812ff71af588d84221a5db5edff651e5fe85
4
- data.tar.gz: 83886130d5a88d1d594a425d6ab0db2aa427fae2
3
+ metadata.gz: a2fa6031aa449ee4371cfa829a9935792127aa99
4
+ data.tar.gz: 4ae2ae1777e0a4b18f3b37e4534a561bcbf831d2
5
5
  SHA512:
6
- metadata.gz: e312ff26145629f00ae94d5894561bb954c5359db18fde128eec3107da3d7cdd6aaa2d959ecd1e59478799d7172b39e2fa3f8a0675b766cd23a8598f0c356cc2
7
- data.tar.gz: a9b08da5091376a43217d14c5018a5bd9a8e96dd192befec7a4e301f56927a15d45b6298d6043072fcb14dced5d47440aee4bc291ee7bb1a6e1b3e7b287bc45e
6
+ metadata.gz: d0ecd916f4dbb0a6c459d8270f0137de90d41e6f171edaa1aa33c14c59b9d62e31e1b02ab568eb943c3de5818ec814286d5c198e9cd9e944b4d4c0b3b6c3e983
7
+ data.tar.gz: 5de248002899ab72f88af68ba13fda40a2ded7250ccfcc3bd7091d75ff15db68b31a56bf322e4b2532a62fbbfa434cedf1a67aa3a7acf83408b09add58b3a0d3
data/flow-cli.gemspec CHANGED
@@ -32,6 +32,8 @@ Gem::Specification.new do |spec|
32
32
  ****************************************************
33
33
  这是 flow.ci CLI 的早期版本,暂时只支持 ios 项目
34
34
 
35
+ 0.0.3 版本新增 flow-cli remote 系列指令,支持传证书,传provisions 文件
36
+
35
37
  )
36
38
 
37
39
  spec.add_development_dependency "bundler", "~> 1.14"
@@ -41,7 +43,9 @@ Gem::Specification.new do |spec|
41
43
  spec.add_development_dependency "rubocop"
42
44
  spec.add_development_dependency "byebug"
43
45
 
44
- spec.add_dependency "thor", ">= 0.15"
45
- spec.add_dependency "tty", ">= 0.7"
46
- spec.add_dependency "fastlane", ">= 2.28"
46
+ spec.add_dependency "thor", "~> 0.18"
47
+ spec.add_dependency "tty", "~> 0.7"
48
+ spec.add_dependency "fastlane", "~> 2.28"
49
+ spec.add_dependency "oj", "~> 2"
50
+ spec.add_dependency "rest-client"
47
51
  end
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'tty'
3
3
  require 'thor'
4
+ require_relative './commands/remote'
4
5
 
5
6
  module Flow::Cli
6
7
  class CmdManager < Thor
@@ -10,12 +11,16 @@ module Flow::Cli
10
11
  @pastel = Pastel.new
11
12
  @error = @pastel.red.bold.detach
12
13
  @warning = @pastel.yellow.detach
14
+ @db_manager = Utils::DbManager
15
+ @api_manager = Utils::FlowApiManager.load_from_db
13
16
  end
14
17
 
18
+ desc "remote ...ARGS", "manage flow ci"
19
+ subcommand "remote", Commands::Remote
20
+
15
21
  desc "build_yaml_file", "build flow ci project yaml"
16
22
  def build_yaml_file
17
23
  config = ProjectAnalytics.new.config
18
-
19
24
  # 用来交互
20
25
  # TODO: 优化点,以后放到其他地方
21
26
  config[:gym_config] = ask_gym_build_options if config[:flow_language] == "objc" && ENV["FLOW_CLI_TEST"] != "TRUE"
@@ -43,7 +48,7 @@ module Flow::Cli
43
48
  print_line
44
49
  end
45
50
 
46
- desc "version", "show flow cli version"
51
+ desc "version", "show flow cli version #{VERSION}"
47
52
  map ['v', '-v', '--version'] => :version
48
53
  def version
49
54
  puts VERSION
@@ -0,0 +1,102 @@
1
+ require 'yaml'
2
+ require 'tty'
3
+ require 'thor'
4
+
5
+ module Flow::Cli
6
+ module Commands
7
+ class Remote < Thor
8
+ def initialize(*args)
9
+ super(*args)
10
+ @prompt = TTY::Prompt.new
11
+ @pastel = Pastel.new
12
+ @error = @pastel.red.bold.detach
13
+ @warning = @pastel.yellow.detach
14
+ @db_manager = Utils::DbManager
15
+ @api_manager = Utils::FlowApiManager.load_from_db
16
+ end
17
+
18
+ desc "login", "bind flow ci account to flow cli."
19
+ def login
20
+ email = @prompt.ask("email?")
21
+ password = @prompt.mask("password?")
22
+ Utils::FlowApiManager.login(email, password)
23
+ puts "login success"
24
+ end
25
+
26
+ desc "project_init", "set a project from flow ci to operation"
27
+ def project_init
28
+ projects = @api_manager.fetch_projects
29
+ begin
30
+ file_origin = `git remote -v`.to_s.match("git.*.git").first
31
+ rescue
32
+ puts @warning.call "read git origin fail..."
33
+ end
34
+
35
+ dict = {}
36
+ dict = Hash[projects.map { |p| [p[:name].to_s, p[:id]] }]
37
+
38
+ current_project_id = @prompt.select("Choose your project?", dict)
39
+
40
+ @db_manager.save_attribute(:current_project_id, current_project_id)
41
+
42
+ flows = @api_manager.fetch_flows(current_project_id)
43
+
44
+ current_flow_id = if flows.count == 1
45
+ flows.first[:id]
46
+ else
47
+ dict = {}
48
+ flows.each { |p| dict[(p[:name]).to_s] = p[:id] }
49
+ @prompt.select("Choose your flow?", dict)
50
+ end
51
+ @db_manager.save_attribute(:current_flow_id, current_flow_id)
52
+ puts "project_id = #{current_project_id}, flow_id = #{current_flow_id}. saved this info..."
53
+ end
54
+
55
+ desc "upload_p12 FILE_PATH [p12 password]", "upload_p12"
56
+ def upload_p12(file_path, password = nil)
57
+ basename = File.basename file_path
58
+ project_init unless @db_manager.read_attribute(:current_flow_id)
59
+
60
+ api_p12s = @api_manager.load_p12s(@db_manager.read_attribute(:current_flow_id))
61
+ old_p12 = api_p12s.find { |p12| p12[:filename] == basename }
62
+ unless old_p12.nil?
63
+ if @prompt.yes? "found a same name file, override?"
64
+ @api_manager.delete_p12(old_p12[:id], @db_manager.read_attribute(:current_flow_id))
65
+ else
66
+ return puts "canceled.."
67
+ end
68
+ end
69
+ @api_manager.upload_p12(@db_manager.read_attribute(:current_flow_id), file_path, password)
70
+ puts "uploaded."
71
+ end
72
+
73
+ desc "list_p12s", "list_p12s"
74
+ def list_p12s
75
+ puts @api_manager.load_p12s(@db_manager.read_attribute(:current_flow_id))
76
+ end
77
+
78
+ desc "upload_provision", "upload_provision"
79
+ def upload_provision(file_path)
80
+ basename = File.basename file_path
81
+ project_init unless @db_manager.read_attribute(:current_flow_id)
82
+
83
+ api_provisions = @api_manager.load_provisions(@db_manager.read_attribute(:current_flow_id))
84
+ old_provision = api_provisions.find { |provision| provision[:filename] == basename }
85
+ unless old_provision.nil?
86
+ if @prompt.yes? "found a same name file, override?"
87
+ @api_manager.delete_provision(old_provision[:id], @db_manager.read_attribute(:current_flow_id))
88
+ else
89
+ return puts "canceled.."
90
+ end
91
+ end
92
+ @api_manager.upload_provision(@db_manager.read_attribute(:current_flow_id), file_path)
93
+ puts "uploaded."
94
+ end
95
+
96
+ desc "list_provisions", "list provisions"
97
+ def list_provisions
98
+ puts @api_manager.load_provisions(@db_manager.read_attribute(:current_flow_id))
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,5 +1,6 @@
1
1
  module Flow
2
2
  module Cli
3
3
  FLOW_YML_NAME = "flow.yml".freeze
4
+ FLOW_API_URL = "http://api.flow.ci"
4
5
  end
5
6
  end
@@ -0,0 +1,4 @@
1
+ require_relative './local_service_rest'
2
+ require_relative './flow_api_rest'
3
+ require_relative './db_manager'
4
+ require_relative './api/flow_api_manager'
@@ -0,0 +1,106 @@
1
+ require_relative "../flow_api_rest"
2
+ module Flow::Cli
3
+ module Utils
4
+ class FlowApiManager
5
+ attr_accessor :email, :password, :user_access_token, :current_org_id,
6
+ :current_project_id, :current_flow_id,
7
+ :current_project_name
8
+
9
+ def initialize(hash = {})
10
+ %i[email password user_access_token].each do |item|
11
+ send "#{item}=", hash[item.to_s]
12
+ end
13
+ yield self if block_given?
14
+ init_access_token if user_access_token.nil?
15
+ end
16
+
17
+ def fetch_orgs
18
+ raw_orgs = FlowApiRest.get("/orgs", access_token: user_access_token)
19
+ raw_orgs.map do |org|
20
+ org.slice(:id, :name)
21
+ end
22
+ end
23
+
24
+ def fetch_projects(specify_org_id = nil)
25
+ org_id = specify_org_id || current_org_id
26
+ send_to_api(:get, "/projects", { org_id: org_id }, %i[id name git_url source])
27
+ end
28
+
29
+ def fetch_project(project_id)
30
+ send_to_api(:get, "/projects/#{project_id}")
31
+ end
32
+
33
+ def fetch_flows(project_id)
34
+ send_to_api(:get, "/projects/#{project_id}/flows")
35
+ end
36
+
37
+ # 5909e8c4ef2cb07bcefc3dbd
38
+ def upload_p12(flow_id, file, password = nil)
39
+ send_to_api(:post, "/flows/#{flow_id}/certificates",
40
+ file: standard_file(file),
41
+ type: "ios",
42
+ password: password)
43
+ end
44
+
45
+ def load_p12s(flow_id)
46
+ send_to_api(:get, "/flows/#{flow_id}/certificates")
47
+ end
48
+
49
+ def delete_p12(p12_id, flow_id)
50
+ send_to_api(:delete, "/certificates/#{p12_id}", flow_id: flow_id)
51
+ end
52
+
53
+ def upload_provision(flow_id, file)
54
+ send_to_api(:post, "/flows/#{flow_id}/mobileprovisions",
55
+ file: standard_file(file),
56
+ flow_id: flow_id)
57
+ end
58
+
59
+ def load_provisions(flow_id)
60
+ send_to_api(:get, "/flows/#{flow_id}/mobileprovisions")
61
+ end
62
+
63
+ def delete_provision(mobileprovisions_id,flow_id)
64
+ send_to_api(:delete, "/mobileprovisions/#{mobileprovisions_id}", flow_id: flow_id)
65
+ end
66
+
67
+ def fetch_flow(flow_id, project_id)
68
+ send_to_api(:get, "/flows/#{flow_id}", project_id: project_id)
69
+ end
70
+
71
+ def send_to_api(action, url, params = {}, slice_items = nil, need_access_token = true)
72
+ params[:access_token] = user_access_token if need_access_token
73
+ params.compact!
74
+ raw_answer = FlowApiRest.send(action, url, params)
75
+
76
+ return raw_answer if slice_items.nil?
77
+ raise "slice need be a array with symbols" unless slice_items.is_a? Array
78
+
79
+ return raw_answer.map { |item| item.slice(*slice_items) } if raw_answer.is_a? Array
80
+ raw_answer.slice(*slice_items)
81
+ end
82
+
83
+ def init_access_token
84
+ answer = self.class.login(email, password)
85
+ self.user_access_token = answer[:access_token]
86
+ end
87
+
88
+ def standard_file(file)
89
+ return File.open(file) if file.is_a?(String)
90
+ file
91
+ end
92
+
93
+ class << self
94
+ def login(email, password)
95
+ dict = FlowApiRest.post("/login", login: email, password: password)
96
+ DbManager.save(email: email, password: password)
97
+ dict
98
+ end
99
+
100
+ def load_from_db
101
+ new(DbManager.read)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,45 @@
1
+ require 'yaml'
2
+
3
+ module Flow::Cli
4
+ module Utils
5
+ class DbManager
6
+ class << self
7
+ FLOW_CLI_CONFIG = "#{ENV['HOME']}/.flow_cli_config.yml".freeze
8
+
9
+ def overide_save(hash)
10
+ File.open(FLOW_CLI_CONFIG, "w") do |file|
11
+ file << hash.to_yaml
12
+ end
13
+ hash
14
+ end
15
+
16
+ def save(settings)
17
+ old = read
18
+ settings = old.merge(settings).compact.stringify_keys
19
+ yaml = settings.to_yaml
20
+ File.open(FLOW_CLI_CONFIG, "w") do |file|
21
+ file << yaml
22
+ end
23
+ settings
24
+ end
25
+
26
+ def save_attribute(key, val)
27
+ dict = read
28
+ dict[key.to_s] = val
29
+ save(dict)
30
+ end
31
+
32
+ def read
33
+ return {} unless File.file?(FLOW_CLI_CONFIG)
34
+ config = YAML.safe_load(File.read(FLOW_CLI_CONFIG))
35
+ raise "yaml load is not a hash #{config.class}" unless config.is_a? Hash
36
+ config
37
+ end
38
+
39
+ def read_attribute(key)
40
+ read[key.to_s]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ require_relative './local_service_rest'
2
+ module Flow::Cli
3
+ module Utils
4
+ class FlowApiRest < LocalServiceRest
5
+ class << self
6
+ def basic_url
7
+ FLOW_API_URL # 子类中复写
8
+ end
9
+
10
+ %i[get delete head post patch put].each do |method|
11
+ alias_method "#{method}_old", method
12
+ define_method method do |*args, &blk|
13
+ ret = __send__ "#{method}_old", *args, &blk
14
+ raise "response_body = #{ret[:response_body]}" if ret.is_a?(Hash) && ret[:status] == false
15
+ ret
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,108 @@
1
+ require 'oj'
2
+ require 'json'
3
+ require 'rest-client'
4
+
5
+ module Flow::Cli
6
+ module Utils
7
+ class LocalServiceRest
8
+ class Error < StandardError; end
9
+ class JSONParseError < Error; end
10
+ class << self
11
+ %w[get delete head].each do |word|
12
+ define_method word.to_sym do |url, params = {}, timeout = 10, retry_times = 5|
13
+ params.merge!(add_those_to_params) # 将默认参数添加到params 里
14
+ url = basic_url + url
15
+ exception = nil
16
+ retry_times.times do
17
+ begin
18
+ headers = json_content_type
19
+ headers[:params] = if headers[:params]
20
+ headers[:params].merge(params)
21
+ else
22
+ params
23
+ end
24
+ response = ::RestClient::Request.execute(
25
+ method: word,
26
+ url: url,
27
+ headers: headers,
28
+ timeout: timeout
29
+ )
30
+ return ::Oj.load(response.body, symbol_keys: true)
31
+ rescue ::Oj::Error
32
+ raise ::LocalServiceRest::JSONParseError('返回的内容JSON解析失败')
33
+ rescue ::RestClient::ExceptionWithResponse => ex # 有返回的错误
34
+ raise ex unless ex.http_code.to_i < 500 && ex.http_code.to_i >= 300 # 这里主要是服务器返回了500 了,没必要解析body
35
+ return { # 这里是服务器有返回的错误,都应该是json 格式的
36
+ status: false,
37
+ json: ::Oj.load(ex.response.body, symbol_keys: true),
38
+ response_body: ex.response.body,
39
+ message: ex.message
40
+ }
41
+ rescue RestClient::Exception => e
42
+ exception = e
43
+ next
44
+ end
45
+ end
46
+ raise exception
47
+ end
48
+ end
49
+
50
+ %w[post patch put].each do |word|
51
+ define_method word.to_sym do |url, payload, timeout = 5, retry_times = 5|
52
+ payload = add_something_to_payload(payload)
53
+ url = build_valid_url(url)
54
+ exception = nil
55
+ retry_times.times do
56
+ begin
57
+ request = ::RestClient::Request.execute(
58
+ method: word,
59
+ url: url,
60
+ payload: payload,
61
+ headers: json_content_type,
62
+ timeout: timeout
63
+ )
64
+ return ::Oj.load(request.body, symbol_keys: true)
65
+ rescue ::Oj::Error
66
+ raise ::LocalServiceRest::JSONParseError('返回的内容JSON解析失败')
67
+ rescue ::RestClient::ExceptionWithResponse => ex # 有返回的错误
68
+ raise ex unless ex.http_code < 500 && ex.http_code >= 300
69
+ return {
70
+ status: false,
71
+ json: ::Oj.load(ex.response.body, symbol_keys: true),
72
+ response_body: ex.response.body,
73
+ message: ex.message
74
+ }
75
+ rescue RestClient::Exception => e
76
+ exception = e
77
+ next
78
+ end
79
+ end
80
+ raise exception
81
+ end
82
+ end
83
+
84
+ def build_valid_url(url)
85
+ add_params = URI.escape(add_those_to_params.collect { |k, v| "#{k}=#{v}" }.join('&'))
86
+ tmp = url.include?('?') ? '&' : '?'
87
+ basic_url + url + tmp + add_params
88
+ end
89
+
90
+ def add_something_to_payload(payload)
91
+ payload.merge(add_those_to_params)
92
+ end
93
+
94
+ def json_content_type
95
+ { accept: :json }
96
+ end
97
+
98
+ def basic_url
99
+ 'http://www.example.com' # 子类中复写
100
+ end
101
+
102
+ def add_those_to_params
103
+ {} # 子类中复写
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,4 +1,59 @@
1
1
  class Hash
2
+ # Slice a hash to include only the given keys. Returns a hash containing
3
+ # the given keys.
4
+ #
5
+ # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
6
+ # # => {:a=>1, :b=>2}
7
+ #
8
+ # This is useful for limiting an options hash to valid keys before
9
+ # passing to a method:
10
+ #
11
+ # def search(criteria = {})
12
+ # criteria.assert_valid_keys(:mass, :velocity, :time)
13
+ # end
14
+ #
15
+ # search(options.slice(:mass, :velocity, :time))
16
+ #
17
+ # If you have an array of keys you want to limit to, you should splat them:
18
+ #
19
+ # valid_keys = [:mass, :velocity, :time]
20
+ # search(options.slice(*valid_keys))
21
+ def slice(*keys)
22
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
23
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
24
+ end
25
+
26
+ # Replaces the hash with only the given keys.
27
+ # Returns a hash containing the removed key/value pairs.
28
+ #
29
+ # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
30
+ # # => {:c=>3, :d=>4}
31
+ def slice!(*keys)
32
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
33
+ omit = slice(*self.keys - keys)
34
+ hash = slice(*keys)
35
+ hash.default = default
36
+ hash.default_proc = default_proc if default_proc
37
+ replace(hash)
38
+ omit
39
+ end
40
+
41
+ # Removes and returns the key/value pairs matching the given keys.
42
+ #
43
+ # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
44
+ # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
45
+ def extract!(*keys)
46
+ keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if key?(key) }
47
+ end
48
+
49
+ def compact
50
+ reject { |_, value| value.nil? }
51
+ end
52
+
53
+ def compact!
54
+ reject! { |_, value| value.nil? }
55
+ end
56
+
2
57
  # Returns a new hash with all keys converted using the +block+ operation.
3
58
  #
4
59
  # hash = { name: 'Rob', age: '28' }
@@ -52,16 +107,28 @@ class Hash
52
107
  # hash.symbolize_keys
53
108
  # # => {:name=>"Rob", :age=>"28"}
54
109
  def symbolize_keys
55
- transform_keys { |key| key.to_sym rescue key }
110
+ transform_keys do |key|
111
+ begin
112
+ key.to_sym
113
+ rescue
114
+ key
115
+ end
116
+ end
56
117
  end
57
- alias_method :to_options, :symbolize_keys
118
+ alias to_options symbolize_keys
58
119
 
59
120
  # Destructively converts all keys to symbols, as long as they respond
60
121
  # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
61
122
  def symbolize_keys!
62
- transform_keys! { |key| key.to_sym rescue key }
123
+ transform_keys! do |key|
124
+ begin
125
+ key.to_sym
126
+ rescue
127
+ key
128
+ end
129
+ end
63
130
  end
64
- alias_method :to_options!, :symbolize_keys!
131
+ alias to_options! symbolize_keys!
65
132
 
66
133
  # Validates all keys in a hash match <tt>*valid_keys</tt>, raising
67
134
  # +ArgumentError+ on a mismatch.
@@ -76,7 +143,7 @@ class Hash
76
143
  valid_keys.flatten!
77
144
  each_key do |k|
78
145
  unless valid_keys.include?(k)
79
- raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
146
+ raise ArgumentError, "Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}"
80
147
  end
81
148
  end
82
149
  end
@@ -128,43 +195,56 @@ class Hash
128
195
  # hash.deep_symbolize_keys
129
196
  # # => {:person=>{:name=>"Rob", :age=>"28"}}
130
197
  def deep_symbolize_keys
131
- deep_transform_keys { |key| key.to_sym rescue key }
198
+ deep_transform_keys do |key|
199
+ begin
200
+ key.to_sym
201
+ rescue
202
+ key
203
+ end
204
+ end
132
205
  end
133
206
 
134
207
  # Destructively converts all keys to symbols, as long as they respond
135
208
  # to +to_sym+. This includes the keys from the root hash and from all
136
209
  # nested hashes and arrays.
137
210
  def deep_symbolize_keys!
138
- deep_transform_keys! { |key| key.to_sym rescue key }
211
+ deep_transform_keys! do |key|
212
+ begin
213
+ key.to_sym
214
+ rescue
215
+ key
216
+ end
217
+ end
139
218
  end
140
219
 
141
220
  private
142
- # support methods for deep transforming nested hashes and arrays
143
- def _deep_transform_keys_in_object(object, &block)
144
- case object
145
- when Hash
146
- object.each_with_object({}) do |(key, value), result|
147
- result[yield(key)] = _deep_transform_keys_in_object(value, &block)
148
- end
149
- when Array
150
- object.map { |e| _deep_transform_keys_in_object(e, &block) }
151
- else
152
- object
221
+
222
+ # support methods for deep transforming nested hashes and arrays
223
+ def _deep_transform_keys_in_object(object, &block)
224
+ case object
225
+ when Hash
226
+ object.each_with_object({}) do |(key, value), result|
227
+ result[yield(key)] = _deep_transform_keys_in_object(value, &block)
153
228
  end
229
+ when Array
230
+ object.map { |e| _deep_transform_keys_in_object(e, &block) }
231
+ else
232
+ object
154
233
  end
234
+ end
155
235
 
156
- def _deep_transform_keys_in_object!(object, &block)
157
- case object
158
- when Hash
159
- object.keys.each do |key|
160
- value = object.delete(key)
161
- object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
162
- end
163
- object
164
- when Array
165
- object.map! { |e| _deep_transform_keys_in_object!(e, &block) }
166
- else
167
- object
236
+ def _deep_transform_keys_in_object!(object, &block)
237
+ case object
238
+ when Hash
239
+ object.keys.each do |key|
240
+ value = object.delete(key)
241
+ object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
168
242
  end
243
+ object
244
+ when Array
245
+ object.map! { |e| _deep_transform_keys_in_object!(e, &block) }
246
+ else
247
+ object
169
248
  end
249
+ end
170
250
  end
@@ -1,5 +1,5 @@
1
1
  module Flow
2
2
  module Cli
3
- VERSION = "0.0.2".freeze
3
+ VERSION = "0.0.3".freeze
4
4
  end
5
5
  end
data/lib/flow/cli.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require_relative "./cli/version"
2
2
  require_relative "./cli/constant"
3
3
  require_relative "./cli/vendors/all"
4
+ require_relative "./cli/utils/all"
4
5
  require_relative "./cli/exception"
6
+
5
7
  require_relative "./cli/project_analytics"
6
8
  require_relative "./cli/flow_yaml_builder"
7
9
  require_relative "./cli/ios_build_step_generator"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - atpking
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-10 00:00:00.000000000 Z
11
+ date: 2017-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -98,44 +98,72 @@ dependencies:
98
98
  name: thor
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.15'
103
+ version: '0.18'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.15'
110
+ version: '0.18'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: tty
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0.7'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.7'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: fastlane
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
131
  version: '2.28'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '2.28'
139
+ - !ruby/object:Gem::Dependency
140
+ name: oj
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '2'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rest-client
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
139
167
  description: Flow CI CLI, used to build yaml, run ci yaml locally.
140
168
  email:
141
169
  - atpking@gmail.com
@@ -159,11 +187,17 @@ files:
159
187
  - flow-cli.gemspec
160
188
  - lib/flow/cli.rb
161
189
  - lib/flow/cli/cmd_manager.rb
190
+ - lib/flow/cli/commands/remote.rb
162
191
  - lib/flow/cli/constant.rb
163
192
  - lib/flow/cli/exception.rb
164
193
  - lib/flow/cli/flow_yaml_builder.rb
165
194
  - lib/flow/cli/ios_build_step_generator.rb
166
195
  - lib/flow/cli/project_analytics.rb
196
+ - lib/flow/cli/utils/all.rb
197
+ - lib/flow/cli/utils/api/flow_api_manager.rb
198
+ - lib/flow/cli/utils/db_manager.rb
199
+ - lib/flow/cli/utils/flow_api_rest.rb
200
+ - lib/flow/cli/utils/local_service_rest.rb
167
201
  - lib/flow/cli/vendors/all.rb
168
202
  - lib/flow/cli/vendors/hash.rb
169
203
  - lib/flow/cli/version.rb
@@ -176,7 +210,7 @@ post_install_message: "\n _____ _ _____ ______ ___ ____ _ ___
176
210
  \\ /\\ / / | | | | | | | | |\n | _| | |__| |_| |\\ V V /| |___ | | |
177
211
  |___| |___ | |\n |_| |_____\\___/ \\_/\\_/(_)____|___| \\____|_____|___|\n\n
178
212
  ****************************************************\n 这是 flow.ci CLI 的早期版本,暂时只支持
179
- ios 项目\n\n "
213
+ ios 项目\n\n0.0.3 版本新增 flow-cli remote 系列指令,支持传证书,传provisions 文件\n\n "
180
214
  rdoc_options: []
181
215
  require_paths:
182
216
  - lib