Class: Fir::Cli

Inherits:
Object
  • Object
show all
Defined in:
lib/fir-cli/version.rb,
lib/fir-cli.core.ext.rb,
lib/fir-cli.utils.ext.rb,
lib/fir-cli-commands/00-info.rb,
lib/fir-cli-commands/00-login.rb,
lib/fir-cli-commands/01-config.rb,
lib/fir-cli-commands/10-resign.rb,
lib/fir-cli-commands/00-profile.rb,
lib/fir-cli-commands/00-upgrade.rb,
lib/fir-cli-commands/00-version.rb,
lib/fir-cli-commands/11-publish.rb,
lib/fir-cli-commands/12-build_ipa.rb

Constant Summary collapse

VERSION =
'0.2.0'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Cli

Returns a new instance of Cli.



4
5
6
7
8
9
10
# File 'lib/fir-cli.utils.ext.rb', line 4

def initialize(*args)
  super
  @tmpfiles = []
  _init_config
  _load_config
  _puts_welcome
end

Class Method Details

.build_ipa_optionsObject



4
5
6
7
8
9
10
# File 'lib/fir-cli-commands/12-build_ipa.rb', line 4

def self.build_ipa_options
  option :workspace, :aliases => '-w', :desc => '编译指定路径中的 workspace', :type => :boolean
  option :scheme, :aliases => '-s', :desc => '如果编译 workspace 则必须指定 scheme'
  option :configuration, :aliases => '-C', :desc => '选择编译的配置,如 Release'
  option :output, :aliases => '-o', :desc => '指定 ipa 的输出路径'
  option :publish, :aliases => '-p', :desc => '设置是否发布到 FIR.im', :type => :boolean
end

.find_extendsObject



11
12
13
14
15
16
# File 'lib/fir-cli.utils.ext.rb', line 11

def self.find_extends
  `gem list --local`
    .each_line("\n")
    .map { |gem| /^[^\s]+/.match(gem)[0] }
    .select { |gem| true if gem.start_with? 'fir-cli-' }
end

.output_optionsObject



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/fir-cli.utils.ext.rb', line 17

def self.output_options
  option :verbose,
         :desc => '设置输出辅助信息的详细程度',
         :type => :string,
         :enum => ['v', 'vv', 'vvv']
  option :quiet,
         :aliases => '-q',
         :desc => '安静模式,不输出任何辅助信息',
         :type => 'boolean'
  option :color,
         :desc => '设置输出带有颜色的信息',
         :type => 'boolean'
end

.publish_optionsObject



5
6
7
8
9
10
# File 'lib/fir-cli-commands/11-publish.rb', line 5

def self.publish_options  
  option :resign, :aliases => '-r', :desc => '设置是否进行企业签名', :type => :boolean
  option :token, :aliases => '-t', :desc => '用户 token'
  option :short, :aliases => '-s', :desc => '自定义短地址'
  option :changelog, :aliases => '-c', :desc => '修改纪录,默认为空字符串', :default => ''
end

.resign_optionsObject



4
5
6
# File 'lib/fir-cli-commands/10-resign.rb', line 4

def self.resign_options
  option :email, :aliases => '-e', :desc => '邮件地址'
end

Instance Method Details

#build_ipa(path, *args) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/fir-cli-commands/12-build_ipa.rb', line 15

def build_ipa(path, *args)
  if _os != 'mac'
    _puts "! #{Paint['不支持在非 mac 系统上编译打包', :red]}"
    exit 1
  end
  settings = _convert_settings *args

  path = _path(path).to_s
  project_dir = (Dir.exist? path) ? path : (File.dirname path)

  ipa_path = _path(options[:output]).to_s if options[:output]
  if !ipa_path && !_opt_publish
    _puts "! #{Paint['如果不发布到 FIR.im,则需要指定 ipa 文件的输出路径', :red]}"
    exit 1
  end
  if !ipa_path
    Dir.mktmpdir do |_d|
      ipa_path = _d.to_s
      _build_ipa project_dir, settings, options,
                 :ipa_path => ipa_path
      return _batch_publish ipa_path
    end
  end
  _build_ipa project_dir, settings, options,
             :ipa_path => ipa_path
  return if !_opt_publish
  if Dir.exists? ipa_path
    _batch_publish ipa_path
  elsif File.exists? ipa_path
    publish ipa_path
  end
