fir-cli 0.2.0 → 0.2.1.a
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/Gemfile.lock +2 -1
- data/README.md +89 -106
- data/fir-cli.gemspec +1 -0
- data/fir-cli.rb +5 -0
- data/lib/fir-cli/version.rb +1 -1
- data/lib/fir-cli-commands/00-login.rb +2 -2
- data/lib/fir-cli-commands/00-profile.rb +2 -2
- data/lib/fir-cli-commands/01-config.rb +2 -13
- data/lib/fir-cli-commands/100-resign_codesign.rb +54 -0
- data/lib/fir-cli-commands/{10-resign.rb → 100-resign_tapbeta.rb} +11 -11
- data/lib/fir-cli-commands/101-resign.rb +26 -0
- data/lib/fir-cli-commands/11-publish.rb +3 -3
- data/lib/fir-cli-commands/12-build_ipa.rb +14 -17
- data/lib/fir-cli.chk.rb +33 -0
- data/lib/fir-cli.core.rb +96 -0
- data/lib/{fir-cli.core.ext.rb → fir-cli.fir.rb} +16 -9
- data/lib/fir-cli.opt.rb +33 -0
- data/lib/fir-cli.output.rb +55 -0
- data/lib/fir-cli.utils.rb +105 -0
- data/lib/lagunitas.ext.rb +2 -2
- data/lib/lagunitas.patch.rb +2 -3
- metadata +26 -6
- data/lib/fir-cli.utils.ext.rb +0 -247
data/lib/fir-cli.utils.ext.rb
DELETED
@@ -1,247 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
module Fir
|
3
|
-
class Cli
|
4
|
-
def initialize(*args)
|
5
|
-
super
|
6
|
-
@tmpfiles = []
|
7
|
-
_init_config
|
8
|
-
_load_config
|
9
|
-
_puts_welcome
|
10
|
-
end
|
11
|
-
def self.find_extends
|
12
|
-
`gem list --local`
|
13
|
-
.each_line("\n")
|
14
|
-
.map { |gem| /^[^\s]+/.match(gem)[0] }
|
15
|
-
.select { |gem| true if gem.start_with? 'fir-cli-' }
|
16
|
-
end
|
17
|
-
def self.output_options
|
18
|
-
option :verbose,
|
19
|
-
:desc => '设置输出辅助信息的详细程度',
|
20
|
-
:type => :string,
|
21
|
-
:enum => ['v', 'vv', 'vvv']
|
22
|
-
option :quiet,
|
23
|
-
:aliases => '-q',
|
24
|
-
:desc => '安静模式,不输出任何辅助信息',
|
25
|
-
:type => 'boolean'
|
26
|
-
option :color,
|
27
|
-
:desc => '设置输出带有颜色的信息',
|
28
|
-
:type => 'boolean'
|
29
|
-
end
|
30
|
-
private
|
31
|
-
def _extends
|
32
|
-
@extends ||= Cli.find_extends
|
33
|
-
end
|
34
|
-
def _init_config
|
35
|
-
@uconfig = UserConfig.new '.fir'
|
36
|
-
@global_config = @uconfig['global.yaml']
|
37
|
-
end
|
38
|
-
def _load_config
|
39
|
-
@config = @uconfig[_profile]
|
40
|
-
end
|
41
|
-
def _profile
|
42
|
-
@global_config['profile'] || 'default.yaml'
|
43
|
-
end
|
44
|
-
def _path(path)
|
45
|
-
path = Pathname.new(Dir.pwd).join(path).cleanpath
|
46
|
-
end
|
47
|
-
no_commands do
|
48
|
-
%w(token email verbose origin branch).each do |_m|
|
49
|
-
define_method "_opt_#{_m}" do
|
50
|
-
unless instance_variable_get("@#{_m}")
|
51
|
-
instance_variable_set("@#{_m}", options[_m.to_sym] || @config[_m] )
|
52
|
-
end
|
53
|
-
instance_variable_get("@#{_m}")
|
54
|
-
end
|
55
|
-
private "_opt_#{_m}".to_sym
|
56
|
-
end
|
57
|
-
%w(publish resign quiet color trim).each do |_m|
|
58
|
-
define_method "_opt_#{_m}" do
|
59
|
-
return false if options[_m.to_sym] == false
|
60
|
-
unless instance_variable_get("@#{_m}")
|
61
|
-
instance_variable_set("@#{_m}", options[_m.to_sym] || @config[_m] )
|
62
|
-
end
|
63
|
-
instance_variable_get("@#{_m}")
|
64
|
-
end
|
65
|
-
private "_opt_#{_m}".to_sym
|
66
|
-
end
|
67
|
-
end
|
68
|
-
def _is_ipa(path)
|
69
|
-
path.end_with? '.ipa'
|
70
|
-
end
|
71
|
-
def _is_apk(path)
|
72
|
-
path.end_with? '.apk'
|
73
|
-
end
|
74
|
-
def _is_workspace(path)
|
75
|
-
path.end_with? '.xcworkspace'
|
76
|
-
end
|
77
|
-
def _is_xcodeproject(path)
|
78
|
-
path.end_with? '.xcodeproj'
|
79
|
-
end
|
80
|
-
def _is_identifier(str)
|
81
|
-
/^(?:(?:[a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*(?:[A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$/.match str
|
82
|
-
end
|
83
|
-
def _is_email(str)
|
84
|
-
/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)$/i.match str
|
85
|
-
end
|
86
|
-
def _chk_login(prompt = true)
|
87
|
-
if !_opt_token && prompt == true
|
88
|
-
token = _prompt_secret('请输入用户 token:')
|
89
|
-
@token = token if token.length > 0
|
90
|
-
end
|
91
|
-
if !@token
|
92
|
-
_puts_require_token
|
93
|
-
exit 1
|
94
|
-
elsif !_user(@token)
|
95
|
-
_puts_invalid_token
|
96
|
-
exit 1
|
97
|
-
end
|
98
|
-
end
|
99
|
-
def _prompt_secret(prompt)
|
100
|
-
ask(prompt) { |q| q.echo = false }
|
101
|
-
end
|
102
|
-
def _prompt(prompt)
|
103
|
-
ask(prompt) { |q| q }
|
104
|
-
end
|
105
|
-
def _puts(text)
|
106
|
-
return puts _format text if !/^[->!] /.match text
|
107
|
-
return if _opt_quiet
|
108
|
-
case _opt_verbose || 'vv' # If nothing about log is set, use the default option - vv
|
109
|
-
when 'v'
|
110
|
-
puts _format text if text.start_with?('!')
|
111
|
-
when 'vv'
|
112
|
-
puts _format text if text.start_with?('!') || text.start_with?('>')
|
113
|
-
when 'vvv'
|
114
|
-
puts _format text if text.start_with?('!') || text.start_with?('>') || text.start_with?('-')
|
115
|
-
end
|
116
|
-
end
|
117
|
-
def _format(text)
|
118
|
-
return text.gsub /\e\[\d+(?:;\d+)*m/, '' if _opt_color == false
|
119
|
-
text
|
120
|
-
end
|
121
|
-
def _puts_welcome
|
122
|
-
_puts "> #{Paint['欢迎使用 FIR.im 命令行工具,如需帮助请输入:', :green]} fir help"
|
123
|
-
end
|
124
|
-
def _puts_require_token
|
125
|
-
_puts "! #{Paint['用户 token 不能为空', :red]}"
|
126
|
-
end
|
127
|
-
def _puts_invalid_token
|
128
|
-
_puts "! #{Paint['输入的用户 token 不合法', :red]}"
|
129
|
-
end
|
130
|
-
def _puts_invalid_email
|
131
|
-
_puts "! #{Paint['输入的邮件地址不合法', :red]}"
|
132
|
-
end
|
133
|
-
def _info(path, more = false)
|
134
|
-
if _is_ipa path
|
135
|
-
_ipa_info path, more
|
136
|
-
elsif _is_apk path
|
137
|
-
_apk_info path, more
|
138
|
-
else
|
139
|
-
_puts "! #{Paint['只能支持后缀为 ipa 和 apk 的文件', :red]}"
|
140
|
-
exit 1
|
141
|
-
end
|
142
|
-
end
|
143
|
-
def _apk_info(path, more = false)
|
144
|
-
path = _path path
|
145
|
-
apk = Android::Apk.new path
|
146
|
-
info = {
|
147
|
-
:type => 'android',
|
148
|
-
:identifier => apk.manifest.package_name,
|
149
|
-
:name => apk.label,
|
150
|
-
:version => apk.manifest.version_code,
|
151
|
-
:short_version => apk.manifest.version_name
|
152
|
-
}
|
153
|
-
if more
|
154
|
-
info[:icons] = apk.icon.map do |name, data|
|
155
|
-
tfile = Tempfile.new ["icon-#{SecureRandom.hex}", '.png']
|
156
|
-
tfile.write data
|
157
|
-
@tmpfiles.push tfile
|
158
|
-
{
|
159
|
-
:name => File.basename(name),
|
160
|
-
:path => tfile.path
|
161
|
-
}
|
162
|
-
end
|
163
|
-
end
|
164
|
-
info
|
165
|
-
end
|
166
|
-
def _ipa_info(path, more = false)
|
167
|
-
path = _path path
|
168
|
-
ipa = Lagunitas::IPA.new path
|
169
|
-
_puts '> 正在解析 ipa 文件...'
|
170
|
-
app = ipa.app
|
171
|
-
info = {
|
172
|
-
:type => 'ios',
|
173
|
-
:identifier => app.identifier,
|
174
|
-
:name => app.name,
|
175
|
-
:display_name => app.display_name,
|
176
|
-
:version => app.version,
|
177
|
-
:short_version => app.short_version,
|
178
|
-
:devices => app.devices,
|
179
|
-
:release_type => app.release_type,
|
180
|
-
:distribution_name => app.distribution_name
|
181
|
-
}
|
182
|
-
if more
|
183
|
-
if app.icons
|
184
|
-
info[:icons] = app.icons.sort { |a,b| -(a[:width] <=> b[:width]) }.map do |icon|
|
185
|
-
tfile = Tempfile.new ["icon-#{SecureRandom.hex}", '.png']
|
186
|
-
@tmpfiles.push tfile
|
187
|
-
FileUtils.cp icon[:path], tfile.path
|
188
|
-
{
|
189
|
-
:name => File.basename(icon[:path]),
|
190
|
-
:path => tfile.path
|
191
|
-
}
|
192
|
-
end
|
193
|
-
end
|
194
|
-
info[:plist] = app.info
|
195
|
-
app.mobileprovision.delete 'DeveloperCertificates' if app.mobileprovision
|
196
|
-
info[:mobileprovision] = app.mobileprovision
|
197
|
-
end
|
198
|
-
ipa.cleanup
|
199
|
-
info
|
200
|
-
end
|
201
|
-
def _base_path
|
202
|
-
@base_path ||= begin
|
203
|
-
path = @config['base_path'] || 'http://fir.im'
|
204
|
-
path = path.strip
|
205
|
-
if path.end_with? '/'
|
206
|
-
path.chop
|
207
|
-
else
|
208
|
-
path
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
def _os
|
213
|
-
return 'mac' if /darwin/ =~ RUBY_PLATFORM
|
214
|
-
return 'windows' if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
215
|
-
return 'linux'
|
216
|
-
end
|
217
|
-
def _exec(cmd, code=1)
|
218
|
-
output = `#{cmd}`
|
219
|
-
if $?.exitstatus != 0
|
220
|
-
puts output
|
221
|
-
exit code
|
222
|
-
end
|
223
|
-
end
|
224
|
-
def _convert_settings(*settings)
|
225
|
-
settings.reduce({}) do |hash, setting|
|
226
|
-
key,val = setting.split('=', 2).map(&:strip)
|
227
|
-
hash[key.to_sym] = val
|
228
|
-
hash
|
229
|
-
end
|
230
|
-
end
|
231
|
-
def _batch_publish(*dirs)
|
232
|
-
_puts "! #{ Paint['至少需要提供一个文件夹', :red] }" if dirs.length == 0
|
233
|
-
dirs.each do |dir|
|
234
|
-
Dir.foreach(dir) do |_f|
|
235
|
-
if _is_ipa(_f) || _is_apk(_f)
|
236
|
-
_puts "> 正在发布 #{ _f }"
|
237
|
-
begin
|
238
|
-
publish File.join dir, _f
|
239
|
-
rescue Exception => e
|
240
|
-
_puts "! #{ _f } 失败:#{ e.to_s }"
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|