pindo 4.7.0 → 4.7.2

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/aeshelper.rb +30 -2
  3. data/lib/pindo/base/githelper.rb +7 -9
  4. data/lib/pindo/client/aws3sclient.rb +1 -1
  5. data/lib/pindo/client/bossconfigclient.rb +3 -3
  6. data/lib/pindo/client/giteeclient.rb +2 -2
  7. data/lib/pindo/client/pgyerclient.rb +97 -102
  8. data/lib/pindo/command/appstore/iap.rb +1 -1
  9. data/lib/pindo/command/deploy/build.rb +70 -4
  10. data/lib/pindo/command/deploy/cert.rb +68 -67
  11. data/lib/pindo/command/{utils → dev}/applovin.rb +2 -2
  12. data/lib/pindo/command/dev/autobuild.rb +19 -7
  13. data/lib/pindo/command/dev/autoresign.rb +10 -6
  14. data/lib/pindo/command/dev/build.rb +94 -0
  15. data/lib/pindo/command/dev.rb +3 -6
  16. data/lib/pindo/command/ipa/autoresign.rb +4 -1
  17. data/lib/pindo/command/ipa/import.rb +45 -9
  18. data/lib/pindo/command/ipa/output.rb +7 -2
  19. data/lib/pindo/command/lib/update.rb +8 -8
  20. data/lib/pindo/command/pgyer/resign.rb +21 -19
  21. data/lib/pindo/command/pgyer/upload.rb +34 -6
  22. data/lib/pindo/command/utils/renewcert.rb +158 -0
  23. data/lib/pindo/command/utils.rb +1 -1
  24. data/lib/pindo/config/pindoconfig.rb +27 -0
  25. data/lib/pindo/module/appselect.rb +9 -8
  26. data/lib/pindo/module/cert/certhelper.rb +42 -36
  27. data/lib/pindo/module/cert/keychainhelper.rb +25 -13
  28. data/lib/pindo/module/cert/provisioninghelper.rb +1 -1
  29. data/lib/pindo/module/cert/xcodecerthelper.rb +98 -39
  30. data/lib/pindo/module/pgyer/pgyerhelper.rb +50 -28
  31. data/lib/pindo/module/xcode/xcodeappconfig.rb +2 -3
  32. data/lib/pindo/module/xcode/xcodereshandler.rb +41 -13
  33. data/lib/pindo/module/xcode/xcodereshelper.rb +2 -3
  34. data/lib/pindo/options/deployoptions.rb +1 -2
  35. data/lib/pindo/version.rb +1 -1
  36. metadata +5 -4
  37. data/lib/pindo/command/dev/renewcert.rb +0 -142
@@ -3,11 +3,13 @@ require 'open3'
3
3
  require 'security'
4
4
 
5
5
  module Pindo
6
-
6
+
7
7
  module KeychainHelper
8
8
 
9
9
  def self.import_file(path, keychain_path, keychain_password: nil, certificate_password: "", skip_set_partition_list: false, output: false)
10
- puts "Could not find file '#{path}'" unless File.exist?(path)
10
+ # puts path
11
+
12
+ # puts "Could not find file '#{path}'" unless File.exist?(path)
11
13
 
12
14
  password_part = " -P #{certificate_password.shellescape}"
13
15
 
@@ -19,22 +21,28 @@ module Pindo
19
21
  command << " -T /usr/bin/productsign" # to not be asked for permission when using an installer cert for macOS
20
22
  command << " 1> /dev/null" unless output
21
23
 
22
- sensitive_command = command.gsub(password_part, " -P ********")
23
- UI.command(sensitive_command) if output
24
- Open3.popen3(command) do |stdin, stdout, stderr, thrd|
25
- UI.command_output(stdout.read.to_s) if output
24
+ # puts command
25
+ # sensitive_command = command.gsub(password_part, " -P ********")
26
26
 
27
+ # UI.command(sensitive_command) if output
28
+ Open3.popen3(command) do |stdin, stdout, stderr, thrd|
29
+ # UI.command_output(stdout.read.to_s) if output
30
+ # puts "123"
27
31
  # Set partition list only if success since it can be a time consuming process if a lot of keys are installed