end

#configObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/fir-cli-commands/01-config.rb', line 10

def config
  if options.length > 0
    options.each do |option|
      _puts "> #{Paint[option[0].to_s.rjust(10), :blue]} : #{@config[option[0].to_s]} => #{option[1]}"
      @config[option[0].to_s] = option[1]
    end
    if @config['token'] && !_user(@config['token'])
      _puts_invalid_token
      exit 1
    end
    @config.save
  end
  _puts '> 设置完成,您现在使用的设置是'
  @config.save
  @config.each { |conf| _puts "> #{Paint[conf[0].to_s.rjust(10), :blue]} => #{conf[1]}" }
end

#info(path) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/fir-cli-commands/00-info.rb', line 8

def info(path)
  app = _info path, options[:all]
  app.each { |i| _puts "#{Paint[i[0].to_s.rjust(18), :blue]}  #{i[1]}" }
  if options[:fir]
    fir_app = _fir_info app[:identifier], app[:type]
    fir_app.each { |i| _puts "#{Paint[i[0].to_s.rjust(18), :blue]}  #{i[1]}" }
  end
end

#loginObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/fir-cli-commands/00-login.rb', line 6

def 
  token = _prompt_secret('输入你的用户 token:')
  if token.empty?
    _puts_require_token
    exit 1
  end
  user = _user token
  if !user
    _puts_invalid_token
    exit 1
  end
  if _opt_token && _opt_token != token
    _puts "> 已登陆用户: #{_opt_token}"
    _puts "> 替换为用户: #{token}"
  end
  if user[:email]
    _puts "> 设置用户邮件地址为: #{user[:email]}"
    @config['email'] = user[:email]
  end
  @config['token'] = token
  @config.save
  _puts "> 当前登陆用户为:#{token}"
end

#profile(prof) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/fir-cli-commands/00-profile.rb', line 7

def profile(prof)
  if prof == 'global'
    _puts '! 不能使用 global 作为配置文件名'
    exit 1
  end
  prof = "#{prof}.yaml"
  if options[:delete]
    _puts "> 正在删除配置文件:#{prof}"
    @uconfig.delete prof
  else
    if _profile == prof
      _puts "! #{Paint["你正在使用该配置:#{prof}", :red]}"
      exit 1
    end
    _puts "> 正在使用配置文件:#{_profile}"
    _puts "> 即将替换为:#{prof}"
    @global_config['profile'] = prof
    @global_config.save
    _load_config
    _puts "> 已替换为:#{prof}"
    config
  end
end

#publish(path) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fir-cli-commands/11-publish.rb', line 14

def publish(path)
  if _opt_resign && _is_ipa(path)
    tfile = Tempfile.new ["resign-#{SecureRandom.hex}", '.ipa']
    resign path, tfile.path
    path = tfile.path
  end
  app = _info path, true
  fir_app = _fir_info app[:identifier], app[:type]

  id = fir_app[:id]
  bundle_app = fir_app[:bundle][:pkg]
  bundle_icon = fir_app[:bundle][:icon]
  
  if app[:icons] != nil && app[:icons].length > 0
    icon_path = app[:icons][0][:path]

    if _is_ipa path
      _puts '> 转换图标...'
      Pngdefry.defry icon_path, icon_path
    end

    _puts "> 上传图标..."
    RestClient.post bundle_icon[:url],
                    :key => bundle_icon[:key],
                    :token => bundle_icon[:token],
                    :file => File.new(icon_path, 'rb')

    _puts '> 上传图标成功'
  end

  _puts '> 上传应用...'
  res = RestClient.post bundle_app[:url],
                        :key => bundle_app[:key],
                        :token => bundle_app[:token],
                        :file => File.new(path, 'rb')
  _puts '> 上传应用成功'
  upload_res = JSON.parse res.body, :symbolize_names => true

  _fir_put fir_app[:id],
          :name => app[:display_name] || app[:name],
          :short => options[:short] || fir_app[:short],
          # :desc => options[:describe] || fir_app[:desc]
          # :show => options[:public] || fir_app[:show]
          :source => 'fir-cli'
          
  _fir_vput_complete upload_res[:versionOid],
                     :version => app[:version],
                     :versionShort => app[:short_version],
                     :devices => app[:devices],
                     :release_type => app[:release_type]

  _fir_vput upload_res[:versionOid],
           :changelog => options[:changelog]

  # Get updated app info
  fir_app = _fir_info app[:identifier]
  _puts "> #{_base_path}/#{fir_app[:short]}"
