fir-cli 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,23 +3,16 @@
3
3
  module FIR
4
4
  module Mapping
5
5
 
6
- def mapping *args, options
7
- @file_path = File.absolute_path(args.first.to_s)
8
- @token = options[:token] || current_token
9
- @proj = options[:proj].to_s
10
- @version = options[:version].to_s
11
- @build = options[:build].to_s
12
-
13
- check_file_exist @file_path
14
- check_token_cannot_be_blank @token
15
- check_project_id_cannot_be_blank
6
+ def mapping(*args, options)
7
+ initialize_and_check_mapping_options(args, options)
8
+ check_file_and_token
16
9
 
17
10
  logger.info "Creating bughd project's version......."
18
11
  logger_info_dividing_line
19
12
 
20
13
  @full_version = find_or_create_bughd_full_version
21
14
 
22
- logger.info "Uploading mapping file......."
15
+ logger.info 'Uploading mapping file.......'
23
16
 
24
17
  upload_mapping_file
25
18
  logger_info_dividing_line
@@ -42,51 +35,64 @@ module FIR
42
35
 
43
36
  private
44
37
 
45
- def check_project_id_cannot_be_blank
46
- if @proj.blank?
47
- logger.error "Project id can't be blank"
48
- exit 1
49
- end
50
- end
38
+ def initialize_and_check_mapping_options(args, options)
39
+ @file_path = File.absolute_path(args.first.to_s)
40
+ @token = options[:token] || current_token
41
+ @proj = options[:proj].to_s
42
+ @version = options[:version].to_s
43
+ @build = options[:build].to_s
44
+ end
51
45
 
52
- def uuid
53
- @uuid ||= fetch_user_uuid(@token)
54
- end
46
+ def check_file_and_token
47
+ check_file_exist(@file_path)
48
+ check_token_cannot_be_blank(@token)
49
+ check_project_id_cannot_be_blank
50
+ end
55
51
 
56
- def generate_temp_mapping_file
57
- tmp_file_path = "#{Dir.tmpdir}/#{File.basename(@file_path)}-fircli"
58
- FileUtils.cp(@file_path, tmp_file_path)
52
+ def check_project_id_cannot_be_blank
53
+ return unless @proj.blank?
59
54
 
60
- tmp_file_path = zip_mapping_file(tmp_file_path)
61
- tmp_file_path = dsym_or_txt_file(tmp_file_path)
55
+ logger.error "Project id can't be blank"
56
+ exit 1
57
+ end
62
58
 
63
- tmp_file_path
64
- end
59
+ def uuid
60
+ @uuid ||= fetch_user_uuid(@token)
61
+ end
62
+
63
+ def generate_temp_mapping_file
64
+ tmp_file_path = "#{Dir.tmpdir}/#{File.basename(@file_path)}-fircli"
65
+ FileUtils.cp(@file_path, tmp_file_path)
66
+
67
+ tmp_file_path = zip_mapping_file(tmp_file_path)
68
+ tmp_file_path = dsym_or_txt_file(tmp_file_path)
65
69
 
66
- def zip_mapping_file tmp_file_path
67
- if File.size?(tmp_file_path) > 50*1000*1000
68
- logger.info "Zipping mapping file......."
70
+ tmp_file_path
71
+ end
69
72
 
70
- system("zip -qr #{tmp_file_path}.zip #{tmp_file_path}")
71
- tmp_file_path = tmp_file_path + '.zip'
73
+ def zip_mapping_file(tmp_file_path)
74
+ if File.size?(tmp_file_path) > 50 * 1000 * 1000
75
+ logger.info 'Zipping mapping file.......'
72
76
 
73
- logger.info "Zipped Mapping file size - #{File.size?(tmp_file_path)}"
74
- end
77
+ system("zip -qr #{tmp_file_path}.zip #{tmp_file_path}")
78
+ tmp_file_path += '.zip'
75
79
 
76
- tmp_file_path
80
+ logger.info "Zipped Mapping file size - #{File.size?(tmp_file_path)}"
77
81
  end
78
82
 
79
- def dsym_or_txt_file tmp_file_path
80
- if File.is_dsym?(@file_path)
81
- FileUtils.mv(tmp_file_path, tmp_file_path + '.dSYM')
82
- tmp_file_path = tmp_file_path + '.dSYM'
83
- elsif File.is_txt?(@file_path)
84
- FileUtils.mv(tmp_file_path, tmp_file_path + '.txt')
85
- tmp_file_path = tmp_file_path + '.txt'
86
- end
83
+ tmp_file_path
84
+ end
87
85
 
