flow-cli 0.0.2 → 0.0.3

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: 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