28
32
  if thrd.value.success? && !skip_set_partition_list
33
+ # puts "安装成功!"
29
34
  keychain_password ||= resolve_keychain_password(keychain_path)
30
35
  set_partition_list(path, keychain_path, keychain_password: keychain_password, output: output)
31
36
  else
32
37
  # Output verbose if file is already installed since not an error otherwise we will show the whole error
33
38
  err = stderr.read.to_s.strip
39
+
34
40
  if err.include?("SecKeychainItemImport") && err.include?("The specified item already exists in the keychain")
35
- # UI.verbose("'#{File.basename(path)}' is already installed on this machine")
41
+ # UI.verbose("'}' is already installed on this machine")
42
+ # puts "证书key已经存在,安装完成!"
36
43
  else
37
- raise Informative, err
44
+ # puts err
45
+ # raise Informative, err
38
46
  end
39
47
  end
40
48
  end
@@ -64,8 +72,9 @@ module Pindo
64
72
  # Helper.show_loading_indicator("Setting key partition list... (this can take a minute if there are a lot of keys installed)")
65
73
 
66
74
  # Strip keychain password from command output
67
- sensitive_command = command.gsub(password_part, " -k ********")
68
- UI.command(sensitive_command) if output
75
+ # sensitive_command = command.gsub(password_part, " -k ********")
76
+ # puts command
77
+ # UI.command(sensitive_command) if output
69
78
  Open3.popen3(command) do |stdin, stdout, stderr, thrd|
70
79
  unless thrd.value.success?
71
80
  err = stderr.read.to_s.strip
@@ -73,6 +82,9 @@ module Pindo
73
82
  # Inform user when no/wrong password was used as its needed to prevent UI permission popup from Xcode when signing
74
83
  if err.include?("SecKeychainItemSetAccessWithPassword")
75
84
  keychain_name = File.basename(keychain_path, ".*")
85
+ # puts "password #{keychain_password}"
86
+ # puts "keychain #{keychain_name}"
87
+ # puts "security #{server_name(keychain_name)}"
76
88
  Security::InternetPassword.delete(server: server_name(keychain_name))
77
89
 
78
90
  # UI.important("")
@@ -83,9 +95,9 @@ module Pindo
83
95
  # UI.important("Please look at the following docs to see how to set a keychain password:")
84
96
  # UI.important(" - https://docs.fastlane.tools/actions/sync_code_signing")
85
97
  # UI.important(" - https://docs.fastlane.tools/actions/get_certificates")
86
- puts "密码错误"
98
+ # puts "证书密码错误!"
87
99
  else
88
- raise Informative, err
100
+ puts err
89
101
  end
90
102
  end
91
103
  end
@@ -130,7 +142,7 @@ module Pindo
130
142
 
131
143
  # server name used for accessing the macOS keychain
132
144
  def self.server_name(keychain_name)
133
- ["fastlane", "keychain", keychain_name].join("_")
145
+ ["pindo", "keychain", keychain_name].join("_")
134
146
  end
135
147
 
136
148
  private_class_method :server_name
@@ -89,7 +89,7 @@ module Pindo
89
89
 
90
90
 
91
91
  destination = File.join(profiles_path, profile_filename(path, keychain_path))
92
- puts "Installing provisioning profile... #{destination}"
92
+ # puts "Installing provisioning profile... #{destination}"
93
93
 
94
94
  if path != destination
95
95
  # copy to Xcode provisioning profile directory
@@ -1,5 +1,6 @@
1
1
 
2
2
  require 'fileutils'
3
+ require 'pindo/base/aeshelper'
3
4
 
4
5
  module Pindo
5
6
 
@@ -69,12 +70,17 @@ module Pindo
69
70
 
70
71
  new_project_obj.targets.each do |target|
71
72
 
73
+ if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
74
+ target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:bundle])
75
+ next
76
+ end
72
77
  provisioning_info = nil
73
78
 
74
79
  if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application])
75
80
  bundle_id_map_key = target_map["MainTarget"]
