lkpackage 0.1.6

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f4a55f7a6f80fcfc542eb38daa47a3a31b2c83e5264233916537aea1ff61f53d
4
+ data.tar.gz: 6f4445da436807abc700a5824702b8d9e765898ed0b535e085322552f6d6eefe
5
+ SHA512:
6
+ metadata.gz: 63e97236b5eb710e739e0bb3b43fbd394bd3a1ee5b535d621e53eb05dee3a14aae7786994092556772f3eae47a69c20e1db812c40613bba0446d83b3db9ba76e
7
+ data.tar.gz: 74da79e2dd7c681a99b00a9356ee93e7a5ae7075ae3059a9ef3002d5492e5face7ae91b5a2f1775ee55dc1b368ca39fa1c100da5477e64f0fee5789368f59a67
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in lkpackage.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 yangjie
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Lkpackage
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lkpackage`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'lkpackage'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install lkpackage
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lkpackage.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lkpackage"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lkpackage
4
+ VERSION = "0.1.6"
5
+ end
data/lib/lkpackage.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lkpackage/version"
4
+ require_relative "./package"
5
+
6
+ module Lkpackage
7
+ class Error < StandardError; end
8
+ # Your code goes here...
9
+
10
+
11
+
12
+ def self.package(podspecFile = "", tagVersion = "", needPackageLib = '0', repoSource = "", releaseNotes = "release notes", lintRepoSources = "git@gitlab.leoao-inc.com:Lefit_iOS_Organization/PrivatePods.git,git@gitlab.leoao-inc.com:Lefit_iOS_ThirdSDK/ThirdSDKSpec.git,git@gitlab.leoao-inc.com:Lefit_LFE_Architecture_Organization/Lefit_Platform_iOS/PlatformSDKSpec.git")
13
+ if podspecFile.empty?
14
+ raise "podspec 文件名为空"
15
+ end
16
+ if tagVersion.empty?
17
+ raise "请输入版本号"
18
+ end
19
+ if repoSource.empty?
20
+ raise "请输入 repo source"
21
+ end
22
+
23
+ packageCommand = "ruby package.rb #{podspecFile} #{tagVersion} #{needPackageLib} #{repoSource} #{releaseNotes} #{lintRepoSources}"
24
+ system packageCommand
25
+
26
+ end
27
+
28
+
29
+
30
+
31
+
32
+ end
data/lib/package.rb ADDED
@@ -0,0 +1,742 @@
1
+ #!/usr/bin/ruby
2
+ require './podspec_model'
3
+ require 'fileutils'
4
+ require 'JSON'
5
+
6
+ CURRENT_PATH = Dir.pwd #返回当前执行路径,并非 rb 文件路径
7
+ puts "当前执行路径为:" + CURRENT_PATH
8
+
9
+ #传参 0:podspec文件名(exp:xxx.podspec) 1:tag 版本 2:是否打包静态库(0:不打,1:打静态库) 3:repo source(exp:https://github.com/CocoaPods/Specs.git) 4:release note, 5: lint repo sources
10
+ PODSPEC_FILE = ARGV[0]
11
+ puts "podspec 文件名为:" + PODSPEC_FILE
12
+ #pod 组件名(去掉 .podspec 后缀)
13
+ POD_NAME = PODSPEC_FILE.split(".")[0]
14
+ puts "pod 库为:" + POD_NAME
15
+
16
+ TAG_VERSION = ARGV[1]
17
+ puts "tag 版本号:" + TAG_VERSION
18
+
19
+ IS_NEED_PACKAGE_LIB = ARGV[2]
20
+
21
+ REPO_SOURCE = ARGV[3]
22
+ puts "repo source: " + REPO_SOURCE
23
+
24
+ RELEASE_NOTES = ARGV[4]
25
+ puts "release notes: " + RELEASE_NOTES
26
+
27
+ if ARGV.size >= 6
28
+ LINT_REPO_SOURCES = ARGV[5]
29
+ else
30
+ LINT_REPO_SOURCES = "git@gitlab.leoao-inc.com:Lefit_iOS_Organization/PrivatePods.git,git@gitlab.leoao-inc.com:Lefit_iOS_ThirdSDK/ThirdSDKSpec.git,git@gitlab.leoao-inc.com:Lefit_LFE_Architecture_Organization/Lefit_Platform_iOS/PlatformSDKSpec.git"
31
+ end
32
+
33
+
34
+ def git_make_tag
35
+ puts "----------------- git_make_tag "
36
+ gitpullCommand = "git pull"
37
+ output = system gitpullCommand
38
+ unless output == true
39
+ raise "==== #{PODSPEC_FILE} !!!git pull 执行失败 ❌"
40
+ end
41
+ `sed -i '' 's/s.version.*=.*$/s.version = \"#{TAG_VERSION}\"/' #{PODSPEC_FILE}`
42
+ `git add .`
43
+ `git commit -m "update to new version #{TAG_VERSION}"`
44
+ gitTagCommand = "git tag #{TAG_VERSION} -m '#{RELEASE_NOTES}'"
45
+ output = system gitTagCommand
46
+ unless output == true
47
+ puts "!!!! error 打tag失败 ❌"
48
+ raise "!!!! error 打tag失败 ❌"
49
+ end
50
+ gitPushCommand = "git push origin #{TAG_VERSION}"
51
+ output = system gitPushCommand
52
+ unless output == true
53
+ `git tag -d #{TAG_VERSION}`
54
+ puts "!!!! error 打tag失败 :推送tag到远端错误 ❌"
55
+ raise "!!!! error 打tag失败 :推送tag到远端错误 ❌"
56
+ end
57
+ pushCommand = "git push origin"
58
+ system pushCommand
59
+ end
60
+
61
+
62
+ #删除本地和远程分支
63
+ def delete_tag
64
+ puts "----------------- delete_tag "
65
+ deleteTagCommand = "git tag -d #{TAG_VERSION}"
66
+ system deleteTagCommand
67
+ deleteRemoteTagcommond = "git push origin :refs/tags/#{TAG_VERSION}"
68
+ output = system deleteRemoteTagcommond
69
+ unless output == true
70
+ raise "==== #{PODSPEC_FILE} 删除远端 tag 失败 ❌"
71
+ end
72
+ end
73
+
74
+
75
+ # pod repo push
76
+ # Validates `NAME.podspec` or `*.podspec` in the current working dir, creates a
77
+ # directory and version folder for the pod in the local copy of `REPO`
78
+ # (/Users/yangjie/.cocoapods/repos/[REPO]), copies the podspec file into the
79
+ # version directory, and finally it pushes `REPO` to its remote.
80
+ # ⚠️ 验证的是本地路径下的 .podspec 文件,所以,可以修改原始 .podspec 文件内容后,再进行发布到 REPO
81
+ def pod_repo_push (skipTests)
82
+ puts "----------------- pod_repo_push "
83
+ skip_tests = ""
84
+ if skipTests == true
85
+ # Lint skips building and running tests during validation
86
+ skip_tests = " --skip-tests"
87
+ end
88
+ repoPushCommand = "pod repo push #{REPO_SOURCE} #{PODSPEC_FILE} --verbose --allow-warnings --use-libraries --skip-import-validation#{skip_tests} --sources='#{LINT_REPO_SOURCES}'"
89
+ output = system repoPushCommand
90
+ puts "==== pod repo push result:#{output}"
91
+ if output == true
92
+ puts "==== #{POD_NAME} 打 tag 成功 ✅"
93
+ else
94
+ puts "==== #{POD_NAME} 打 tag 失败. ❌"
95
+ raise "==== #{POD_NAME} 打 tag 失败. ❌"
96
+ end
97
+ end
98
+
99
+
100
+ #生成 podspec 对象
101
+ def create_podspec_model(podspec_file)
102
+ output = %x{pod ipc spec #{podspec_file}}
103
+ # 生成 spec_model 对象
104
+ spec_model = PodspecModel.new(output)
105
+ return spec_model
106
+ end
107
+
108
+
109
+ #打包静态库
110
+ # 每个 podspec 文件,对应一个pod仓库/子仓库,将该 podspec 打包静态库后,需要将静态库.a以及资源文件重新组织起来压缩上传到server,文件目录规定入下:
111
+ # - PODSPEC_NAME
112
+ # - _Headers
113
+ # - _Resources
114
+ # - _Vendored_frameworks
115
+ # _ _Verdored_libraries
116
+ # 注:若没有特定文件,那么对应的文件夹就不会创建
117
+ def package_lib(spec_model)
118
+ puts "----------------- package_lib "
119
+ #执行打包命令
120
+ packageCommand = "pod package #{PODSPEC_FILE} --spec-sources='#{LINT_REPO_SOURCES}' --library --force --exclude-deps --no-mangle --verbose"
121
+ puts "==== 打包命令为:" + packageCommand
122
+ puts "==== 开始执行打包静态库命令: #{PODSPEC_FILE}"
123
+ output = system packageCommand
124
+ puts "==== 打包静态库命令执行结果:#{output}"
125
+ if output == true
126
+ puts "==== #{PODSPEC_FILE} pod package 执行成功."
127
+ else
128
+ raise "==== #{PODSPEC_FILE} !!!打包静态库失败 ❌"
129
+ end
130
+
131
+ #对打包结果进行整理并压缩为 .zip 文件
132
+ #定义变量:package打包自动生成的文件夹名字
133
+ libFileFolderName = "#{POD_NAME}-#{spec_model.version}"
134
+
135
+ # 查找并复制文件到 ./libFileFolderName/temp/POD_NAME_VERSION 下,在复制之前,首先清空 ./libFileFolderName/temp/POD_NAME_VERSION 文件夹
136
+ tempLibFilePath = "./#{libFileFolderName}/temp/#{POD_NAME}_#{TAG_VERSION}"
137
+ if Dir.exist?(tempLibFilePath)
138
+ # 删除 POD_NAME 文件夹以及 POD_NAME 文件夹下的所有文件
139
+ FileUtils.rm_r tempLibFilePath, :force => true
140
+ end
141
+ FileUtils.mkdir_p tempLibFilePath
142
+
143
+ # 找到 .a ,并复制到 ./libFileFolderName/temp/POD_NAME 下
144
+ libPath = "#{libFileFolderName}/ios/lib#{POD_NAME}.a"
145
+ if File.exist?(libPath)
146
+ FileUtils.cp_r libPath, tempLibFilePath
147
+ end
148
+
149
+ # 找到资源文件,并复制到 tempLibFilePath/_Resources 路径下
150
+ # podspec采用resources 指定资源文件
151
+ if !spec_model.resources.nil?
152
+ if !Dir.exist?("#{tempLibFilePath}/_Resources")
153
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Resources"
154
+ end
155
+ if "#{spec_model.resources.class}".eql?("String")
156
+ puts "======= string spec_model.resources: #{spec_model.resources}"
157
+ resources_arr = Dir.glob(spec_model.resources)
158
+ puts "======= resources path arr: #{resources_arr}"
159
+ resources_arr.each { |resource_item|
160
+ puts "======= resources item: #{resource_item}"
161
+ if File.directory?(resource_item)
162
+ if File.extname(resource_item).eql?(".bundle")
163
+ FileUtils.cp_r resource_item, "#{tempLibFilePath}/_Resources"
164
+ end
165
+ next
166
+ end
167
+ FileUtils.cp_r resource_item, "#{tempLibFilePath}/_Resources"
168
+ }
169
+ elsif "#{spec_model.resources.class}".eql?("Array")
170
+ puts "======= array spec_model.resources: #{spec_model.resources}"
171
+ spec_model.resources.each { |resource|
172
+ puts "======= resource: #{resource}"
173
+ res_path_arr = Dir.glob(resource)
174
+ puts "======= resources path arr: #{res_path_arr}"
175
+ res_path_arr.each { |res_path_item|
176
+ puts "======= resources item: #{res_path_item}"
177
+ if File.directory?(res_path_item)
178
+ if File.extname(res_path_item).eql?(".bundle")
179
+ FileUtils.cp_r res_path_item, "#{tempLibFilePath}/_Resources"
180
+ end
181
+ next
182
+ end
183
+ FileUtils.cp_r res_path_item, "#{tempLibFilePath}/_Resources"
184
+ }
185
+ }
186
+ end
187
+ end
188
+ # podspec 采用 resource_bundles 指定资源文件
189
+ # 打包静态库后,将 resource_bundles 指定的资源按照键值对打包成对应的 .bundle 文件,同样拷贝到 tempLibFilePath/_Resources 中
190
+ # 这样,外部引用资源,都统一使用 s.resourcces = [...] 即可
191
+ unless spec_model.resource_bundles.nil?
192
+ if !Dir.exist?("#{tempLibFilePath}/_Resources")
193
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Resources"
194
+ end
195
+ if "#{spec_model.resource_bundles.class}".eql?("Hash")
196
+ spec_model.resource_bundles.each { |key,value|
197
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Resources/#{key}.bundle" # 创建多层文件夹,如果某个文件夹已经存在,则该文件夹不再创建
198
+ if "#{value.class}".eql?("String")
199
+ resbundle_path_arr = Dir.glob(value)
200
+ resbundle_path_arr.each { |resbundle_path_item|
201
+ if File.directory?(resbundle_path_item)
202
+ # 如果 resource_bundles 中又引入了 bundle 资源,则终止程序并给出错误警告,因为此时,编译后会在 key bundle 中再次嵌入这个 sour bundle,也就是bundle中包含bundle,这种情况往往不是我们预期的。
203
+ if File.extname(resbundle_path_item).eql?(".bundle")
204
+ raise "!!!!!!!!! resource_bundles 中,不能指定引入 bundle 文件 !> #{resbundle_path_item}"
205
+ end
206
+ next
207
+ end
208
+ FileUtils.cp_r resbundle_path_item, "#{tempLibFilePath}/_Resources/#{key}.bundle"
209
+ }
210
+ elsif "#{value.class}".eql?("Array")
211
+ value.each { |value_item|
212
+ resbundle_path_arr = Dir.glob(value_item)
213
+ resbundle_path_arr.each { |resbundle_path_item|
214
+ if File.directory?(resbundle_path_item)
215
+ if resbundle_path_item.include?(".bundle")
216
+ raise "!!!!!!!!!!! resource_bundles 中,不能指定引入 bundle 文件 !> #{resbundle_path_item}"
217
+ end
218
+ next
219
+ end
220
+ FileUtils.cp_r resbundle_path_item, "#{tempLibFilePath}/_Resources/#{key}.bundle"
221
+ }
222
+ }
223
+ end
224
+ }
225
+ else
226
+ raise "!!!!!!!!!!!! resource_bundles 不是 Hash 类型,请检查 podspec 文件中关于 resource_bundles 的配置"
227
+ end
228
+ end
229
+
230
+ # 查找头文件,并拷贝到 tempLibFilePath/_Headers 下。
231
+ if !spec_model.public_header_files.nil?
232
+ puts "=== 指定了 public header file"
233
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Headers"
234
+ if "#{spec_model.public_header_files.class}".eql?("String")
235
+ puts "==== string 类型"
236
+ headerFiles_path_arr = Dir.glob(spec_model.public_header_files)
237
+ puts headerFiles_path_arr
238
+ headerFiles_path_arr.each { |headerFiles_path_item|
239
+ puts headerFiles_path_item
240
+ puts File.extname(headerFiles_path_item)
241
+ if File.extname(headerFiles_path_item).eql?(".h")
242
+ FileUtils.cp_r headerFiles_path_item, "#{tempLibFilePath}/_Headers"
243
+ end
244
+ }
245
+ elsif "#{spec_model.public_header_files.class}".eql?("Array")
246
+ puts "============ array 类型"
247
+ puts "============ "+"#{spec_model.public_header_files}"
248
+ spec_model.public_header_files.each { |public_header_file_item|
249
+ headerFiles_path_arr = Dir.glob(public_header_file_item)
250
+ puts "==== "+"#{headerFiles_path_arr}"
251
+ headerFiles_path_arr.each { |headerFiles_path_item|
252
+ puts "==== "+"{#headerFiles_path_item}"
253
+ puts File.extname(headerFiles_path_item)
254
+ if File.extname(headerFiles_path_item).eql?(".h")
255
+ FileUtils.cp_r headerFiles_path_item, "#{tempLibFilePath}/_Headers"
256
+ end
257
+ }
258
+ }
259
+ end
260
+ else
261
+ puts "=========== 没有指定 public header file"
262
+ unless spec_model.source_files.nil?
263
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Headers"
264
+ if "#{spec_model.source_files.class}".eql?("String")
265
+ headers_arr = Dir.glob(spec_model.source_files)
266
+ headers_arr.each { |header_path_item|
267
+ if File.extname(header_path_item).eql?(".h")
268
+ FileUtils.cp_r header_path_item, "#{tempLibFilePath}/_Headers"
269
+ end
270
+ }
271
+ elsif "#{spec_model.source_files.class}".eql?("Array")
272
+ spec_model.source_files.each { |source_file_item|
273
+ header_path_arr = Dir.glob(source_file_item)
274
+ header_path_arr.each { |header_path_item|
275
+ if File.extname(header_path_item).eql?(".h")
276
+ FileUtils.cp_r header_path_item, "#{tempLibFilePath}/_Headers"
277
+ end
278
+ }
279
+ }
280
+ end
281
+ end
282
+ end
283
+
284
+
285
+ # 查找 vendored 文件,并拷贝到 tempLibFilePath/_Vendored_frameworks 和 tempLibFilePath/_Verdored_libraries 目录下
286
+ unless spec_model.vendored_frameworks.nil?
287
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Vendored_frameworks"
288
+ if "#{spec_model.vendored_frameworks.class}".eql?("String")
289
+ vendored_f_path_arr = Dir.glob(spec_model.vendored_frameworks)
290
+ vendored_f_path_arr.each { |vendored_f_path_item|
291
+ if File.extname(vendored_f_path_item).eql?(".framework")
292
+ FileUtils.cp_r vendored_f_path_item, "#{tempLibFilePath}/_Vendored_frameworks"
293
+ end
294
+ }
295
+ elsif "#{spec_model.vendored_frameworks.class}".eql?("Array")
296
+ spec_model.vendored_frameworks.each { |vendored_framework_item|
297
+ vendored_f_path_arr = Dir.glob(vendored_framework_item)
298
+ vendored_f_path_arr.each { |vendored_f_path_item|
299
+ if File.extname(vendored_f_path_item).eql?(".framework")
300
+ FileUtils.cp_r vendored_f_path_item, "#{tempLibFilePath}/_Vendored_frameworks"
301
+ end
302
+ }
303
+ }
304
+ end
305
+ end
306
+ unless spec_model.vendored_libraries.nil?
307
+ FileUtils.mkdir_p "#{tempLibFilePath}/_Verdored_libraries"
308
+ if "#{spec_model.vendored_libraries.class}".eql?("String")
309
+ vendored_l_path_arr = Dir.glob(spec_model.vendored_libraries)
310
+ vendored_l_path_arr.each { |vendored_l_path_item|
311
+ if File.directory?(vendored_l_path_item)
312
+ next
313
+ end
314
+ FileUtils.cp_r vendored_l_path_item, "#{tempLibFilePath}/_Verdored_libraries"
315
+ }
316
+ elsif "#{spec_model.vendored_libraries.class}".eql?("Array")
317
+ spec_model.vendored_libraries.each { |vendored_library_item|
318
+ vendored_l_path_arr = Dir.glob(vendored_library_item)
319
+ vendored_l_path_arr.each { |vendored_l_path_item|
320
+ if File.directory?(vendored_l_path_item)
321
+ next
322
+ end
323
+ FileUtils.cp_r vendored_l_path_item, "#{tempLibFilePath}/_Verdored_libraries"
324
+ }
325
+ }
326
+ end
327
+ end
328
+
329
+
330
+ puts "========= 更改当前进程工作路径到 ./temp 下,执行压缩命令"
331
+ Dir.chdir("./#{libFileFolderName}/temp") do
332
+ zip_command = "zip -r ./#{POD_NAME}_#{TAG_VERSION}.zip ./#{POD_NAME}_#{TAG_VERSION}"
333
+ output = system zip_command
334
+ unless output == true
335
+ raise "!!!!!!zip 压缩失败 ❌"
336
+ end
337
+ puts "========= 压缩完成!"
338
+ end
339
+ puts "="
340
+ puts "="
341
+ puts "======== 恢复到原始工作路径 ./"
342
+
343
+
344
+ puts "======== # 上传 zip 到 ftp 服务器 ./"
345
+ zipFile = "./#{libFileFolderName}/temp/#{POD_NAME}_#{TAG_VERSION}.zip"
346
+ unless File.exist?("#{zipFile}")
347
+ puts "不存在压缩文件,退出。"
348
+ raise "!!!! 不存在压缩文件: #{zipFile} ❌"
349
+ end
350
+ # ftp 服务器路径
351
+ scp_folder_path = "/opt/Lefit_iOS_Components/Lefit_iOS_libs/#{POD_NAME}"
352
+ scp_zip_file = "#{scp_folder_path}/#{POD_NAME}_#{TAG_VERSION}.zip"
353
+ # 创建远程目录
354
+ ssh_command = "ssh root@172.16.150.90 mkdir -p #{scp_folder_path}"
355
+ system ssh_command
356
+ # 拷贝文件
357
+ scp_command = "scp #{zipFile} root@172.16.150.90:#{scp_zip_file}"
358
+ output = system scp_command
359
+ unless output == true
360
+ raise "!!!! error 拷贝 zip 文件到远程服务器失败 ❌"
361
+ end
362
+ end
363
+
364
+
365
+
366
+
367
+ # 处理 podspec 文件,
368
+ # 判断是否是 sunspec 行
369
+ def isSubspecInLine(line)
370
+ if line =~ /^\s*(s.subspec)/
371
+ return true
372
+ end
373
+ return false
374
+ end
375
+
376
+
377
+ # 判断是否是空白行/空行/注释行,关键函数
378
+ def isLineEmptyOrBlankOrAnnotate(line)
379
+ if line =~ /^\s*(#|$)/
380
+ return true
381
+ end
382
+ return false
383
+ end
384
+
385
+ def is_the_begin_podspec_line(line)
386
+ if line =~ /^\s*(Pod::Spec*)/
387
+ return true
388
+ end
389
+ return false
390
+ end
391
+
392
+ #判断一行 line 是否是某个关键字的结尾,关键函数
393
+ # 编写 podspec 文件需要遵守的规则:
394
+ # 1. 能写在一行,就写在一行
395
+ # 2. 不能写在一行的,换行都要添加逗号,每行都要添加逗号
396
+ def is_podspec_keyword_end(currentLine)
397
+ #以逗号结尾,肯定没有结束
398
+ if currentLine =~ /,\s*(#|$)/
399
+ return false
400
+ end
401
+ # #以 ] 或者 } 结尾,并且前后没有任何内容,肯定结束
402
+ if currentLine =~ /^\s*(\]|\})\s*(#|$)/
403
+ return true
404
+ end
405
+ # 一行包含 = [ ] 肯定结束
406
+ if currentLine =~ /.*=\s.*\[*\]\s*(#|$)/
407
+ return true
408
+ end
409
+ # 一行包含 = { } 肯定结束
410
+ if currentLine =~ /.*=\s.*\{*\}\s*(#|$)/
411
+ return true
412
+ end
413
+ # 一行只有 = { 或者 = [ 肯定没结束
414
+ if currentLine =~ /.*=\s.*(\{|\[)\s*(#|$)/
415
+ return false
416
+ end
417
+
418
+ return true
419
+ end
420
+
421
+
422
+ # 根据 LCLoginUI.podspec 模版进行自动写入文件
423
+ # 生成新的 .podspec 文件,并 push 到repo;成功后,删除生成的文件,并恢复之前的 .podspec 文件
424
+ def create_temp_podspec_and_push_repo(repoObj)
425
+ isTheBeginPodspecLine = false
426
+ isSourceFileStart = false
427
+ isSourceFileEnd = false
428
+ isResourcesStart = false
429
+ isResourcesEnd = false
430
+ isResourceBundlesStart = false
431
+ isResourceBundlesEnd = false
432
+ isVendoredLibrariesStart = false
433
+ isVendoredLibrariesEnd = false
434
+ isVendoredFrameworksStart = false
435
+ isVendoredFrameworksEnd = false
436
+ isPreservepathsStart = false
437
+ isPreservepathsEnd = false
438
+ isPublicHeaderFilesStart = false
439
+ isPublicHeaderFilesEnd = false
440
+
441
+ # 标记是否插入了 preserve_path 代码
442
+ isInsertPreservePath = false
443
+ # 标记是否插入了 vendored_library 代码
444
+ isInsertVendoredLibraries = false;
445
+
446
+ begin
447
+ #重命名
448
+ File::rename( "#{repoObj.name}.podspec", "#{repoObj.name}_temp.podspec" )
449
+ `touch #{repoObj.name}.podspec`
450
+ newfile = File.open("./#{repoObj.name}.podspec", "r+")
451
+ tempfile = File.open("#{repoObj.name}_temp.podspec", "r+")
452
+ tempfile.each do |line|
453
+ flag1 = isLineEmptyOrBlankOrAnnotate line
454
+ if flag1 == true
455
+ newfile.puts(line)
456
+ next
457
+ end
458
+ if isTheBeginPodspecLine == false
459
+ flag2 = is_the_begin_podspec_line line #判断 podspec 文件的第一句
460
+ if flag2 == true
461
+ isTheBeginPodspecLine = true
462
+ newfile.puts(line)
463
+ next
464
+ end
465
+ end
466
+
467
+ if line =~ /^\s*(s\.source)\s*=/
468
+ newfile.puts(" #=========================================== 脚本自动处理这一段内容 ==========================================")
469
+ newfile.puts(" # 存在这部分代码,说明这个库,是需要打包静态库的,这是已知条件")
470
+ newfile.puts(" # 如果正在打静态库,或者指定了源码,则开启源码模式")
471
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
472
+ newfile.puts(" puts \"================ Notice: #{repoObj.name} is source now\"")
473
+ newfile.puts(" "+line)
474
+ newfile.puts(" "+"s.prepare_command = \"ruby -r \\\'lkdownloadlib\\\' -e \\\'Lkdownloadlib.download(\\\"#{repoObj.name}\\\", \\\"#{repoObj.version}\\\")\\\'\"")
475
+ newfile.puts(" else # 开启静态库模式")
476
+ newfile.puts(" puts \"================ Notice: #{repoObj.name} is lib now\"")
477
+ newfile.puts(" s.source = { :http => \"http://ios-component.leoao-inc.com/Lefit_iOS_libs/#{repoObj.name}/#{repoObj.name}_#{repoObj.version}.zip\"}")
478
+ newfile.puts(" # pod 会根据 s.source 下载静态库 zip 文件,但是为了避免切换静态库时 pod cache clean,这里还得同时下载对应的源码")
479
+ newfile.puts(" # 没有下载过源码,才进行下载")
480
+ newfile.puts(" "+"s.prepare_command = \"ruby -r \\\'lkdownloadsource\\\' -e \\\'Lkdownloadsource.download(\\\"#{repoObj.name}\\\", \\\"#{repoObj.version}\\\", \\\"#{repoObj.source['git']}\\\")\\\'\"")
481
+ newfile.puts(" end")
482
+ next
483
+ end
484
+ #================================
485
+ if line =~ /^\s*(s\.source_files)\s*=/
486
+ isSourceFileStart = true
487
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
488
+ newfile.puts(" "+line)
489
+ isSourceFileEnd = is_podspec_keyword_end line
490
+ if isSourceFileEnd == true
491
+ newfile.puts(" else")
492
+ newfile.puts(" s.source_files = \'#{repoObj.name}_#{repoObj.version}/_Headers/*\'")
493
+ newfile.puts(" end")
494
+ end
495
+ next
496
+ end
497
+ if isSourceFileStart && isSourceFileEnd == false
498
+ isSourceFileEnd = is_podspec_keyword_end line
499
+ if isSourceFileEnd == true # 结束
500
+ newfile.puts(" "+line)
501
+ newfile.puts(" else")
502
+ newfile.puts(" s.source_files = \'#{repoObj.name}_#{repoObj.version}/_Headers/*\'")
503
+ newfile.puts(" end")
504
+ else
505
+ newfile.puts(line) #未结束
506
+ end
507
+ next
508
+ end
509
+
510
+ #================================
511
+ if line =~ /^\s*(s\.resource.)\s*=/
512
+ isResourcesStart = true
513
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
514
+ newfile.puts(" "+line)
515
+ isResourcesEnd = is_podspec_keyword_end line
516
+ if isResourcesEnd == true
517
+ newfile.puts(" else")
518
+ newfile.puts(" s.resources = \"#{repoObj.name}_#{repoObj.version}/_Resources/*\"")
519
+ newfile.puts(" end")
520
+ end
521
+ next
522
+ end
523
+ if isResourcesStart && isResourcesEnd == false
524
+ isResourcesEnd = is_podspec_keyword_end line
525
+ if isResourcesEnd == true # 结束
526
+ newfile.puts(" "+line)
527
+ newfile.puts(" else")
528
+ newfile.puts(" s.resources = \"#{repoObj.name}_#{repoObj.version}/_Resources/*\"")
529
+ newfile.puts(" end")
530
+ else
531
+ newfile.puts(line) #未结束
532
+ end
533
+ next
534
+ end
535
+
536
+ #================================
537
+ if line =~ /^\s*(s\.resource_bundle.)\s*=/
538
+ isResourceBundlesStart = true
539
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
540
+ newfile.puts(line)
541
+ isResourceBundlesEnd = is_podspec_keyword_end line
542
+ if isResourceBundlesEnd == true
543
+ newfile.puts(" end")
544
+ end
545
+ next
546
+ end
547
+ if isResourceBundlesStart && isResourceBundlesEnd == false
548
+ isResourceBundlesEnd = is_podspec_keyword_end line
549
+ if isResourceBundlesEnd == true # 结束
550
+ newfile.puts(line)
551
+ newfile.puts(" end")
552
+ else
553
+ newfile.puts(line) #未结束
554
+ end
555
+ next
556
+ end
557
+
558
+ #================================
559
+ if line =~ /^\s*(s\.vendored_framework.)\s*=/
560
+ isVendoredFrameworksStart = true
561
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
562
+ newfile.puts(" "+line)
563
+ isVendoredFrameworksEnd = is_podspec_keyword_end line
564
+ if isVendoredFrameworksEnd == true
565
+ newfile.puts(" else")
566
+ newfile.puts(" s.vendored_frameworks = \"#{repoObj.name}_#{repoObj.version}/_Vendored_frameworks/*.framework\"")
567
+ newfile.puts(" end")
568
+ end
569
+ next
570
+ end
571
+ if isVendoredFrameworksStart && isVendoredFrameworksEnd == false
572
+ isVendoredFrameworksEnd = is_podspec_keyword_end line
573
+ if isVendoredFrameworksEnd == true # 结束
574
+ newfile.puts(line)
575
+ newfile.puts(" else")
576
+ newfile.puts(" s.vendored_frameworks = \"#{repoObj.name}_#{repoObj.version}/_Vendored_frameworks/*.framework\"")
577
+ newfile.puts(" end")
578
+ else
579
+ newfile.puts(line) #未结束
580
+ end
581
+ next
582
+ end
583
+
584
+ #================================
585
+ if line =~ /^\s*(s\.vendored_librar.*)\s*=/
586
+ isVendoredLibrariesStart = true
587
+ isVendoredLibrariesEnd = is_podspec_keyword_end line
588
+ next
589
+ end
590
+ if isVendoredLibrariesStart && isVendoredLibrariesEnd == false
591
+ isVendoredLibrariesEnd = is_podspec_keyword_end line
592
+ next
593
+ end
594
+
595
+ if isInsertVendoredLibraries == false && isSourceFileEnd == true
596
+ puts ">>>>>>>>>>>>>>>>>>>>>> 正在插入调试代码"
597
+ newfile.puts(" #")
598
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
599
+ if repoObj.vendored_libraries
600
+ newfile.puts(" s.vendored_libraries = #{repoObj.vendored_libraries}")
601
+ end
602
+ newfile.puts(" ")
603
+ newfile.puts(" else")
604
+ if repoObj.vendored_libraries
605
+ temparr = repoObj.vendored_libraries + ["#{repoObj.name}_#{repoObj.version}/_Verdored_libraries/*\.a","#{repoObj.name}_#{repoObj.version}/*\.a"]
606
+ else
607
+ temparr = ["#{repoObj.name}_#{repoObj.version}/_Verdored_libraries/*\.a","#{repoObj.name}_#{repoObj.version}/*\.a"]
608
+ end
609
+ newfile.puts(" s.vendored_libraries = #{temparr}")
610
+ newfile.puts(" end")
611
+ newfile.puts(" #")
612
+ isInsertVendoredLibraries = true
613
+ end
614
+
615
+ #================================
616
+ # preserve_path是必须要有的,所以忽略原有的 preserve_path ,自定义添加它
617
+ if line =~ /^\s*(s\.preserve_path.)\s*=/
618
+ isPreservepathsStart = true
619
+ isPreservepathsEnd = is_podspec_keyword_end line
620
+ if isPreservepathsEnd == true
621
+ #
622
+ end
623
+ next
624
+ end
625
+ if isPreservepathsStart && isPreservepathsEnd == false
626
+ isPreservepathsEnd = is_podspec_keyword_end line
627
+ if isPreservepathsEnd == true # 结束
628
+ #
629
+ end
630
+ next
631
+ end
632
+ if isInsertPreservePath == false && isSourceFileEnd == true
633
+ newfile.puts(" #")
634
+ #保留源码和静态库文件夹不被删除
635
+ if repoObj.preserve_paths
636
+ arr = repoObj.preserve_paths + ["#{repoObj.name}/*","#{repoObj.name}_#{repoObj.version}/*","Gemfile"]
637
+ else
638
+ arr = ["#{repoObj.name}/*","#{repoObj.name}_#{repoObj.version}/*","Gemfile"]
639
+ end
640
+ newfile.puts(" s.preserve_paths = #{arr}")
641
+ newfile.puts(" #")
642
+ isInsertPreservePath = true
643
+ end
644
+
645
+ # public_header_file , 只有源码指定
646
+ if line =~ /^\s*(s\.public_header_file.)\s*=/
647
+ isPublicHeaderFilesStart = true
648
+ newfile.puts(" if ENV[\"#{repoObj.name}package\"] == \"1\" || ENV[\"#{repoObj.name}source\"] == \"1\" || ENV[\"source\"] == \"1\"")
649
+ newfile.puts(" "+line)
650
+ isPublicHeaderFilesEnd = is_podspec_keyword_end line
651
+ if isPublicHeaderFilesEnd == true
652
+ newfile.puts(" end")
653
+ end
654
+ next
655
+ end
656
+ if isPublicHeaderFilesStart && isPublicHeaderFilesEnd == false
657
+ isPublicHeaderFilesEnd = is_podspec_keyword_end line
658
+ if isPublicHeaderFilesEnd == true # 结束
659
+ newfile.puts(" end")
660
+ end
661
+ next
662
+ end
663
+
664
+
665
+
666
+
667
+
668
+ # 其他不关心的行,直接写入到新的文件
669
+ newfile.puts(line)
670
+ next
671
+ end
672
+
673
+ tempfile.close
674
+ newfile.close
675
+
676
+ #pod repo push,推送本地 podspec 文件到 REPO 仓库
677
+ pod_repo_push true
678
+
679
+ rescue => exception # 处理错误
680
+ #处理异常
681
+ # 这里加上 raise 程序才会终止,不会继续执行
682
+ puts exception.message
683
+ puts exception.backtrace.inspect
684
+ tempfile.close
685
+ newfile.close
686
+ raise "!!!! error,重新生成 podspec 文件时发生异常!❌ "
687
+
688
+ ensure
689
+ # 在这里恢复之前的文件状态
690
+ deletePodspecCommand = "rm -rf #{PODSPEC_FILE}"
691
+ system deletePodspecCommand
692
+ File::rename( "#{POD_NAME}_temp.podspec", "#{PODSPEC_FILE}")
693
+ end
694
+ end
695
+
696
+
697
+
698
+
699
+ #
700
+ #
701
+ git_make_tag
702
+ if IS_NEED_PACKAGE_LIB == '0'
703
+ puts "========== 不需要打包静态库"
704
+ begin
705
+ #是否忽略编译:因为需要编译,所以传入 false
706
+ pod_repo_push false
707
+ rescue => exception
708
+ delete_tag
709
+ puts exception.message
710
+ puts exception.backtrace.inspect
711
+ raise "++++++++++ 程序终止"
712
+ end
713
+ else
714
+ begin
715
+ puts "========== 需要打包静态库"
716
+
717
+ podspecObj = create_podspec_model "#{PODSPEC_FILE}"
718
+ if podspecObj.subspecs
719
+ raise "!!!!! error:暂时不支持带有 subspec 的pod仓库打包静态库 ❌ ,请修改打包脚本传参!"
720
+ end
721
+
722
+ package_lib podspecObj
723
+
724
+ # 打包静态库并成功上传后,需要进行 pod repo push,此时验证的是当前路径下的 podspec 文件,但是不需要下载刚才打好的静态库,所以需要设置一个正在打包的标志位
725
+ # 以此为依据判断不需要额外下载操作,使用源码模式校验 podspec 文件
726
+ # 设置正在打包组件以及静态库标志位,用于全局判断该 pod 库正在打包
727
+ ENV["#{POD_NAME}package"] = "1"
728
+ create_temp_podspec_and_push_repo podspecObj
729
+ puts "============= 打包成功。✅ ✅ ✅ ✅ ✅ ✅ "
730
+ rescue => exception # 处理错误
731
+ delete_tag
732
+ puts exception.message
733
+ puts exception.backtrace.inspect
734
+ raise "++++++++++ 程序终止"
735
+ ensure # 确保会执行
736
+ puts "============= 清除 package 标志位"
737
+ #打包结束,设置 package 标志
738
+ ENV["#{POD_NAME}package"] = "0"
739
+
740
+ end
741
+
742
+ end
@@ -0,0 +1,92 @@
1
+ require 'JSON'
2
+
3
+ class PodspecModel
4
+ #
5
+ attr_accessor :name
6
+ attr_accessor :version
7
+ attr_accessor :homepage
8
+ # "source": {
9
+ # "git": "git@gitlab.leoao-inc.com:Lefit_LFE_Architecture_Organization/Lefit_Platform_iOS/LPLoginEngine.git",
10
+ # "tag": "2.3.1"
11
+ # }
12
+ attr_accessor :source
13
+
14
+ #
15
+ attr_accessor :authors
16
+
17
+ # 以下几个是数组
18
+ attr_accessor :frameworks
19
+ attr_accessor :libraries
20
+ attr_accessor :vendored_frameworks
21
+
22
+ # "vendored_libraries": "fff.a"
23
+ attr_accessor :vendored_libraries
24
+
25
+ # "source_files": [
26
+ # "LKLoginEngine/LKLoginEngine/**/*.h",
27
+ # "LKLoginEngine/LKLoginEngine/**/*.m"
28
+ # ]
29
+ attr_accessor :source_files
30
+
31
+ # "resources": [
32
+ # "LKLoginEngine/Resource/*.pnd"
33
+ # ]
34
+ attr_accessor :resources
35
+
36
+ # "resource_bundles": {
37
+ # "LKLoginEngine": [
38
+ # "LKLoginEngine/Assets/*.png",
39
+ # "LKLoginEngine/Assets/Audio.wav"
40
+ # ]
41
+ # }
42
+ attr_accessor :resource_bundles
43
+
44
+ # "public_header_files": "LKLoginEngine/LKLoginEngine/**/*.h"
45
+ attr_accessor :public_header_files
46
+
47
+ attr_accessor :ios
48
+ attr_accessor :osx
49
+
50
+ attr_accessor :dependencies
51
+
52
+ # "preserve_paths": [
53
+ # "Gemfile",
54
+ # "fastlane/Pluginfile",
55
+ # "LKLoginEngine/LKLoginEngine",
56
+ # "LKLoginEngine/LKLoginEngine.framework",
57
+ # "LKLoginEngine/Resources",
58
+ # "LKLoginEngine/Vendor/**/*.{a,framework,bundle}"
59
+ # ]
60
+ attr_accessor :preserve_paths
61
+
62
+ attr_accessor :default_subspecs
63
+ attr_accessor :subspecs
64
+
65
+ def initialize
66
+
67
+ end
68
+
69
+
70
+ def initialize (json)
71
+ obj = JSON.parse(json)
72
+ self.name = obj["name"]
73
+ self.version = obj["version"]
74
+ self.homepage = obj["homepage"]
75
+ self.source = obj["source"]
76
+ self.authors = obj["authors"]
77
+ self.frameworks = obj["frameworks"]
78
+ self.libraries = obj["libraries"]
79
+ self.vendored_frameworks = obj["vendored_frameworks"]
80
+ self.vendored_libraries = obj["vendored_libraries"]
81
+ self.source_files = obj["source_files"]
82
+ self.resources = obj["resources"]
83
+ self.resource_bundles = obj["resource_bundles"]
84
+ self.public_header_files = obj["public_header_files"]
85
+ self.ios = obj["ios"]
86
+ self.osx = obj["osx"]
87
+ self.dependencies = obj["dependencies"]
88
+ self.preserve_paths = obj["preserve_paths"]
89
+ self.default_subspecs = obj["default_subspecs"]
90
+ self.subspecs = obj["subspecs"]
91
+ end
92
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lkpackage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - yangjie
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Write a longer description or delete this line.
14
+ email:
15
+ - yangjie2107@qq.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - LICENSE.txt
22
+ - README.md
23
+ - Rakefile
24
+ - bin/console
25
+ - bin/setup
26
+ - lib/lkpackage.rb
27
+ - lib/lkpackage/version.rb
28
+ - lib/package.rb
29
+ - lib/podspec_model.rb
30
+ homepage: http://gitlab.leoao-inc.com/yangjie/lkpackage
31
+ licenses:
32
+ - MIT
33
+ metadata:
34
+ allowed_push_host: https://rubygems.org
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.4.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.0.3
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Write a short summary, because RubyGems requires one.
54
+ test_files: []