pindo 5.17.4 → 5.17.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c72f7acb18bc2b9f09eee1bd25386ac612a29ac7a37b5a4f35e9b56853f5c86
4
- data.tar.gz: 196b9a7f836a67de966ff2f5e4a27dfe1805e0fa2098de6b767e865cbc386a68
3
+ metadata.gz: 2dc0ea199e9881c190ba29b0da86845f0f628d92e8d44fdc5276a00ab8945a23
4
+ data.tar.gz: 5c001a0004db9f0cfe726bbf20bfbd855c8cbdd65e35a63043cf62f059b4d513
5
5
  SHA512:
6
- metadata.gz: 2ec1d2ba069d15615d2a209a1c8497ae43c0f88b4a072e74ba6020e169225d6e37e4f51163741cf3e15375f17004d6a53220aae2e70d482bcc2edf79da7a5d24
7
- data.tar.gz: c7dc2c39a97a172654d6c9aad3132865dcf0a3b95122d9590477bd496d5a3e3d2338bfdfbf17ec47e9c849115bd614fb5e5c7939c3daff22fc43d4c9a4508fe1
6
+ metadata.gz: 3cf203666f973af0185f1a7cd0b700e918e6fe4a273ce5af2324cfa7e809c55ea2c6669b1678d54b0d3c851660d0021c3edd60d0a20253ab47f68b5b6df70ad2
7
+ data.tar.gz: 1dad5465cd43d8e974ba99c059f0f7a9995144c5af8c890c092c471fd677ca657bd024ffb677d42463b4ad27c6bc91644fba8acb5be86f1c360870de46d7413a
@@ -70,19 +70,27 @@ module Pindo
70
70
 
71
71
  $ pindo and autobuild --proj="My App" # 指定项目名称
72
72
 
73
- $ pindo and autobuild # 编译、打tag
73
+ $ pindo and autobuild # 编译、打 tag
74
74
 
75
75
  $ pindo and autobuild --release # 编译 Release 包
76
76
 
77
- $ pindo and autobuild --upload # 编译、打tag、上传、发上传消息
77
+ $ pindo and autobuild --upload # 编译、打 tag、上传、发上传消息
78
78
 
79
- $ pindo and autobuild --media # 编译、打tag、上传、发上传消息、上传媒体附件
79
+ $ pindo and autobuild --media # 编译、打 tag、上传、发上传消息、上传媒体附件
80
80
 
81
- $ pindo and autobuild --bind # 编译、打tag、上传、发上传消息、上传媒体附件 + 绑定包到工作流
81
+ $ pindo and autobuild --bind # 编译、打 tag、上传、发上传消息、上传媒体附件 + 绑定包到工作流
82
82
 
83
- $ pindo and autobuild --send # 编译、打tag、上传、发上传消息、上传媒体附件、绑定包到工作流 + 发送群消息
83
+ $ pindo and autobuild --send # 编译、打 tag、上传、发上传消息、上传媒体附件、绑定包到工作流 + 发送群消息
84
84
 
85
85
  $ pindo and autobuild --multi # 使用并发模式执行
86
+
87
+ $ pindo and autobuild --git-commit=skip # 跳过 Git 提交检查(不处理未提交文件)
88
+
89
+ $ pindo and autobuild --git-commit=reset # 重置未提交的更改
90
+
91
+ $ pindo and autobuild --git-commit=stash # 暂存未提交的更改
92
+
93
+ $ pindo and autobuild --tag_type=none # 不创建 Git Tag
86
94
  DESC
87
95
 
88
96
  # 定义此命令使用的参数项
@@ -133,6 +141,7 @@ module Pindo
133
141
  @args_ver_inc = Pindo::Options::GitOptions.parse_version_increase_type(@options[:ver_inc])
134
142
  @args_tag_type = Pindo::Options::GitOptions.parse_create_tag_type(@options[:tag_type])
135
143
  @args_tag_pre = @options[:tag_pre] || 'v'