76
81
  provisioning_info = provisioning_info_array.select { |s| s["type"].to_s.eql?(bundle_id_map_key.to_s) }.first
77
- elsif
82
+ else
83
+
78
84
  target_map.each do |k, v|
79
85
  if target.name.to_s.end_with?(k)
80
86
  bundle_id_map_key = v.to_s
@@ -83,29 +89,34 @@ module Pindo
83
89
  end
84
90
  end
85
91
 
86
- target.build_configurations.each do |config|
87
- target_atts_obj[target.uuid] = target_atts_obj[target.uuid] || {}
88
- target_atts_obj[target.uuid]['DevelopmentTeam'] = team_id_vaule
89
- target_atts_obj[target.uuid]['ProvisioningStyle'] = "Manual"
90
- config.build_settings['DEVELOPMENT_TEAM'] = team_id_vaule
91
- config.build_settings['DEVELOPMENT_TEAM[sdk=iphoneos*]'] = team_id_vaule
92
- config.build_settings['CODE_SIGN_STYLE'] = "Manual"
93
-
94
- config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Distribution"
95
- config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Distribution"
96
-
97
- if cert_type == "development"
98
- config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Development"
99
- config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Development"
100
- end
92
+ # puts "=====1 target name: #{target.name.to_s} bundle_id_map_key: #{bundle_id_map_key} provisioning_info: #{provisioning_info}"
101
93
 
102
- if !provisioning_info.nil?
103
- config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = provisioning_info["bundle_id"]
104
- config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = provisioning_info['profile_name']
105
- config.build_settings['PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]'] = provisioning_info['profile_name']
106
-
94
+ if !provisioning_info.nil?
95
+ target.build_configurations.each do |config|
96
+ target_atts_obj[target.uuid] = target_atts_obj[target.uuid] || {}
97
+ target_atts_obj[target.uuid]['DevelopmentTeam'] = team_id_vaule
98
+ target_atts_obj[target.uuid]['ProvisioningStyle'] = "Manual"
99
+ config.build_settings['DEVELOPMENT_TEAM'] = team_id_vaule
100
+ config.build_settings['DEVELOPMENT_TEAM[sdk=iphoneos*]'] = team_id_vaule
101
+ config.build_settings['CODE_SIGN_STYLE'] = "Manual"
102
+
103
+ config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Distribution"
104
+ config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Distribution"
105
+
106
+ if cert_type == "development"
107
+ config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Development"
108
+ config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Development"
109
+ end
110
+
111
+ if !provisioning_info.nil?
112
+ config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = provisioning_info["bundle_id"]
113
+ config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = provisioning_info['profile_name']
114
+ config.build_settings['PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]'] = provisioning_info['profile_name']
115
+
116
+ end
107
117
  end
108
118
  end
119
+
109
120
 
110
121
  end
111
122
  new_project_obj.save
@@ -120,6 +131,11 @@ module Pindo
120
131
 
121
132
  project_obj.targets.each do |target|
122
133
 
134
+ if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
135
+ target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:bundle])
136
+ next
137
+ end
138
+
123
139
  temp_entitlements_file = target.build_configurations.first.build_settings['CODE_SIGN_ENTITLEMENTS']
124
140
  if !temp_entitlements_file.nil? && !temp_entitlements_file.empty?
125
141
  entitlements_plist_path = File.join(new_project_dir, temp_entitlements_file)
@@ -127,27 +143,37 @@ module Pindo
127
143
  if !File.exist?(entitlements_plist_path)
128
144
  raise Informative, "Target: #{target.name.to_s} 找不到文件 #{entitlements_plist_path}"
129
145
  end
130
- end
131
146
 
132
- temp_info = target.build_configurations.first.build_settings['INFOPLIST_FILE']
133
- info_plist_path = File.join(new_project_dir, temp_info)
134
- if target.product_type.to_s.eql?("com.apple.product-type.application") && !File.exist?(info_plist_path)
135
- raise Informative, "Missing Target #{target.name.to_s} Info.plist!!! #{info_plist_path} Modify Info.plist Error !!!"
147
+ if !group_id.nil?
148
+ modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, group_id:group_id)
149
+ end
150
+
151
+ if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
152
+ add_swark_entitlement(entitlements_plist_path:entitlements_plist_path, bundle_id_dict:provisioning_info_array)
153
+ if !icloud_id.nil?
154
+ modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, icloud_id:icloud_id)
155
+ end
156
+ end
157
+
136
158
  end
