pod-pipeline 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: 675d0ddaa029cc0b8945f68529698c99774c5345b60da818ea827d18134d5972
4
+ data.tar.gz: 0a9afea692777250dceaa4e2f13facb714a91641699c662f3023568368d347be
5
+ SHA512:
6
+ metadata.gz: df852956c2047496a99e5c5d081ce42eaa3fc83b0492a5199a6fd6f75c1cd393273a3987a2a194860deba484ccdc9d34a1acf9f00dbf1bcf27b4716835ad463f
7
+ data.tar.gz: 4bdb21e4ca1eb50a57c2b2ddfd7941d2f16966699d3ab6b152fdee910a431df47d91430b33f8a8b905c5f0f953f12aa92fc6320e14975d56ba0941619899e429
data/bin/ppl ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pod-pipeline'
3
+
4
+ if Encoding.default_external != Encoding::UTF_8
5
+
6
+ STDERR.puts <<-DOC
7
+ \e[33mWARNING: Pod-Pipeline requires your terminal to be using UTF-8 encoding.
8
+ Consider adding the following to ~/.profile:
9
+
10
+ export LANG=en_US.UTF-8
11
+ \e[0m
12
+ DOC
13
+
14
+ end
15
+
16
+ PPL::Command.run(ARGV)
@@ -0,0 +1,3 @@
1
+ module PPL
2
+ autoload :Command, 'pod-pipeline/command'
3
+ end
@@ -0,0 +1,119 @@
1
+ require 'claide'
2
+
3
+ module PPL
4
+ class Command < CLAide::Command
5
+ require 'pod-pipeline/command/scan'
6
+ require 'pod-pipeline/command/build'
7
+ require 'pod-pipeline/command/update'
8
+ require 'pod-pipeline/command/publish'
9
+
10
+ self.abstract_command = true
11
+ self.command = 'ppl'
12
+ self.description = 'Pod-Pipeline 是 CocoaPods 的流水线工具.'
13
+
14
+ def self.options
15
+ [
16
+ ['--help', '展示改命令的介绍面板'],
17
+ ]
18
+ end
19
+
20
+ def self.options_extension
21
+ options = Array.new
22
+ options_extension_hash.each { |_key, _options_extension|
23
+ _options_extension.each { |_option_extension|
24
+ options << [_option_extension.first.gsub(/(--)(.*)/,"\\1#{_key}-\\2"), _option_extension.last]
25
+ }
26
+ }
27
+ options
28
+ end
29
+
30
+ def self.options_extension_hash
31
+ Hash[
32
+
33
+ ]
34
+ end
35
+
36
+ def self.run(argv)
37
+ ensure_not_root_or_allowed! argv
38
+ verify_minimum_git_version!
39
+ verify_xcode_license_approved!
40
+
41
+ super(argv)
42
+ end
43
+
44
+ #
45
+ # 确保root用户
46
+ #
47
+ # @return [void]
48
+ #
49
+ def self.ensure_not_root_or_allowed!(argv, uid = Process.uid, is_windows = Gem.win_platform?)
50
+ root_allowed = argv.include?('--allow-root') || !ENV['COCOAPODS_ALLOW_ROOT'].nil?
51
+ help! 'You cannot run Pod-Pipeline as root.' unless root_allowed || uid != 0 || is_windows
52
+ end
53
+
54
+ # 读取Git版本号,返回一个新的 {Gem::Version} 实例
55
+ #
56
+ # @return [Gem::Version]
57
+ #
58
+ def self.git_version
59
+ raw_version = `git version`
60
+ unless match = raw_version.scan(/\d+\.\d+\.\d+/).first
61
+ raise "Failed to extract git version from `git --version` (#{raw_version.inspect})"
62
+ end
63
+ Gem::Version.new(match)
64
+ end
65
+
66
+ # 检查Git版本号是否低于 1.8.5
67
+ #
68
+ # @raise Git版本号低于 1.8.5
69
+ #
70
+ # @return [void]
71
+ #
72
+ def self.verify_minimum_git_version!
73
+ if git_version < Gem::Version.new('1.8.5')
74
+ raise 'You need at least git version 1.8.5 to use Pod-Pipeline'
75
+ end
76
+ end
77
+
78
+ #
79
+ # 检查xcode许可是否被批准
80
+ #
81
+ # @return [void]
82
+ #
83
+ def self.verify_xcode_license_approved!
84
+ if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success?
85
+ raise 'You have not agreed to the Xcode license, which ' \
86
+ 'you must do to use CocoaPods. Agree to the license by running: ' \
87
+ '`xcodebuild -license`.'
88
+ end
89
+ end
90
+
91
+ def initialize(argv)
92
+ @argv_extension = Hash.new
93
+ self.class.options_extension_hash.each_key { |key|
94
+ @argv_extension[key] = Array.new
95
+ self.class.options.each do |option|
96
+ name = option.first
97
+ if name.include?(key)
98
+ is_option = name.include? '='
99
+ if is_option
100
+ option = name.gsub(/(--)(.*)(=.*)/,"\\2")
101
+ value = argv.option(option, '')
102
+ @argv_extension[key] << name.gsub(/(--.*=)(.*)/,"\\1#{value}").gsub("#{key}-",'') unless value.empty?
103
+ else
104
+ flag = name.gsub(/(--)(.*)/,'\\2')
105
+ value = argv.flag?(flag)
106
+ @argv_extension[key] << name.gsub("#{key}-",'') if value
107
+ end
108
+ end
109
+ end
110
+ }
111
+
112
+ super
113
+ end
114
+
115
+ def argv_extension
116
+ @argv_extension
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,184 @@
1
+ require 'fileutils'
2
+
3
+ require 'pod-pipeline/util/scanner'
4
+ require 'pod-pipeline/util/xcodebuild'
5
+ require 'pod-pipeline/util/binary'
6
+ require 'pod-pipeline/util/bundle'
7
+
8
+ require 'pod-pipeline/extension/dir-ppl'
9
+
10
+ module PPL
11
+ class Command
12
+ class Build < Command
13
+ self.summary = '项目构建'
14
+ self.description = <<-DESC
15
+ 构建项目代码、资源文件和依赖库,生成Framework包和Bundle包
16
+ DESC
17
+ self.arguments = [
18
+ CLAide::Argument.new('项目根目录(默认使用当前目录)', false),
19
+ ]
20
+ def self.options
21
+ [
22
+ ['--output=./', '项目构建的输出目录。(默认使用项目根目录)'],
23
+ ['--configuration=Release', '项目构建的环境。(默认为Release)'],
24
+ ['--arch=arm64,armv7,x86_64', '项目构建的架构。(默认为 arm64,armv7,x86_64)'],
25
+ ['--combine=local,pod', '项目构建后合并依赖库的二进制文件,local为本地依赖库,pod为CocoaPods依赖库。(默认为 local)'],
26
+ ['--bundle-merge=merge', '是否合并所有资源包,参数为合并后的资源包名。(默认为 不合并)'],
27
+ ].concat(super)
28
+ end
29
+
30
+ def initialize(argv)
31
+ @path = argv.arguments!
32
+ @output = argv.option('output', '').split(',').first
33
+ @configuration = argv.option('configuration', '').split(',').first
34
+ @archs = argv.option('arch', '').split(',')
35
+ @combines = argv.option('combine', '').split(',')
36
+ @bundle_merge = argv.option('bundle-merge', '').split(',').first
37
+
38
+ @projectPath = @path.count.zero? ? Pathname.pwd.to_s : @path.first
39
+ @output = @output ? @output : @projectPath
40
+
41
+ super
42
+ end
43
+
44
+ def run
45
+ PPL::Scanner.new(@projectPath, ["pod", "workspace"]).run
46
+
47
+ @podspec = PPL::Scanner.podspec
48
+ @workspace = PPL::Scanner.workspace
49
+ puts "Pod: #{@podspec}"
50
+ puts "Workspace: #{@workspace.path}"
51
+
52
+ #初始化 构建目录
53
+ reset_dir
54
+
55
+ #构建
56
+ puts "\n[构建 #{@configuration} 环境的 #{@archs.join(", ")} 架构项目]"
57
+ @archs.each do |arch|
58
+ XCodebuild.build(@workspace.path, @podspec.name, arch, @configuration, @build_path)
59
+ end
60
+
61
+ #添加头文件
62
+ puts "\n[添加Framework头文件]"
63
+ add_headers
64
+
65
+ #合并二进制文件
66
+ puts "\n[合并 #{@combines.join(", ")} 的二进制文件]"
67
+ combine_binarys(@combines.include?('local'), @combines.include?('pod'))
68
+
69
+ #拷贝资源包
70
+ puts "\n[拷贝 #{@combines.join(", ")} 的资源包 到输出目录]"
71
+ copy_bundles(@combines.include?('local'), @combines.include?('pod'))
72
+
73
+ #合并资源包
74
+ if @bundle_merge
75
+ puts "\n[合并的资源包内容 到 #{@bundle_merge}.bundle]"
76
+ merge_bundles
77
+ end
78
+
79
+ #拷贝构建内容到Pod目录
80
+ puts "\n[拷贝内容到Pod目录]"
81
+ copy_pod
82
+ end
83
+
84
+ def reset_dir
85
+ #初始化 构建目录
86
+ @build_path = "#{@output}/#{@podspec.name}-#{@podspec.version}"
87
+ Dir.reset(@build_path)
88
+ #初始化 Framework目录
89
+ @framework_path = "#{@build_path}/#{@podspec.name}.framework"
90
+ Dir.reset(@framework_path)
91
+ @framework_headers_path = "#{@framework_path}/Headers"
92
+ Dir.reset(@framework_headers_path)
93
+ #初始化 SDK目录
94
+ @sdk_path = "#{@output}/#{@podspec.name}/#{@podspec.name}SDK"
95
+ Dir.reset(@sdk_path)
96
+ end
97
+
98
+ def add_headers
99
+ header_stands = "#{@output}/Example/Pods/Headers/Public/#{@podspec.name}/*.h"
100
+ Dir[header_stands].each do |header_stand|
101
+ if File.ftype(header_stand).eql? 'link'
102
+ puts File.basename(header_stand)
103
+
104
+ header = "#{File.dirname(header_stand)}/#{File.readlink(header_stand)}"
105
+ FileUtils.cp(header, @framework_headers_path)
106
+ end
107
+ end
108
+ end
109
+
110
+ def combine_binarys(local_dependency, pod_dependency)
111
+ binary = "#{@framework_path}/#{@podspec.name}"
112
+ #添加 构建生成的二进制文件
113
+ inputs = ["#{@build_path}/**/lib#{@podspec.name}.a"]
114
+ if local_dependency
115
+ #添加 本地依赖的二进制文件
116
+ inputs << "#{@output}/#{@podspec.name}/Libraries/**/*.a"
117
+ inputs << "#{@output}/#{@podspec.name}/Frameworks/**/*.framework/*"
118
+ end
119
+ if pod_dependency
120
+ #添加 Pod依赖库构建生成的二进制文件
121
+ inputs << "#{@build_path}/**/lib*.a";
122
+ #添加 Pod依赖库预先构建的二进制文件
123
+ inputs << "#{@output}/Example/Pods/**/*SDK/*.framework/*"
124
+ #添加 Pod依赖库本地依赖的二进制文件
125
+ inputs << "#{@output}/Example/Pods/**/Libraries/**/*.a"
126
+ inputs << "#{@output}/Example/Pods/**/Frameworks/**/*.framework/*"
127
+ end
128
+
129
+ Binary.combine(binary, inputs)
130
+ Binary.thin(binary, @archs)
131
+ end
132
+
133
+ def copy_bundles(local_dependency, pod_dependency)
134
+ #添加 构建生成的资源包
135
+ inputs = ["#{@output}/**/#{@podspec.name}/*.bundle"]
136
+ if local_dependency
137
+ #添加 本地依赖的资源包
138
+ inputs << "#{@output}/#{@podspec.name}/Libraries/**/*.bundle"
139
+ inputs << "#{@output}/#{@podspec.name}/Frameworks/**/*.bundle"
140
+ end
141
+ if pod_dependency
142
+ #添加 Pod依赖库构建生成的资源包
143
+ inputs << "#{@build_path}/**/*.bundle"
144
+ #添加 Pod依赖库预先构建的资源包
145
+ inputs << "#{@output}/Example/Pods/**/*SDK/*.bundle"
146
+ #添加 Pod依赖库本地依赖的资源包
147
+ inputs << "#{@output}/Example/Pods/**/Libraries/**/*.bundle"
148
+ inputs << "#{@output}/Example/Pods/**/Frameworks/**/*.bundle"
149
+ end
150
+
151
+ Bundle.cp(inputs, @build_path)
152
+ end
153
+
154
+ def merge_bundles
155
+ #初始化资源文件夹
156
+ bundle_path = "#{@build_path}/#{@bundle_merge}"
157
+ Dir.reset(bundle_path)
158
+
159
+ #合并资源文件
160
+ Dir["#{@build_path}/*.bundle/*"].each do |asset|
161
+ `cp -fr "#{asset}" "#{bundle_path}"`
162
+ end
163
+
164
+ #删除bundle
165
+ Dir["#{@build_path}/*.bundle/"].each do |bundle|
166
+ `rm -fr "#{bundle}"`
167
+ end
168
+
169
+ #将资源文件夹命名为 .bundle 格式
170
+ `mv "#{bundle_path}" "#{bundle_path}.bundle"`
171
+ end
172
+
173
+ def copy_pod
174
+ Dir["#{@framework_path}"].each do |framework|
175
+ `cp -fr "#{framework}" "#{@sdk_path}"`
176
+ end
177
+ Dir["#{@build_path}/*.bundle"].each do |bundle|
178
+ `cp -fr "#{bundle}" "#{@sdk_path}"`
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
@@ -0,0 +1,69 @@
1
+ require 'cocoapods'
2
+ require 'cocoapods-core'
3
+
4
+ require 'pod/command/trunk'
5
+
6
+ require 'pod-pipeline/util/scanner'
7
+
8
+ require 'pod-pipeline/extension/version-ppl.rb'
9
+ require 'pod-pipeline/extension/linter-ppl'
10
+ require 'pod-pipeline/extension/validator-ppl'
11
+
12
+ module PPL
13
+ class Command
14
+ class Publish < Command
15
+ self.summary = '项目发布'
16
+ self.description = <<-DESC
17
+ 整合项目发布流程
18
+ DESC
19
+ self.arguments = [
20
+ CLAide::Argument.new('项目根目录(默认使用当前目录)', false),
21
+ ]
22
+ def self.options
23
+ [
24
+ ['--repo=master', 'Pod库所属的repo。(默认使用官方repo:master)'],
25
+ ].concat(super).concat(options_extension)
26
+ end
27
+
28
+ def self.options_extension_hash
29
+ Hash[
30
+ 'build' => PPL::Command::Build.options,
31
+ 'update' => PPL::Command::Update.options,
32
+ 'trunk-push' => Pod::Command::Trunk::Push.options,
33
+ 'repo-push' => Pod::Command::Repo::Push.options
34
+ ]
35
+ end
36
+
37
+ def initialize(argv)
38
+ @path = argv.arguments!
39
+ @repo = argv.option('repo', '').split(',').first
40
+
41
+ @projectPath = @path.count.zero? ? Pathname.pwd.to_s : @path.first
42
+ @is_master = false
43
+ unless @repo
44
+ @repo = 'master'
45
+ @is_master = true
46
+ end
47
+
48
+ super
49
+ end
50
+
51
+ def run
52
+ PPL::Command::Build.run([@projectPath] + argv_extension['build'])
53
+ PPL::Command::Update.run([@projectPath] + argv_extension['update'])
54
+
55
+ PPL::Scanner.new(@projectPath, ['pod']).run
56
+
57
+ podspec_file = PPL::Scanner.linter.file
58
+
59
+ if @is_master
60
+ push_argv = [podspec_file] + argv_extension['trunk-push']
61
+ Pod::Command::Trunk::Push.run(push_argv)
62
+ else
63
+ push_argv = [@repo, podspec_file] + argv_extension['repo-push']
64
+ Pod::Command::Repo::Push.run(push_argv)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,37 @@
1
+ require 'pod-pipeline/util/scanner'
2
+
3
+ module PPL
4
+ class Command
5
+ class Scan < Command
6
+ self.summary = '项目扫描'
7
+ self.description = <<-DESC
8
+ 获取项目的关键参数
9
+ DESC
10
+ self.arguments = [
11
+ CLAide::Argument.new('项目根目录(默认使用当前目录)', false),
12
+ ]
13
+ def self.options
14
+ [
15
+ ['--channel=pod,git,workspace', '扫描内容。(默认扫描所有内容)']
16
+ ].concat(super)
17
+ end
18
+
19
+ def initialize(argv)
20
+ @path = argv.arguments!
21
+ @channels = argv.option('channel', '').split(',')
22
+
23
+ @projectPath = @path.count.zero? ? Pathname.pwd.to_s : @path.first
24
+
25
+ super
26
+ end
27
+
28
+ def run
29
+ PPL::Scanner.new(@projectPath, @channels).run
30
+
31
+ puts "Pod: #{PPL::Scanner.podspec}" if PPL::Scanner.podspec
32
+ puts "Git: remote = #{PPL::Scanner.git.remote}, branch = #{PPL::Scanner.git.branches.current.first}" if PPL::Scanner.git
33
+ puts "Workspace: #{PPL::Scanner.workspace.path}" if PPL::Scanner.workspace
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,91 @@
1
+ require 'cocoapods'
2
+ require 'cocoapods-core'
3
+
4
+ require 'pod/command/trunk'
5
+
6
+ require 'pod-pipeline/util/scanner'
7
+
8
+ require 'pod-pipeline/extension/version-ppl.rb'
9
+ require 'pod-pipeline/extension/linter-ppl'
10
+ require 'pod-pipeline/extension/validator-ppl'
11
+
12
+ module PPL
13
+ class Command
14
+ class Update < Command
15
+ self.summary = '项目扫描'
16
+ self.description = <<-DESC
17
+ 更新项目内容
18
+ DESC
19
+ self.arguments = [
20
+ CLAide::Argument.new('项目根目录(默认使用当前目录)', false),
21
+ ]
22
+ def self.options
23
+ [
24
+ ['--channel=version,git', '更新内容。(默认更新所有内容)'],
25
+ ['--version=x.x.x', '新版本号。(默认使用patch+1)']
26
+ ].concat(super)
27
+ end
28
+
29
+ def initialize(argv)
30
+ @path = argv.arguments!
31
+ @channels = argv.option('channel', '').split(',')
32
+ @new_version = argv.option('version', '').split(',').first
33
+
34
+ @projectPath = @path.count.zero? ? Pathname.pwd.to_s : @path.first
35
+ @is_master = false
36
+ unless @repo
37
+ @repo = 'master'
38
+ @is_master = true
39
+ end
40
+
41
+ super
42
+ end
43
+
44
+ def run
45
+ PPL::Scanner.new(@projectPath, ['pod', 'git']).run
46
+
47
+ @channels = ["all"] if @channels.count.zero?
48
+
49
+ puts "\n[更新 #{@channels.join(", ")} 内容]"
50
+
51
+ @channels.each do |channel|
52
+ case channel
53
+ when "all"
54
+ update_version
55
+ update_git
56
+ when "version"
57
+ update_version
58
+ when "git"
59
+ update_git
60
+ else
61
+ raise "暂不支持#{channel}内容扫描"
62
+ end
63
+ end
64
+ end
65
+
66
+ def update_version
67
+ version = PPL::Scanner.podspec.version
68
+ raise "版本号异常,无法更新" unless version
69
+ if @new_version
70
+ version.archiving(@new_version)
71
+ else
72
+ version.increase_patch
73
+ end
74
+
75
+ PPL::Scanner.linter.write_to_file('version', version.version)
76
+ end
77
+
78
+ def update_git
79
+ git = PPL::Scanner.git
80
+ new_tag = PPL::Scanner.podspec.version.version
81
+ git.tags.each do |tag|
82
+ raise "当前版本 #{new_tag} 已发布,请尝试其他版本号" if tag.name.eql? new_tag
83
+ end
84
+ git.add('.')
85
+ git.commit_all(new_tag)
86
+ git.add_tag(new_tag)
87
+ git.push(git.remote, git.branches.current.first, true)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,6 @@
1
+ class Dir
2
+ def self.reset(path)
3
+ `rm -fr "#{path}"`
4
+ `mkdir "#{path}"`
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'git'
2
+
3
+ module Git
4
+ class Branches
5
+ def current
6
+ self.local.select { |b| b.current }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Pod
2
+ class Specification
3
+ class Linter
4
+ def write_to_file(property, value)
5
+ puts "[写入 #{property} = #{value}]"
6
+ file_content = File.read file
7
+ file_content.gsub!(/(.*.#{property}.*=.*)('.*')/,"\\1'#{value}'")
8
+ File.open(file, "w") { |f|
9
+ f.puts file_content
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'cocoapods'
2
+
3
+ module Pod
4
+ class Validator
5
+ def xcodebuild(action, scheme, configuration, deployment_target:)
6
+ require 'fourflusher'
7
+ command = %W(clean #{action} -workspace #{File.join(validation_dir, 'App.xcworkspace')} -scheme #{scheme} -configuration #{configuration})
8
+ command += %w(--help)
9
+
10
+ if analyze
11
+ command += %w(CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer)
12
+ end
13
+
14
+ begin
15
+ _xcodebuild(command, true)
16
+ rescue => e
17
+ message = 'Returned an unsuccessful exit code.'
18
+ message += ' You can use `--verbose` for more information.' unless config.verbose?
19
+ error('xcodebuild', message)
20
+ e.message
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Pod
2
+ class Version
3
+ def increase_major
4
+ numeric_segments[0] = numeric_segments[0].to_i + 1
5
+ archiving(numeric_segments.join('.'))
6
+ end
7
+
8
+ def increase_minor
9
+ numeric_segments[1] = numeric_segments[1].to_i + 1
10
+ archiving(numeric_segments.join('.'))
11
+ end
12
+
13
+ def increase_patch
14
+ numeric_segments[2] = numeric_segments[2].to_i + 1
15
+ archiving(numeric_segments.join('.'))
16
+ end
17
+
18
+ def archiving(new_version)
19
+ puts "[修改版本号:#{version} => #{new_version}]"
20
+ @version = new_version
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require 'xcodeproj'
2
+
3
+ module Xcodeproj
4
+ class Workspace
5
+ attr_accessor :path
6
+
7
+ def self.open(path)
8
+ workspace = new_from_xcworkspace(path)
9
+ workspace.path = path
10
+ workspace
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ module PPL
2
+ class Binary
3
+ def self.combine(output, inputs, ignore="")
4
+ puts "\n目标文件:#{output}\n"
5
+
6
+ #获取合并文件的路径序列
7
+ input_file_queue=""
8
+ inputs.each do |input|
9
+ puts "\n合并路径:#{input}"
10
+
11
+ Dir[input].each do |input_file|;
12
+ #若 input_file 为目录 则跳过
13
+ next if Dir.exists? input_file
14
+ #若 input_file 为被忽略标记的文件 则跳过
15
+ unless ignore.empty?
16
+ next if File.basename(input_file).include? File.basename(ignore)
17
+ end
18
+ #若 input_file 为非二进制文件 则跳过
19
+ info_log = `lipo -info "#{input_file}" > /dev/null 2>&1
20
+ echo result:$?`
21
+ next unless info_log.include? 'result:0'
22
+ #若 input_file 为序列中已存在的文件 则跳过
23
+ next if input_file_queue.include? input_file
24
+
25
+ #合并
26
+ puts "=> #{input_file}"
27
+ input_file_queue += " \"#{input_file}\""
28
+ end
29
+ end
30
+
31
+ #若合并文件序列不为空,执行合并
32
+ unless input_file_queue.empty?
33
+ if File.exists? output
34
+ output_temp = output+'.temp'
35
+ File.rename(output, output_temp)
36
+
37
+ combine_log =
38
+ `libtool -static -o "#{output}" "#{output_temp}" #{input_file_queue} > /dev/null 2>&1
39
+ echo result:$?`
40
+ raise "\ncombine log:\n#{combine_log}" unless combine_log.include? 'result:0'
41
+
42
+ File.delete(output_temp)
43
+ else
44
+ combine_log =
45
+ `libtool -static -o "#{output}" #{input_file_queue} > /dev/null 2>&1
46
+ echo result:$?`
47
+ raise "\ncombine log:\n#{combine_log}" unless combine_log.include? 'result:0'
48
+ end
49
+ end
50
+ end
51
+
52
+ def self.thin(binary, archs)
53
+ archs.each do |arch|
54
+ thin_log =
55
+ `lipo "#{binary}" -thin #{arch} -output "#{binary}-#{arch}" > /dev/null 2>&1
56
+ echo result:$?`
57
+ unless thin_log.include? 'result:0'
58
+ puts "lipo -thin 异常"
59
+ return
60
+ end
61
+ end
62
+ File.delete(binary)
63
+
64
+ binary_pieces = "#{binary}-*"
65
+ combine(binary, [binary_pieces])
66
+
67
+ Dir[binary_pieces].each do |binary_piece|
68
+ File.delete(binary_piece)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,21 @@
1
+ module PPL
2
+ class Bundle
3
+ def self.cp(inputs, output)
4
+ puts "\n目标文件:#{output}\n"
5
+
6
+ #获取合并文件的路径序列
7
+ inputs.each do |input|
8
+ puts "\n合并路径:#{input}"
9
+
10
+ Dir[input].each do |input_bundle|;
11
+ #若 input_bundle 为输出目录 则跳过
12
+ next if input_bundle.eql? output
13
+
14
+ #合并
15
+ puts "合并资源包:" + input_bundle
16
+ FileUtils.cp_r(input_bundle, output, :preserve => true)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,114 @@
1
+ require 'cocoapods-core'
2
+ require 'git'
3
+ require 'xcodeproj'
4
+
5
+ require 'pod-pipeline/extension/git-ppl.rb'
6
+ require 'pod-pipeline/extension/workspace-ppl.rb'
7
+
8
+ module PPL
9
+ class Scanner
10
+ @@linter = nil
11
+ @@podspec = nil
12
+ @@git = nil
13
+ @@workspace = nil
14
+
15
+ def initialize(projectPath, channels)
16
+ @projectPath = projectPath
17
+ @channels = channels
18
+ end
19
+
20
+ def run
21
+ @channels = ["all"] if @channels.count.zero?
22
+
23
+ puts "\n[扫描 #{@channels.join(", ")} 内容]"
24
+
25
+ @channels.each do |channel|
26
+ case channel
27
+ when "all"
28
+ @@linter = scan_pod @projectPath
29
+ @@podspec = @@linter.spec
30
+ @@git = scan_git @projectPath
31
+ @@workspace = scan_workspace @projectPath
32
+ when "pod"
33
+ @@linter = scan_pod @projectPath
34
+ @@podspec = @@linter.spec
35
+ when "git"
36
+ @@git = scan_git @projectPath
37
+ when "workspace"
38
+ @@workspace = scan_workspace @projectPath
39
+ else
40
+ raise "暂不支持#{channel}内容扫描"
41
+ end
42
+ end
43
+ end
44
+
45
+ #----------------------------------------#
46
+
47
+ def self.linter
48
+ @@linter
49
+ end
50
+
51
+ def self.podspec
52
+ @@podspec
53
+ end
54
+
55
+ def self.git
56
+ @@git
57
+ end
58
+
59
+ def self.workspace
60
+ @@workspace
61
+ end
62
+
63
+ #----------------------------------------#
64
+
65
+ private
66
+
67
+ #
68
+ # 检查项目的 podspec 文件
69
+ #
70
+ # @param [String] projectPath 项目根目录
71
+ #
72
+ # @return [Pod::Specification] 新 {Pod::Specification} 实例
73
+ #
74
+ def scan_pod(projectPath)
75
+ podspec_files = Pathname.glob(projectPath + '/*.podspec{.json,}')
76
+ if podspec_files.count.zero? || podspec_files.count > 1
77
+ raise '未找到或存在多个 *.podspec 文件'
78
+ end
79
+ podspec_file = podspec_files.first
80
+ linter = Pod::Specification::Linter.new(podspec_file)
81
+ unless linter.spec
82
+ raise 'podspec文件异常'
83
+ end
84
+ linter
85
+ end
86
+
87
+ #
88
+ # 检查项目的 Git 库
89
+ #
90
+ # @param [String] projectPath 项目根目录
91
+ #
92
+ # @return [Git::Base] 新 {Git::Base} 实例
93
+ #
94
+ def scan_git(projectPath)
95
+ Git.open(projectPath)
96
+ end
97
+
98
+ #
99
+ # 检查项目的 workspace
100
+ #
101
+ # @param [String] projectPath 项目根目录
102
+ #
103
+ # @return [Xcodeproj::Workspace] 新的 {Xcodeproj::Workspace} 实例
104
+ #
105
+ def scan_workspace(projectPath)
106
+ workspace_files = Dir[projectPath + '/Example/*.xcworkspace']
107
+ if workspace_files.count.zero? || workspace_files.count > 1
108
+ raise '未找到或存在多个 *.xcworkspace 文件'
109
+ end
110
+ workspace_file = workspace_files.first
111
+ Xcodeproj::Workspace.open(workspace_file)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,28 @@
1
+ module PPL
2
+ class XCodebuild
3
+ def self.build(workspace, scheme, arch, configuration, output)
4
+ puts "Building #{arch} ..."
5
+
6
+ sdk =
7
+ case
8
+ when arch.include?("arm") then 'iphoneos'
9
+ when arch.include?("86") then 'iphonesimulator'
10
+ else raise "暂时不支持 #{arch} 架构" unless sdk
11
+ end
12
+
13
+ build_log =
14
+ `xcodebuild\
15
+ -workspace "#{workspace}"\
16
+ -scheme #{scheme}\
17
+ -sdk #{sdk}\
18
+ -arch #{arch}\
19
+ -configuration #{configuration}\
20
+ -UseModernBuildSystem=NO\
21
+ -quiet\
22
+ MACH_O_TYPE=staticlib\
23
+ BUILD_DIR="#{output}/#{arch}"
24
+ echo result:$?`
25
+ raise "\nbuild log:\n#{build_log}" unless build_log.include? 'result:0'
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pod-pipeline
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - 郑贤达
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cocoapods-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.10.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.10.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: cocoapods-trunk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.0
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '2.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.4.0
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: git
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.1
54
+ - - "<"
55
+ - !ruby/object:Gem::Version
56
+ version: '2.0'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.1
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '2.0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: xcodeproj
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.19.0
74
+ - - "<"
75
+ - !ruby/object:Gem::Version
76
+ version: '2.0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.19.0
84
+ - - "<"
85
+ - !ruby/object:Gem::Version
86
+ version: '2.0'
87
+ - !ruby/object:Gem::Dependency
88
+ name: claide
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 1.0.2
94
+ - - "<"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ type: :runtime
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 1.0.2
104
+ - - "<"
105
+ - !ruby/object:Gem::Version
106
+ version: '2.0'
107
+ description: 为组件化开发设计的集项目构建、发布为一体的强大工具
108
+ email: zhengxianda0512@gmail.com
109
+ executables:
110
+ - ppl
111
+ extensions: []
112
+ extra_rdoc_files: []
113
+ files:
114
+ - bin/ppl
115
+ - lib/pod-pipeline.rb
116
+ - lib/pod-pipeline/command.rb
117
+ - lib/pod-pipeline/command/build.rb
118
+ - lib/pod-pipeline/command/publish.rb
119
+ - lib/pod-pipeline/command/scan.rb
120
+ - lib/pod-pipeline/command/update.rb
121
+ - lib/pod-pipeline/extension/dir-ppl.rb
122
+ - lib/pod-pipeline/extension/git-ppl.rb
123
+ - lib/pod-pipeline/extension/linter-ppl.rb
124
+ - lib/pod-pipeline/extension/validator-ppl.rb
125
+ - lib/pod-pipeline/extension/version-ppl.rb
126
+ - lib/pod-pipeline/extension/workspace-ppl.rb
127
+ - lib/pod-pipeline/util/binary.rb
128
+ - lib/pod-pipeline/util/bundle.rb
129
+ - lib/pod-pipeline/util/scanner.rb
130
+ - lib/pod-pipeline/util/xcodebuild.rb
131
+ homepage: https://github.com/TokiGems/pod-pipeline
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubygems_version: 3.0.3
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: Cocoapods流水线工具
154
+ test_files: []