unipod 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +79 -0
- data/exe/unipod +13 -0
- data/lib/unipod/command/install.rb +384 -0
- data/lib/unipod/command/push.rb +384 -0
- data/lib/unipod/command/server.rb +115 -0
- data/lib/unipod/command.rb +40 -0
- data/lib/unipod/config.rb +393 -0
- data/lib/unipod/server/cache_manager.rb +1106 -0
- data/lib/unipod/server/download_handler.rb +359 -0
- data/lib/unipod/server/index.html +460 -0
- data/lib/unipod/server/package_builder_queue.rb +255 -0
- data/lib/unipod/server/server.rb +393 -0
- data/lib/unipod/server/server_handler.rb +526 -0
- data/lib/unipod/ui.rb +173 -0
- data/lib/unipod/version.rb +5 -0
- data/lib/unipod.rb +33 -0
- metadata +226 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c7188707354d3aaa6e73863b24e0e063900b6cfeb1464e85444f90a0c2a5ee6a
|
4
|
+
data.tar.gz: 2ffdac624a5407164017bfd5979a710ddbc1c25d320e1608ffaed8015ff5784f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48d4a07e99595b6d9190628e8439a360e10acd7b6af009a063b32091c2ea41de1cd62bd8415a392227824fb66b1afc40901c94056e148d944a616a01de1bab41
|
7
|
+
data.tar.gz: f4c2f9b4e8e9567763f18b77cc280ef24533824b0187851086dce91b0d8d2f0b03fad98c5cc1aff4594e39cb1c0762cbec4cf8592c1a776c440b732a5ba1b1ba
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2023 UniPod
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# UniPod
|
2
|
+
|
3
|
+
UniPod是一个用于管理Unity包的命令行工具,类似于CocoaPods对iOS包的管理。
|
4
|
+
|
5
|
+
## 安装
|
6
|
+
|
7
|
+
使用RubyGems安装:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install unipod
|
11
|
+
```
|
12
|
+
|
13
|
+
## 使用方法
|
14
|
+
|
15
|
+
### 初始化项目
|
16
|
+
|
17
|
+
在Unity项目目录中创建一个`UnipodFile`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
# UnipodFile 示例
|
21
|
+
dependency 'Analytics', '~> 1.0'
|
22
|
+
dependency 'UIKit', '~> 2.3.1'
|
23
|
+
```
|
24
|
+
|
25
|
+
### 安装依赖
|
26
|
+
|
27
|
+
```bash
|
28
|
+
# 安装UnipodFile中的所有依赖
|
29
|
+
unipod install
|
30
|
+
|
31
|
+
# 安装特定包
|
32
|
+
unipod install Analytics
|
33
|
+
```
|
34
|
+
|
35
|
+
### 推送包到仓库
|
36
|
+
|
37
|
+
```bash
|
38
|
+
# 推送包到默认仓库
|
39
|
+
unipod push path/to/package.unitypackage
|
40
|
+
|
41
|
+
# 推送到指定仓库
|
42
|
+
unipod push path/to/package.unitypackage --repo=private-repo
|
43
|
+
```
|
44
|
+
|
45
|
+
### 启动本地服务器
|
46
|
+
|
47
|
+
```bash
|
48
|
+
# 启动默认配置的服务器
|
49
|
+
unipod server
|
50
|
+
|
51
|
+
# 自定义端口和主机
|
52
|
+
unipod server --port=9000 --host=0.0.0.0
|
53
|
+
```
|
54
|
+
|
55
|
+
## 开发
|
56
|
+
|
57
|
+
```bash
|
58
|
+
# 克隆仓库
|
59
|
+
git clone https://github.com/yourusername/unipod.git
|
60
|
+
cd unipod
|
61
|
+
|
62
|
+
# 安装依赖
|
63
|
+
bundle install
|
64
|
+
|
65
|
+
# 安装开发版本到本地
|
66
|
+
rake install
|
67
|
+
```
|
68
|
+
|
69
|
+
## 贡献
|
70
|
+
|
71
|
+
1. Fork 项目
|
72
|
+
2. 创建特性分支 (`git checkout -b feature/amazing-feature`)
|
73
|
+
3. 提交变更 (`git commit -m 'Add some amazing feature'`)
|
74
|
+
4. 推送到分支 (`git push origin feature/amazing-feature`)
|
75
|
+
5. 创建Pull Request
|
76
|
+
|
77
|
+
## 许可证
|
78
|
+
|
79
|
+
本项目使用MIT许可证 - 详见 [LICENSE](LICENSE) 文件
|
data/exe/unipod
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'unipod'
|
6
|
+
|
7
|
+
begin
|
8
|
+
UniPod::Command.run(ARGV)
|
9
|
+
rescue => e
|
10
|
+
UniPod::UI.error "发生错误: #{e.message}"
|
11
|
+
UniPod::UI.error e.backtrace.join("\n") if ENV['UNIPOD_DEBUG']
|
12
|
+
exit 1
|
13
|
+
end
|
@@ -0,0 +1,384 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'pathname'
|
6
|
+
require 'unipod/config'
|
7
|
+
require 'unipod/server/cache_manager'
|
8
|
+
require 'unipod/server/package_builder_queue'
|
9
|
+
|
10
|
+
module UniPod
|
11
|
+
class Command
|
12
|
+
class Install < Command
|
13
|
+
self.summary = '安装项目所需的Unity包'
|
14
|
+
self.description = <<-DESC
|
15
|
+
安装Unity项目所需的包依赖,读取manifest.json中定义的包列表。
|
16
|
+
1. 读取Unity项目当前需要的所有Package(版本号形式引入的Package)
|
17
|
+
2. 从索引库中获取这些Package的依赖信息
|
18
|
+
3. 下载所有需要的Package的Git仓库,并生成.tgz文件
|
19
|
+
4. 将Package解压到Unity项目的Library/PackageCache目录
|
20
|
+
|
21
|
+
如果提供了特定的包名,则只安装该包。
|
22
|
+
DESC
|
23
|
+
|
24
|
+
self.arguments = [
|
25
|
+
CLAide::Argument.new('PACKAGE', false)
|
26
|
+
]
|
27
|
+
|
28
|
+
def self.options
|
29
|
+
[
|
30
|
+
['--repo-update', '在安装前更新本地仓库'],
|
31
|
+
['--project-path=PATH', 'Unity项目的路径,默认为当前目录'],
|
32
|
+
['--verbose', '显示详细安装过程']
|
33
|
+
].concat(super)
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(argv)
|
37
|
+
@package_name = argv.shift_argument
|
38
|
+
@repo_update = argv.flag?('repo-update', false)
|
39
|
+
@verbose = argv.flag?('verbose', false)
|
40
|
+
@project_path = argv.option('project-path', Dir.pwd)
|
41
|
+
@cache_manager = nil
|
42
|
+
@builder_queue = nil
|
43
|
+
@unity_packages = {}
|
44
|
+
@processed_packages = {}
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate!
|
49
|
+
super
|
50
|
+
manifest_path = File.join(@project_path, 'Packages', 'manifest.json')
|
51
|
+
unless File.exist?(manifest_path)
|
52
|
+
help! "未找到Unity项目的manifest.json文件: #{manifest_path}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def run
|
57
|
+
UI.puts Rainbow("正在安装Unity包...").green
|
58
|
+
|
59
|
+
# 读取Unity项目的manifest.json文件,包括scopedRegistries配置
|
60
|
+
read_unity_manifest
|
61
|
+
|
62
|
+
# 初始化缓存管理器
|
63
|
+
@cache_manager = UniPod::Server::CacheManager.new(verbose: @verbose)
|
64
|
+
|
65
|
+
# 初始化包构建队列
|
66
|
+
@builder_queue = UniPod::Server::PackageBuilderQueue.instance
|
67
|
+
@builder_queue.start(@cache_manager, verbose: @verbose)
|
68
|
+
|
69
|
+
# 如果需要,更新仓库
|
70
|
+
if @repo_update
|
71
|
+
UI.puts "更新本地仓库缓存..."
|
72
|
+
@cache_manager.refresh_cache
|
73
|
+
end
|
74
|
+
|
75
|
+
begin
|
76
|
+
# 根据参数决定安装特定包还是所有依赖
|
77
|
+
if @package_name
|
78
|
+
UI.puts "安装特定包: #{@package_name}"
|
79
|
+
install_package(@package_name)
|
80
|
+
else
|
81
|
+
UI.puts "扫描并安装所有所需的包..."
|
82
|
+
install_all_dependencies
|
83
|
+
end
|
84
|
+
|
85
|
+
UI.puts Rainbow("所有包安装完成!").green
|
86
|
+
ensure
|
87
|
+
# 停止包构建队列
|
88
|
+
@builder_queue.stop if @builder_queue
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# 读取Unity项目的manifest.json文件,获取项目所需的包和索引库配置
|
95
|
+
def read_unity_manifest
|
96
|
+
manifest_path = File.join(@project_path, 'Packages', 'manifest.json')
|
97
|
+
if File.exist?(manifest_path)
|
98
|
+
begin
|
99
|
+
manifest_data = JSON.parse(File.read(manifest_path))
|
100
|
+
|
101
|
+
# 读取dependencies部分
|
102
|
+
if manifest_data['dependencies'].is_a?(Hash)
|
103
|
+
dependencies = manifest_data['dependencies']
|
104
|
+
|
105
|
+
# 筛选出以版本号形式引入的包(不是本地路径或git URL)
|
106
|
+
dependencies.each do |package_name, version|
|
107
|
+
# 跳过本地路径或git URL形式的包
|
108
|
+
unless version.start_with?('file:', 'git:', 'https://', 'git@')
|
109
|
+
# 标准化版本号(删除^和~等前缀)
|
110
|
+
clean_version = version.gsub(/[\^~>=<]/, '')
|
111
|
+
@unity_packages[package_name] = clean_version
|
112
|
+
UI.puts "发现包: #{package_name}@#{clean_version}" if @verbose
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
UI.puts "Unity项目中发现 #{@unity_packages.size} 个需要通过UniPod安装的包"
|
117
|
+
else
|
118
|
+
UI.puts "manifest.json中没有找到dependencies部分或格式不正确"
|
119
|
+
end
|
120
|
+
|
121
|
+
# 读取scopedRegistries部分,获取索引库配置
|
122
|
+
if manifest_data['scopedRegistries'].is_a?(Array)
|
123
|
+
scoped_registries = manifest_data['scopedRegistries']
|
124
|
+
|
125
|
+
UI.puts "发现 #{scoped_registries.size} 个作用域注册表配置" if @verbose
|
126
|
+
|
127
|
+
# 处理每个scopedRegistry
|
128
|
+
scoped_registries.each do |registry|
|
129
|
+
if registry['index_url']
|
130
|
+
registry_name = registry['name'] || extract_repo_name_from_url(registry['index_url'])
|
131
|
+
index_url = registry['index_url']
|
132
|
+
scopes = registry['scopes'] || []
|
133
|
+
|
134
|
+
UI.puts "发现索引库: #{registry_name} (#{index_url}), 作用域: #{scopes.join(', ')}" if @verbose
|
135
|
+
|
136
|
+
# 将索引库信息传递给Config
|
137
|
+
UniPod::Config.add_index_repo(registry_name, index_url)
|
138
|
+
|
139
|
+
# 记录作用域与索引库的映射关系
|
140
|
+
scopes.each do |scope|
|
141
|
+
UniPod::Config.add_scope_mapping(scope, registry_name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
else
|
146
|
+
UI.puts "manifest.json中没有找到scopedRegistries部分或格式不正确"
|
147
|
+
end
|
148
|
+
rescue JSON::ParserError => e
|
149
|
+
UI.error "解析manifest.json文件失败: #{e.message}"
|
150
|
+
end
|
151
|
+
else
|
152
|
+
UI.error "未找到Unity项目的manifest.json文件: #{manifest_path}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# 从URL中提取仓库名称
|
157
|
+
def extract_repo_name_from_url(url)
|
158
|
+
return nil if url.nil? || url.empty?
|
159
|
+
|
160
|
+
# 处理不同格式的Git URL
|
161
|
+
repo_name = nil
|
162
|
+
|
163
|
+
# 处理SSH格式: git@github.com:user/repo.git
|
164
|
+
if url.start_with?('git@')
|
165
|
+
match = url.match(/git@[^:]+:([^\/]+)\/([^\.]+)/)
|
166
|
+
repo_name = match[2] if match && match[2]
|
167
|
+
# 处理HTTPS格式: https://github.com/user/repo.git
|
168
|
+
elsif url.start_with?('http://', 'https://', 'git://')
|
169
|
+
uri = URI.parse(url)
|
170
|
+
path = uri.path
|
171
|
+
# 移除.git后缀和前导/
|
172
|
+
path = path.sub(/\.git$/, '').sub(/^\//, '')
|
173
|
+
# 获取最后一部分作为仓库名
|
174
|
+
repo_name = path.split('/').last
|
175
|
+
end
|
176
|
+
|
177
|
+
# 如果提取失败,使用URL的哈希值作为后备
|
178
|
+
unless repo_name
|
179
|
+
require 'digest'
|
180
|
+
repo_name = "repo-#{Digest::MD5.hexdigest(url)[0..7]}"
|
181
|
+
end
|
182
|
+
|
183
|
+
# 确保仓库名称只包含合法字符
|
184
|
+
repo_name.gsub(/[^a-zA-Z0-9_-]/, '_')
|
185
|
+
end
|
186
|
+
|
187
|
+
# 安装所有Unity项目需要的包
|
188
|
+
def install_all_dependencies
|
189
|
+
# 先筛选出存在于索引库中的包
|
190
|
+
valid_packages = {}
|
191
|
+
|
192
|
+
UI.puts "正在筛选manifest中的包..."
|
193
|
+
@unity_packages.each do |package_name, version|
|
194
|
+
# 检查包是否存在于索引库中
|
195
|
+
package_info = @cache_manager.get_package_info(package_name)
|
196
|
+
if package_info
|
197
|
+
valid_packages[package_name] = version
|
198
|
+
UI.puts "√ 包 #{package_name}@#{version} 在索引库中存在" if @verbose
|
199
|
+
else
|
200
|
+
UI.puts "× 跳过包 #{package_name}@#{version} (未在索引库中找到)" if @verbose
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
UI.puts "共找到 #{valid_packages.size}/#{@unity_packages.size} 个包在索引库中存在"
|
205
|
+
|
206
|
+
# 将所有有效包添加到处理队列
|
207
|
+
packages_to_process = valid_packages.dup
|
208
|
+
|
209
|
+
# 处理所有包
|
210
|
+
until packages_to_process.empty?
|
211
|
+
package_name, version = packages_to_process.shift
|
212
|
+
next if @processed_packages.key?("#{package_name}@#{version}")
|
213
|
+
|
214
|
+
# 安装包及其依赖
|
215
|
+
new_dependencies = install_package_with_dependencies(package_name, version)
|
216
|
+
|
217
|
+
# 将新的依赖添加到处理队列
|
218
|
+
new_dependencies.each do |dep_name, dep_version|
|
219
|
+
# 再次检查依赖包是否在索引库中存在
|
220
|
+
if @cache_manager.get_package_info(dep_name) && !@processed_packages.key?("#{dep_name}@#{dep_version}")
|
221
|
+
packages_to_process[dep_name] = dep_version
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# 安装特定的包
|
228
|
+
def install_package(package_name)
|
229
|
+
# 检查是否在Unity包列表中
|
230
|
+
unless @unity_packages.key?(package_name)
|
231
|
+
UI.puts "警告: 包 #{package_name} 不在Unity项目的manifest.json中"
|
232
|
+
if UI.confirm("是否仍然要安装此包?")
|
233
|
+
# 默认使用最新版本
|
234
|
+
@unity_packages[package_name] = 'latest'
|
235
|
+
else
|
236
|
+
return
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# 检查包是否存在于索引库中
|
241
|
+
package_info = @cache_manager.get_package_info(package_name)
|
242
|
+
unless package_info
|
243
|
+
UI.error "包 #{package_name} 在索引库中不存在,无法安装"
|
244
|
+
return
|
245
|
+
end
|
246
|
+
|
247
|
+
# 安装包及其依赖
|
248
|
+
install_package_with_dependencies(package_name, @unity_packages[package_name])
|
249
|
+
end
|
250
|
+
|
251
|
+
# 安装包及其依赖,返回依赖列表
|
252
|
+
def install_package_with_dependencies(package_name, version)
|
253
|
+
package_key = "#{package_name}@#{version}"
|
254
|
+
|
255
|
+
# 如果已经处理过此包,直接返回
|
256
|
+
return {} if @processed_packages.key?(package_key)
|
257
|
+
|
258
|
+
UI.puts Rainbow("处理包: #{package_key}").yellow
|
259
|
+
|
260
|
+
# 获取包信息
|
261
|
+
package_info = @cache_manager.get_package_info(package_name)
|
262
|
+
unless package_info
|
263
|
+
# UI.puts "警告: 在索引库中未找到包 #{package_name},这可能是Unity内置包或公共包"
|
264
|
+
@processed_packages[package_key] = true
|
265
|
+
return {}
|
266
|
+
end
|
267
|
+
|
268
|
+
# 确定要安装的版本
|
269
|
+
if version == 'latest' && package_info['version']
|
270
|
+
version = package_info['version']
|
271
|
+
UI.puts "使用最新版本: #{version}" if @verbose
|
272
|
+
end
|
273
|
+
|
274
|
+
# 获取包的特定版本信息
|
275
|
+
version_info = nil
|
276
|
+
if package_info['versions'] && package_info['versions'][version]
|
277
|
+
version_info = package_info['versions'][version]
|
278
|
+
else
|
279
|
+
# UI.puts "警告: 未找到包 #{package_name} 的版本 #{version},使用最新版本信息"
|
280
|
+
version_info = package_info
|
281
|
+
end
|
282
|
+
|
283
|
+
# 收集依赖信息
|
284
|
+
dependencies = {}
|
285
|
+
if version_info && version_info['dependencies'].is_a?(Hash)
|
286
|
+
version_info['dependencies'].each do |dep_name, dep_version|
|
287
|
+
# 标准化版本号
|
288
|
+
clean_version = dep_version.gsub(/[\^~>=<]/, '')
|
289
|
+
dependencies[dep_name] = clean_version
|
290
|
+
end
|
291
|
+
|
292
|
+
UI.puts "包 #{package_key} 有 #{dependencies.size} 个依赖项" if @verbose
|
293
|
+
end
|
294
|
+
|
295
|
+
# 下载并安装包
|
296
|
+
tarball_path = download_and_extract_package(package_name, version, version_info)
|
297
|
+
|
298
|
+
# 如果安装成功,标记为已处理
|
299
|
+
if tarball_path
|
300
|
+
@processed_packages[package_key] = true
|
301
|
+
return dependencies
|
302
|
+
else
|
303
|
+
UI.puts "警告: 包 #{package_key} 安装失败"
|
304
|
+
@processed_packages[package_key] = false
|
305
|
+
return {}
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
# 下载并解压包到Unity项目的Library/PackageCache目录
|
310
|
+
def download_and_extract_package(package_name, version, version_info)
|
311
|
+
tarball_name = "#{package_name}-#{version}.tgz"
|
312
|
+
|
313
|
+
# 检查是否已存在tarball文件
|
314
|
+
tarball_path = @cache_manager.get_package_tarball(package_name, tarball_name)
|
315
|
+
|
316
|
+
if tarball_path && File.exist?(tarball_path)
|
317
|
+
UI.puts "使用缓存的tarball: #{tarball_path}" if @verbose
|
318
|
+
else
|
319
|
+
# 需要从Git仓库构建tarball
|
320
|
+
UI.puts "未找到包 #{package_name}@#{version} 的tarball,尝试构建..."
|
321
|
+
|
322
|
+
if version_info && version_info['git'] && version_info['git']['url']
|
323
|
+
git_url = version_info['git']['url']
|
324
|
+
git_tag = version_info['git']['tag'] || "v#{version}"
|
325
|
+
git_branch = version_info['git']['branch'] || 'main'
|
326
|
+
|
327
|
+
UI.puts "从Git仓库构建包: #{git_url} (tag: #{git_tag})"
|
328
|
+
|
329
|
+
# 使用同步方式构建包,因为我们需要立即安装
|
330
|
+
if @cache_manager.clone_and_build_package(package_name, git_url, git_tag, git_branch)
|
331
|
+
tarball_path = @cache_manager.get_package_tarball(package_name, tarball_name)
|
332
|
+
if !tarball_path || !File.exist?(tarball_path)
|
333
|
+
UI.error "构建包失败: #{package_name}@#{version}"
|
334
|
+
return nil
|
335
|
+
end
|
336
|
+
else
|
337
|
+
UI.error "克隆Git仓库失败: #{git_url}"
|
338
|
+
return nil
|
339
|
+
end
|
340
|
+
else
|
341
|
+
UI.error "包 #{package_name}@#{version} 没有Git仓库信息,无法构建"
|
342
|
+
return nil
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
# 解压包到Unity项目的Library/PackageCache目录
|
347
|
+
extract_package_to_unity(package_name, version, tarball_path)
|
348
|
+
|
349
|
+
return tarball_path
|
350
|
+
end
|
351
|
+
|
352
|
+
# 解压包到Unity项目的Library/PackageCache目录
|
353
|
+
def extract_package_to_unity(package_name, version, tarball_path)
|
354
|
+
# 确定目标目录
|
355
|
+
package_cache_dir = File.join(@project_path, 'Library', 'PackageCache')
|
356
|
+
package_dir = File.join(package_cache_dir, "#{package_name}@#{version}")
|
357
|
+
|
358
|
+
# 创建目标目录
|
359
|
+
FileUtils.mkdir_p(package_cache_dir)
|
360
|
+
|
361
|
+
# 如果目标目录已存在,先删除
|
362
|
+
if Dir.exist?(package_dir)
|
363
|
+
UI.puts "目标目录已存在,删除: #{package_dir}" if @verbose
|
364
|
+
FileUtils.rm_rf(package_dir)
|
365
|
+
end
|
366
|
+
|
367
|
+
# 创建目标目录
|
368
|
+
FileUtils.mkdir_p(package_dir)
|
369
|
+
|
370
|
+
# 解压tarball到目标目录
|
371
|
+
UI.puts "解压包到: #{package_dir}"
|
372
|
+
system("tar -xzf #{tarball_path} -C #{package_dir}")
|
373
|
+
|
374
|
+
if $?.success?
|
375
|
+
UI.puts Rainbow("✓ 已安装: #{package_name}@#{version}").green
|
376
|
+
return true
|
377
|
+
else
|
378
|
+
UI.error "解压包失败: #{package_name}@#{version}"
|
379
|
+
return false
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|