88
- tmp_file_path
86
+ def dsym_or_txt_file(tmp_file_path)
87
+ if File.dsym?(@file_path)
88
+ FileUtils.mv(tmp_file_path, tmp_file_path + '.dSYM')
89
+ tmp_file_path += '.dSYM'
90
+ elsif File.text?(@file_path)
91
+ FileUtils.mv(tmp_file_path, tmp_file_path + '.txt')
92
+ tmp_file_path += '.txt'
89
93
  end
90
94
 
95
+ tmp_file_path
96
+ end
91
97
  end
92
98
  end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative './common'
4
+
5
+ module FIR
6
+ module Parser
7
+ class Apk
8
+ include Parser::Common
9
+
10
+ def initialize(path)
11
+ @apk = ::Android::Apk.new(path)
12
+ end
13
+
14
+ def full_info(options)
15
+ if options.fetch(:full_info, false)
16
+ basic_info.merge!(icons: tmp_icons)
17
+ end
18
+
19
+ basic_info
20
+ end
21
+
22
+ def basic_info
23
+ @basic_info ||= {
24
+ type: 'android',
25
+ identifier: @apk.manifest.package_name,
26
+ name: @apk.label,
27
+ build: @apk.manifest.version_code.to_s,
28
+ version: @apk.manifest.version_name.to_s
29
+ }
30
+ end
31
+
32
+ # @apk.icon is a hash, { icon_name: icon_data }
33
+ def tmp_icons
34
+ @apk.icon.map { |_, data| generate_tmp_icon(data) }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module FIR
4
+ module Parser
5
+ module Common
6
+
7
+ def generate_tmp_icon data
8
+ tmp_icon_path = "#{Dir.tmpdir}/icon-#{SecureRandom.hex[4..9]}.png"
9
+ File.open(tmp_icon_path, 'w+') { |f| f << data }
10
+ tmp_icon_path
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,9 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require_relative './common'
4
+
3
5
  module FIR
4
6
  module Parser
5
-
6
7
  class Ipa
8
+ include Parser::Common
7
9
 
8
10
  def initialize(path)
9
11
  @path = path
@@ -29,7 +31,7 @@ module FIR
29
31
  end
30
32
 
31
33
  def has_metadata?
32
- File.file? metadata_path
34
+ File.file?(metadata_path)
33
35
  end
34
36
 
35
37
  def metadata_path
@@ -56,11 +58,32 @@ module FIR
56
58
  end
57
59
 
58
60
  class App
59
-
60
61
  def initialize(path)
61
62
  @path = path
62
63
  end
63
64
 
65
+ def full_info(options)
66
+ if options.fetch(:full_info, false)
67
+ basic_info.merge!(icons: tmp_icons)
68
+ end
69
+
70
+ basic_info
71
+ end
72
+
73
+ def basic_info
74
+ @basic_info ||= {
75
+ type: 'ios',
76
+ identifier: identifier,
77
+ name: name,
78
+ display_name: display_name,
79
+ build: version.to_s,
80
+ version: short_version.to_s,
81
+ devices: devices,
82
+ release_type: release_type,
83
+ distribution_name: distribution_name
84
+ }
85
+ end
86
+
64
87
  def info
65
88
  @info ||= CFPropertyList.native_types(
66
89
  CFPropertyList::List.new(file: File.join(@path, 'Info.plist')).value)
@@ -86,6 +109,10 @@ module FIR
86
109
  info['CFBundleShortVersionString']
87
110
  end
88
111
 
112
+ def tmp_icons
113
+ icons.map { |data| generate_tmp_icon(data) }
114
+ end
115
+
89
116
  def icons
90
117
  @icons ||= begin
91
118
  icons = []
@@ -93,7 +120,7 @@ module FIR
93
120
  icons << get_image(name)
94
121
  icons << get_image("#{name}@2x")
95
122
  end
96
- icons.delete_if { |i| !i }
123
+ icons.delete_if &:!
97
124
  rescue NoMethodError
98
125
  []
99
126
  end
@@ -143,15 +170,12 @@ module FIR
143
170
 
144
171
  private
145
172
 
146
- def get_image name
147
- path = File.join(@path, "#{name}.png")
148
- return nil unless File.exist?(path)
149
- path
150
- end
173
+ def get_image(name)
174
+ path = File.join(@path, "#{name}.png")
175
+ return nil unless File.exist?(path)
176
+ path
177
+ end
151
178
  end
152
179
  end
153
-
154
- class Apk
155
- end
156
180
  end
