fir-cli 0.1.9 → 0.2.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/Gemfile.lock +1 -1
- data/lib/fir-cli/version.rb +1 -1
- data/lib/fir-cli-commands/01-config.rb +0 -1
- data/lib/fir-cli-commands/12-build_ipa.rb +124 -66
- data/lib/fir-cli.utils.ext.rb +22 -1
- data/lib/lagunitas.patch.rb +22 -10
- metadata +1 -2
- data/lib/fir-cli-commands/00-git.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a24b1b028bb3fa518bb091e2ab408a7adda62fe8
|
4
|
+
data.tar.gz: 68f5fa9e8492ee4ebb397f254254fb5b307b82d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5423d1e143c6413724ab28bed45a95377b63fd8f6dafce2468a802e743cb83160f6821a0c71bae3f997500aeb292c7e16be0eda2156124a944d688dfca01b74
|
7
|
+
data.tar.gz: 8d74ec61bbcc0ed9b2f0d6f271222953c2b699e2667c3c407fc31a6bc88a9cc39b98ec11211c4444e05f5e421d00ec76ab9612ec0c270f215e3982e95fa90d26
|
data/Gemfile.lock
CHANGED
data/lib/fir-cli/version.rb
CHANGED
@@ -6,7 +6,6 @@ module Fir
|
|
6
6
|
option :email, :aliases => '-e', :desc => '邮件地址'
|
7
7
|
option :resign, :aliases => '-r', :desc => '是否以企业签名发布 ios 应用', :type => :boolean
|
8
8
|
option :publish, :aliases => '-p', :desc => '编译打包自动发布至 FIR.im', :type => :boolean
|
9
|
-
git_options
|
10
9
|
output_options
|
11
10
|
def config
|
12
11
|
if options.length > 0
|
@@ -2,97 +2,155 @@
|
|
2
2
|
module Fir
|
3
3
|
class Cli
|
4
4
|
def self.build_ipa_options
|
5
|
-
option :
|
6
|
-
option :
|
7
|
-
option :
|
8
|
-
option :
|
9
|
-
option :
|
10
|
-
option :output_ipa, :aliases => '-o', :desc => '指定 ipa 的输出路径'
|
11
|
-
option :output_app, :desc => '指定 app 的输出路径'
|
12
|
-
option :publish, :aliases => '-p', :desc => '设置是否直接发布到 FIR.im', :type => :boolean
|
5
|
+
option :workspace, :aliases => '-w', :desc => '编译指定路径中的 workspace', :type => :boolean
|
6
|
+
option :scheme, :aliases => '-s', :desc => '如果编译 workspace 则必须指定 scheme'
|
7
|
+
option :configuration, :aliases => '-C', :desc => '选择编译的配置,如 Release'
|
8
|
+
option :output, :aliases => '-o', :desc => '指定 ipa 的输出路径'
|
9
|
+
option :publish, :aliases => '-p', :desc => '设置是否发布到 FIR.im', :type => :boolean
|
13
10
|
end
|
14
|
-
desc 'build_ipa PATH [options] [settings]', '编译 ios app
|
11
|
+
desc 'build_ipa PATH [options] [settings]', '编译 ios app 项目'
|
15
12
|
build_ipa_options
|
16
13
|
publish_options
|
17
14
|
output_options
|
18
|
-
def build_ipa(path, *
|
15
|
+
def build_ipa(path, *args)
|
19
16
|
if _os != 'mac'
|
20
17
|
_puts "! #{Paint['不支持在非 mac 系统上编译打包', :red]}"
|
21
18
|
exit 1
|
22
19
|
end
|
23
|
-
settings = _convert_settings *
|
24
|
-
ipa_path = _path options[:output_ipa] if options[:output_ipa]
|
25
|
-
if !ipa_path
|
26
|
-
use_tmpfile = true
|
27
|
-
ipa_path = Tempfile.new(["#{SecureRandom.hex}", '.ipa']).path
|
28
|
-
end
|
29
|
-
app_path = _path options[:output_app] if options[:output_app]
|
30
|
-
mp_path = _path options[:mobileprovision] if options[:mobileprovision]
|
20
|
+
settings = _convert_settings *args
|
31
21
|
|
32
|
-
|
33
|
-
:ipa_path => ipa_path,
|
34
|
-
:app_path => app_path
|
35
|
-
}
|
36
|
-
# TODO: pull from a git repo
|
37
|
-
# if options[:git] != nil
|
38
|
-
# git(path) { |_d| _build_ipa _d, settings, vars }
|
39
|
-
# else
|
40
|
-
# end
|
41
|
-
|
42
|
-
path = _path path
|
22
|
+
path = _path(path).to_s
|
43
23
|
project_dir = (Dir.exist? path) ? path : (File.dirname path)
|
44
|
-
_build_ipa project_dir, settings, vars
|
45
24
|
|
25
|
+
ipa_path = _path(options[:output]).to_s if options[:output]
|
26
|
+
if !ipa_path && !_opt_publish
|
27
|
+
_puts "! #{Paint['如果不发布到 FIR.im,则需要指定 ipa 文件的输出路径', :red]}"
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
if !ipa_path
|
31
|
+
Dir.mktmpdir do |_d|
|
32
|
+
ipa_path = _d.to_s
|
33
|
+
_build_ipa project_dir, settings, options,
|
34
|
+
:ipa_path => ipa_path
|
35
|
+
return _batch_publish ipa_path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
_build_ipa project_dir, settings, options,
|
39
|
+
:ipa_path => ipa_path
|
46
40
|
return if !_opt_publish
|
47
|
-
|
41
|
+
if Dir.exists? ipa_path
|
42
|
+
_batch_publish ipa_path
|
43
|
+
elsif File.exists? ipa_path
|
44
|
+
publish ipa_path
|
45
|
+
end
|
48
46
|
end
|
49
47
|
|
50
48
|
private
|
49
|
+
# *args 的每一个参数必须为 hash, 可以以任何顺序包含 settings, arguments, opts 的参数
|
50
|
+
# settings 的特点是 key 全部为大写字母
|
51
|
+
# arguments 的特点是 key 为 x_ 开头
|
52
|
+
# 不符合 settings 及 arguments 的为 opts
|
51
53
|
def _build_ipa(project_dir, *args)
|
52
|
-
|
53
|
-
|
54
|
-
if args.length == 1
|
55
|
-
args[0].each { |_k, _v| if _k.match /^[A-Z]+$/ then settings[_k] = _v else vars[_k] = _v end }
|
56
|
-
else
|
57
|
-
settings, vars = args[0..1]
|
58
|
-
end
|
54
|
+
ignore_args = %w(:project :workspace :sdk :scheme)
|
55
|
+
ignore_sets = %w(TARGET_BUILD_DIR)
|
59
56
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
setstr, argstr, opts = begin
|
58
|
+
_setstr, _argstr, _opts = ['', '-sdk iphoneos', {}]
|
59
|
+
args.inject(&:merge).each do |_k, _v|
|
60
|
+
_k = _k.to_s
|
61
|
+
if _k.match /^[_A-Z0-9]+$/
|
62
|
+
next if ignore_sets.include? _k
|
63
|
+
_setstr += " #{_k}"
|
64
|
+
_setstr += "=\"#{_v}\"" if _v
|
65
|
+
elsif _k.start_with? ':'
|
66
|
+
next if ignore_args.include? _k
|
67
|
+
_argstr += " -#{_k[1..-1]}"
|
68
|
+
_argstr += " \"#{_v}\"" if _v.class == String && !_v.empty?
|
69
|
+
else
|
70
|
+
_opts[_k.to_sym] = _v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
[_setstr, _argstr, _opts]
|
68
74
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
75
|
+
project = begin
|
76
|
+
if _is_xcodeproject project_dir
|
77
|
+
project_dir
|
78
|
+
elsif _is_workspace project_dir
|
79
|
+
opts[:workspace] = true
|
80
|
+
project_dir
|
81
|
+
elsif opts[:workspace]
|
82
|
+
_spaces = Dir["#{project_dir}/*.xcworkspace"]
|
83
|
+
if _spaces.length == 0
|
84
|
+
_puts "! #{Paint['指定目录中找不到 workspace 文件,无法编译', :red]}"
|
85
|
+
exit 1
|
86
|
+
end
|
87
|
+
_spaces[0]
|
88
|
+
else
|
89
|
+
_projs = Dir["#{project_dir}/*.xcodeproj"]
|
90
|
+
if _projs.length == 0
|
91
|
+
_puts "! #{Paint['指定目录中找不到 project 文件,无法编译', :red]}"
|
92
|
+
exit 1
|
93
|
+
else
|
94
|
+
_projs[0]
|
95
|
+
end
|
76
96
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
_exec "rm #{ipa_path}" if File.exist? ipa_path
|
86
|
-
_exec "zip -qr #{ipa_path} Payload"
|
97
|
+
end
|
98
|
+
|
99
|
+
Dir.mktmpdir do |_d|
|
100
|
+
setstr += " TARGET_BUILD_DIR=#{_d} CONFIGURATION_BUILD_DIR=#{_d}"
|
101
|
+
if opts[:workspace]
|
102
|
+
unless opts[:scheme]
|
103
|
+
_puts "! #{Paint['如果编译 workspace, 则必须指定一个 scheme', :red]}"
|
104
|
+
exit 1
|
87
105
|
end
|
106
|
+
argstr += " -workspace \"#{project}\" -scheme \"#{opts[:scheme]}\""
|
107
|
+
else
|
108
|
+
argstr += " -project \"#{project}\""
|
109
|
+
end
|
110
|
+
|
111
|
+
argstr += " -configuration \"#{opts[:configuration]}\"" if opts[:configuration]
|
88
112
|
|
89
|
-
|
90
|
-
|
91
|
-
|
113
|
+
# _puts '> 正在清除缓存'
|
114
|
+
# _exec "xcodebuild clean #{argstr} 2>&1"
|
115
|
+
_puts '> 正在编译'
|
116
|
+
_exec "xcodebuild build #{argstr} #{setstr} 2>&1"
|
117
|
+
Dir.chdir(_d) do
|
118
|
+
apps = Dir['*.app']
|
119
|
+
if opts[:ipa_path]
|
120
|
+
ipa_path = opts[:ipa_path]
|
121
|
+
if Dir.exist? ipa_path
|
122
|
+
apps.each do |app|
|
123
|
+
_ipa_path = File.join ipa_path, "#{File.basename app, '.app'}.ipa"
|
124
|
+
_zip_ipa File.join(_d, app), _ipa_path
|
125
|
+
end
|
126
|
+
elsif apps.length > 1
|
127
|
+
_puts "! #{Paint['项目编译输出了多个 app,需要指定一个已经存在的目录作为输出目录', :red]}"
|
128
|
+
exit 1
|
129
|
+
elsif apps.length == 0
|
130
|
+
_puts "! #{Paint['项目编译没有输出 app,无法打包 ipa', :red]}"
|
131
|
+
exit 1
|
132
|
+
else
|
133
|
+
ipa_path += '.ipa' unless ipa_path.end_with? '.ipa'
|
134
|
+
_zip_ipa File.join(_d, apps[0]), ipa_path
|
135
|
+
end
|
92
136
|
end
|
93
137
|
end
|
94
138
|
_puts '> 完成'
|
95
139
|
end
|
96
140
|
end
|
141
|
+
def _zip_ipa(app_path, ipa_path)
|
142
|
+
Dir.mktmpdir do |_d|
|
143
|
+
Dir.chdir(_d) do
|
144
|
+
Dir.mkdir "Payload"
|
145
|
+
FileUtils.cp_r app_path, 'Payload'
|
146
|
+
if File.exist? ipa_path
|
147
|
+
_puts "> 删除已有文件 #{ipa_path}"
|
148
|
+
_exec "rm -r #{ipa_path}"
|
149
|
+
end
|
150
|
+
_puts "> 正在打包 app: #{File.basename app_path} 到 #{ipa_path}"
|
151
|
+
_exec "zip -qr #{ipa_path} Payload"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
97
155
|
end
|
98
156
|
end
|
data/lib/fir-cli.utils.ext.rb
CHANGED
@@ -71,6 +71,12 @@ module Fir
|
|
71
71
|
def _is_apk(path)
|
72
72
|
path.end_with? '.apk'
|
73
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
|
74
80
|
def _is_identifier(str)
|
75
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
|
76
82
|
end
|
@@ -175,7 +181,7 @@ module Fir
|
|
175
181
|
}
|
176
182
|
if more
|
177
183
|
if app.icons
|
178
|
-
info[:icons] = app.icons.
|
184
|
+
info[:icons] = app.icons.sort { |a,b| -(a[:width] <=> b[:width]) }.map do |icon|
|
179
185
|
tfile = Tempfile.new ["icon-#{SecureRandom.hex}", '.png']
|
180
186
|
@tmpfiles.push tfile
|
181
187
|
FileUtils.cp icon[:path], tfile.path
|
@@ -222,5 +228,20 @@ module Fir
|
|
222
228
|
hash
|
223
229
|
end
|
224
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
|
225
246
|
end
|
226
247
|
end
|
data/lib/lagunitas.patch.rb
CHANGED
@@ -6,17 +6,29 @@ module Lagunitas
|
|
6
6
|
@root = root
|
7
7
|
end
|
8
8
|
def icons
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
icons.delete_if { |i| !i }
|
16
|
-
rescue
|
17
|
-
# info['CFBundleIcons'] might be nil
|
18
|
-
nil
|
9
|
+
icons = []
|
10
|
+
info['CFBundleIcons']['CFBundlePrimaryIcon']['CFBundleIconFiles'].each do |name|
|
11
|
+
icons << get_image(name)
|
12
|
+
icons << get_image("#{name}.png")
|
13
|
+
icons << get_image("#{name}@2x.png")
|
14
|
+
icons << get_image("#{name}@3x.png")
|
19
15
|
end
|
16
|
+
icons.delete_if { |i| !i }
|
17
|
+
rescue
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
def get_image(name)
|
21
|
+
path = File.join @path, name
|
22
|
+
return nil unless File.exist? path
|
23
|
+
|
24
|
+
dimensions = Pngdefry.dimensions(path)
|
25
|
+
{
|
26
|
+
path: path,
|
27
|
+
width: dimensions.first,
|
28
|
+
height: dimensions.last
|
29
|
+
}
|
30
|
+
rescue Errno::ENOENT
|
31
|
+
nil
|
20
32
|
end
|
21
33
|
end
|
22
34
|
class IPA
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fir-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FIR.im
|
@@ -165,7 +165,6 @@ files:
|
|
165
165
|
- bin/fir
|
166
166
|
- fir-cli.gemspec
|
167
167
|
- fir-cli.rb
|
168
|
-
- lib/fir-cli-commands/00-git.rb
|
169
168
|
- lib/fir-cli-commands/00-info.rb
|
170
169
|
- lib/fir-cli-commands/00-login.rb
|
171
170
|
- lib/fir-cli-commands/00-profile.rb
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
module Fir
|
3
|
-
class Cli
|
4
|
-
def self.git_options
|
5
|
-
option :git, :desc => '设置 git 源'
|
6
|
-
option :origin, :desc => '设置 git clone 的 origin'
|
7
|
-
option :branch, :desc => '设置 git clone 的 branch'
|
8
|
-
end
|
9
|
-
no_commands do
|
10
|
-
def git(path)
|
11
|
-
arguments = '--depth 1'
|
12
|
-
%w(origin branch).each do |_m|
|
13
|
-
opt = method("_opt_#{_m}".to_sym).call
|
14
|
-
arguments += " --#{_m} #{opt}" if opt
|
15
|
-
end
|
16
|
-
|
17
|
-
Dir.mktmpdir do |dir|
|
18
|
-
_puts "> 克隆源代码 #{_opt_git}#{path}"
|
19
|
-
Dir.chdir(dir) do
|
20
|
-
_exec "git clone -q #{_opt_git}#{path} ./ #{arguments}"
|
21
|
-
yield dir if block_given?
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
private
|
27
|
-
def _opt_git
|
28
|
-
default = @config['git'] || 'git@github.com'
|
29
|
-
return default if options[:git] == 'git'
|
30
|
-
options[:git] || default
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|