144
+ # 解析 --git-commit 参数(不设置默认值,以便区分用户是否指定了参数)
136
145
  @args_git_commit = Pindo::Options::GitOptions.parse_git_commit_type(@options[:git_commit])
137
146
 
138
147
  super
@@ -211,11 +220,26 @@ module Pindo
211
220
 
212
221
  # 1. Git 提交任务
213
222
  # 提前询问用户如何处理未提交的文件
214
- process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
215
- project_dir: config[:project_path],
216
- interactive: @args_git_commit.nil?,
217
- default_process_type: @args_git_commit
218
- )
223
+ # 如果用户指定了 --git-commit 参数,直接使用该参数;否则交互式询问
224
+ user_specified_git_commit = @options[:git_commit] != nil
225
+
226
+ Funlog.instance.info("DEBUG: @options[:git_commit] = #{@options[:git_commit].inspect}")
227
+ Funlog.instance.info("DEBUG: @args_git_commit = #{@args_git_commit.inspect}")
228
+ Funlog.instance.info("DEBUG: user_specified_git_commit = #{user_specified_git_commit}")
229
+
230
+ if user_specified_git_commit
231
+ # 用户指定了 --git-commit 参数,直接使用
232
+ process_type = @args_git_commit || Pindo::UncommittedFilesProcessType::SKIP
233
+ Funlog.instance.info("使用用户指定的 Git 提交处理方式:#{process_type}")
234
+ else
235
+ # 未指定参数,交互式询问
236
+ process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
237
+ project_dir: config[:project_path],
238
+ interactive: true,
239
+ default_process_type: nil
240
+ )
241
+ end
242
+
219
243
  git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
220
244
  config[:project_path],
221
245
  release_branch: @args_release_branch,
@@ -40,6 +40,11 @@ module Pindo
40
40
  # 2. 处理 Unity 作为 lib 的原生工程(Unity 放在 Unity 目录下)
41
41
  elsif Pindo::AndroidProjectHelper.unity_as_lib_android_project?(project_dir)
42
42
  puts "处理 Unity 作为 lib 的原生工程..."
43
+
44
+ # 确保主工程能继承 Unity 导出的关键 gradle.properties 配置
45
+ # 包括 android.aapt2FromMavenOverride 与 org.gradle.java.home
46
+ Pindo::AndroidProjectHelper.sync_gradle_properties_from_unity_to_main(project_dir)
47
+
43
48
  unity_dir = File.join(project_dir, "Unity")
44
49
 
45
50
  if File.directory?(unity_dir)
@@ -273,6 +273,61 @@ module Pindo
273
273
  android_dir
274
274
  end
275
275
 
276
+ # 在 Unity 作为 lib 的工程中,将 Unity 根目录下 gradle.properties
277
+ # 中的关键配置同步到主工程的 gradle.properties 中
278
+ # 当前仅同步以下键:
279
+ # - android.aapt2FromMavenOverride
280
+ # - org.gradle.java.home
281
+ def sync_gradle_properties_from_unity_to_main(project_path)
282
+ return unless unity_as_lib_android_project?(project_path)
283
+
284
+ unity_gradle_properties = File.join(project_path, "Unity", "gradle.properties")
285
+ return unless File.exist?(unity_gradle_properties)
286
+
287
+ keys_to_sync = [
288
+ "android.aapt2FromMavenOverride",
289
+ "org.gradle.java.home",
290
+ ]
291
+
292
+ unity_values = {}
293
+ File.read(unity_gradle_properties).each_line do |line|
294
+ stripped = line.strip
295
+ next if stripped.empty? || stripped.start_with?("#", "!")
296
+
297
+ keys_to_sync.each do |key|
298
+ # 兼容前后有空格的 "key = value" 写法
299
+ if stripped =~ /^#{Regexp.escape(key)}\s*=\s*(.+)$/
300
+ unity_values[key] = Regexp.last_match(1).strip
301
+ end
302
+ end
303
+ end
304
+
305
+ return if unity_values.empty?
306
+
307
+ main_gradle_properties = File.join(project_path, "gradle.properties")
308
+ main_content = File.exist?(main_gradle_properties) ? File.read(main_gradle_properties) : ""
309
+ original_content = main_content.dup
310
+
311
+ keys_to_sync.each do |key|
312
+ value = unity_values[key]
313
+ next unless value
314
+
315
+ key_regex = /^#{Regexp.escape(key)}\s*=.*$/
316
+ if main_content =~ key_regex
317
+ # 替换已存在的配置行
318
+ main_content = main_content.gsub(key_regex, "#{key}=#{value}")
319
+ else
320
+ # 追加新的配置行
321
+ main_content << "\n" unless main_content.empty? || main_content.end_with?("\n")
322
+ main_content << "#{key}=#{value}\n"
323
+ end
324
+ end
325
+
326
+ return if main_content == original_content
327
+
328
+ File.write(main_gradle_properties, main_content)
329
+ end
330
+
276
331
  private