157
181
  end
@@ -3,20 +3,14 @@
3
3
  module FIR
4
4
  module Publish
5
5
 
6
- def publish *args, options
7
- @file_path = File.absolute_path(args.first.to_s)
8
- @token = options[:token] || current_token
9
- @changelog = options[:changelog].to_s.to_utf8
10
- @short = options[:short].to_s
11
-
6
+ def publish(*args, options)
7
+ initialize_publish_options(args, options)
12
8
  check_supported_file_and_token
13
9
 
14
- logger.info "Publishing app......."
10
+ logger.info 'Publishing app.......'
15
11
  logger_info_dividing_line
16
12
 
17
- file_type = File.extname(@file_path).delete(".")
18
-
19
- @app_info = send("#{file_type}_info", @file_path, true)
13
+ @app_info = send("#{@file_type}_info", @file_path, full_info: true)
20
14
  @uploading_info = fetch_uploading_info
21
15
  @app_id = @uploading_info[:id]
22
16
 
@@ -25,15 +19,7 @@ module FIR
25
19
  logger_info_dividing_line
26
20
  logger.info "Published succeed: #{fir_api[:domain]}/#{fetch_app_info[:short]}"
27
21
 
28
- if options[:mappingfile] && options[:proj]
29
- logger_info_blank_line
30
-
31
- mapping options[:mappingfile], proj: options[:proj],
32
- build: @app_info[:build],
33
- version: @app_info[:version],
34
- token: @token
35
- end
36
-
22
+ upload_mapping_file_with_publish(options)
37
23
  logger_info_blank_line
38
24
  end
39
25
 
@@ -41,77 +27,79 @@ module FIR
41
27
  @icon_cert = @uploading_info[:cert][:icon]
42
28
  @binary_cert = @uploading_info[:cert][:binary]
43
29
 
44
- upload_app_icon
30
+ upload_app_icon unless @app_info[:icons].blank?
45
31
  upload_app_binary
46
32
  upload_device_info
47
33
  update_app_info
48
34
  end
49
35
 
50
36
  def upload_app_icon
51
- unless @app_info[:icons].blank?
52
- logger.info "Uploading app's icon......"
37
+ logger.info 'Uploading app icon......'
53
38
 
54
- icon_path = @app_info[:icons].max_by { |f| File.size(f) }
39
+ uploaded_info = post(@icon_cert[:upload_url], uploading_icon_info)
55
40
 
56
- hash = {
57
- key: @icon_cert[:key],
58
- token: @icon_cert[:token],
59
- file: File.new(icon_path, "rb")
60
- }
41
+ return if uploaded_info[:is_completed]
61
42
 
62
- uploaded_info = post(@icon_cert[:upload_url], hash)
43
+ logger.error 'Upload app icon failed'
44
+ exit 1
45
+ end
46
+
47
+ def uploading_icon_info
48
+ icon = @app_info[:icons].max_by { |f| File.size(f) }
63
49
 
64
- unless uploaded_info[:is_completed]
65
- logger.error "Upload app icon failed"
66
- exit 1
67
- end
68
- end
50
+ {
51
+ key: @icon_cert[:key],
52
+ token: @icon_cert[:token],
53
+ file: File.new(icon, 'rb')
54
+ }
69
55
  end
70
56
 
71
57
  def upload_app_binary
72
- logger.info "Uploading app......"
58
+ logger.info 'Uploading app binary......'
59
+
60
+ uploaded_info = post(@binary_cert[:upload_url], uploading_binary_info)
61
+
62
+ return if uploaded_info[:is_completed]
63
+
64
+ logger.error 'Upload app binary failed'
65
+ exit 1
66
+ end
73
67
 