137
159
 
160
+ temp_info = target.build_configurations.first.build_settings['INFOPLIST_FILE']
161
+ if !temp_info.nil? && !temp_info.empty?
162
+ info_plist_path = File.join(new_project_dir, temp_info)
163
+ if !File.exist?(info_plist_path)
164
+ raise Informative, "Missing Target #{target.name.to_s} Info.plist!!! #{info_plist_path} Modify Info.plist Error !!!"
165
+ end
138
166
 
139
- if target.product_type.to_s.eql?("com.apple.product-type.application") then
140
- add_swark_entitlement(entitlements_plist_path:entitlements_plist_path, bundle_id_dict:provisioning_info_array)
141
- if !icloud_id.nil?
142
- modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, icloud_id:icloud_id)
143
- modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:icloud_id)
144
- else
145
- modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:nil)
167
+ if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
168
+ if !icloud_id.nil?
169
+ modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:icloud_id)
170
+ else
171
+ modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:nil)
172
+ end
146
173
  end
174
+
147
175
  end
148
- if !group_id.nil?
149
- modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, group_id:group_id)
150
- end
176
+
151
177
  end
152
178
 
153
179
  end
@@ -200,7 +226,40 @@ module Pindo
200
226
  end
201
227
  end
202
228
 
203
- def create_upload_cert_info(apple_id:nil, cert_type:nil, provisioning_info_array:nil)
229
+ def create_upload_cert_info(apple_id:nil, cert_type:nil)
230
+
231
+ cert_dest_dir = File.join(Dir.pwd, "cert")
232
+ if !File.exist?(cert_dest_dir)
233
+ FileUtils.mkdir_p(cert_dest_dir)
234
+ end
235
+
236
+
237
+ cert_git_url = pindo_single_config.deploy_cert_giturl
238
+ if apple_id.eql?(pindo_single_config.demo_apple_id)
239
+ cert_git_url = pindo_single_config.dev_cert_giturl
240
+ end
241
+ cert_reponame = cert_git_url.split("/").last.chomp(".git")
242
+ certs_dir = getcode_to_dir(reponame:cert_reponame, remote_url:cert_git_url, path: pindo_single_config.pindo_dir, new_branch:apple_id)
243
+
244
+ cert_git_dir = cert_type.downcase
245
+ if !cert_type.downcase.include?("development")
246
+ cert_git_dir = "distribution"
247
+ end
248
+
249
+ keys = Dir[File.join(certs_dir, "certs", cert_git_dir.to_s, "*.p12")]
250
+ decrypt_password = AESHelper.fetch_password(keychain_name:cert_git_url)
251
+ output_dir = Dir.mktmpdir
252
+ key_path = AESHelper.decrypt_specific_file(src_file: keys.first, password:decrypt_password, output_dir: output_dir)
253
+ if key_path.nil? || key_path.empty? || !File.exist?(key_path)
254
+ AESHelper.delete_password(keychain_name:cert_git_url)
255
+ raise Informative, "证书解析失败,密码错误!"
256
+ end
257
+
258
+ FileUtils.copy(key_path, File.join(cert_dest_dir, "#{cert_type}.p12"))
259
+
260
+ end
261
+
262
+ def create_upload_provisioning_info(apple_id:nil, cert_type:nil, provisioning_info_array:nil)
204
263
 
205
264
  cert_dir = File.join(Dir.pwd, "cert")
206
265
  cert_json_file = File.join(cert_dir, "certs.json")
@@ -247,8 +306,8 @@ module Pindo
247
306
 
248
307
  cert_item["cert_id"] = cert_item["cert_id"] || bundle_id_signing_identity
249
308
  cert_item["password"] = "goodcert1"