277
332
  end
278
333
  end
@@ -234,6 +234,8 @@ module Pindo
234
234
  project = Xcodeproj::Project.open(proj_fullname)
235
235
 
236
236
  project.targets.each do |target|
237
+ # 跳过非 native target(如 PBXAggregateTarget)
238
+ next unless target.respond_to?(:product_type)
237
239
  # 跳过 framework、library 等类型
238
240
  if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) ||
239
241
  target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
@@ -286,6 +288,8 @@ module Pindo
286
288
  target_map = get_target_name_map
287
289
 
288
290
  project.targets.each do |target|
291
+ # 跳过非 native target(如 PBXAggregateTarget)
292
+ next unless target.respond_to?(:product_type)
289
293
  # 跳过 framework、library 等类型
290
294
  if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) ||
291
295
  target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
@@ -746,6 +746,28 @@ module Pindo
746
746
  Dir.chdir(current_project_dir)
747
747
  ipa_file_upload = web_res_zip_fullname
748
748
  end
749
+ if !ipa_file_upload.nil? &&
750
+ File.extname(ipa_file_upload).downcase.eql?(".exe")
751
+
752
+ windows_exe_path = File.expand_path(ipa_file_upload)
753
+ windows_build_dir = File.dirname(windows_exe_path)
754
+ windows_zip_dir = File.dirname(windows_build_dir)
755
+ windows_build_name = File.basename(windows_exe_path, File.extname(windows_exe_path))
756
+ windows_exe_name = File.basename(windows_exe_path)
757
+ windows_zip_fullname = File.join(windows_zip_dir, windows_build_name + ".zip")
758
+
759
+ if File.exist?(windows_zip_fullname)
760
+ FileUtils.rm_rf(windows_zip_fullname)
761
+ end
762
+
763
+ current_project_dir = Dir.pwd
764
+ Zip::File.open(windows_zip_fullname, Zip::File::CREATE) do |zipfile|
765
+ Dir.chdir windows_build_dir
766
+ zipfile.add(windows_exe_name, windows_exe_name)
767
+ end
768
+ Dir.chdir(current_project_dir)
769
+ ipa_file_upload = windows_zip_fullname
770
+ end
749
771
  unless !ipa_file_upload.nil? && File.exist?(ipa_file_upload)
750
772
  return
751
773
  end
@@ -15,7 +15,7 @@ module Pindo
15
15
  end
16
16
 
17
17
  # 初始化上传任务
18
- # @param file_type [String] 文件类型:'ipa' | 'apk' | 'html' | 'mac'
18
+ # @param file_type [String] 文件类型:'ipa' | 'apk' | 'html' | 'mac' | 'exe'
19
19
  # @param upload_path [String] 搜索文件的路径
20
20
  # @param upload_file [String] 要上传的文件(nil 表示自动查找)
21
21
  # @param options [Hash] 选项
@@ -24,7 +24,7 @@ module Pindo
24
24
  # @option options [String] :project_name 项目名称(可选)