74
- hash = {
68
+ def uploading_binary_info
69
+ {
75
70
  key: @binary_cert[:key],
76
71
  token: @binary_cert[:token],
77
- file: File.new(@file_path, "rb"),
72
+ file: File.new(@file_path, 'rb'),
78
73
  # Custom variables
79
- "x:name" => @app_info[:display_name] || @app_info[:name],
80
- "x:build" => @app_info[:build],
81
- "x:version" => @app_info[:version],
82
- "x:changelog" => @changelog,
83
- "x:release_type" => @app_info[:release_type],
74
+ 'x:name' => @app_info[:display_name] || @app_info[:name],
75
+ 'x:build' => @app_info[:build],
76
+ 'x:version' => @app_info[:version],
77
+ 'x:changelog' => @changelog,
78
+ 'x:release_type' => @app_info[:release_type]
84
79
  }
85
-
86
- uploaded_info = post(@binary_cert[:upload_url], hash)
87
-
88
- unless uploaded_info[:is_completed]
89
- logger.error "Upload app binary failed"
90
- exit 1
91
- end
92
80
  end
93
81
 
94
82
  def upload_device_info
95
- unless @app_info[:devices].blank?
96
- logger.info "Updating devices info......"
83
+ return if @app_info[:devices].blank?
97
84
 
98
- post fir_api[:udids_url], key: @binary_cert[:key],
99
- udids: @app_info[:devices].join(","),
100
- api_token: @token
101
- end
85
+ logger.info 'Updating devices info......'
86
+
87
+ post fir_api[:udids_url], key: @binary_cert[:key],
88
+ udids: @app_info[:devices].join(','),
89
+ api_token: @token
102
90
  end
103
91
 
104
92
  def update_app_info
105
- unless @short.blank?
106
- logger.info "Updating app info......"
93
+ return if @short.blank?
94
+
95
+ logger.info 'Updating app info......'
107
96
 
108
- patch fir_api[:app_url] + "/#{@app_id}", short: @short,
109
- api_token: @token
110
- end
97
+ patch fir_api[:app_url] + "/#{@app_id}", short: @short,
98
+ api_token: @token
111
99
  end
112
100
 
113
101
  def fetch_uploading_info
114
- logger.info "Fetching #{@app_info[:identifier]}@FIR.im uploading info......"
102
+ logger.info "Fetching #{@app_info[:identifier]}@fir.im uploading info......"
115
103
 
116
104
  post fir_api[:app_url], type: @app_info[:type],
117
105
  bundle_id: @app_info[:identifier],
@@ -119,19 +107,37 @@ module FIR
119
107
  end
120
108
 
121
109
  def fetch_app_info
122
- logger.info "Fetch app info from FIR.im"
110
+ logger.info 'Fetch app info from fir.im'
123
111
 
124
112
  get fir_api[:app_url] + "/#{@app_id}", api_token: @token
125
113
  end
126
114
 
115
+ def upload_mapping_file_with_publish(options)
116
+ return if !options[:mappingfile] || !options[:proj]
117
+
118
+ logger_info_blank_line
119
+
120
+ mapping options[:mappingfile], proj: options[:proj],
121
+ build: @app_info[:build],
122
+ version: @app_info[:version],
123
+ token: @token
124
+ end
125
+
127
126
  private
128
127
 
129
- def check_supported_file_and_token
130
- check_file_exist @file_path
131
- check_supported_file @file_path
132
- check_token_cannot_be_blank @token
133
- fetch_user_info @token
134
- end
128
+ def initialize_publish_options(args, options)
129
+ @file_path = File.absolute_path(args.first.to_s)
130
+ @file_type = File.extname(@file_path).delete('.')
131
+ @token = options[:token] || current_token
132
+ @changelog = options[:changelog].to_s.to_utf8
133
+ @short = options[:short].to_s
134
+ end
135
135
 
136
+ def check_supported_file_and_token
137
+ check_file_exist(@file_path)
138
+ check_supported_file(@file_path)
139
+ check_token_cannot_be_blank(@token)
140
+ fetch_user_info(@token)
141
+ end
136
142
  end
137
143
  end
data/lib/fir/util.rb CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  require_relative './util/http'
4
4
  require_relative './util/config'
5
- require_relative './util/parser'
5
+ require_relative './util/parser/apk'
6
+ require_relative './util/parser/ipa'
6
7
  require_relative './util/login'
7
8
  require_relative './util/me'
8
9
  require_relative './util/info'
@@ -30,49 +31,49 @@ module FIR
30
31
 
31
32
  attr_accessor :logger
32
33
 
33
- def fetch_user_info token
34
+ def fetch_user_info(token)
34
35
  get fir_api[:user_url], api_token: token
35
36
  end
36
37
 
37
- def fetch_user_uuid token
38
+ def fetch_user_uuid(token)
38
39
  user_info = fetch_user_info(token)
39
40
  user_info[:uuid]
40
41
  end
41
42
 
42
- def check_file_exist path
43
- unless File.file?(path)
44
- logger.error "File does not exist"
45
- exit 1
46
- end
43
+ def check_file_exist(path)
44
+ return if File.file?(path)
45
+
46
+ logger.error 'File does not exist'
47
+ exit 1
47
48
  end
48
49
 
49
- def check_supported_file path
50
- unless APP_FILE_TYPE.include?(File.extname(path))
51
- logger.error "Unsupported file type"
52
- exit 1
53
- end
50
+ def check_supported_file(path)
51
+ return if APP_FILE_TYPE.include?(File.extname(path))
52
+
53
+ logger.error 'Unsupported file type'
54
+ exit 1
54
55
  end
55
56
 
56
- def check_token_cannot_be_blank token
57
- if token.blank?
58
- logger.error "Token can't be blank"
59
- exit 1
60
- end
57
+ def check_token_cannot_be_blank(token)
58
+ return unless token.blank?
59
+
60
+ logger.error 'Token can not be blank'
61
+ exit 1
61
62
  end
62
63
 
63
64
  def check_logined
64
- if current_token.blank?
65
- logger.error "Please use `fir login` first"
66
- exit 1
67
- end
65
+ return unless current_token.blank?
66
+
67
+ logger.error 'Please use `fir login` first'
68
+ exit 1
68
69
  end
69
70
 
70
71
  def logger_info_blank_line
71
- logger.info ""
72
+ logger.info ''
72
73
  end
73
74
 
74
75
  def logger_info_dividing_line
75
- logger.info "✈ -------------------------------------------- ✈"
76
+ logger.info '✈ -------------------------------------------- ✈'
76
77
  end
77
78
  end
78
79
  end
data/lib/fir/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module FIR
4
- VERSION = "1.2.2"
4
+ VERSION = '1.2.3'
5
5
  end
@@ -5,7 +5,7 @@ class BuildAppTest < Minitest::Test
5
5
  def test_build_app
6
6
  if ENV['BUILD_TEST']
7
7
  options = OpenStruct.new
8
- options.send("publish?=", true)
8
+ options.send('publish?=', true)
9
9
 
10
10
  assert FIR.build_ipa(default_ipa_project, options)
11
11
  assert FIR.build_apk(default_apk_project, options)
data/test/info_test.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  class InfoTest < Minitest::Test
4
4
 
5
5
  def test_apk_info
6
- info = FIR.apk_info(default_apk, true)
6
+ info = FIR.apk_info(default_apk, full_info: true)
7
7
 
8
8
  assert_equal 'android', info[:type]
9
9
  assert_equal 'com.bughd.myapplication', info[:identifier]
@@ -17,7 +17,7 @@ class InfoTest < Minitest::Test
17
17
  end
18
18
 
19
19
  def test_ipa_info
20
- info = FIR.ipa_info(default_ipa, true)
20
+ info = FIR.ipa_info(default_ipa, full_info: true)
21
21
 
22
22
  assert_equal 'ios', info[:type]
23
23
  assert_equal 'im.fir.build-ipa', info[:identifier]
@@ -31,9 +31,6 @@ class InfoTest < Minitest::Test
31
31
  # assert_equal 'adhoc', info[:release_type]
32
32
  # assert_equal default_distribution_name, info[:distribution_name]
33
33
 
34
- assert_equal true, info[:plist].is_a?(Hash)
35
- assert_equal true, info[:mobileprovision].is_a?(Hash)
36
-
37
34
  assert FIR.info(default_ipa, {})
38
35
  end
39
36
  end
data/test/mapping_test.rb CHANGED
@@ -12,7 +12,7 @@ class MappingTest < Minitest::Test
12
12
  if ENV['MAPPING_TEST']
13
13
  assert FIR.mapping(default_dsym_mapping, options.merge(proj: default_bughd_project_ios_id))
14
14
  assert FIR.mapping(default_txt_mapping, options.merge(proj: default_bughd_project_android_id))
15
- assert FIR.mapping(bigger_txt_mapping, options.merge(proj: default_bughd_project_android_id))
15
+ assert FIR.mapping(bigger_txt_mapping, options.merge(proj: default_bughd_project_android_id))
16
16
  end
17
17
  end
18
18
  end
data/test/test_helper.rb CHANGED
@@ -6,7 +6,6 @@ require 'fir'
6
6
  require 'codeclimate-test-reporter'
7
7
  CodeClimate::TestReporter.start
8
8
 
9
-
10
9
  FIR.logger = Logger.new(STDOUT)
11
10
 
12
11
  class Minitest::Test
@@ -56,7 +55,7 @@ class Minitest::Test
56
55
  end
57
56
 
58
57
  def default_device_udid
59
- "cf8b87e3f469d7b185fd64c057778aecbc2017a6"
58
+ 'cf8b87e3f469d7b185fd64c057778aecbc2017a6'
60
59
  end
61
60
 
62
61
  def default_distribution_name