250
- cert_item["cert_file"] = "#{cert_type}.p12".downcase
251
- cert_item["cert_type"] = cert_type.downcase
309
+ cert_item["cert_file"] = "#{cert_type}.p12"
310
+ cert_item["cert_type"] = cert_type
252
311
  cert_item["cert_provisioning_group"] = cert_item["cert_provisioning_group"] || []
253
312
 
254
313
 
@@ -36,21 +36,27 @@ module Pindo
36
36
  def login
37
37
  @pgyer_client = PgyerClient.new
38
38
  if @force_login || !@has_login
39
- @has_login = @pgyer_client.do_login(force_login:@force_login)
39
+ @has_login = @pgyer_client.do_login(force_login:@force_login)
40
40
  @force_login = false
41
+ else
42
+ @has_login = @pgyer_client.do_login(force_login:false)
41
43
  end
42
44
  return @has_login
43
45
  end
44
46
 
45
47
  def prepare_upload(working_directory:nil, proj_name:nil)
46
48
  upload_proj_name = proj_name
49
+ if upload_proj_name.nil? || upload_proj_name.empty?
50
+ upload_proj_name = @proj_name
51
+ end
52
+
47
53
  app_info_obj = nil
48
54
  if login
49
55
 
50
- if !proj_name.nil?
56
+ if !upload_proj_name.nil?
51
57
  app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
52
58
  end
53
-
59
+
54
60
  if !app_info_obj.nil?
55
61
  return app_info_obj
56
62
  end
@@ -58,35 +64,35 @@ module Pindo
58
64
  proj_name_array = []
59
65
  if File.exist?(File.join(working_directory, "config.json"))
60
66
  config_json = JSON.parse(File.read(File.join(working_directory, "config.json")))
61
- proj_name_array << config_json["project_info"]["project_name"]
67
+ proj_name_array << config_json["project_info"]["project_name"]
62
68
  end
63
69
 