25
25
  # @option options [String] :upload_desc 上传描述(可选)
26
26
  def initialize(file_type, upload_path, upload_file, options = {})
27
- @file_type = file_type # 'ipa' | 'apk' | 'html' | 'mac'
27
+ @file_type = file_type # 'ipa' | 'apk' | 'html' | 'mac' | 'exe'
28
28
  @upload_path = upload_path # 搜索文件的路径
29
29
  @upload_file = upload_file # 要上传的文件(nil 表示自动查找)
30
30
  @upload_desc = options[:upload_desc] # 上传描述
@@ -41,6 +41,8 @@ module Pindo
41
41
  "上传 WebGL包"
42
42
  when 'mac'
43
43
  "上传 macOS App包"
44
+ when 'exe'
45
+ "上传 Windows EXE包"
44
46
  else
45
47
  "上传 #{file_type.upcase}"
46
48
  end
@@ -149,6 +151,8 @@ module Pindo
149
151
  File.join(@upload_path, "**", "*.html")
150
152
  when 'mac'
151
153
  File.join(@upload_path, "**", "*.app")
154
+ when 'exe'
155
+ File.join(@upload_path, "**", "*.exe")
152
156
  else
153
157
  raise "不支持的文件类型: #{@file_type}"
154
158
  end
@@ -255,6 +255,8 @@ module Pindo
255
255
  project_obj = Xcodeproj::Project.open(xcodeproj_file)
256
256
 
257
257
  project_obj.targets.each do |target|
258
+ # 跳过非 native target(如 PBXAggregateTarget)
259
+ next unless target.respond_to?(:product_type)
258
260
  if target.product_type.to_s == "com.apple.product-type.application"
259
261
  temp_info = target.build_configurations.first.build_settings['INFOPLIST_FILE']
260
262
  return File.join(project_dir, temp_info) if temp_info
@@ -15,7 +15,7 @@ module Pindo
15
15
  def get_xcodeproj_icon_path()
16
16
 
17
17
  icon_path = nil
18
- select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
18
+ select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
19
19
 
20
20
  project_dir = @project_obj.project_dir
21
21
 
@@ -91,7 +91,7 @@ module Pindo
91
91
 
92
92
  def get_xcodeproj_imessage_icon_path
93
93
  icon_path = nil
94
- select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
94
+ select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
95
95
  project_dir = @project_obj.project_dir
96
96
  if !select_target.nil?
97
97
  file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
@@ -170,7 +170,7 @@ module Pindo
170
170
 
171
171
  launchimg_path = nil
172
172
  assets_path = nil
173
- select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
173
+ select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
174
174
  project_dir = @project_obj.project_dir
175
175
  if !select_target.nil?
176
176
  assets_objs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
@@ -36,6 +36,8 @@ module Pindo
36
36
 
37
37
  project_obj = Xcodeproj::Project.open(project_fullname)
38
38
  project_obj.targets.each do |target|
39
+ # 跳过非 native target(如 PBXAggregateTarget)
40
+ next unless target.respond_to?(:product_type)
39
41
  if target.product_type.to_s.eql?("com.apple.product-type.application")
40
42
  temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
41
43
  if temp_info_file && !temp_info_file.empty?
@@ -137,6 +139,8 @@ module Pindo
137
139
 
138
140
  project_obj = Xcodeproj::Project.open(project_fullname)
139
141
  project_obj.targets.each do |target|
142
+ # 跳过非 native target(如 PBXAggregateTarget)
143
+ next unless target.respond_to?(:product_type)
140
144
  if target.product_type.to_s.eql?("com.apple.product-type.application")
141
145
  temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
142
146
  if temp_info_file && !temp_info_file.empty?
@@ -206,6 +210,8 @@ module Pindo
206
210
 
207
211
  project_obj = Xcodeproj::Project.open(project_fullname)
208
212
  project_obj.targets.each do |target|
213
+ # 跳过非 native target(如 PBXAggregateTarget)
214
+ next unless target.respond_to?(:product_type)
209
215
  if target.product_type.to_s.eql?("com.apple.product-type.application")
