pindo 4.7.0 → 4.7.1

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.
@@ -39,6 +39,10 @@ module Pindo
39
39
  @args_send_flag = argv.flag?('send', false)
40
40
  @args_proj_name = argv.option('proj')
41
41
 
42
+ if @args_send_flag
43
+ @args_upload_flag = true
44
+ end
45
+
42
46
  super
43
47
  @additional_args = argv.remainder!
44
48
  end
@@ -58,7 +62,7 @@ module Pindo
58
62
  end
59
63
 
60
64
  app_info_obj = nil
61
- if @args_upload_flag || @args_send_flag
65
+ if @args_upload_flag
62
66
  proj_name = @args_proj_name
63
67
  app_info_obj = PgyerHelper.share_instace.prepare_upload(working_directory:Dir.pwd, proj_name:proj_name)
64
68
  end
@@ -120,7 +124,18 @@ module Pindo
120
124
  ipa_file_upload = Dir.glob(build_path).max_by {|f| File.mtime(f)}
121
125
 
122
126
  if !ipa_file_upload.nil? && !app_info_obj.nil?
123
- result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:nil)
127
+ description = nil
128
+ if File.exist?(File.join(pindo_new_project_dir, ".release_info"))
129
+ description = File.read(File.join(pindo_new_project_dir, ".release_info"))
130
+ else
131
+ if File.exist?(File.join(pindo_new_project_dir, ".git"))
132
+ description = git!(%W(-C #{pindo_new_project_dir} show -s --format='%h %s')).strip
133
+ unless !description.nil? && description.length > 10
134
+ description = nil
135
+ end
136
+ end
137
+ end
138
+ result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:description)
124
139
  if !result_data.nil? && !result_data["data"].nil? && !result_data["data"]["id"].nil?
125
140
  msg_data = PgyerHelper.share_instace.make_msg_data(app_info_obj:app_info_obj, app_version_info_obj:result_data["data"])
126
141
  PgyerHelper.share_instace.print_app_version_info(msg_data:msg_data)
@@ -45,6 +45,10 @@ module Pindo
45
45
  @args_send_flag = argv.flag?('send', false)
46
46
  @args_proj_name = argv.option('proj')
47
47
 
48
+ if @args_send_flag
49
+ @args_upload_flag = true
50
+ end
51
+
48
52
  super
49
53
  @additional_args = argv.remainder!
50
54
  end
@@ -0,0 +1,94 @@
1
+ require 'highline/import'
2
+ require 'fileutils'
3
+ require 'json'
4
+ require 'xcodeproj'
5
+ require 'gym'
6
+
7
+ module Pindo
8
+ class Command
9
+ class Dev < Command
10
+ class Build < Dev
11
+
12
+
13
+ self.summary = '编译工程,并支持上传ipa到测试网站'
14
+
15
+ self.description = <<-DESC
16
+ 编译工程. 用法:在工程目录下执行 pindo dev build --upload
17
+ DESC
18
+
19
+ self.arguments = [
20
+
21
+ ]
22
+
23
+
24
+ def self.options
25
+ [
26
+ ['--proj', '指定上传到pgyer对应的项目名称(大小写空格忽略),用法:pindo ipa autobuild --proj=aichatv4'],
27
+ ['--upload', '是否上传编译后的ipa, 用法:pindo ipa autobuild --upload'],
28
+ ['--send', '上传到之后是否发送测试信息,用法:pindo ipa autobuild --send'],
29
+ ].concat(super)
30
+ end
31
+
32
+ def initialize(argv)
33
+
34
+ @args_upload_flag = argv.flag?('upload', false)
35
+ @args_send_flag = argv.flag?('send', false)
36
+ @args_proj_name = argv.option('proj')
37
+
38
+ if @args_send_flag
39
+ @args_upload_flag = true
40
+ end
41
+
42
+ super
43
+ @additional_args = argv.remainder!
44
+ end
45
+
46
+ def run
47
+
48
+
49
+ app_info_obj = nil
50
+ if @args_upload_flag
51
+ proj_name = @args_proj_name
52
+ app_info_obj = PgyerHelper.share_instace.prepare_upload(working_directory:Dir.pwd, proj_name:proj_name)
53
+ end
54
+
55
+ args_temp = []
56
+ Pindo::Command::Deploy::Build::run(args_temp)
57
+
58
+
59
+ pindo_new_project_dir = Dir.pwd
60
+ build_path = File.join(pindo_new_project_dir, "build", "*.ipa")
61
+ ipa_file_upload = Dir.glob(build_path).max_by {|f| File.mtime(f)}
62
+
63
+ if !ipa_file_upload.nil? && !app_info_obj.nil?
64
+
65
+ description = nil
66
+ if File.exist?(File.join(pindo_new_project_dir, ".release_info"))
67
+ description = File.read(File.join(pindo_new_project_dir, ".release_info"))
68
+ else
69
+ if File.exist?(File.join(pindo_new_project_dir, ".git"))
70
+ description = git!(%W(-C #{pindo_new_project_dir} show -s --format='%h %s')).strip
71
+ unless !description.nil? && description.length > 10
72
+ description = nil
73
+ end
74
+ end
75
+ end
76
+ result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:description)
77
+ if !result_data.nil? && !result_data["data"].nil? && !result_data["data"]["id"].nil?
78
+ msg_data = PgyerHelper.share_instace.make_msg_data(app_info_obj:app_info_obj, app_version_info_obj:result_data["data"])
79
+ PgyerHelper.share_instace.print_app_version_info(msg_data:msg_data)
80
+ if @args_send_flag
81
+ PgyerHelper.share_instace.send_apptest_wechat_msg(msg_data:msg_data)
82
+ end
83
+ end
84
+ end
85
+
86
+ system "open #{project_dir}"
87
+
88
+ end
89
+
90
+
91
+ end
92
+ end
93
+ end
94
+ end
@@ -8,6 +8,7 @@ require 'pindo/command/dev/pub'
8
8
  require 'pindo/command/dev/debug'
9
9
  require 'pindo/command/dev/autoresign'
10
10
  require 'pindo/command/dev/autobuild'
11
+ require 'pindo/command/dev/build'
11
12
  # require 'pindo/command/dev/renewcert'
12
13
  # require 'pindo/command/dev/pgyercert'
13
14
  # require 'pindo/command/dev/createbuild'
@@ -46,6 +46,10 @@ module Pindo
46
46
  @args_send_flag = argv.flag?('send', false)
47
47
  @args_proj_name = argv.option('proj')
48
48
 
49
+ if @args_send_flag
50
+ @args_upload_flag = true
51
+ end
52
+
49
53
  super
50
54
  @additional_args = argv.remainder!
51
55
  end
@@ -175,7 +175,7 @@ module Pindo
175
175
  end
176
176
  end
177
177
 
178
- if pods_array.include?("FancyAD")
178
+ if pods_array.include?("FancyAD") || pods_array.include?("AppLovinSDK")
179
179
  puts
180
180
  puts "Run Applovin Script ..."
181
181
  Dir.chdir(pindo_new_project_dir)
@@ -45,6 +45,11 @@ module Pindo
45
45
  @args_send_flag = argv.flag?('send', false)
46
46
  @args_increase_flag = argv.flag?('increase', false)
47
47
 
48
+
49
+ if @args_send_flag
50
+ @args_upload_flag = true
51
+ end
52
+
48
53
  super
49
54
  end
50
55
 
@@ -53,22 +53,22 @@ module Pindo
53
53
 
54
54
  private_source = sources.select { |s| s.git? && s.url.to_s.eql?(pod_index_url)}.first
55
55
  if !private_source.nil?
56
-
57
- puts "地址:#{private_source.url}"
58
- puts "目录:#{private_source.repo}"
56
+
57
+ puts "私有Pod地址:#{pod_index_url}"
58
+ puts "私有Pod目录:~/.cocoapods"
59
59
  getcode_to_dir(reponame:File.basename(private_source.repo), remote_url: pod_index_url, path:repos_path)
60
60
  else
61
- puts "地址:#{pod_index_url}"
62
- puts "目录:~/.cocoapods"
61
+ puts "私有Pod地址:#{pod_index_url}"
62
+ puts "私有Pod目录:~/.cocoapods"
63
63
  repository_name = pod_index_url.split("/").last.chomp(".git")
64
64
  getcode_to_dir(reponame:repository_name, remote_url: pod_index_url, path:repos_path)
65
65
  end
66
-
66
+
67
67
 
68
68
  if @args_install_flag
69
69
  begin
70
- if File.exist?("#{working_dir}/Podfile")
71
- Pod::Command::Install::run(['--clean-install'])
70
+ if File.exist?("#{working_dir}/Podfile")
71
+ Pod::Command::Install::run(['--clean-install'])
72
72
  end
73
73
  rescue => e
74
74
  puts e.message
@@ -281,6 +281,14 @@ module Pindo
281
281
  return url
282
282
  end
283
283
 
284
+ def cert_key_password
285
+ cert_key_password = ''
286
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
287
+ cert_key_password = @pindo_user_config_json["develop_accout_info"]["cert_key_password"]
288
+ end
289
+ return cert_key_password
290
+ end
291
+
284
292
  def deploy_cert_giturl
285
293
  url = ''
286
294
  if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
@@ -288,6 +296,16 @@ module Pindo
288
296
  end
289
297
  return url
290
298
  end
299
+
300
+ def deploy_cert_decrypt_password
301
+ pass = ''
302
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
303
+ pass = @pindo_user_config_json["develop_accout_info"]["deploy_cert_decrypt_password"]
304
+ end
305
+ return pass
306
+ end
307
+
308
+
291
309
 
292
310
  def dev_cert_giturl
293
311
  url = ''
@@ -297,6 +315,15 @@ module Pindo
297
315
  return url
298
316
  end
299
317
 
318
+
319
+ def dev_cert_decrypt_password
320
+ pass = ''
321
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
322
+ pass = @pindo_user_config_json["develop_accout_info"]["dev_cert_decrypt_password"]
323
+ end
324
+ return pass
325
+ end
326
+
300
327
  def demo_apple_id
301
328
  url = ''
302
329
  if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
@@ -45,7 +45,6 @@ module Pindo
45
45
 
46
46
  def all_tool_bundleid
47
47
  setting_file = File.join(pindo_single_config.pindo_env_configdir,'bundleid_config.json')
48
- puts setting_file
49
48
  setting_json = load_setting(setting_file:setting_file)
50
49
  sub_json = []
51
50
  if !setting_json.nil? && !setting_json['all_tool_bundleid'].nil?
@@ -86,10 +85,10 @@ module Pindo
86
85
  puts "具体参考文档: https://tower.im/teams/851356/repository_documents/714/"
87
86
  puts ""
88
87
  puts "App Type:"
89
-
88
+ puts
90
89
  cli.choose do |menu| # you can also use constants like :blue
91
- menu.header = "选用哪个bundle id?"
92
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
90
+ menu.header = "可用的Bundle Id如下:"
91
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
93
92
  menu.index_suffix = ") "
94
93
  if !sub_setting_json.nil?
95
94
  sub_setting_json.each do |key, items|
@@ -115,9 +114,10 @@ module Pindo
115
114
 
116
115
  cli = HighLine.new
117
116
  menu_choice="None"
117
+ puts
118
118
  cli.choose do |menu| # you can also use constants like :blue
119
- menu.header = "选用哪个bundle id?"
120
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
119
+ menu.header = "可用的Bundle Id如下:"
120
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
121
121
  if !all_bundleid.nil? && all_bundleid.length > 0
122
122
  for bunld_id in all_bundleid do
123
123
  menu.choice(bunld_id) do |details|
@@ -140,10 +140,11 @@ module Pindo
140
140
 
141
141
  cli = HighLine.new
142
142
  menu_choice="None"
143
+ puts
143
144
  cli.choose do |menu| # you can also use constants like :blue
144
145
 
145
- menu.header = "选用哪个bundle id?"
146
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
146
+ menu.header = "可用的Bundle Id如下:"
147
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
147
148
  if !all_bundleid.nil? && all_bundleid.length > 0
148
149
  for bunld_id in all_bundleid do
149
150
  menu.choice(bunld_id) do |details|
@@ -9,11 +9,7 @@ require 'pindo/module/cert/provisioninghelper'
9
9
  module Pindo
10
10
 
11
11
  module CertHelper
12
-
13
- def server_name(keychain_name)
14
- ["match", keychain_name].join("_")
15
- end
16
-
12
+
17
13
  def get_cert_info(cer_certificate)
18
14
  # can receive a certificate path or the file data
19
15
  begin
@@ -65,7 +61,7 @@ module Pindo
65
61
  (/darwin/ =~ RUBY_PLATFORM) != nil
66
62
  end
67
63
 
68
- def install_certs(certs_dir:nil, cert_type:nil)
64
+ def install_certs(cert_url:nil, certs_dir:nil, cert_type:nil)
69
65
 
70
66
 
71
67
  if !cert_type.downcase.include?("development")
@@ -79,45 +75,59 @@ module Pindo
79
75
  raise Informative, "No certificates found in #{certs_dir}"
80
76
  else
81
77
  output_dir = Dir.mktmpdir
82
- decrypt_password = "Gxtest#1"
83
-
78
+
79
+ decrypt_password = AESHelper.fetch_password(keychain_name:cert_url)
84
80
  Funlog.instance.fancyinfo_start("正在安装证书...")
85
81
 
86
82
  cert_path = AESHelper.decrypt_specific_file(src_file: certs.first, password:decrypt_password, output_dir: output_dir)
83
+ unless cert_path.nil? || File.exist?(cert_path)
84
+ AESHelper.delete_password(keychain_name:cert_url)
85
+ raise Informative, "证书解析失败,密码错误!"
86
+ end
87
+
87
88
  key_path = AESHelper.decrypt_specific_file(src_file: keys.first, password:decrypt_password, output_dir: output_dir)
89
+ unless key_path.nil? || File.exist?(key_path)
90
+ AESHelper.delete_password(keychain_name:cert_url)
91
+ raise Informative, "证书解析失败,密码错误!"
92
+ end
88
93
 
89
94
  unless is_cert_valid?(cert_path)
90
- raise Informative, "Your certificate '#{File.basename(cert_path)}' is not valid, please check end date and renew it if necessary"
95
+ raise Informative, "证书已经过期,请重新生产新证书!"
91
96
  end
92
97
 
98
+
93
99
  if isMac?
94
100
 
95
101
  keychain_name = "login.keychain"
96
-
97
102
  if FastlaneCore::CertChecker.installed?(cert_path, in_keychain: nil)
98
103
  Funlog.instance.fancyinfo_success("证书#{File.basename(cert_path)}已安装,无需重复安装!")
99
104
  else
100
- cert_password = "goodcert1"
105
+
106
+ cert_password = Pindoconfig.instance.cert_key_password
101
107
  keychain = 'login.keychain'
102
108
  keychain_path = FastlaneCore::Helper.keychain_path(keychain)
103
109
 
104
- KeychainHelper.import_file(cert_path, keychain_path, keychain_password: cert_password, certificate_password: "", skip_set_partition_list: false, output: false)
105
- KeychainHelper.import_file(key_path, keychain_path, keychain_password: cert_password, certificate_password: "", skip_set_partition_list: false, output: false)
110
+ KeychainHelper.import_file(cert_path, keychain_path, keychain_password: cert_password, certificate_password:'' )
111
+ KeychainHelper.import_file(key_path, keychain_path, keychain_password: cert_password, certificate_password: '')
106
112
 
107
113
 
108
114
  Funlog.instance.fancyinfo_success("证书'#{File.basename(cert_path)}'安装完成!")
109
115
  end
110
116
  else
111
- puts "非Mac电脑不支持安装证书."
117
+ Funlog.instance.fancyinfo_error("非Mac电脑不支持安装证书!")
112
118
  end
113
119
 
114
120
  end
115
121
 
116
- def install_provisionfiles(certs_dir:nil, bundle_id_map:nil, cert_type:nil)
122
+ def install_provisionfiles(cert_url:nil, certs_dir:nil, bundle_id_map:nil, cert_type:nil)
123
+
124
+
125
+ Funlog.instance.fancyinfo_start("正在安装Provisioning Profiles文件...")
126
+
117
127
 
118
128
  if cert_type.downcase.include?("development")
119
129
  cert_type = "Development"
120
- elsif cert_type.downcase.include?("Adhoc")
130
+ elsif cert_type.downcase.include?("adhoc")
121
131
  cert_type = "Adhoc"
122
132
  else
123
133
  cert_type = "AppStore"
@@ -133,13 +143,12 @@ module Pindo
133
143
 
134
144
  bundle_id_map.each do |type, bundle_id_temp|
135
145
  profile_filename = File.join(certs_dir, "profiles", cert_type.downcase.to_s,[cert_type.to_s, bundle_id_temp].join('_') + '.mobileprovision')
136
-
137
146
  unless File.exist?(profile_filename)
138
147
  un_exist_files << profile_filename
139
148
  next
140
149
  end
141
- puts "正在安装 #{profile_filename}..."
142
- decrypt_password = "Gxtest#1"
150
+ # puts "正在安装 #{bundle_id_temp}..."
151
+ decrypt_password = AESHelper.fetch_password(keychain_name:cert_url)
143
152
  output_dir = Dir.mktmpdir
144
153
  file_decrypt = AESHelper.decrypt_specific_file(src_file: profile_filename, password:decrypt_password, output_dir: output_dir)
145
154
  destpath = Provisioninghelper.install(file_decrypt)
@@ -151,17 +160,19 @@ module Pindo
151
160
  provisioning_info['profile_name'] = parsed_data['Name']
152
161
  provisioning_info['profile_path'] = destpath
153
162
 
163
+
154
164
  cert_info = get_cert_info(parsed_data["DeveloperCertificates"].first.string).to_h
155
165
  provisioning_info['signing_identity'] = cert_info["Common Name"]
156
166
  provisioning_info['team_id'] = parsed_data["TeamIdentifier"].first
157
167
 
158
- puts JSON.pretty_generate(provisioning_info)
168
+ # puts JSON.pretty_generate(provisioning_info)
159
169
  provisioning_info_array << provisioning_info
160
170
  end
161
171
 
162
-
172
+ Funlog.instance.fancyinfo_success("Provisioning Profiles文件安装完成!")
163
173
 
164
174
  if un_exist_files.size > 0
175
+ Funlog.instance.fancyinfo_error("证书Provisioning Profiles文件不存在!")
165
176
  raise Informative, "The following profiles do not exist: #{un_exist_files.join(', ')}"
166
177
  end
167
178
 
@@ -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