64
70
  xcodeproj_file_name = Dir.glob(File.join(Dir.pwd, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
65
71
  upload_proj_name = File.basename(xcodeproj_file_name, ".xcodeproj") if xcodeproj_file_name
66
72
  if !upload_proj_name.nil? && !upload_proj_name.empty?
67
- proj_name_array << upload_proj_name
73
+ proj_name_array << upload_proj_name
68
74
  end
69
-
75
+
70
76
  puts
71
77
  dir_base_name = File.basename(working_directory)
72
78
  unless ["Desktop", "Documents", "Downloads"].include?(dir_base_name)
73
79
  proj_name_array << dir_base_name
74
80
  end
75
-
81
+
76
82
  proj_name_array << "自定义输入Pyger上的App代号"
77
83
 
78
84
  if proj_name_array.size > 1
79
85
  cli = HighLine.new
80
86
  upload_proj_name = cli.choose do |menu|
81
- menu.prompt = "请选择对应的Pgyer App代号:"
87
+ menu.prompt = "请选择Pgyer上的App代号:"
82
88
  menu.choices(*proj_name_array)
83
89
  end
84
90
  if upload_proj_name.include?("自定义输入")
85
- upload_proj_name = ask('请输入对应Pyger上的App代号(大小写空格忽略):') || nil
91
+ upload_proj_name = ask('请输入Pyger上的App代号(大小写空格忽略):') || nil
86
92
  upload_proj_name = upload_proj_name.strip
87
93
  end
88
94
  else
89
- upload_proj_name = ask('请输入对应Pyger上的App代号(大小写空格忽略):') || nil
95
+ upload_proj_name = ask('请输入Pyger上的App代号(大小写空格忽略):') || nil
90
96
  upload_proj_name = upload_proj_name.strip
91
97
  end
92
98
 
@@ -94,15 +100,18 @@ module Pindo
94
100
  app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
95
101
 
96
102
  if app_info_obj.nil?
97
- upload_proj_name = ask('请输入对应Pyger上的App代号(大小写空格忽略):') || nil
103
+ upload_proj_name = ask('没有找到结果,请重新输入Pyger上的App代号(大小写空格忽略):') || nil
98
104
  upload_proj_name = upload_proj_name.strip
99
105
  app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
100
106
  end
101
107
 
102
108
  if app_info_obj.nil?
103
- raise Informative, "#{upload_proj_name} 错误, 请输入正确的App代号, pgyer网站没有该App"
109
+ raise Informative, "#{upload_proj_name} 名称错误, 请输入正确的App代号,Pgyer网站没有该App!!!"
104
110
  end
111
+ else
112
+ raise Informative, "请先登录Pgyer网站"
105
113
  end
114
+ @proj_name = upload_proj_name
106
115
  app_info_obj
107
116
  end
108
117
 
@@ -110,20 +119,28 @@ module Pindo
110
119
 
111
120
  args_ipa_file_dir = File.expand_path(File::dirname(ipa_file_upload))
112
121
  ipa_file_upload=File.join(args_ipa_file_dir, File.basename(ipa_file_upload))
113
-
114
122
  current_project_dir = Dir.pwd
115
- puts "current_project_dir : #{current_project_dir}"
116
- puts description
117
- puts File.exist?(File.join(current_project_dir, ".git"))
118
123
  if description.nil? && File.exist?(File.join(current_project_dir, ".git"))
119
- commit_id_info = git_latest_commit_id(local_repo_dir:current_project_dir)
120
- if commit_id_info
121
- description = "commit " + commit_id_info
124
+ description = git!(%W(-C #{current_project_dir} show -s --format=commit::%H)).strip
125
+ xcodeproj_file_name = Dir.glob(File.join(current_project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
126
+ if !xcodeproj_file_name.nil? && !xcodeproj_file_name.empty? && File.exist?(xcodeproj_file_name)
127
+ project_obj = Xcodeproj::Project.open(xcodeproj_file_name)
128
+ main_target = project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
129
+ provisioning_profile_name = main_target.build_configurations.first.build_settings['PROVISIONING_PROFILE_SPECIFIER'].downcase.split(" ")
130
+ if provisioning_profile_name.include?("adhoc")
131
+ description = git!(%W(-C #{current_project_dir} show -s --format=commit::%H)).strip
132
+ elsif provisioning_profile_name.include?("development")
133
+ if File.exist?(File.join(current_project_dir, ".release_info"))
134
+ description = File.read(File.join(current_project_dir, ".release_info"))
135
+ else
136
+ description = git!(%W(-C #{current_project_dir} show -s --format=%h::%s)).strip
137
+ end
138
+ elsif provisioning_profile_name.include?("appstore")
139
+ description = "提交包重签名"
140
+ end
122
141
  end
123
142
  end
124
143
 
125
- puts "description : #{description}"
126
-
127
144
  addtach_file = nil
128
145
  if ipa_file_upload.include?(File.join(current_project_dir, "build")) && File.exist?(File.join(current_project_dir, "VMData"))
129
146
 
@@ -150,7 +167,8 @@ module Pindo
150
167
 
151
168
  puts
152
169
  puts "上传项目: #{app_info_obj["appName"]}"
153
- puts "上传备注: #{description}"
170
+ print "上传备注: "
171
+ puts description
154
172
 
155
173
 
156
174
  aws_client = AWSS3Client.new
@@ -206,9 +224,12 @@ module Pindo
206
224
  end
207
225
 
208
226
 
209
- def send_apptest_wechat_msg(msg_data:nil)
227
+ def send_apptest_wechat_msg(msg_data:nil, wechat_url:nil)
210
228
 
211
- wechat_msg_url = get_user_local_wechat_url()
229
+ wechat_msg_url = wechat_url
230
+ if wechat_msg_url.nil? || wechat_msg_url.empty?
231
+ wechat_msg_url = get_user_local_wechat_url()
232
+ end
212
233
 
213
234
  if !wechat_msg_url.nil? && wechat_msg_url.length >1
214
235
 
@@ -264,7 +285,7 @@ module Pindo
264
285
  req.headers['Content-Type'] = 'application/json'
265
286
  req.body = body_data.to_json
266
287
  end
267
-
288
+
268
289
 
269
290
  body_data = {
270
291
  msgtype:"text",
@@ -387,7 +408,7 @@ module Pindo
387
408
  Funlog.instance.fancyinfo_error("拉取app信息列表失败!")
388
409
  raise Informative, "Pgyer网络数据异常!!!"
389
410
  end
390
-
411
+
391
412
 
392
413
  return app_info_list
393
414
  end
@@ -397,6 +418,7 @@ module Pindo
397
418
  Funlog.instance.fancyinfo_start("正在拉取app上传记录...")
398
419
 
399
420
  appId = app_info_obj["appId"]
421
+ # puts "appId #{appId}"
400
422
  version_data = @pgyer_client.get_app_version_list_req(appId:appId) || {}
401
423
 
402
424
  if version_data["data"].nil? || version_data["data"].size <=0
@@ -424,7 +446,7 @@ module Pindo
424
446
  app_incId_index = ask('请选择上面的Build号:')
425
447
 
426
448
  end
427
-
449
+
428
450
  Funlog.instance.fancyinfo_success("拉取app上传记录完成!")
429
451
 
430
452
  version_item_obj = nil
@@ -508,7 +530,7 @@ module Pindo
508
530
  return true
509
531
  else
510
532
  Funlog.instance.fancyinfo_error("重签名失败!")
511
- return false
533
+ return false
512
534
  end
513
535
 
514
536
  end
@@ -7,8 +7,7 @@ module Pindo
7
7
  module XcodeAppConfig
8
8
 
9
9
  def auto_increase_buildnumber(app_config_file:nil)
10
-
11
- if !File.exist?(app_config_file)
10
+ if File.exist?(app_config_file)
12
11
  config_json = JSON.parse(File.read(app_config_file))
13
12
  app_version = config_json['app_info']['app_version']
14
13
  app_build_version = config_json['app_info']['app_build_version']
@@ -26,7 +25,7 @@ module Pindo
26
25
  app_build_version = app_build_version_array.join(".")
27
26
 
28
27
  config_json['app_info']['app_build_version'] = app_build_version
29
- File.open(app_origin_config, "w") do |file|
28
+ File.open(app_config_file, "w") do |file|
30
29
  file.write(JSON.pretty_generate(config_json))
31
30
  file.close
32
31
  end
@@ -72,20 +72,36 @@ module Pindo
72
72
 
73
73
  def initialize(proj_fullname:nil)
74
74
  @proj_fullname = proj_fullname
75
- @project_obj = Xcodeproj::Project.open(proj_fullname)
75
+ @project_obj = Xcodeproj::Project.open(proj_fullname)
76
76
  end
77
77
 
78
78
  def get_xcodeproj_icon_path
79
+
80
+ icon_path = nil
79
81
  select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
80
- file_ref = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") }.first
81
- icon_path = File.join(file_ref.real_path,"AppIcon.appiconset")
82
+ if !select_target.nil?
83
+ file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
84
+ file_refs.each do |file_ref|
85
+ icon_path = File.join(file_ref.real_path,"AppIcon.appiconset")
86
+ if File.exist?(icon_path)
87
+ break
88
+ else
89
+ next
90
+ end
91
+ end
92
+ end
93
+
94
+ if icon_path.nil? || icon_path.empty? || !File.exist?(icon_path)
95
+ raise Informative, "没有找到Xcode icon 目录"
96
+ end
97
+
82
98
  return icon_path
83
99
  end
84
100
 
85
101
  def install_icon_res(new_icon_dir:nil)
86
102
  icon_path = get_xcodeproj_icon_path
87
103
  begin
88
- FileUtils.rm_rf(icon_path)
104
+ FileUtils.rm_rf(icon_path)
89
105
  FileUtils.mkdir_p(icon_path)
90
106
  rescue StandardError => e
91
107
  end
@@ -109,17 +125,29 @@ module Pindo
109
125
  def get_xcodeproj_imessage_icon_path
110
126
  icon_path = nil
111
127
  select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
112
- if select_target.nil?
113
- file_ref = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") }.first
114
- icon_path = File.join(file_ref.real_path,"iMessage App Icon.stickersiconset")
128
+ if !select_target.nil?
129
+ file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
130
+ file_refs.each do |file_ref|
131
+ icon_path = File.join(file_ref.real_path,"iMessage App Icon.stickersiconset")
132
+ if File.exist?(icon_path)
133
+ break
134
+ else
135
+ next
136
+ end
137
+ end
138
+
139
+ if icon_path.nil? || icon_path.empty? || !File.exist?(icon_path)
140
+ raise Informative, "没有找到Xcode iMessage icon 目录"
141
+ end
115
142
  end
143
+
116
144
  return icon_path
117
145
  end
118
146
 
119
147
  def install_imessage_icon_res(new_icon_dir:nil)
120
148
  icon_path = get_xcodeproj_imessage_icon_path
121
149
  begin
122
- FileUtils.rm_rf(icon_path)
150
+ FileUtils.rm_rf(icon_path)
123
151
  FileUtils.mkdir_p(icon_path)
124
152
  rescue StandardError => e
125
153
  end
@@ -147,7 +175,7 @@ module Pindo
147
175
  launchimg_path = nil
148
176
  select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
149
177
  file_ref = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") }.first
150
-
178
+
151
179
  assets_path = file_ref.real_path
152
180
  if File.exist?(File.join(assets_path, "LaunchImage.imageset"))
153
181
  launchimg_path = File.join(assets_path, "LaunchImage.imageset")
@@ -167,9 +195,9 @@ module Pindo
167
195
  end
168
196
 
169
197
  project_origin_launchimg = Dir.glob(File.join(xcodeproj_launchimg_path, "/*.png")).max_by {|f| File.mtime(f)}
170
-
198
+
171
199
  if project_origin_launchimg.nil? || !File.exist?(project_origin_launchimg)
172
- return
200
+ return
173
201
  end
174
202
 
175
203
  if File.exist?(project_origin_launchimg) && !File.exist?(launchimg_file)
@@ -177,7 +205,7 @@ module Pindo
177
205
  end
178
206
 
179
207
  begin
180
- FileUtils.rm_rf(xcodeproj_launchimg_path)
208
+ FileUtils.rm_rf(xcodeproj_launchimg_path)
181
209
  FileUtils.mkdir_p(xcodeproj_launchimg_path)
182
210
  rescue StandardError => e
183
211
  end
@@ -190,7 +218,7 @@ module Pindo
190
218
  File.open(File.join(xcodeproj_launchimg_path, "Contents.json"), "w") do |f|
191
219
  f.write(JSON.pretty_generate(launch_json))
192
220
  end
193
-
221
+
194
222
  end
195
223
 
196
224
  end
@@ -63,7 +63,7 @@ module Pindo
63
63
  'sips',
64
64
  '--matchTo', '/System/Library/ColorSync/Profiles/sRGB Profile.icc',
65
65
  '-z', width.to_s, height.to_s,
66
- icon_name,
66
+ icon_ori_name,
67
67
  '--out', File.join(new_icon_dir, image_name)
68
68
  ]
69
69
  Executable.capture_command('sips', command, capture: :out)
@@ -83,7 +83,6 @@ module Pindo
83
83
  create_icon(icon_name: icon_name, new_icon_dir: new_icon_dir, xcode_icon_json: XcodoeResConst.xcode_ios_icon_json)
84
84
  icon_dir = File.dirname(icon_name)
85
85
  imessage_icon = File.join(icon_dir, "icon1024_768.png")
86
-
87
86
  new_imessage_icon_dir = File.join(new_icon_dir, "imessage")
88
87
 
89
88
  if File.exist?(imessage_icon)
@@ -92,7 +91,7 @@ module Pindo
92
91
  rescue => e
93
92
  puts e
94
93
  end
95
- create_imessage_icon(icon_name: imessage_icon, image_icon_name:imessage_icon, new_icon_dir: new_imessage_icon_dir, xcode_icon_json: XcodoeResConst.xcode_ios_imessage_icon_json)
94
+ create_imessage_icon(icon_name: icon_name, image_icon_name:imessage_icon, new_icon_dir: new_imessage_icon_dir, xcode_icon_json: XcodoeResConst.xcode_ios_imessage_icon_json)
96
95
  end
97
96
  end
98
97