end

#resign(ipath, opath) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fir-cli-commands/10-resign.rb', line 10

def resign(ipath, opath)
  _puts "! #{Paint['resign.tapbeta.com 签名服务风险提示', :red]}"
  _puts '! tapbeta 无法保证签名证书的长期有效性,苹果随时可'
  _puts '! 能封杀他们的企业账号,所有由这个企业账号签发的证'
  _puts '! 书都会失效。你如果使用该网站提供的证书进行应用签'
  _puts "! 发,请注意:#{Paint['当证书失效后,所有通过已失效证书签名', :red ]}"
  _puts "! #{Paint['的应用都会无法正常运行;同时托管在 fir.im 的应用', :red ]}"
  _puts "! #{Paint['将无法正常安装。', :red ]}"
  if _opt_email == nil
    @email = _prompt '请输入你的邮件地址:'
    if !@email || @email.length == 0
      _puts "! #{Paint['你需要提供邮件地址才能使用 resign.tapbeta.com 的', :red]}"
      _puts "! #{Paint['签名服务, 请使用', :red]} fir config --email=EMAIL #{Paint['进行设', :red]}"
      _puts "! #{Paint['置', :red]}"
      exit 1
    elsif !_is_email @email
      _puts_invalid_email
      exit 1
    end
  end
  if !_is_ipa ipath
    _puts "! #{Paint['只能给以 ipa 为扩展名的文件签名', :red]}"
    exit 1
  end
  _puts '> 正在申请上传令牌...'
  upload_res = RestClient.post 'http://api.resign.tapbeta.com/public/upload',
                               :email => @email,
                               :file => File.basename(ipath)
  form = JSON.parse upload_res.body, :symbolize_names => true
  tapbeta = {}
  form.each do |f|
    if /^tb_/.match f[0]
      tapbeta[f[0]] = f[1]
      form.delete f[0]
    end
  end
  form[:file] = File.new Pathname.new(Dir.pwd).join(ipath).cleanpath, 'rb'
  _puts '> 正在上传...'
  res = RestClient.post tapbeta[:tb_upload_url], form

  # Upyun's notify is fucking, handle it specific
  # if tapbeta[:tb_upload_url].include? 'upyun'
  #   RestClient.get "#{form[:'notify-url']}?#{URI.encode_www_form JSON.parse res.body}"
  # end


  _puts '> 正在排队...'
  nped = true
  info = {}
  loop do
    res = RestClient.get "http://api.resign.tapbeta.com/public/#{tapbeta[:tb_upload_key]}", 
                         :params => { :__mr => 'eyJ1cmwiOiIkKHVybCkiLCAicmVzaWduU3RhdHVzIjogIiQocmVzaWduU3RhdHVzKSIsICJzdGF0dXMiOiAiJChzdGF0dXMpIn0=' }
    info = JSON.parse res.body, :symbolize_names => true
    if nped && info[:resignStatus] == 'doing'
      _puts '> 正在签名...'
      nped = false
    end
    if info[:status] == 'error'
      _puts "! #{Paint['签名失败', :red]}"
      exit 1
    elsif info[:status] == 'timeout'
      _puts "! #{Paint['签名超时', :red]}"
      exit 1
    end
    break if info[:url] != ''
    sleep 5
  end
  opath = Pathname.new(Dir.pwd).join(opath).cleanpath
  _puts "> 正在下载到 #{opath}..."
  `curl #{info[:url]} -o #{opath} -s`
end

#upgradeObject



6
7
8
9
10
11
12
13
# File 'lib/fir-cli-commands/00-upgrade.rb', line 6

def upgrade
  _puts '> gem update fir-cli'
  `gem update fir-cli`
  _extends.each do |gem|
    _puts "> gem update #{gem}"
    `gem update #{gem}`
  end
end

#versionObject



6
7
8
# File 'lib/fir-cli-commands/00-version.rb', line 6

def version
  _puts "FIR Cli #{VERSION}"
end