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.
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ module Fir
3
+ class Cli
4
+ private
5
+ def _chk_login!(prompt = true)
6
+ if !_opt_token && prompt == true
7
+ token = _prompt_secret('请输入用户 token:')
8
+ @token = token if token.length > 0
9
+ end
10
+ if !@token
11
+ _puts_require_token
12
+ _exit
13
+ elsif !_user(@token)
14
+ _puts_invalid_token
15
+ _exit
16
+ end
17
+ end
18
+ def _chk_os!(os)
19
+ if _os != os
20
+ _puts "! #{Paint["该指令不支持在非 #{os} 系统执行", :red]}"
21
+ _exit
22
+ end
23
+ end
24
+ def _chk_opt!(*opts)
25
+ opts.each do |_opt|
26
+ if !_opt? _opt.to_sym
27
+ _puts "! #{Paint["缺少参数 #{_opt}", :red]}"
28
+ _exit
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,96 @@
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
+ private
12
+ def _info(path, more = false)
13
+ if _is_ipa? path
14
+ _ipa_info path, more
15
+ elsif _is_apk? path
16
+ _apk_info path, more
17
+ else
18
+ _puts "! #{Paint['只能支持后缀为 ipa 和 apk 的文件', :red]}"
19
+ _exit
20
+ end
21
+ end
22
+ def _apk_info(path, more = false)
23
+ path = _path path
24
+ apk = Android::Apk.new path
25
+ info = {
26
+ :type => 'android',
27
+ :identifier => apk.manifest.package_name,
28
+ :name => apk.label,
29
+ :version => apk.manifest.version_code,
30
+ :short_version => apk.manifest.version_name
31
+ }
32
+ if more
33
+ info[:icons] = apk.icon.map do |name, data|
34
+ tfile = Tempfile.new ["icon-#{SecureRandom.hex}", '.png']
35
+ tfile.write data
36
+ @tmpfiles.push tfile
37
+ {
38
+ :name => File.basename(name),
39
+ :path => tfile.path
40
+ }
41
+ end
42
+ end
43
+ info
44
+ end
45
+ def _ipa_info(path, more = false)
46
+ path = _path path
47
+ ipa = Lagunitas::IPA.new path
48
+ _puts '> 正在解析 ipa 文件...'
49
+ app = ipa.app
50
+ info = {
51
+ :type => 'ios',
52
+ :identifier => app.identifier,
53
+ :name => app.name,
54
+ :display_name => app.display_name,
55
+ :version => app.version,
56
+ :short_version => app.short_version,
57
+ :devices => app.devices,
58
+ :release_type => app.release_type,
59
+ :distribution_name => app.distribution_name
60
+ }
61
+ if more
62
+ if app.icons
63
+ info[:icons] = app.icons.sort { |a,b| -(a[:width] <=> b[:width]) }.map do |icon|
64
+ tfile = Tempfile.new ["icon-#{SecureRandom.hex}", '.png']
65
+ @tmpfiles.push tfile
66
+ FileUtils.cp icon[:path], tfile.path
67
+ {
68
+ :name => File.basename(icon[:path]),
69
+ :path => tfile.path
70
+ }
71
+ end
72
+ end
73
+ info[:plist] = app.info
74
+ app.mobileprovision.delete 'DeveloperCertificates' if app.mobileprovision
75
+ info[:mobileprovision] = app.mobileprovision
76
+ end
77
+ ipa.cleanup
78
+ info
79
+ end
80
+ def _batch_publish(*dirs)
81
+ _puts "! #{ Paint['至少需要提供一个文件夹', :red] }" if dirs.length == 0
82
+ dirs.each do |dir|
83
+ Dir.foreach(dir) do |_f|
84
+ if _is_ipa?(_f) || _is_apk?(_f)
85
+ _puts "> 正在发布 #{ _f }"
86
+ begin
87
+ publish File.join dir, _f
88
+ # rescue Exception => e
89
+ # _puts "! #{ _f } 失败:#{ e.to_s }"
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -2,34 +2,41 @@
2
2
  module Fir
3
3
  class Cli
4
4
  private
