pod-pipeline 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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: []