210
216
  temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
211
217
  if temp_info_file && !temp_info_file.empty?
@@ -295,6 +301,8 @@ module Pindo
295
301
  # 更新所有application类型target的版本号
296
302
  updated_targets = []
297
303
  project.targets.each do |target|
304
+ # 跳过非 native target(如 PBXAggregateTarget)
305
+ next unless target.respond_to?(:product_type)
298
306
  # 只处理application类型的target
299
307
  if target.product_type.to_s.eql?("com.apple.product-type.application")
300
308
  target.build_configurations.each do |config|
@@ -384,6 +392,8 @@ module Pindo
384
392
  project_obj = Xcodeproj::Project.open(project_fullname)
385
393
 
386
394
  project_obj.targets.each do |target|
395
+ # 跳过非 native target(如 PBXAggregateTarget)
396
+ next unless target.respond_to?(:product_type)
387
397
  if target.product_type.to_s.eql?("com.apple.product-type.application")
388
398
  temp_entitlements_file = target.build_configurations.first.build_settings['CODE_SIGN_ENTITLEMENTS']
389
399
  if temp_entitlements_file && !temp_entitlements_file.empty?
@@ -95,7 +95,7 @@ module Pindo
95
95
 
96
96
  project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
97
97
  project_obj = Xcodeproj::Project.open(project_fullname)
98
- select_target = project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
98
+ select_target = project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
99
99
  file_ref = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("GoogleService-Info.plist") }.first
100
100
 
101
101
  if !file_ref.nil?
@@ -143,6 +143,8 @@ module Pindo
143
143
  end
144
144
 
145
145
  project_obj.targets.each do |target|
146
+ # 跳过非 native target(如 PBXAggregateTarget)
147
+ next unless target.respond_to?(:product_type)
146
148
 
147
149
  exe_binary_name = config_json['app_info']['app_display_name']
148
150
  exe_binary_name = exe_binary_name.gsub(/ /, '');
@@ -329,6 +331,8 @@ module Pindo
329
331
 
330
332
  info_plist_path = nil
331
333
  project_obj.targets.each do |target|
334
+ # 跳过非 native target(如 PBXAggregateTarget)
335
+ next unless target.respond_to?(:product_type)
332
336
  temp_info = target.build_configurations.first.build_settings['INFOPLIST_FILE']
333
337
  if !temp_info.nil?
334
338
  info_plist_path = File.join(project_dir, temp_info)
@@ -513,7 +517,7 @@ module Pindo
513
517
  project_obj = Xcodeproj::Project.open(project_fullname)
514
518
 
515
519
  project_build_platform = project_obj.root_object.build_configuration_list.get_setting("SDKROOT")["Release"]
516
- main_target = project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
520
+ main_target = project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
517
521
  provisioning_profile_name = main_target.build_configurations.first.build_settings['PROVISIONING_PROFILE_SPECIFIER'].downcase
518
522
 
519
523
  # 确定构建类型和 iCloud 环境
data/lib/pindo/version.rb CHANGED
@@ -6,7 +6,7 @@ require 'time'
6
6
 
7
7
  module Pindo
8
8
 
9
- VERSION = "5.17.4"
9
+ VERSION = "5.17.5"
10
10
 
11
11
  class VersionCheck
12
12
  RUBYGEMS_API = 'https://rubygems.org/api/v1/gems/pindo.json'
@@ -557,4 +557,4 @@ module Pindo
557
557
  end
558
558
  end
559
559
  end
560
- end
560
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pindo
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.17.4
4
+ version: 5.17.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - wade
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-03-08 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: claide
@@ -511,7 +511,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
511
511
  - !ruby/object:Gem::Version
512
512
  version: 3.0.0
513
513
  requirements: []
514
- rubygems_version: 3.6.3
514
+ rubygems_version: 4.0.3
515
515
  specification_version: 4
516
516
  summary: easy work
517
517
  test_files: []