5
+ def _fir_url
6
+ @base_path ||= begin
7
+ path = @config['base_path'] || 'http://fir.im'
8
+ path = path.strip
9
+ path = path.end_with?('/') ? path.chop : path
10
+ end
11
+ end
5
12
  def _fir_info(identifier, type = 'ios')
6
13
  _puts "> 正在获取 #{identifier}@FIR.im 的应用信息..."
7
- _chk_login
14
+ _chk_login!
8
15
  body = { :token => @token, :type => type }
9
- res = RestClient.get "#{_base_path}/api/v2/app/info/#{identifier}?#{URI.encode_www_form body}"
16
+ res = RestClient.get "#{_fir_url}/api/v2/app/info/#{identifier}?#{URI.encode_www_form body}"
10
17
  JSON.parse res.body, :symbolize_names => true
11
18
  end
12
19
  def _fir_put(id, body)
13
- _chk_login
20
+ _chk_login!
14
21
  body[:token] = @token
15
22
  _puts '> 正在更新 fir 的应用信息...'
16
- RestClient.put "#{_base_path}/api/v2/app/#{id}?#{URI.encode_www_form body}", body
23
+ RestClient.put "#{_fir_url}/api/v2/app/#{id}?#{URI.encode_www_form body}", body
17
24
  _puts '> 更新成功'
18
25
  end
19
26
  def _fir_vput_complete(id, body)
20
- _chk_login
27
+ _chk_login!
21
28
  body[:token] = @token
22
29
  _puts '> 正在更新 fir 的应用版本信息...'
23
- RestClient.put "#{_base_path}/api/v2/appVersion/#{id}/complete?#{URI.encode_www_form body}", body
30
+ RestClient.put "#{_fir_url}/api/v2/appVersion/#{id}/complete?#{URI.encode_www_form body}", body
24
31
  _puts '> 更新成功'
25
32
  end
26
33
  def _fir_vput(id, body)
27
- _chk_login
34
+ _chk_login!
28
35
  body[:token] = @token
29
- RestClient.put "#{_base_path}/api/v2/appVersion/#{id}?#{URI.encode_www_form body}", body
36
+ RestClient.put "#{_fir_url}/api/v2/appVersion/#{id}?#{URI.encode_www_form body}", body
30
37
  end
31
38
  def _user(token)
32
- RestClient.get "#{_base_path}/api/v2/user/me?token=#{token}" do |res|
39
+ RestClient.get "#{_fir_url}/api/v2/user/me?token=#{token}" do |res|
33
40
  case res.code
34
41
  when 200
