pindo 5.13.15 → 5.14.0
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 +4 -4
- data/lib/pindo/command/unity/packbuild.rb +133 -42
- data/lib/pindo/command/unity/packinit.rb +1 -44
- data/lib/pindo/command/unity/packpush.rb +32 -282
- data/lib/pindo/module/task/core/task_executor.rb +1 -4
- data/lib/pindo/module/task/model/nuget/nuget_build_task.rb +54 -0
- data/lib/pindo/module/task/model/nuget/nuget_upload_task.rb +222 -0
- data/lib/pindo/module/task/model/nuget_task.rb +29 -0
- data/lib/pindo/module/task/output/multi_line_output_manager.rb +5 -10
- data/lib/pindo/module/task/task_reporter.rb +26 -20
- data/lib/pindo/module/unity/nuget_helper.rb +56 -25
- data/lib/pindo/version.rb +2 -2
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eec99d18d1a2c8b5f0dff73a278fce6f34becc035f5473697da37cd1bd723af5
|
|
4
|
+
data.tar.gz: 28eeca5c0f8a6299d8a362fd8e3ae42d20d4e963041c5b286bf4945b2ae5ae4f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 35c7963a3ecebd37c9a5384ae16f61dc64c7d92db55480e8ee97e36a6e79045f75d3b03e3a3d854b1062a44a3ab5a63a6414366e21ebd7d5ed8b983c7f75a248
|
|
7
|
+
data.tar.gz: 2c07c3191a1492ec9a72fc96c2014676240d6924474a0a6fd31dff8876099a4a898c9df62c56dfb876166c0a5363bbcf349f4e515696d97c4649ef2be2be053b
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
2
|
require 'json'
|
|
3
|
+
require 'highline/import'
|
|
4
|
+
require 'nokogiri'
|
|
3
5
|
require 'pindo/module/unity/nuget_helper'
|
|
6
|
+
require 'pindo/module/task/task_manager'
|
|
7
|
+
require 'pindo/module/task/model/git/git_commit_task'
|
|
8
|
+
require 'pindo/module/task/model/git/git_tag_task'
|
|
9
|
+
require 'pindo/module/task/model/nuget/nuget_build_task'
|
|
10
|
+
require 'pindo/options/options'
|
|
4
11
|
|
|
5
12
|
module Pindo
|
|
6
13
|
class Command
|
|
@@ -14,77 +21,161 @@ module Pindo
|
|
|
14
21
|
|
|
15
22
|
支持功能:
|
|
16
23
|
|
|
24
|
+
* 自动Git提交检查
|
|
25
|
+
|
|
17
26
|
* 读取package.json配置
|
|
18
27
|
|
|
19
28
|
* 生成.nuspec文件
|
|
20
29
|
|
|
21
30
|
* 打包成.nupkg格式
|
|
22
31
|
|
|
23
|
-
*
|
|
32
|
+
* 自动打Git Tag
|
|
24
33
|
|
|
25
34
|
使用示例:
|
|
26
35
|
|
|
27
36
|
$ pindo unity packbuild # 打包当前目录的Unity Package
|
|
28
37
|
|
|
38
|
+
$ pindo unity packbuild --ver-inc=patch # 打包并增加修订版本号
|
|
39
|
+
|
|
29
40
|
DESC
|
|
30
41
|
|
|
31
42
|
def self.arguments
|
|
32
43
|
[]
|
|
33
44
|
end
|
|
34
45
|
|
|
46
|
+
# 定义此命令使用的参数项
|
|
47
|
+
def self.option_items
|
|
48
|
+
@option_items ||= Pindo::Options::GitOptions.all
|
|
49
|
+
end
|
|
50
|
+
|
|
35
51
|
def self.options
|
|
36
|
-
|
|
52
|
+
option_items.map(&:to_claide_option).concat(super)
|
|
37
53
|
end
|
|
38
54
|
|
|
39
55
|
def initialize(argv)
|
|
40
|
-
|
|
56
|
+
@options = initialize_options(argv)
|
|
57
|
+
|
|
58
|
+
# Git 参数
|
|
59
|
+
@args_release_branch = @options[:release_branch] || 'master'
|
|
60
|
+
@args_ver_inc = Pindo::Options::GitOptions.parse_version_increase_type(@options[:ver_inc] || 'mini')
|
|
61
|
+
@args_tag_type = Pindo::Options::GitOptions.parse_create_tag_type(@options[:tag_type] || 'new')
|
|
62
|
+
@args_tag_pre = @options[:tag_pre] || 'v'
|
|
63
|
+
|
|
64
|
+
super
|
|
41
65
|
end
|
|
42
66
|
|
|
43
67
|
def run
|
|
44
68
|
package_dir = Dir.pwd
|
|
45
69
|
|
|
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
|
+
Funlog.instance.fancyinfo_start("Unity Package 打包流程")
|
|
71
|
+
|
|
72
|
+
# 创建任务管理器
|
|
73
|
+
task_manager = Pindo::TaskSystem::TaskManager.instance
|
|
74
|
+
task_manager.clear_all
|
|
75
|
+
|
|
76
|
+
tasks = []
|
|
77
|
+
|
|
78
|
+
# 0. 预检查:获取并确认版本号
|
|
79
|
+
# 先执行初始化检查以确保文件存在
|
|
80
|
+
Pindo::Unity::NugetHelper.nuget_init(package_dir)
|
|
81
|
+
|
|
82
|
+
nuspec_file = Pindo::Unity::NugetHelper.find_nuspec_file(package_dir)
|
|
83
|
+
unless nuspec_file
|
|
84
|
+
raise Informative, "初始化后仍未找到 .nuspec 文件,无法继续"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
nuspec_info = Pindo::Unity::NugetHelper.parse_nuspec(nuspec_file)
|
|
88
|
+
current_version = nuspec_info['version']
|
|
89
|
+
|
|
90
|
+
puts ""
|
|
91
|
+
puts "即将编译 NuGet Package 的版本是 #{current_version.yellow}"
|
|
92
|
+
if agree("确认是否继续? (Y/n)")
|
|
93
|
+
confirmed_version = current_version
|
|
70
94
|
else
|
|
71
|
-
puts "
|
|
72
|
-
|
|
95
|
+
puts ""
|
|
96
|
+
confirmed_version = ask("请输入新的打包版本号: ") { |q| q.required = true }.to_s.strip
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if confirmed_version.empty?
|
|
100
|
+
raise Informative, "版本号不能为空"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# 更新 .nuspec 和 package.json 中的版本号(如果用户修改了)
|
|
104
|
+
if confirmed_version != current_version
|
|
105
|
+
Funlog.instance.fancyinfo_update("更新配置文件版本号: #{confirmed_version}")
|
|
106
|
+
# 这里我们需要手动更新一下,因为 GitCommitTask 只是提交,不负责改文件内容
|
|
107
|
+
# update_package_json_from_nuspec 会用到 nuspec_info,我们先更新 nuspec_info
|
|
108
|
+
nuspec_info['version'] = confirmed_version
|
|
109
|
+
|
|
110
|
+
# 更新 .nuspec 文件
|
|
111
|
+
# 注意:这里需要重新生成或更新 xml,为了简单调用 NugetHelper 的更新逻辑
|
|
112
|
+
# 但 NugetHelper 目前没有单独更新 version 的公开方法,我们可以读取->修改->写入
|
|
113
|
+
doc = Nokogiri::XML(File.read(nuspec_file))
|
|
114
|
+
doc.remove_namespaces!
|
|
115
|
+
metadata = doc.at_xpath('//metadata')
|
|
116
|
+
version_node = metadata.at_xpath('version')
|
|
117
|
+
if version_node
|
|
118
|
+
version_node.content = confirmed_version
|
|
119
|
+
File.write(nuspec_file, doc.to_xml)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# 同步到 package.json
|
|
123
|
+
Pindo::Unity::NugetHelper.update_package_json_from_nuspec(nuspec_info, package_dir)
|
|
124
|
+
Funlog.instance.fancyinfo_success("版本号已更新")
|
|
73
125
|
end
|
|
74
126
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
127
|
+
# 1. Git 提交任务 (确保工作区干净,或提交预构建更改)
|
|
128
|
+
# 交互式询问用户如何处理未提交文件
|
|
129
|
+
process_type = Pindo::GitHandler.get_uncommitted_files_process_type(
|
|
130
|
+
project_dir: package_dir,
|
|
131
|
+
interactive: true
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
git_commit_task = Pindo::TaskSystem::GitCommitTask.new(
|
|
135
|
+
package_dir,
|
|
136
|
+
release_branch: @args_release_branch,
|
|
137
|
+
ver_inc: @args_ver_inc, # 虽然有 fixed_version,但保留此参数无妨
|
|
138
|
+
tag_type: @args_tag_type,
|
|
139
|
+
tag_pre: @args_tag_pre,
|
|
140
|
+
process_type: process_type,
|
|
141
|
+
commit_message: "chore: nuget packbuild v#{confirmed_version}",
|
|
142
|
+
fixed_version: confirmed_version # 传入确认后的版本号
|
|
143
|
+
)
|
|
144
|
+
tasks << git_commit_task
|
|
145
|
+
|
|
146
|
+
# 2. Nuget 构建任务
|
|
147
|
+
nuget_build_task = Pindo::TaskSystem::NugetBuildTask.new(
|
|
148
|
+
project_path: package_dir
|
|
149
|
+
)
|
|
150
|
+
nuget_build_task.dependencies << git_commit_task.id
|
|
151
|
+
tasks << nuget_build_task
|
|
152
|
+
|
|
153
|
+
# 3. Git Tag 任务 (依赖构建成功)
|
|
154
|
+
git_tag_task = Pindo::TaskSystem::GitTagTask.new(
|
|
155
|
+
package_dir,
|
|
156
|
+
release_branch: @args_release_branch,
|
|
157
|
+
ver_inc: @args_ver_inc,
|
|
158
|
+
tag_type: @args_tag_type,
|
|
159
|
+
tag_pre: @args_tag_pre,
|
|
160
|
+
fixed_version: confirmed_version # 传入确认后的版本号
|
|
161
|
+
)
|
|
162
|
+
git_tag_task.dependencies << nuget_build_task.id
|
|
163
|
+
tasks << git_tag_task
|
|
164
|
+
|
|
165
|
+
# 添加并执行任务
|
|
166
|
+
tasks.each { |task| task_manager.add_task(task) }
|
|
167
|
+
task_manager.start
|
|
168
|
+
|
|
169
|
+
# 打印构建结果
|
|
170
|
+
if nuget_build_task.status == :success && nuget_build_task.result
|
|
171
|
+
nupkg_file = nuget_build_task.result[:nupkg_file]
|
|
172
|
+
puts ""
|
|
173
|
+
Funlog.instance.fancyinfo_success("打包完成")
|
|
174
|
+
puts " 📦 生成文件: #{File.basename(nupkg_file)}"
|
|
175
|
+
puts " 📁 完整路径: #{nupkg_file}"
|
|
176
|
+
puts ""
|
|
177
|
+
Funlog.instance.fancyinfo_update("下一步: 运行 pindo unity packpush 上传到 JPS")
|
|
178
|
+
end
|
|
88
179
|
end
|
|
89
180
|
|
|
90
181
|
end
|
|
@@ -41,50 +41,7 @@ module Pindo
|
|
|
41
41
|
|
|
42
42
|
def run
|
|
43
43
|
package_dir = Dir.pwd
|
|
44
|
-
|
|
45
|
-
puts "=" * 60
|
|
46
|
-
puts "🔧 Unity Package 初始化"
|
|
47
|
-
puts "=" * 60
|
|
48
|
-
puts
|
|
49
|
-
|
|
50
|
-
# 检测文件存在情况
|
|
51
|
-
status = Pindo::Unity::NugetHelper.detect_files(package_dir)
|
|
52
|
-
|
|
53
|
-
puts "文件检测:"
|
|
54
|
-
puts " package.json: #{status[:has_package_json] ? '✅' : '❌'}"
|
|
55
|
-
puts " .nuspec: #{status[:has_nuspec] ? '✅' : '❌'}"
|
|
56
|
-
if status[:nuspec_file]
|
|
57
|
-
puts " 路径: #{File.basename(status[:nuspec_file])}"
|
|
58
|
-
end
|
|
59
|
-
puts
|
|
60
|
-
|
|
61
|
-
# 根据4种情况处理
|
|
62
|
-
case [status[:has_package_json], status[:has_nuspec]]
|
|
63
|
-
when [true, false]
|
|
64
|
-
puts "📝 情况A:只有 package.json"
|
|
65
|
-
puts " → 创建 .nuspec(ID 使用驼峰格式)"
|
|
66
|
-
puts
|
|
67
|
-
Pindo::Unity::NugetHelper.handle_case_a(package_dir)
|
|
68
|
-
when [false, true]
|
|
69
|
-
puts "📝 情况B:只有 .nuspec"
|
|
70
|
-
puts " → 创建 package.json(name 使用全小写)"
|
|
71
|
-
puts
|
|
72
|
-
Pindo::Unity::NugetHelper.handle_case_b(package_dir, status[:nuspec_file])
|
|
73
|
-
when [true, true]
|
|
74
|
-
puts "📝 情况C:同时存在两个文件"
|
|
75
|
-
puts " → 以 .nuspec 为准同步到 package.json"
|
|
76
|
-
puts
|
|
77
|
-
Pindo::Unity::NugetHelper.handle_case_c(package_dir, status[:nuspec_file])
|
|
78
|
-
when [false, false]
|
|
79
|
-
puts "❌ 情况D:都不存在"
|
|
80
|
-
Pindo::Unity::NugetHelper.handle_case_d(package_dir)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
puts
|
|
84
|
-
puts "=" * 60
|
|
85
|
-
puts "✅ 初始化完成!"
|
|
86
|
-
puts "=" * 60
|
|
87
|
-
puts
|
|
44
|
+
Pindo::Unity::NugetHelper.nuget_init(package_dir)
|
|
88
45
|
puts "下一步:"
|
|
89
46
|
puts " 运行 pindo unity pack 进行打包"
|
|
90
47
|
end
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
require 'highline/import'
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
require 'json'
|
|
4
|
-
require 'jpsclient'
|
|
5
4
|
require 'claide'
|
|
6
5
|
require 'pindo/module/unity/nuget_helper'
|
|
6
|
+
require 'pindo/module/task/task_manager'
|
|
7
|
+
require 'pindo/module/task/model/nuget/nuget_upload_task'
|
|
7
8
|
|
|
8
9
|
module Pindo
|
|
9
10
|
class Command
|
|
10
11
|
class Unity < Command
|
|
11
12
|
class Packpush < Unity
|
|
12
13
|
|
|
13
|
-
self.summary = 'NuGet: 将NuGet
|
|
14
|
+
self.summary = 'NuGet: 将NuGet包推送到JPS系统'
|
|
14
15
|
|
|
15
16
|
self.description = <<-DESC
|
|
16
|
-
将NuGet
|
|
17
|
+
将NuGet包推送到JPS系统。
|
|
17
18
|
|
|
18
19
|
支持功能:
|
|
19
20
|
|
|
@@ -23,7 +24,7 @@ module Pindo
|
|
|
23
24
|
|
|
24
25
|
* 上传前用户确认
|
|
25
26
|
|
|
26
|
-
*
|
|
27
|
+
* 使用任务系统执行上传
|
|
27
28
|
|
|
28
29
|
* 支持环境变量控制
|
|
29
30
|
|
|
@@ -64,9 +65,9 @@ module Pindo
|
|
|
64
65
|
def run
|
|
65
66
|
package_dir = Dir.pwd
|
|
66
67
|
|
|
67
|
-
puts
|
|
68
|
+
puts ""
|
|
68
69
|
puts "🚀 上传 Unity Package 到 JPS"
|
|
69
|
-
puts "
|
|
70
|
+
puts ""
|
|
70
71
|
|
|
71
72
|
# 如果没有指定文件或文件不存在,则查找
|
|
72
73
|
if @args_nupkg_file.nil? || !File.exist?(@args_nupkg_file)
|
|
@@ -87,14 +88,13 @@ module Pindo
|
|
|
87
88
|
raise Informative, "未找到 .nupkg 文件"
|
|
88
89
|
end
|
|
89
90
|
|
|
90
|
-
# 从 nuspec 文件或 package.json
|
|
91
|
+
# 从 nuspec 文件或 package.json 获取包信息(用于显示)
|
|
91
92
|
package_info = get_package_info_for_upload(package_dir) rescue nil
|
|
92
93
|
|
|
93
|
-
#
|
|
94
|
-
puts
|
|
94
|
+
# 显示包信息并确认
|
|
95
95
|
if package_info && !package_info.empty?
|
|
96
96
|
puts "📦 包信息:"
|
|
97
|
-
puts
|
|
97
|
+
puts ""
|
|
98
98
|
puts " 名称: #{package_info['displayName']}"
|
|
99
99
|
puts " ID: #{package_info['name']}"
|
|
100
100
|
puts " 版本: #{package_info['version']}"
|
|
@@ -102,11 +102,11 @@ module Pindo
|
|
|
102
102
|
puts " 大小: #{sprintf('%.2f', File.size(@args_nupkg_file) / 1024.0 / 1024.0)} MB"
|
|
103
103
|
else
|
|
104
104
|
puts "📦 上传文件:"
|
|
105
|
-
puts
|
|
105
|
+
puts ""
|
|
106
106
|
puts " 文件: #{@args_nupkg_file}"
|
|
107
107
|
puts " 大小: #{sprintf('%.2f', File.size(@args_nupkg_file) / 1024.0 / 1024.0)} MB"
|
|
108
108
|
end
|
|
109
|
-
puts
|
|
109
|
+
puts ""
|
|
110
110
|
|
|
111
111
|
# 检查是否设置了强制上传环境变量
|
|
112
112
|
force_upload = ENV['NUGET_UPLOAD_FORCE']
|
|
@@ -114,7 +114,7 @@ module Pindo
|
|
|
114
114
|
if force_upload && !force_upload.empty?
|
|
115
115
|
puts "🚀 检测到 NUGET_UPLOAD_FORCE 环境变量,跳过确认直接上传..."
|
|
116
116
|
else
|
|
117
|
-
#
|
|
117
|
+
# 确认上传
|
|
118
118
|
answer = agree("确认上传?(Y/n)")
|
|
119
119
|
unless answer
|
|
120
120
|
puts "已取消上传"
|
|
@@ -122,300 +122,50 @@ module Pindo
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
upload_to_jps_nuget(@args_nupkg_file, package_info)
|
|
125
|
+
puts ""
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# 上传成功后自动打 tag(仅在有包信息时)
|
|
133
|
-
if package_info && !package_info.empty?
|
|
134
|
-
create_git_tag_from_nuspec(package_dir)
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
private
|
|
139
|
-
|
|
140
|
-
def upload_to_jps_nuget(nupkg_file, package_info)
|
|
141
|
-
# 1. 登录 JPS
|
|
142
|
-
config_file = File.join(
|
|
143
|
-
Pindoconfig.instance.pindo_common_configdir,
|
|
144
|
-
"jps_client_config.json"
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
puts "🔐 登录 JPS..."
|
|
148
|
-
jps_client = JPSClient::Client.new(config_file: config_file)
|
|
149
|
-
login_success = jps_client.do_login(force_login: false)
|
|
150
|
-
|
|
151
|
-
unless login_success
|
|
152
|
-
raise Informative, "JPS 登录失败,请检查配置"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
puts "✅ 登录成功"
|
|
156
|
-
puts
|
|
157
|
-
|
|
158
|
-
# 2. 查询 Nuget 项目
|
|
159
|
-
nuget_project = find_nuget_project(jps_client)
|
|
160
|
-
puts
|
|
161
|
-
|
|
162
|
-
# 3. 上传文件到存储(使用 nuget-resource bucket)
|
|
163
|
-
puts "📤 上传文件到存储..."
|
|
164
|
-
|
|
165
|
-
# 修改配置使用 nuget-resource bucket
|
|
166
|
-
config_json = jps_client.config_json
|
|
167
|
-
config_json['upload_config']['bucket_name'] = 'nuget-resource'
|
|
168
|
-
|
|
169
|
-
# 开始上传主文件,记录开始时间
|
|
170
|
-
file_size_mb = File.size(nupkg_file) / (1024.0 * 1024.0)
|
|
171
|
-
puts "\n开始上传文件 (#{file_size_mb.round(2)} MB)..."
|
|
172
|
-
upload_start_time = Time.now
|
|
173
|
-
|
|
174
|
-
upload_client = JPSClient::UploadClient.new(jps_client)
|
|
175
|
-
file_url = upload_client.upload_file(binary_file: nupkg_file)
|
|
176
|
-
|
|
177
|
-
# 计算上传耗时
|
|
178
|
-
upload_duration = Time.now - upload_start_time
|
|
179
|
-
upload_speed = file_size_mb / upload_duration
|
|
180
|
-
puts "✅ 文件上传完成! 耗时: #{upload_duration.round(2)} 秒, 平均速度: #{upload_speed.round(2)} MB/s"
|
|
181
|
-
|
|
182
|
-
if file_url.nil?
|
|
183
|
-
raise Informative, "文件上传失败"
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
puts "✅ 文件上传成功"
|
|
187
|
-
puts
|
|
188
|
-
|
|
189
|
-
# 4. 提交到 JPS 项目
|
|
190
|
-
puts "📋 提交到 JPS 项目..."
|
|
191
|
-
|
|
192
|
-
result = jps_client.upload_nuget_package(
|
|
193
|
-
projectId: nuget_project['id'],
|
|
194
|
-
params: {
|
|
195
|
-
packageUrl: file_url,
|
|
196
|
-
attachFileUrls: []
|
|
197
|
-
}
|
|
127
|
+
# 创建上传任务
|
|
128
|
+
upload_task = Pindo::TaskSystem::NugetUploadTask.new(
|
|
129
|
+
project_path: package_dir,
|
|
130
|
+
nupkg_file: @args_nupkg_file
|
|
198
131
|
)
|
|
199
132
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
raise Informative, "提交失败: #{error_msg}"
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def find_nuget_project(jps_client)
|
|
210
|
-
puts "🔍 查询 Nuget 项目..."
|
|
211
|
-
|
|
212
|
-
result = jps_client.get_project_list(params: {})
|
|
213
|
-
|
|
214
|
-
unless result && (result['code'] == 0 || result['code'] == 200)
|
|
215
|
-
raise Informative, "获取项目列表失败"
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
projects = result['data'] || []
|
|
219
|
-
|
|
220
|
-
if projects.empty?
|
|
221
|
-
raise Informative, "JPS 中没有任何项目,请联系管理员创建"
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# 优先通过固定 ID 查找 Nuget 组件库项目
|
|
225
|
-
target_project_id = '5e6b36f61b614ed88086373ef874616c'
|
|
226
|
-
nuget_project = projects.find { |p| p['id'] == target_project_id }
|
|
227
|
-
|
|
228
|
-
if nuget_project
|
|
229
|
-
puts "✅ 找到 Nuget 组件库项目: #{nuget_project['projectName']} (ID: #{nuget_project['id']})"
|
|
230
|
-
return nuget_project
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
# 如果没找到固定 ID,让用户输入项目名称
|
|
234
|
-
puts
|
|
235
|
-
puts "⚠️ 未找到默认 Nuget 组件库项目 (ID: #{target_project_id})"
|
|
236
|
-
puts
|
|
237
|
-
|
|
238
|
-
project_name = ask('请输入 Nuget组件的项目名称:') || ''
|
|
239
|
-
project_name = project_name.strip
|
|
240
|
-
|
|
241
|
-
if project_name.empty?
|
|
242
|
-
raise Informative, "项目名称不能为空"
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
# 根据用户输入的名称匹配项目(去掉空格后比较)
|
|
246
|
-
nuget_project = projects.find do |p|
|
|
247
|
-
p['projectName']&.gsub(/\s+/, '')&.downcase == project_name.gsub(/\s+/, '').downcase
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
if nuget_project.nil?
|
|
251
|
-
puts
|
|
252
|
-
puts "❌ 未找到名为 '#{project_name}' 的项目"
|
|
253
|
-
puts
|
|
254
|
-
raise Informative, "请确认项目名称是否正确,或联系 JPS 管理员添加项目权限"
|
|
255
|
-
end
|
|
133
|
+
# 执行任务
|
|
134
|
+
task_manager = Pindo::TaskSystem::TaskManager.instance
|
|
135
|
+
task_manager.clear_all
|
|
136
|
+
task_manager.add_task(upload_task)
|
|
137
|
+
task_manager.start
|
|
256
138
|
|
|
257
|
-
puts "
|
|
258
|
-
|
|
259
|
-
|
|
139
|
+
puts ""
|
|
140
|
+
Funlog.instance.fancyinfo_success("上传完成!")
|
|
141
|
+
puts ""
|
|
260
142
|
end
|
|
261
143
|
|
|
262
|
-
|
|
263
|
-
if result['data'] && result['data']['id']
|
|
264
|
-
puts " JPS ID: #{result['data']['id']}"
|
|
265
|
-
end
|
|
266
|
-
end
|
|
144
|
+
private
|
|
267
145
|
|
|
146
|
+
# 获取包信息(用于确认显示)
|
|
268
147
|
def get_package_info_for_upload(package_dir)
|
|
269
|
-
#
|
|
148
|
+
# 优先从 .nuspec 文件读取
|
|
270
149
|
nuspec_file = Pindo::Unity::NugetHelper.find_nuspec_file(package_dir)
|
|
271
150
|
|
|
272
151
|
if nuspec_file && File.exist?(nuspec_file)
|
|
273
152
|
nuspec_info = Pindo::Unity::NugetHelper.parse_nuspec(nuspec_file)
|
|
274
153
|
|
|
275
|
-
# 转换为统一的格式(与 package.json 兼容)
|
|
276
|
-
# 注意:保持 nuspec 中 ID 的原始格式(驼峰)
|
|
277
154
|
return {
|
|
278
|
-
'name' => nuspec_info['id'],
|
|
155
|
+
'name' => nuspec_info['id'],
|
|
279
156
|
'version' => nuspec_info['version'],
|
|
280
157
|
'displayName' => nuspec_info['title'] || nuspec_info['id'],
|
|
281
158
|
'description' => nuspec_info['description']
|
|
282
159
|
}
|
|
283
160
|
end
|
|
284
161
|
|
|
285
|
-
#
|
|
162
|
+
# 从 package.json 读取
|
|
286
163
|
package_json_path = File.join(package_dir, "package.json")
|
|
287
|
-
|
|
288
164
|
if File.exist?(package_json_path)
|
|
289
165
|
return JSON.parse(File.read(package_json_path))
|
|
290
166
|
end
|
|
291
167
|
|
|
292
|
-
|
|
293
|
-
raise Informative, "未找到 .nuspec 或 package.json 文件,无法获取包信息"
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
def create_git_tag_from_nuspec(package_dir)
|
|
297
|
-
puts "🏷️ 创建 Git Tag..."
|
|
298
|
-
|
|
299
|
-
# 检查并更新 .gitignore 文件
|
|
300
|
-
ensure_build_directory_ignored(package_dir)
|
|
301
|
-
|
|
302
|
-
# 检查是否有未提交的文件
|
|
303
|
-
check_uncommitted_files(package_dir)
|
|
304
|
-
|
|
305
|
-
# 获取 .nuspec 文件并解析版本
|
|
306
|
-
nuspec_file = Pindo::Unity::NugetHelper.find_nuspec_file(package_dir)
|
|
307
|
-
unless nuspec_file
|
|
308
|
-
puts "⚠️ 未找到 .nuspec 文件,跳过创建 tag"
|
|
309
|
-
return
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
nuspec_info = Pindo::Unity::NugetHelper.parse_nuspec(nuspec_file)
|
|
313
|
-
version = nuspec_info['version']
|
|
314
|
-
|
|
315
|
-
unless version && !version.empty?
|
|
316
|
-
puts "⚠️ .nuspec 中未找到版本号,跳过创建 tag"
|
|
317
|
-
return
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
puts "版本号: #{version}"
|
|
321
|
-
puts
|
|
322
|
-
|
|
323
|
-
# 调用 pindo dev tag 命令,使用 --tag 参数
|
|
324
|
-
begin
|
|
325
|
-
tag_cmd = Pindo::Command::Utils::Tag.new(CLAide::ARGV.new(["--tag=#{version}"]))
|
|
326
|
-
tag_cmd.run
|
|
327
|
-
puts "✅ Git Tag 创建成功"
|
|
328
|
-
rescue => e
|
|
329
|
-
puts "⚠️ 创建 Git Tag 失败: #{e.message}"
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
def check_uncommitted_files(package_dir)
|
|
334
|
-
# 获取未跟踪和已修改的文件
|
|
335
|
-
untracked_files = Pindo::GitHandler.git!(%W(-C #{package_dir} ls-files --others --exclude-standard)).strip
|
|
336
|
-
modified_files = Pindo::GitHandler.git!(%W(-C #{package_dir} diff --name-only)).strip
|
|
337
|
-
staged_files = Pindo::GitHandler.git!(%W(-C #{package_dir} diff --cached --name-only)).strip
|
|
338
|
-
|
|
339
|
-
all_uncommitted = []
|
|
340
|
-
all_uncommitted += untracked_files.split("\n").reject(&:empty?) if !untracked_files.empty?
|
|
341
|
-
all_uncommitted += modified_files.split("\n").reject(&:empty?) if !modified_files.empty?
|
|
342
|
-
all_uncommitted += staged_files.split("\n").reject(&:empty?) if !staged_files.empty?
|
|
343
|
-
|
|
344
|
-
# 过滤掉 build 相关目录
|
|
345
|
-
all_uncommitted = all_uncommitted.reject do |file|
|
|
346
|
-
file.start_with?('build/') || file.start_with?('Build/') ||
|
|
347
|
-
file.start_with?('/build/') || file.start_with?('/Build/')
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
if all_uncommitted.any?
|
|
351
|
-
puts
|
|
352
|
-
puts "═" * 60
|
|
353
|
-
puts "⚠️ 警告:检测到未提交的文件".red
|
|
354
|
-
puts "═" * 60
|
|
355
|
-
puts
|
|
356
|
-
puts "以下文件尚未提交到 Git:".red
|
|
357
|
-
puts
|
|
358
|
-
all_uncommitted.each do |file|
|
|
359
|
-
puts " • #{file}".red
|
|
360
|
-
end
|
|
361
|
-
puts
|
|
362
|
-
puts "═" * 60
|
|
363
|
-
puts "建议先提交这些文件,或将它们添加到 .gitignore 中".red
|
|
364
|
-
puts "═" * 60
|
|
365
|
-
puts
|
|
366
|
-
end
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
def ensure_build_directory_ignored(package_dir)
|
|
370
|
-
gitignore_path = File.join(package_dir, '.gitignore')
|
|
371
|
-
|
|
372
|
-
# 要忽略的目录
|
|
373
|
-
build_patterns = [
|
|
374
|
-
'build/',
|
|
375
|
-
'/build/',
|
|
376
|
-
'Build/',
|
|
377
|
-
'/Build/'
|
|
378
|
-
]
|
|
379
|
-
|
|
380
|
-
# 读取现有的 .gitignore 内容
|
|
381
|
-
existing_patterns = []
|
|
382
|
-
if File.exist?(gitignore_path)
|
|
383
|
-
existing_patterns = File.readlines(gitignore_path).map(&:strip).reject(&:empty?)
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
# 检查是否已经包含 build 目录的忽略规则
|
|
387
|
-
has_build_ignore = existing_patterns.any? do |pattern|
|
|
388
|
-
pattern = pattern.strip
|
|
389
|
-
# 检查是否匹配 build 目录的各种形式
|
|
390
|
-
build_patterns.any? { |bp| pattern == bp || pattern == bp.chomp('/') }
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
# 如果没有包含 build 目录,则添加
|
|
394
|
-
unless has_build_ignore
|
|
395
|
-
puts "📝 更新 .gitignore 文件,添加 build/ 目录..."
|
|
396
|
-
|
|
397
|
-
# 追加 build 目录到 .gitignore
|
|
398
|
-
File.open(gitignore_path, 'a') do |file|
|
|
399
|
-
# 如果文件不为空且最后没有换行,添加换行
|
|
400
|
-
file.puts if existing_patterns.any? && !File.read(gitignore_path).end_with?("\n")
|
|
401
|
-
file.puts "# Unity build output"
|
|
402
|
-
file.puts "build/"
|
|
403
|
-
file.puts "Build/"
|
|
404
|
-
end
|
|
405
|
-
|
|
406
|
-
puts "✅ 已将 build 目录添加到 .gitignore"
|
|
407
|
-
|
|
408
|
-
# 提交 .gitignore 的更改
|
|
409
|
-
begin
|
|
410
|
-
Pindo::GitHandler.git!(%W(-C #{package_dir} add .gitignore))
|
|
411
|
-
Pindo::GitHandler.git!(%W(-C #{package_dir} commit -m "chore: 添加 build 目录到 .gitignore"))
|
|
412
|
-
puts "✅ 已提交 .gitignore 更改"
|
|
413
|
-
rescue => e
|
|
414
|
-
puts "⚠️ 提交 .gitignore 失败: #{e.message}"
|
|
415
|
-
end
|
|
416
|
-
else
|
|
417
|
-
puts "✅ .gitignore 已包含 build 目录规则"
|
|
418
|
-
end
|
|
168
|
+
{}
|
|
419
169
|
end
|
|
420
170
|
|
|
421
171
|
end
|
|
@@ -109,7 +109,7 @@ module Pindo
|
|
|
109
109
|
# @param task [PindoTask] 任务对象
|
|
110
110
|
def execute_task_legacy(task)
|
|
111
111
|
# 显示任务开始信息
|
|
112
|
-
@reporter.
|
|
112
|
+
@reporter.print_task_title(task)
|
|
113
113
|
|
|
114
114
|
begin
|
|
115
115
|
# 在主线程中执行任务
|
|
@@ -122,9 +122,6 @@ module Pindo
|
|
|
122
122
|
# 任务失败
|
|
123
123
|
@reporter.print_task_failure(task, e)
|
|
124
124
|
end
|
|
125
|
-
|
|
126
|
-
# 任务完成后输出分隔线
|
|
127
|
-
@reporter.print_task_footer
|
|
128
125
|
end
|
|
129
126
|
end
|
|
130
127
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'pindo/module/task/model/nuget_task'
|
|
2
|
+
require 'pindo/module/unity/nuget_helper'
|
|
3
|
+
|
|
4
|
+
module Pindo
|
|
5
|
+
module TaskSystem
|
|
6
|
+
class NugetBuildTask < NugetTask
|
|
7
|
+
|
|
8
|
+
def self.task_key
|
|
9
|
+
:nuget_build
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(project_path:)
|
|
13
|
+
super("NugetBuild", project_path: project_path)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def do_work
|
|
17
|
+
puts
|
|
18
|
+
puts "📦 [Task] 开始执行 Nuget 打包..."
|
|
19
|
+
|
|
20
|
+
# 1. 初始化检查 (同步 package.json 和 .nuspec)
|
|
21
|
+
puts "🔍 执行初始化检查..."
|
|
22
|
+
Pindo::Unity::NugetHelper.nuget_init(@project_path)
|
|
23
|
+
puts
|
|
24
|
+
|
|
25
|
+
# 2. 获取 nuspec 文件
|
|
26
|
+
nuspec_file = Pindo::Unity::NugetHelper.find_nuspec_file(@project_path)
|
|
27
|
+
unless nuspec_file
|
|
28
|
+
raise Informative, "未找到 .nuspec 文件,打包无法继续"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# 3. 生成 Release Notes
|
|
32
|
+
puts "📝 生成 Release Notes..."
|
|
33
|
+
release_notes = Pindo::Unity::NugetHelper.generate_release_notes_from_git(@project_path)
|
|
34
|
+
|
|
35
|
+
if release_notes && !release_notes.empty?
|
|
36
|
+
Pindo::Unity::NugetHelper.update_nuspec_release_notes(nuspec_file, release_notes)
|
|
37
|
+
puts "✅ 已更新 .nuspec 的 releaseNotes 字段"
|
|
38
|
+
else
|
|
39
|
+
puts "⚠️ 未生成 Release Notes,将使用 .nuspec 中已有的内容"
|
|
40
|
+
end
|
|
41
|
+
puts
|
|
42
|
+
|
|
43
|
+
# 4. 执行打包
|
|
44
|
+
nupkg_file = Pindo::Unity::NugetHelper.pack_nupkg(@project_path)
|
|
45
|
+
|
|
46
|
+
# 5. 返回结果 (生成的 nupkg 文件路径)
|
|
47
|
+
{
|
|
48
|
+
nupkg_file: nupkg_file
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
require 'pindo/module/task/model/nuget_task'
|
|
2
|
+
require 'pindo/module/unity/nuget_helper'
|
|
3
|
+
require 'jpsclient'
|
|
4
|
+
|
|
5
|
+
module Pindo
|
|
6
|
+
module TaskSystem
|
|
7
|
+
class NugetUploadTask < NugetTask
|
|
8
|
+
|
|
9
|
+
attr_reader :nupkg_file
|
|
10
|
+
|
|
11
|
+
def self.task_key
|
|
12
|
+
:nuget_upload
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# 初始化上传任务
|
|
16
|
+
# @param project_path [String] 项目路径
|
|
17
|
+
# @param nupkg_file [String] 要上传的 .nupkg 文件路径(可选)
|
|
18
|
+
def initialize(project_path:, nupkg_file: nil)
|
|
19
|
+
super("Nuget包上传到JPS", project_path: project_path)
|
|
20
|
+
@nupkg_file = nupkg_file
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def do_work
|
|
24
|
+
puts
|
|
25
|
+
puts "📦 [Task] 开始上传 Nuget 包到 JPS..."
|
|
26
|
+
puts
|
|
27
|
+
|
|
28
|
+
# 1. 确定要上传的文件
|
|
29
|
+
actual_file = determine_nupkg_file
|
|
30
|
+
unless actual_file && File.exist?(actual_file)
|
|
31
|
+
raise Informative, "未找到 .nupkg 文件"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# 2. 获取包信息
|
|
35
|
+
package_info = get_package_info
|
|
36
|
+
|
|
37
|
+
# 3. 显示上传信息
|
|
38
|
+
display_upload_info(actual_file, package_info)
|
|
39
|
+
|
|
40
|
+
# 4. 执行上传
|
|
41
|
+
upload_to_jps(actual_file, package_info)
|
|
42
|
+
|
|
43
|
+
puts
|
|
44
|
+
puts "✅ Nuget 包上传完成!"
|
|
45
|
+
puts
|
|
46
|
+
|
|
47
|
+
# 返回结果
|
|
48
|
+
{
|
|
49
|
+
uploaded_file: actual_file,
|
|
50
|
+
package_info: package_info
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
# 确定要上传的 nupkg 文件
|
|
57
|
+
def determine_nupkg_file
|
|
58
|
+
if @nupkg_file && File.exist?(@nupkg_file)
|
|
59
|
+
return @nupkg_file
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# 自动查找
|
|
63
|
+
found_file = Pindo::Unity::NugetHelper.find_nupkg_file(@project_path)
|
|
64
|
+
if found_file && File.exist?(found_file)
|
|
65
|
+
return found_file
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# 获取包信息
|
|
72
|
+
def get_package_info
|
|
73
|
+
# 优先从 .nuspec 文件读取
|
|
74
|
+
nuspec_file = Pindo::Unity::NugetHelper.find_nuspec_file(@project_path)
|
|
75
|
+
|
|
76
|
+
if nuspec_file && File.exist?(nuspec_file)
|
|
77
|
+
nuspec_info = Pindo::Unity::NugetHelper.parse_nuspec(nuspec_file)
|
|
78
|
+
|
|
79
|
+
# 转换为统一格式
|
|
80
|
+
return {
|
|
81
|
+
'name' => nuspec_info['id'],
|
|
82
|
+
'version' => nuspec_info['version'],
|
|
83
|
+
'displayName' => nuspec_info['title'] || nuspec_info['id'],
|
|
84
|
+
'description' => nuspec_info['description']
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# 从 package.json 读取
|
|
89
|
+
package_json_path = File.join(@project_path, "package.json")
|
|
90
|
+
if File.exist?(package_json_path)
|
|
91
|
+
return JSON.parse(File.read(package_json_path))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# 返回空信息
|
|
95
|
+
{}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# 显示上传信息
|
|
99
|
+
def display_upload_info(file_path, package_info)
|
|
100
|
+
puts "📦 包信息:"
|
|
101
|
+
puts
|
|
102
|
+
|
|
103
|
+
if package_info && !package_info.empty?
|
|
104
|
+
puts " 名称: #{package_info['displayName']}"
|
|
105
|
+
puts " ID: #{package_info['name']}"
|
|
106
|
+
puts " 版本: #{package_info['version']}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
puts " 文件: #{file_path}"
|
|
110
|
+
puts " 大小: #{sprintf('%.2f', File.size(file_path) / 1024.0 / 1024.0)} MB"
|
|
111
|
+
puts
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# 上传到 JPS
|
|
115
|
+
def upload_to_jps(nupkg_file, package_info)
|
|
116
|
+
# 1. 登录 JPS
|
|
117
|
+
config_file = File.join(
|
|
118
|
+
Pindoconfig.instance.pindo_common_configdir,
|
|
119
|
+
"jps_client_config.json"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
puts "🔐 登录 JPS..."
|
|
123
|
+
jps_client = JPSClient::Client.new(config_file: config_file)
|
|
124
|
+
login_success = jps_client.do_login(force_login: false)
|
|
125
|
+
|
|
126
|
+
unless login_success
|
|
127
|
+
raise Informative, "JPS 登录失败,请检查配置"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
puts "✅ 登录成功"
|
|
131
|
+
puts
|
|
132
|
+
|
|
133
|
+
# 2. 查询 Nuget 项目
|
|
134
|
+
nuget_project = find_nuget_project(jps_client)
|
|
135
|
+
puts
|
|
136
|
+
|
|
137
|
+
# 3. 上传文件到存储
|
|
138
|
+
puts "📤 上传文件到存储..."
|
|
139
|
+
|
|
140
|
+
# 使用 nuget-resource bucket
|
|
141
|
+
config_json = jps_client.config_json
|
|
142
|
+
config_json['upload_config']['bucket_name'] = 'nuget-resource'
|
|
143
|
+
|
|
144
|
+
# 开始上传,记录时间
|
|
145
|
+
file_size_mb = File.size(nupkg_file) / (1024.0 * 1024.0)
|
|
146
|
+
puts "开始上传文件 (#{file_size_mb.round(2)} MB)..."
|
|
147
|
+
upload_start_time = Time.now
|
|
148
|
+
|
|
149
|
+
upload_client = JPSClient::UploadClient.new(jps_client)
|
|
150
|
+
file_url = upload_client.upload_file(binary_file: nupkg_file)
|
|
151
|
+
|
|
152
|
+
# 计算上传耗时
|
|
153
|
+
upload_duration = Time.now - upload_start_time
|
|
154
|
+
upload_speed = file_size_mb / upload_duration
|
|
155
|
+
puts "✅ 文件上传完成! 耗时: #{upload_duration.round(2)} 秒, 平均速度: #{upload_speed.round(2)} MB/s"
|
|
156
|
+
|
|
157
|
+
if file_url.nil?
|
|
158
|
+
raise Informative, "文件上传失败"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
puts "✅ 文件上传成功"
|
|
162
|
+
puts
|
|
163
|
+
|
|
164
|
+
# 4. 提交到 JPS 项目
|
|
165
|
+
puts "📋 提交到 JPS 项目..."
|
|
166
|
+
|
|
167
|
+
result = jps_client.upload_nuget_package(
|
|
168
|
+
projectId: nuget_project['id'],
|
|
169
|
+
params: {
|
|
170
|
+
packageUrl: file_url,
|
|
171
|
+
attachFileUrls: []
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if result && (result['code'] == 0 || result['code'] == 200)
|
|
176
|
+
puts "✅ 提交成功"
|
|
177
|
+
print_upload_result(result)
|
|
178
|
+
else
|
|
179
|
+
error_msg = result['message'] || result['msg'] || '未知错误'
|
|
180
|
+
raise Informative, "提交失败: #{error_msg}"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# 查找 Nuget 项目
|
|
185
|
+
def find_nuget_project(jps_client)
|
|
186
|
+
puts "🔍 查询 Nuget 项目..."
|
|
187
|
+
|
|
188
|
+
result = jps_client.get_project_list(params: {})
|
|
189
|
+
|
|
190
|
+
unless result && (result['code'] == 0 || result['code'] == 200)
|
|
191
|
+
raise Informative, "获取项目列表失败"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
projects = result['data'] || []
|
|
195
|
+
|
|
196
|
+
if projects.empty?
|
|
197
|
+
raise Informative, "JPS 中没有任何项目,请联系管理员创建"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# 优先通过固定 ID 查找
|
|
201
|
+
target_project_id = '5e6b36f61b614ed88086373ef874616c'
|
|
202
|
+
nuget_project = projects.find { |p| p['id'] == target_project_id }
|
|
203
|
+
|
|
204
|
+
if nuget_project
|
|
205
|
+
puts "✅ 找到 Nuget 组件库项目: #{nuget_project['projectName']} (ID: #{nuget_project['id']})"
|
|
206
|
+
return nuget_project
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# 如果没找到,抛出错误(Task 模式不支持交互式输入)
|
|
210
|
+
raise Informative, "未找到默认 Nuget 组件库项目 (ID: #{target_project_id}),请联系管理员"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# 打印上传结果
|
|
214
|
+
def print_upload_result(result)
|
|
215
|
+
if result['data'] && result['data']['id']
|
|
216
|
+
puts " JPS ID: #{result['data']['id']}"
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'pindo/module/task/pindo_task'
|
|
2
|
+
|
|
3
|
+
module Pindo
|
|
4
|
+
module TaskSystem
|
|
5
|
+
class NugetTask < PindoTask
|
|
6
|
+
attr_reader :project_path
|
|
7
|
+
|
|
8
|
+
def self.task_type
|
|
9
|
+
:nuget
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.task_key
|
|
13
|
+
:nuget_base
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(name, project_path:)
|
|
17
|
+
super(name)
|
|
18
|
+
@project_path = project_path
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def required_resources
|
|
22
|
+
# Nuget 任务通常是基于文件系统的,需要锁定项目目录
|
|
23
|
+
[
|
|
24
|
+
{ type: :file_system, directory: @project_path }
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -84,11 +84,10 @@ module Pindo
|
|
|
84
84
|
def start_task(task_id)
|
|
85
85
|
@mutex.synchronize do
|
|
86
86
|
display = @task_displays[task_id]
|
|
87
|
-
display&.add_line("任务开始")
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
write_log(task_id, "
|
|
88
|
+
# 不在终端显示泛泛的"任务开始",任务名称已经足够清晰
|
|
89
|
+
# 只在日志文件中记录
|
|
90
|
+
write_log(task_id, "开始执行")
|
|
92
91
|
|
|
93
92
|
render_terminal
|
|
94
93
|
end
|
|
@@ -110,9 +109,7 @@ module Pindo
|
|
|
110
109
|
|
|
111
110
|
display&.mark_success(msg)
|
|
112
111
|
|
|
113
|
-
write_log(task_id, "
|
|
114
|
-
write_log(task_id, "任务成功: #{msg}")
|
|
115
|
-
write_log(task_id, "=" * 60)
|
|
112
|
+
write_log(task_id, "✓ 任务成功: #{msg}")
|
|
116
113
|
|
|
117
114
|
close_log(task_id)
|
|
118
115
|
render_terminal
|
|
@@ -127,9 +124,7 @@ module Pindo
|
|
|
127
124
|
display = @task_displays[task_id]
|
|
128
125
|
display&.mark_error(error_message)
|
|
129
126
|
|
|
130
|
-
write_log(task_id, "
|
|
131
|
-
write_log(task_id, "任务失败: #{error_message}")
|
|
132
|
-
write_log(task_id, "=" * 60)
|
|
127
|
+
write_log(task_id, "✗ 任务失败: #{error_message}")
|
|
133
128
|
|
|
134
129
|
close_log(task_id)
|
|
135
130
|
render_terminal
|
|
@@ -22,8 +22,8 @@ module Pindo
|
|
|
22
22
|
|
|
23
23
|
puts "\n"
|
|
24
24
|
puts "\e[34m" + "=" * 60
|
|
25
|
-
puts " 任务执行计划 (#{strategy.name})"
|
|
26
|
-
puts "=" * 60
|
|
25
|
+
puts "\e[34m" + " 任务执行计划 (#{strategy.name})"
|
|
26
|
+
puts "\e[34m" + "=" * 60
|
|
27
27
|
|
|
28
28
|
tasks_by_type.each do |type, tasks|
|
|
29
29
|
# 直接从任务类获取显示名称
|
|
@@ -32,25 +32,28 @@ module Pindo
|
|
|
32
32
|
else
|
|
33
33
|
type.to_s.capitalize
|
|
34
34
|
end
|
|
35
|
-
puts "\
|
|
35
|
+
puts "\e[34m"
|
|
36
|
+
puts "\e[34m" + " #{type_name}: #{tasks.count} 个任务"
|
|
36
37
|
|
|
37
38
|
# 显示该类型下的每个任务名称
|
|
38
39
|
tasks.each do |task|
|
|
39
|
-
puts " - #{task.name}"
|
|
40
|
+
puts "\e[34m" + " - #{task.name}"
|
|
40
41
|
end
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
puts "\
|
|
44
|
-
puts "
|
|
44
|
+
puts "\e[34m"
|
|
45
|
+
puts "\e[34m" + " 总计: #{@queue.pending_count} 个任务"
|
|
46
|
+
puts "\e[34m" + "=" * 60 + "\e[0m"
|
|
45
47
|
puts "\n"
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
#
|
|
50
|
+
# 输出任务执行标题
|
|
49
51
|
# @param task [PindoTask] 任务对象
|
|
50
|
-
def
|
|
52
|
+
def print_task_title(task)
|
|
51
53
|
puts ""
|
|
52
|
-
puts "
|
|
53
|
-
puts "
|
|
54
|
+
puts ("*" * 60).cyan
|
|
55
|
+
puts "▶ Task Start: #{task.name}".cyan
|
|
56
|
+
puts ("*" * 60).cyan
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
# 输出任务成功信息
|
|
@@ -58,29 +61,32 @@ module Pindo
|
|
|
58
61
|
def print_task_success(task)
|
|
59
62
|
time_str = task.execution_time ? task.execution_time.round(2) : 0
|
|
60
63
|
puts ""
|
|
61
|
-
puts "
|
|
64
|
+
puts ("*" * 60).cyan
|
|
65
|
+
puts "✓ Task End: #{task.name} 完成 (#{time_str}s)".cyan
|
|
66
|
+
puts ("*" * 60).cyan
|
|
67
|
+
puts ""
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
# 输出任务失败信息
|
|
65
71
|
# @param task [PindoTask] 任务对象
|
|
66
72
|
# @param error [Exception] 错误对象
|
|
67
73
|
def print_task_failure(task, error)
|
|
68
|
-
puts "
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
puts ""
|
|
75
|
+
puts ("*" * 60).cyan
|
|
76
|
+
puts "✗ Task End: #{task.name} 失败".cyan
|
|
77
|
+
puts "错误信息: #{error.message}".cyan
|
|
71
78
|
|
|
72
79
|
# 打印堆栈信息用于调试(仅在 PINDO_DEBUG 模式下)
|
|
73
80
|
if ENV['PINDO_DEBUG'] && error.backtrace && !error.backtrace.empty?
|
|
74
|
-
puts "
|
|
81
|
+
puts ""
|
|
82
|
+
puts "堆栈信息:".cyan
|
|
75
83
|
error.backtrace.first(10).each do |line|
|
|
76
|
-
puts " #{line}"
|
|
84
|
+
puts " #{line}".cyan
|
|
77
85
|
end
|
|
78
86
|
end
|
|
79
|
-
end
|
|
80
87
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# 简化输出,不需要额外的分隔线
|
|
88
|
+
puts ("*" * 60).cyan
|
|
89
|
+
puts ""
|
|
84
90
|
end
|
|
85
91
|
|
|
86
92
|
# 输出执行摘要
|
|
@@ -8,6 +8,42 @@ module Pindo
|
|
|
8
8
|
module Unity
|
|
9
9
|
class NugetHelper
|
|
10
10
|
|
|
11
|
+
# ============================================
|
|
12
|
+
# 初始化逻辑封装
|
|
13
|
+
# ============================================
|
|
14
|
+
|
|
15
|
+
def self.nuget_init(package_dir)
|
|
16
|
+
Funlog.instance.fancyinfo_start("Unity Package 初始化")
|
|
17
|
+
|
|
18
|
+
# 检测文件存在情况
|
|
19
|
+
status = detect_files(package_dir)
|
|
20
|
+
|
|
21
|
+
puts " 📄 package.json: #{status[:has_package_json] ? '✅' : '❌'}"
|
|
22
|
+
puts " 📄 .nuspec: #{status[:has_nuspec] ? '✅' : '❌'}"
|
|
23
|
+
if status[:nuspec_file]
|
|
24
|
+
puts " 路径: #{File.basename(status[:nuspec_file])}"
|
|
25
|
+
end
|
|
26
|
+
puts ""
|
|
27
|
+
|
|
28
|
+
# 根据4种情况处理
|
|
29
|
+
case [status[:has_package_json], status[:has_nuspec]]
|
|
30
|
+
when [true, false]
|
|
31
|
+
Funlog.instance.fancyinfo_update("情况A: 仅有 package.json,创建 .nuspec")
|
|
32
|
+
handle_case_a(package_dir)
|
|
33
|
+
when [false, true]
|
|
34
|
+
Funlog.instance.fancyinfo_update("情况B: 仅有 .nuspec,创建 package.json")
|
|
35
|
+
handle_case_b(package_dir, status[:nuspec_file])
|
|
36
|
+
when [true, true]
|
|
37
|
+
Funlog.instance.fancyinfo_update("情况C: 两个文件都存在,以 .nuspec 为准同步")
|
|
38
|
+
handle_case_c(package_dir, status[:nuspec_file])
|
|
39
|
+
when [false, false]
|
|
40
|
+
Funlog.instance.fancyinfo_error("情况D: 两个文件都不存在")
|
|
41
|
+
handle_case_d(package_dir)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
Funlog.instance.fancyinfo_success("初始化完成")
|
|
45
|
+
end
|
|
46
|
+
|
|
11
47
|
# ============================================
|
|
12
48
|
# ID 格式转换
|
|
13
49
|
# ============================================
|
|
@@ -79,10 +115,7 @@ module Pindo
|
|
|
79
115
|
# 检查 README.md 是否存在
|
|
80
116
|
readme_path = File.join(package_dir, "README.md")
|
|
81
117
|
unless File.exist?(readme_path)
|
|
82
|
-
|
|
83
|
-
puts " README.md 是 NuGet 包的必需文件"
|
|
84
|
-
puts " 请创建 README.md 文件后再运行此命令"
|
|
85
|
-
puts
|
|
118
|
+
Funlog.instance.fancyinfo_warning("未找到 README.md 文件,打包前请创建")
|
|
86
119
|
end
|
|
87
120
|
|
|
88
121
|
nuspec_path = File.join(package_dir, "#{package_info['displayName']}.nuspec")
|
|
@@ -91,14 +124,10 @@ module Pindo
|
|
|
91
124
|
nuspec_id = to_camelcase_id(package_info['name'])
|
|
92
125
|
generate_nuspec_from_package_json(package_info, nuspec_path, nuspec_id)
|
|
93
126
|
|
|
94
|
-
puts "
|
|
95
|
-
puts "
|
|
96
|
-
puts "
|
|
97
|
-
|
|
98
|
-
unless File.exist?(readme_path)
|
|
99
|
-
puts
|
|
100
|
-
puts "⚠️ 重要提示: 打包前请确保创建 README.md 文件!"
|
|
101
|
-
end
|
|
127
|
+
puts " ✓ 已创建 #{package_info['displayName']}.nuspec"
|
|
128
|
+
puts " package.json name: #{package_info['name']} (全小写)"
|
|
129
|
+
puts " .nuspec id: #{nuspec_id} (驼峰)"
|
|
130
|
+
puts ""
|
|
102
131
|
end
|
|
103
132
|
|
|
104
133
|
# 情况B:只有 .nuspec,创建 package.json
|
|
@@ -112,9 +141,10 @@ module Pindo
|
|
|
112
141
|
package_json_name = to_lowercase_id(nuspec_info['id'])
|
|
113
142
|
generate_package_json_from_nuspec(nuspec_info, package_json_path, package_json_name)
|
|
114
143
|
|
|
115
|
-
puts "
|
|
116
|
-
puts "
|
|
117
|
-
puts "
|
|
144
|
+
puts " ✓ 已创建 package.json"
|
|
145
|
+
puts " .nuspec id: #{nuspec_info['id']} (驼峰)"
|
|
146
|
+
puts " package.json name: #{package_json_name} (全小写)"
|
|
147
|
+
puts ""
|
|
118
148
|
end
|
|
119
149
|
|
|
120
150
|
# 情况C:同时存在,以 .nuspec 为准同步到 package.json
|
|
@@ -125,28 +155,29 @@ module Pindo
|
|
|
125
155
|
conflicts = check_conflicts(package_info, nuspec_info)
|
|
126
156
|
|
|
127
157
|
if conflicts.empty?
|
|
128
|
-
puts "✅ package.json 和 .nuspec 信息一致"
|
|
129
|
-
|
|
130
158
|
# 即使一致,也要确保 ID 格式正确
|
|
131
159
|
expected_package_name = to_lowercase_id(nuspec_info['id'])
|
|
132
160
|
expected_nuspec_id = nuspec_info['id'] # 保持驼峰
|
|
133
161
|
|
|
134
162
|
if package_info['name'] != expected_package_name
|
|
135
|
-
puts "
|
|
136
|
-
puts "
|
|
163
|
+
puts " ✓ 修正 package.json name 格式"
|
|
164
|
+
puts " #{package_info['name']} → #{expected_package_name}"
|
|
137
165
|
update_package_json_name(package_dir, expected_package_name)
|
|
166
|
+
else
|
|
167
|
+
puts " ✓ 两个文件信息一致"
|
|
138
168
|
end
|
|
139
169
|
else
|
|
140
|
-
|
|
141
|
-
conflicts.each { |msg| puts "
|
|
142
|
-
puts
|
|
170
|
+
Funlog.instance.fancyinfo_warning("检测到不一致,以 .nuspec 为准同步:")
|
|
171
|
+
conflicts.each { |msg| puts " - #{msg}" }
|
|
172
|
+
puts ""
|
|
143
173
|
|
|
144
174
|
# 以 .nuspec 为准,更新 package.json
|
|
145
175
|
update_package_json_from_nuspec(nuspec_info, package_dir)
|
|
146
|
-
puts "
|
|
147
|
-
puts "
|
|
148
|
-
puts "
|
|
176
|
+
puts " ✓ 已同步 package.json"
|
|
177
|
+
puts " .nuspec id: #{nuspec_info['id']} (驼峰)"
|
|
178
|
+
puts " package.json name: #{to_lowercase_id(nuspec_info['id'])} (全小写)"
|
|
149
179
|
end
|
|
180
|
+
puts ""
|
|
150
181
|
end
|
|
151
182
|
|
|
152
183
|
# 情况D:都不存在,报错
|
data/lib/pindo/version.rb
CHANGED
|
@@ -6,13 +6,13 @@ require 'time'
|
|
|
6
6
|
|
|
7
7
|
module Pindo
|
|
8
8
|
|
|
9
|
-
VERSION = "5.
|
|
9
|
+
VERSION = "5.14.0"
|
|
10
10
|
|
|
11
11
|
class VersionCheck
|
|
12
12
|
RUBYGEMS_API = 'https://rubygems.org/api/v1/gems/pindo.json'
|
|
13
13
|
VERSION_INFO_FILE = File.expand_path('~/.pindo/version_info.yml')
|
|
14
14
|
CHECK_INTERVAL = 5 * 60 * 60 # 5小时检查一次
|
|
15
|
-
CONFIG_MIN_VERSION = '1.
|
|
15
|
+
CONFIG_MIN_VERSION = '1.3.0' # 硬编码的配置版本要求
|
|
16
16
|
|
|
17
17
|
class << self
|
|
18
18
|
# 主版本检查方法(保持向后兼容)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pindo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- wade
|
|
@@ -454,6 +454,9 @@ files:
|
|
|
454
454
|
- lib/pindo/module/task/model/jps/jps_upload_media_task.rb
|
|
455
455
|
- lib/pindo/module/task/model/jps/jps_upload_task.rb
|
|
456
456
|
- lib/pindo/module/task/model/jps_task.rb
|
|
457
|
+
- lib/pindo/module/task/model/nuget/nuget_build_task.rb
|
|
458
|
+
- lib/pindo/module/task/model/nuget/nuget_upload_task.rb
|
|
459
|
+
- lib/pindo/module/task/model/nuget_task.rb
|
|
457
460
|
- lib/pindo/module/task/model/resign/ipa_local_resign_task.rb
|
|
458
461
|
- lib/pindo/module/task/model/unity/unity_config_task.rb
|
|
459
462
|
- lib/pindo/module/task/model/unity/unity_export_task.rb
|