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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dbb82db6a565fb7b448b2dd8643b8991250b022
4
- data.tar.gz: 8ebacaa4ee598e06fcdf645c0070cef5822f1205
3
+ metadata.gz: a24b1b028bb3fa518bb091e2ab408a7adda62fe8
4
+ data.tar.gz: 68f5fa9e8492ee4ebb397f254254fb5b307b82d0
5
5
  SHA512:
6
- metadata.gz: 8f53a74550bce7e5f7294f7f613b9db1e544b79cfb94fa1ef588590b8f7a92566d9589e56c2700d79c7ca38ce0cea37bcb3014ea9312b0e6a26d3eebc00ad0ab
7
- data.tar.gz: 67616767e8c833f3d73c246d05a06580a364723c4757b71ace737ff6e1c1c189e2f3ac94eceb0210d32d8e90f75af68993b24e657b16ac30cd35af17a842fafa
6
+ metadata.gz: a5423d1e143c6413724ab28bed45a95377b63fd8f6dafce2468a802e743cb83160f6821a0c71bae3f997500aeb292c7e16be0eda2156124a944d688dfca01b74
7
+ data.tar.gz: 8d74ec61bbcc0ed9b2f0d6f271222953c2b699e2667c3c407fc31a6bc88a9cc39b98ec11211c4444e05f5e421d00ec76ab9612ec0c270f215e3982e95fa90d26
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fir-cli (0.1.9)
4
+ fir-cli (0.2.0)
5
5
  highline (~> 1.6)
6
6
  lagunitas (= 0.0.1)
7
7
  paint (~> 0.9)
@@ -1,5 +1,5 @@
1
1
  module Fir
2
2
  class Cli
3
- VERSION = '0.1.9'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -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 :x_project, :desc => '选择编译的项目文件'
6
- option :x_scheme, :desc => '选择使用的 Scheme'
7
- option :x_target, :desc => '选择编译的 Target'
8
- option :x_alltarget, :desc => '编译全部 Target', :type => :boolean
9
- option :x_configuration, :desc => '选择编译使用的配置'
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 项目,输出至 ODIR'
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, *settings)
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 *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
- vars = {
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
- publish ipa_path.to_s
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
- settings = {}
53
- vars = {}
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
- settings = settings.select { |_k| _k != 'TARGET_BUILD_DIR' }
61
- .map { |_k, _v| "#{_k}=\"#{_v}\"" }
62
- .join(' ')
63
- arguments = '-sdk iphoneos'
64
- options.each do |_k, _v|
65
- break if !_k.start_with? 'x_'
66
- arguments += " -#{_k[2..-1]}" if _v
67
- arguments += " #{_v}" if _v.class == String
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
- Dir.mktmpdir do |_d|
70
- settings += " TARGET_BUILD_DIR=#{_d}"
71
- Dir.chdir(project_dir) do
72
- _puts '> 正在清除缓存'
73
- _exec "xcodebuild clean 2>&1"
74
- _puts '> 正在编译'
75
- _exec "xcodebuild build #{arguments} #{settings} 2>&1"
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
- Dir.chdir(_d) do
78
- ipa_path = vars[:ipa_path]
79
- if ipa_path
80
- basename = File.basename Dir['*.app'][0], '.app'
81
- ipa_path = File.join(ipa_path, 'build_ipa.ipa') if Dir.exist? ipa_path
82
- _puts '> 正在打包'
83
- _exec 'mkdir Payload'
84
- _exec 'mv *.app ./Payload'
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
- if vars[:app_path]
90
- _puts '> 正在复制 app 文件'
91
- _exec "mv ./Payload/*.app #{vars[:app_path]}"
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
@@ -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.reverse.map do |icon|
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
@@ -6,17 +6,29 @@ module Lagunitas
6
6
  @root = root
7
7
  end
8
8
  def icons
9
- @icons ||= begin
10
- icons = []
11
- info['CFBundleIcons']['CFBundlePrimaryIcon']['CFBundleIconFiles'].each do |name|
12
- icons << get_image(name)
13
- icons << get_image("#{name}@2x")
14
- end
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.1.9
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