35
42
  JSON.parse res.body, :symbolize_names => true
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ module Fir
3
+ class Cli
4
+ no_commands do
5
+ %w(token email verbose origin branch mobile_provision sign entitlements).each do |_m|
6
+ define_method "_opt_#{_m}" do
7
+ unless instance_variable_get("@#{_m}")
8
+ instance_variable_set("@#{_m}", options[_m.to_sym] || @config[_m] )
9
+ end
10
+ instance_variable_get("@#{_m}")
11
+ end
12
+ private "_opt_#{_m}".to_sym
13
+ end
14
+ %w(publish resign quiet color trim).each do |_m|
15
+ define_method "_opt_#{_m}" do
16
+ return false if options[_m.to_sym] == false
17
+ unless instance_variable_get("@#{_m}")
18
+ instance_variable_set("@#{_m}", options[_m.to_sym] || @config[_m] )
19
+ end
20
+ instance_variable_get("@#{_m}")
21
+ end
22
+ private "_opt_#{_m}".to_sym
23
+ end
24
+ end
25
+ private
26
+ def _opt (*opts)
27
+ opts.map { |_opt| method("_opt_#{_opt}").call }
28
+ end
29
+ def _opt? (*opts)
30
+ opts.each { |_opt| return false if !method("_opt_#{_opt}").call }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ # coding: utf-8
2
+ module Fir
3
+ class Cli
4
+ def self.output_options
5
+ option :verbose,
6
+ :desc => '设置输出辅助信息的详细程度',
7
+ :type => :string,
8
+ :enum => ['v', 'vv', 'vvv']
9
+ option :quiet,
10
+ :aliases => '-q',
11
+ :desc => '安静模式,不输出任何辅助信息',
12
+ :type => 'boolean'
13
+ option :color,
14
+ :desc => '设置输出带有颜色的信息',
15
+ :type => 'boolean'
16
+ end
17
+ private
18
+ def _puts(text)
19
+ return puts _format text if !/^[->!] /.match text
20
+ return if _opt_quiet
21
+ case _opt_verbose || 'vv' # If nothing about log is set, use the default option - vv
22
+ when 'v'
23
+ puts _format text if text.start_with?('!')
24
+ when 'vv'
25
+ puts _format text if text.start_with?('!') || text.start_with?('>')
26
+ when 'vvv'
27
+ puts _format text if text.start_with?('!') || text.start_with?('>') || text.start_with?('-')
28
+ end
29
+ end
30
+ def _format(text)
31
+ return text.gsub /\e\[\d+(?:;\d+)*m/, '' if _opt_color == false
32
+ text
33
+ end
34
+ def _puts_welcome
35
+ _puts "> #{Paint['欢迎使用 FIR.im 命令行工具,如需帮助请输入:', :green]} fir help"
36
+ end
37
+ def _puts_require_token
38
+ _puts "! #{Paint['用户 token 不能为空', :red]}"
39
+ end
40
+ def _puts_invalid_token
41
+ _puts "! #{Paint['输入的用户 token 不合法', :red]}"
42
+ end
43
+ def _puts_invalid_email
44
+ _puts "! #{Paint['输入的邮件地址不合法', :red]}"
45
+ end
46
+ def _prompt_secret(prompt)
47
+ prompt = '' if _opt_quiet
48
+ ask(prompt) { |_q| _q.echo = false }
49
+ end
50
+ def _prompt(prompt)
51
+ prompt = '' if _opt_quiet
52
+ ask(prompt) { |_q| _q }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,105 @@
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
+ private
18
+ def _init_config
19
+ @uconfig = UserConfig.new '.fir'
20
+ @global_config = @uconfig['global.yaml']
21
+ end
22
+ def _load_config
23
+ @config = @uconfig[_profile]
24
+ end
25
+ def _set_config(configs)
26
+ if configs.length > 0
27
+ configs.each do |option|
28
+ _puts "> #{Paint[option[0].to_s.rjust(10), :blue]} : #{@config[option[0].to_s]} => #{option[1]}"
29
+ @config[option[0].to_s] = option[1]
30
+ end
31
+ if @config['token'] && !_user(@config['token'])
32
+ _puts_invalid_token
33
+ _exit
34
+ end
35
+ @config.save
36
+ end
37
+ end
38
+ def _profile
39
+ @global_config['profile'] || 'default.yaml'
40
+ end
41
+ def _path(path)
42
+ path = Pathname.new(Dir.pwd).join(path).cleanpath
43
+ end
44
+ def _is_ipa?(path)
45
+ path.end_with? '.ipa'
46
+ end
47
+ def _is_apk?(path)
48
+ path.end_with? '.apk'
49
+ end
50
+ def _is_workspace?(path)
51
+ path.end_with? '.xcworkspace'
52
+ end
53
+ def _is_xcodeproject?(path)
54
+ path.end_with? '.xcodeproj'
55
+ end
56
+ def _is_identifier?(str)
57
+ /^(?:(?:[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
58
+ end
59
+ def _is_email?(str)
60
+ /^[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
61
+ end
62
+ def _os
63
+ return 'mac' if /darwin/ =~ RUBY_PLATFORM
64
+ return 'windows' if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
65
+ return 'linux'
66
+ end
67
+ def _exit
68
+ exit 1
69
+ end
70
+ def _exec(cmd)
71
+ output = `#{cmd}`
72
+ if $?.exitstatus != 0
73
+ puts output
74
+ _exit
75
+ end
76
+ end
77
+ def _convert_settings(*settings)
78
+ settings.reduce({}) do |hash, setting|
79
+ key,val = setting.split('=', 2).map(&:strip)
80
+ hash[key.to_sym] = val
81
+ hash
82
+ end
83
+ end
84
+ def _edit(ipath, opath=nil)
85
+ ipath = _path ipath
86
+ if !opath then opath = ipath else opath = _path opath end
87
+ extname = File.extname opath
88
+ Dir.mktmpdir do |_d|
89
+ Dir.chdir(_d) do
90
+
91
+ Zip::ZipFile.open(ipath) do |_z|
92
+ _z.each do |_entry|
93
+ entrypath = File.join _d, _entry.name
94
+ FileUtils.mkdir_p File.dirname entrypath
95
+ _z.extract _entry, entrypath unless File.file? entrypath
96
+ end
97
+ end
98
+ yield _d if block_given?
99
+ File.unlink opath if File.file? opath
100
+ _exec "zip -qr #{opath} Payload"
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
data/lib/lagunitas.ext.rb CHANGED
@@ -15,7 +15,7 @@ module Lagunitas
15
15
  end
16
16
  def mobileprovision?
17
17
  return true if @mobileprovision
18
- File.exists? File.join @path, 'embedded.mobileprovision'
18
+ File.file? File.join @path, 'embedded.mobileprovision'
19
19
  end
20
20
  def devices
21
21
  mobileprovision['ProvisionedDevices'] if mobileprovision
@@ -30,7 +30,7 @@ module Lagunitas
30
30
  end
31
31
  def metadata?
32
32
  return true if @metadata
33
- File.exists? File.join @root, 'iTunesMetadata.plist'
33
+ File.file? File.join @root, 'iTunesMetadata.plist'
34
34
  end
35
35
  def release_type
36
36
  @release_type ||= begin
@@ -19,8 +19,7 @@ module Lagunitas
19
19
  end
20
20
  def get_image(name)
21
21
  path = File.join @path, name
22
- return nil unless File.exist? path
23
-
22
+ return nil unless File.file? path
24
23
  dimensions = Pngdefry.dimensions(path)
25
24
  {
26
25
  path: path,
@@ -42,7 +41,7 @@ module Lagunitas
42
41
  zip_file.each do |f|
43
42
  f_path = File.join tmp_path, f.name
44
43
  FileUtils.mkdir_p File.dirname f_path
45
- zip_file.extract f, f_path unless File.exist? f_path
44
+ zip_file.extract f, f_path unless File.file? f_path
46
45
  end
47
46
  end
48
47
  tmp_path
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.2.0
4
+ version: 0.2.1.a
5
5
  platform: ruby
6
6
  authors:
7
7
  - FIR.im
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.6'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubyzip
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.9.9
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.9.9
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: bundler
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -171,11 +185,17 @@ files:
171
185
  - lib/fir-cli-commands/00-upgrade.rb
172
186
  - lib/fir-cli-commands/00-version.rb
173
187
  - lib/fir-cli-commands/01-config.rb
174
- - lib/fir-cli-commands/10-resign.rb
188
+ - lib/fir-cli-commands/100-resign_codesign.rb
189
+ - lib/fir-cli-commands/100-resign_tapbeta.rb
190
+ - lib/fir-cli-commands/101-resign.rb
175
191
  - lib/fir-cli-commands/11-publish.rb
176
192
  - lib/fir-cli-commands/12-build_ipa.rb
177
- - lib/fir-cli.core.ext.rb
178
- - lib/fir-cli.utils.ext.rb
193
+ - lib/fir-cli.chk.rb
194
+ - lib/fir-cli.core.rb
195
+ - lib/fir-cli.fir.rb
196
+ - lib/fir-cli.opt.rb
197
+ - lib/fir-cli.output.rb
198
+ - lib/fir-cli.utils.rb
179
199
  - lib/fir-cli/version.rb
180
200
  - lib/lagunitas.ext.rb
181
201
  - lib/lagunitas.patch.rb
@@ -196,9 +216,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
196
216
  version: '0'
197
217
  required_rubygems_version: !ruby/object:Gem::Requirement
198
218
  requirements:
199
- - - ">="
219
+ - - ">"
200
220
  - !ruby/object:Gem::Version
201
- version: '0'
221
+ version: 1.3.1
202
222
  requirements: []
203
223
  rubyforge_project:
204
224
  rubygems_version: 2.4.4