cocoapods-freezer 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8bee456e3188be9d1c42048f880f2d08607f2111
4
+ data.tar.gz: 6d39185feedb5715ee7220ca8a664ca5938c82c2
5
+ SHA512:
6
+ metadata.gz: 7d77376f93e7b74a9f33a89fad532007eb7ad1fe2ec928ec9f79fb92cc089fa3a96961b3ed03118d7577e8c4ca07d9534c109beb78b0bad293b235096b1a7c21
7
+ data.tar.gz: e20529d0dd900de550ddad5e699acc3e00a19cbc3d5bd80b18a644f5aefbbf8311fde45c5a9369eaa47b2f7e687349d4a82dc7d6f64d28fe4845cfb380b17962
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
4
+ demo/
5
+ *.gem
6
+ *.sh
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cocoapods-freezer.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'cocoapods'
8
+
9
+ gem 'mocha'
10
+ gem 'bacon'
11
+ gem 'mocha-on-bacon'
12
+ gem 'prettybacon'
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2018 <>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # cocoapods-freezer
2
+
3
+ cocoapods-freezer is a plugin of cocoapods. It uses for cache of intergation!
4
+
5
+ ## Installation
6
+
7
+ ``` shell
8
+ $ gem install cocoapods-freezer
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ``` shell
14
+ $ pod install --user-freezer
15
+
16
+ ```
17
+
18
+ ## Principle
19
+
20
+ Versions of Pods maintain stability. And the same to the product of Pods. So cocoapods-freezer will cache the product when Pods pre-build. Then it use cache for integate.
21
+
22
+ Appreciate a 🌟 if you like it.
data/README_CH.md ADDED
@@ -0,0 +1,46 @@
1
+ # cocoapods-freezer
2
+
3
+ cocoapods-freezer是一款基于CocoaPods的集成缓存插件。
4
+
5
+ ## 安装
6
+
7
+ ``` shell
8
+ $ gem install cocoapods-freezer
9
+ ```
10
+
11
+ ## 使用
12
+
13
+ ``` shell
14
+ $ pod install --user-freezer
15
+
16
+ ```
17
+
18
+ ## 原理
19
+
20
+ 基于集成的Pod组件版本一般更新频率不高,其源码改动频率同样不高,因此这部分编译产物在一段时间内存在不变性,故通过对这其进行缓存,节省重复编译时间,最终达到提速效果。
21
+
22
+ ## 能力
23
+
24
+ [x] 基于Podfile进行Pods缓存分析,配合'Pod install'进行缓存
25
+ [x] 目前仅支持static-library预打包处理(需屏蔽'use_framework!')
26
+ [x] 目前仅支持release打包配置
27
+ [x] 目前仅支持单iOS平台
28
+ [x] 支持增量打包
29
+ [x] 支持缓存复用
30
+
31
+ ## 计划
32
+
33
+ - 缓存相关
34
+ [] 支持全平台(Platform)、全配置(Configuration)缓存
35
+ [] 支持Framework(Dynamic\Static)方式构建
36
+ [] 支持local类型
37
+ [] 支持swift类型
38
+ [] 缓存路径定制
39
+ [] 打包脚本定制?
40
+ [] Configuration定制?
41
+
42
+ - 命令相关
43
+ [] 支持'pod update'命令工作
44
+ [] 支持'pod freeze'命令的查询、缓存操作
45
+
46
+ 如果你喜欢这个插件,请留下🌟!欢迎提出遇到的问题,以及希望增加的功能!
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ def specs(dir)
4
+ FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
5
+ end
6
+
7
+ desc 'Runs all the specs'
8
+ task :specs do
9
+ sh "bundle exec bacon #{specs('**')}"
10
+ end
11
+
12
+ task :default => :specs
13
+
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cocoapods-freezer/gem_version.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cocoapods-freezer'
8
+ spec.version = CocoapodsFreezer::VERSION
9
+ spec.authors = ['']
10
+ spec.email = ['']
11
+ spec.description = %q{A short description of cocoapods-freezer.}
12
+ spec.summary = %q{A longer description of cocoapods-freezer.}
13
+ spec.homepage = 'https://github.com/EXAMPLE/cocoapods-freezer'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency "cocoapods", '1.5.3'
22
+ spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'rake'
24
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-freezer/gem_version'
@@ -0,0 +1,2 @@
1
+ require 'cocoapods-freezer/command/freeze'
2
+ require 'cocoapods-freezer/command/install'
@@ -0,0 +1,46 @@
1
+ module Pod
2
+ class Command
3
+ # This is an example of a cocoapods plugin adding a top-level subcommand
4
+ # to the 'pod' command.
5
+ #
6
+ # You can also create subcommands of existing or new commands. Say you
7
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
8
+ # (e.g. `pod list deprecated`), there are a few things that would need
9
+ # to change.
10
+ #
11
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
12
+ # the class to exist in the the Pod::Command::List namespace
13
+ # - change this class to extend from `List` instead of `Command`. This
14
+ # tells the plugin system that it is a subcommand of `list`.
15
+ # - edit `lib/cocoapods_plugins.rb` to require this file
16
+ #
17
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
18
+ # in the `plugins.json` file, once your plugin is released.
19
+ #
20
+
21
+ # todo(ca1md0wn)
22
+ # class Freeze < Command
23
+ # self.summary = 'Short description of cocoapods-freezer.'
24
+
25
+ # self.description = <<-DESC
26
+ # Longer description of cocoapods-freezer.
27
+ # DESC
28
+
29
+ # self.arguments = 'NAME'
30
+
31
+ # def initialize(argv)
32
+ # @name = argv.shift_argument
33
+ # super
34
+ # end
35
+
36
+ # def validate!
37
+ # super
38
+ # help! 'A Pod name is required.' unless @name
39
+ # end
40
+
41
+ # def run
42
+ # UI.puts "Add your implementation for the cocoapods-freezer plugin in #{__FILE__}"
43
+ # end
44
+ # end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ module Pod
2
+ class Command
3
+ class Install < Command
4
+ require 'cocoapods-freezer/command/options/use_freezer'
5
+ include UseFreezer
6
+
7
+ define_method(:run) do
8
+ verify_podfile_exists!
9
+
10
+ if use_freezer?
11
+ Freezer::shared.freeze!
12
+ elsif Config.instance.sandbox.manifest && Config.instance.sandbox.manifest.freered?
13
+ Config.instance.sandbox.clear!
14
+ end
15
+
16
+ installer = installer_for_config
17
+ installer.repo_update = repo_update?(:default => false)
18
+ installer.update = false
19
+ installer.install!
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Pod
2
+ class Command
3
+ module Options
4
+ # Provides support for commands to skip updating the spec repositories.
5
+ #
6
+ module UseFreezer
7
+
8
+ module Options
9
+ def options
10
+ [
11
+ ['--use-freezer', 'running cocoapods-freeze before install'],
12
+ ].concat(super)
13
+ end
14
+ end
15
+
16
+ def self.included(base)
17
+ base.extend(Options)
18
+ end
19
+
20
+ def use_freezer?(default: false)
21
+ if @use_freezer.nil?
22
+ default
23
+ else
24
+ @use_freezer
25
+ end
26
+ end
27
+
28
+ def initialize(argv)
29
+ @use_freezer = argv.flag?('use-freezer')
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Pod
2
+ class Config
3
+ def freezer
4
+ return nil unless podfile
5
+
6
+ @freezer ||= new(podfile)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ class Dir
2
+ def self.randdir
3
+ path = nil
4
+ while (path == nil || path.exist?) do
5
+ path = Pathname.new(Dir.tmpdir + rand(999999).to_s) #todo(ca1md0wn)
6
+ end
7
+
8
+ path
9
+ end
10
+
11
+ def self.mkranddir
12
+ path = randdir
13
+ path.mkpath
14
+ path
15
+ end
16
+ end
@@ -0,0 +1,237 @@
1
+ require 'tmpdir'
2
+
3
+ module Pod
4
+ class Freezer
5
+ def self.shared
6
+ @shared ||= (Config.instance.podfile ? new(Config.instance.podfile) : nil)
7
+ end
8
+
9
+ def initialize(podfile)
10
+ raise unless podfile
11
+ @podfile = podfile
12
+ @frozen_pods = []
13
+ @enable = false
14
+ end
15
+
16
+ def enable?
17
+ @enable
18
+ end
19
+
20
+ def exist?
21
+ root.exist?
22
+ end
23
+
24
+ def clear!
25
+ root.rmtree if root.exist?
26
+ end
27
+
28
+ # freeze!
29
+ # todo(ca1md0wn): if Dir of FrozenPods destoryed, should fix by itself!
30
+ def freeze!
31
+ @enable = true
32
+
33
+ Pod::UI.puts "Freezing Pods".green
34
+
35
+ unchange_spec_names = []
36
+ if manifest_path.exist?
37
+ lockfile = Pod::Lockfile.from_file(manifest_path)
38
+ unchange_spec_names = Pod::Installer::Analyzer::SpecsState.new(lockfile.detect_changes_with_podfile(@podfile)).unchanged.to_a
39
+ end
40
+
41
+ # prepare root dir
42
+ root.mkpath unless root.exist?
43
+
44
+ # prepare sandbox
45
+ sandbox = Pod::Sandbox.new(Dir.randdir)
46
+
47
+ # install!
48
+ installer = Pod::Installer.new(sandbox, @podfile , nil)
49
+ installer.repo_update = false # todo(ca1md0wn)
50
+ installer.update = false # todo(ca1md0wn)
51
+ installer.use_by_freezer = true
52
+ installer.install!
53
+
54
+ specs_for_freezing = installer.major_specs
55
+
56
+ # freeze!
57
+ specs_for_freezing.each do |spec|
58
+
59
+ # local not support;
60
+ if sandbox.local?(spec.name)
61
+ Pod::UI.puts "`#{spec.name}` can't freeze because it is local!".red
62
+ next
63
+ end
64
+
65
+ # fetch targets of pod in different platform,
66
+ pod_targets = installer.pod_targets.select do |target|
67
+ target.pod_name == spec.name
68
+ end || []
69
+
70
+ # multiplatform not support(just support ios now!)
71
+ # todo(ca1md0wn)
72
+ unless pod_targets.count > 0
73
+ Pod::UI.puts "`#{spec.name}` can't freeze because it is multiplatforms!".red
74
+ next
75
+ end
76
+
77
+ # swift not support;
78
+ # todo(ca1md0wn)
79
+ # build_as_framework not support;
80
+ # todo(ca1md0wn)
81
+ # should_not_build not support
82
+ not_support = false
83
+ pod_targets.each do |target|
84
+ if !target.should_build?
85
+ Pod::UI.puts "`#{spec.name}` can't freeze because it should not build!".red
86
+ not_support = true
87
+ break
88
+ end
89
+
90
+ if target.uses_swift?
91
+ Pod::UI.puts "`#{spec.name}` can't freeze because it use swift!".red
92
+ not_support = true
93
+ break
94
+ end
95
+
96
+ if target.requires_frameworks?
97
+ Pod::UI.puts "`#{spec.name}` don't support to freeze because it will build as framework!".red
98
+ not_support = true
99
+ break
100
+ end
101
+ end
102
+ next if not_support
103
+
104
+ frozen_pod = FrozenPod.new(spec.name)
105
+
106
+ # setup!
107
+ pod_targets.each do |target|
108
+ # target build when
109
+ # 1.spec change/add 2.product not exist
110
+ if !unchange_spec_names.include?(spec.name) || !(root + target.product_name).exist?
111
+
112
+ product_path = nil
113
+ case target.platform.name
114
+ when :ios then
115
+ # build iphonesimulator!
116
+ iphonesimulator_paths = Pod::Xcodebuild::build_iphonesimulator!(installer.sandbox.project_path.realdirpath, target.name, target.product_name)
117
+ if !iphonesimulator_paths || iphonesimulator_paths.count == 0
118
+ next
119
+ end
120
+
121
+ # build iphoneos!
122
+ iphoneos_paths = Pod::Xcodebuild::build_iphoneos!(installer.sandbox.project_path.realdirpath, target.name, target.product_name)
123
+ if !iphoneos_paths || iphoneos_paths.count == 0
124
+ next
125
+ end
126
+
127
+ # lipo!
128
+ product_path = Pod::Lipo::create!(iphoneos_paths + iphonesimulator_paths, target.product_name)
129
+
130
+ when :osx then
131
+ # todo
132
+ when :watchos then
133
+ # todo
134
+ when :tvos then
135
+ # todo
136
+ end
137
+
138
+ next unless product_path
139
+
140
+ FileUtils.cp_r(product_path, root + target.product_name, :remove_destination => true)
141
+ end
142
+
143
+ frozen_pod.mark!(target.product_name)
144
+ end
145
+
146
+ unless frozen_pod.empty?
147
+ @frozen_pods += [frozen_pod]
148
+ end
149
+
150
+ Pod::UI.puts "`#{spec.name}` freeze!".green
151
+ end
152
+
153
+ # save manifest file
154
+ if sandbox.manifest_path.exist?
155
+ FileUtils.cp_r(sandbox.manifest_path, manifest_path, :remove_destination => true)
156
+ end
157
+
158
+ Pod::UI.puts "Pods freeze complete!".green
159
+ end
160
+
161
+ def frozen_pod_names
162
+ pod_names = @frozen_pods.map do |frozen_pod|
163
+ frozen_pod.pod_name
164
+ end
165
+
166
+ pod_names || []
167
+ end
168
+
169
+ def freezed_pod?(pod_name)
170
+ @frozen_pods.each do |frozen_pod|
171
+ if frozen_pod.pod_name == pod_name
172
+ return true
173
+ end
174
+ end
175
+
176
+ return false
177
+ end
178
+
179
+ def freezed_product?(product_name)
180
+ @frozen_pods.each do |frozen_pod|
181
+ frozen_pod.product_names.each do |name|
182
+ if name == product_name
183
+ return true
184
+ end
185
+ end
186
+ end
187
+
188
+ return false
189
+ end
190
+
191
+ def export!(product_name, path)
192
+ if !path || !freezed_product?(product_name)
193
+ return
194
+ end
195
+
196
+ FileUtils.cp_r(root + product_name, path.to_s, :remove_destination => true)
197
+ end
198
+
199
+ private
200
+
201
+ class FrozenPod
202
+ # String
203
+ attr_reader :pod_name
204
+
205
+ # Array<String>
206
+ attr_reader :product_names
207
+
208
+ def initialize(pod_name)
209
+ @pod_name = pod_name
210
+ @product_names = []
211
+ end
212
+
213
+ def mark!(product_name)
214
+ @product_names += [product_name]
215
+ end
216
+
217
+ def empty?
218
+ if @product_names.count > 0
219
+ return false
220
+ end
221
+
222
+ return true
223
+ end
224
+ end
225
+
226
+ # Array<FrozenPod>
227
+ @frozen_pods
228
+
229
+ def root
230
+ Pathname.new(@podfile.defined_in_file.dirname) + 'FrozenPods'
231
+ end
232
+
233
+ def manifest_path
234
+ root + 'Manifest.lock'
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsFreezer
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,128 @@
1
+ module Pod
2
+ class Installer
3
+
4
+ def major_specs
5
+ root_specs
6
+ end
7
+
8
+ def clean_pods_about_freezed
9
+ Pod::Freezer.shared.frozen_pod_names.each do |pod_name|
10
+ sandbox.clean_pod(pod_name)
11
+ end
12
+
13
+ if sandbox.manifest && sandbox.manifest.frozen_pod_names
14
+ sandbox.manifest.frozen_pod_names.select do |pod_name|
15
+ !Pod::Freezer.shared.frozen_pod_names.include?(pod_name)
16
+ end.each do |pod_name|
17
+ sandbox.clean_pod(pod_name)
18
+ end
19
+ end
20
+ end
21
+
22
+ def resolve_dependencies_about_freezed
23
+ analysis_result.specifications.each do |spec|
24
+ next unless Pod::Freezer.shared.freezed_pod?(spec.root.name)
25
+
26
+ targets = pod_targets.select do |target|
27
+ target.pod_name == spec.root.name
28
+ end
29
+
30
+ if !targets || targets.count == 0
31
+ next
32
+ end
33
+
34
+ targets.each do |target|
35
+ spec.prepare_to_store_freezed(target.platform.name.to_s)
36
+ if Pod::Freezer.shared.freezed_product?(target.product_name)
37
+ spec.store_freezed(target.platform.name.to_s, target.product_name, target.product_type)
38
+ else # not freezed product in platform
39
+ spec.store_freezed_none(target.platform.name.to_s)
40
+ end
41
+ end
42
+
43
+ spec.done_for_store_freezed
44
+ end
45
+ end
46
+
47
+ def install_source_of_pod_about_freezed(pod_name)
48
+ if Pod::Freezer.shared.freezed_pod?(pod_name)
49
+ pod_targets.select do |target|
50
+ target.pod_name == pod_name
51
+ end.map do |target|
52
+ target.product_name
53
+ end.each do |product_name|
54
+ Pod::Freezer.shared.export!(product_name, self.sandbox.pod_dir(pod_name) + product_name)
55
+ end
56
+ end
57
+ end
58
+
59
+ attr_accessor :use_by_freezer
60
+ @use_by_freezer
61
+
62
+ # hook integrate_user_project
63
+ hook_integrate_user_project = instance_method(:integrate_user_project)
64
+ define_method(:integrate_user_project) do
65
+ # ignore when install by freezer
66
+ if @use_by_freezer
67
+ return
68
+ end
69
+
70
+ hook_integrate_user_project.bind(self).()
71
+ end
72
+
73
+ # hook resolve_dependecies
74
+ hook_resolve_dependecies = instance_method(:resolve_dependencies)
75
+ define_method(:resolve_dependencies) do
76
+
77
+ # no hook when install by freezer
78
+ if @use_by_freezer || !Pod::Freezer.shared.enable?
79
+ hook_resolve_dependecies.bind(self).()
80
+ else
81
+ clean_pods_about_freezed
82
+ hook_resolve_dependecies.bind(self).()
83
+ resolve_dependencies_about_freezed
84
+ end
85
+ end
86
+
87
+ # hook install_source_of_pod
88
+
89
+ hook_install_source_of_pod = instance_method(:install_source_of_pod)
90
+ define_method(:install_source_of_pod) do |pod_name|
91
+ # no hook when install by freezer
92
+ if @use_by_freezer || !Pod::Freezer.shared.enable?
93
+ hook_install_source_of_pod.bind(self).(pod_name)
94
+ return
95
+ end
96
+
97
+ pod_installer = create_pod_installer(pod_name)
98
+ pod_installer.install!
99
+ install_source_of_pod_about_freezed(pod_name)
100
+ @installed_specs.concat(pod_installer.specs_by_platform.values.flatten.uniq)
101
+ end
102
+
103
+ # hook write_lockfiles
104
+
105
+ hook_write_lockfiles = instance_method(:write_lockfiles)
106
+ define_method(:write_lockfiles) do
107
+ # no hook when install by freezer
108
+ if @use_by_freezer || !Pod::Freezer.shared.enable?
109
+ hook_write_lockfiles.bind(self).()
110
+ return
111
+ end
112
+
113
+ external_source_pods = analysis_result.podfile_dependency_cache.podfile_dependencies.select(&:external_source).map(&:root_name).uniq
114
+ checkout_options = sandbox.checkout_sources.select { |root_name, _| external_source_pods.include? root_name }
115
+
116
+ @lockfile = Lockfile.generrate_by_freezer(podfile, analysis_result.specifications, checkout_options, analysis_result.specs_by_source, Pod::Freezer.shared.frozen_pod_names)
117
+ UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do
118
+ @lockfile.write_to_disk(config.lockfile_path)
119
+ end
120
+
121
+ UI.message "- Writing Manifest in #{UI.path sandbox.manifest_path}" do
122
+ sandbox.manifest_path.open('w') do |f|
123
+ f.write config.lockfile_path.read
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,22 @@
1
+ module Pod
2
+ module Lipo
3
+ def self.create!(paths, product_name)
4
+ output_path = Dir.mkranddir + product_name
5
+
6
+ begin
7
+ command = "lipo -create"
8
+ paths.each do |pathname|
9
+ command += " " + pathname.to_s
10
+ end
11
+
12
+ command += " -output #{output_path}"
13
+ `#{command}`
14
+ # Pod::UI.puts "lipo succeed!"
15
+ rescue => e
16
+ # Pod::UI.puts "lipo failed! #{e}"
17
+ end
18
+
19
+ output_path
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ module Pod
2
+ class Lockfile
3
+
4
+ def freered?
5
+ frozen_pods = @internal_data['FROZENPODS']
6
+ if !frozen_pods || frozen_pods.count == 0
7
+ return false
8
+ end
9
+
10
+ return true
11
+ end
12
+
13
+ def frozen_pod_names
14
+ @internal_data['FROZENPODS'] || []
15
+ end
16
+
17
+ class << self
18
+ public
19
+ def generrate_by_freezer(podfile, specs, checkout_options, spec_repos = {}, frozen_pods=[])
20
+ hash = {
21
+ 'PODS' => generate_pods_data(specs),
22
+ 'DEPENDENCIES' => generate_dependencies_data(podfile),
23
+ 'SPEC REPOS' => generate_spec_repos(spec_repos),
24
+ 'EXTERNAL SOURCES' => generate_external_sources_data(podfile),
25
+ 'CHECKOUT OPTIONS' => checkout_options,
26
+ 'SPEC CHECKSUMS' => generate_checksums(specs),
27
+ 'PODFILE CHECKSUM' => podfile.checksum,
28
+ 'COCOAPODS' => CORE_VERSION,
29
+ 'FROZENPODS' => frozen_pods,
30
+ }
31
+ Lockfile.new(hash)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module Pod
2
+ class Sandbox
3
+ def clear!
4
+ root.rmtree if root.exist?
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,123 @@
1
+ class Array
2
+ def self.from_attributes(attributes)
3
+ if attributes == nil
4
+ return []
5
+ elsif attributes.is_a?(String) || attributes.is_a?(Pathname)
6
+ return [attributes]
7
+ elsif attributes.is_a?(Array)
8
+ return attributes
9
+ else
10
+ raise
11
+ end
12
+
13
+ []
14
+ end
15
+ end
16
+
17
+ module Pod
18
+
19
+ class Specification
20
+ def done_for_store_freezed
21
+ attributes_hash["source_files"] = []
22
+
23
+ available_platforms.map do |spec_platform|
24
+ platform_name = spec_platform.to_sym
25
+ @consumers[platform_name] = Consumer.new(self, platform_name)
26
+ end
27
+ end
28
+
29
+ def prepare_to_store_freezed(platform_name)
30
+ (attributes_hash[platform_name] = {}) unless attributes_hash[platform_name]
31
+ end
32
+
33
+ def store_freezed_none(platform_name)
34
+ raise unless platform_name && platform_name.is_a?(String)
35
+ attributes_hash[platform_name]["source_files"] = all_source_files(platform_name)
36
+ end
37
+
38
+ def store_freezed(platform_name, product_name, product_type)
39
+ raise unless platform_name && platform_name.is_a?(String)
40
+ raise unless product_name && product_name.is_a?(String)
41
+ raise unless product_type
42
+
43
+ case product_type
44
+ when :framework then
45
+ attributes_hash[platform_name]["source_files"] = []
46
+ vendors = Array.from_attributes(attributes_hash[platform_name]["vendored_frameworks"])
47
+ vendors += [product_name]
48
+ attributes_hash[platform_name]["vendored_frameworks"] = vendors
49
+ when :static_library then
50
+ attributes_hash[platform_name]["source_files"] = header_files_in_all_sources_files(platform_name)
51
+ vendors = Array.from_attributes(attributes_hash[platform_name]["vendored_frameworks"])
52
+ vendors += [product_name]
53
+ attributes_hash[platform_name]["vendored_libraries"] = vendors
54
+ else
55
+ attributes_hash[platform_name]["source_files"] = all_source_files(platform_name)
56
+ return
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def all_source_files_paths(platform_name=nil)
63
+ files = Array.from_attributes(attributes_hash["source_files"])
64
+
65
+ if platform_name && attributes_hash[platform_name]
66
+ files += Array.from_attributes(attributes_hash[platform_name]["source_files"])
67
+ end
68
+
69
+ paths = files.map do |file|
70
+ real_file = file
71
+ if real_file.is_a?(String)
72
+ real_file = Pathname.new(real_file)
73
+ end
74
+
75
+ real_file
76
+ end
77
+
78
+ paths
79
+ end
80
+
81
+ def all_source_files(platform_name=nil)
82
+ all_source_files_paths(platform_name).map do |path|
83
+ path_s = path
84
+ if !path.is_a?(String)
85
+ path_s = path.to_s
86
+ end
87
+
88
+ path_s
89
+ end
90
+ end
91
+
92
+ def header_files_paths_in_all_sources_files(platform_name=nil)
93
+ files = all_source_files_paths(platform_name)
94
+ files = files.select do |file|
95
+ file.extname == nil || file.extname.length == 0 || file.extname.to_s.include?("h")
96
+ end.map do |file|
97
+ real_file = file
98
+ if file.extname && file.extname.length > 0
99
+ real_file = real_file.sub_ext(".{h,hpp}")
100
+ elsif file.to_s.end_with?('*')
101
+ real_file = real_file.sub_ext(".{h,hpp}")
102
+ else # 'file' may be a folder!
103
+ real_file = (real_file + "*").sub_ext(".{h,hpp}")
104
+ end
105
+
106
+ real_file
107
+ end
108
+
109
+ files
110
+ end
111
+
112
+ def header_files_in_all_sources_files(platform_name=nil)
113
+ header_files_paths_in_all_sources_files(platform_name).map do |path|
114
+ path_s = path
115
+ if !path.is_a?(String)
116
+ path_s = path.to_s
117
+ end
118
+
119
+ path_s
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,60 @@
1
+ module Pod
2
+ module Xcodebuild
3
+ def self.build_iphonesimulator!(project, scheme, product_name)
4
+ output_paths = []
5
+ sdk = 'iphonesimulator'
6
+ archs = %w(i386 x86_64)
7
+ archs.each do |arch|
8
+ output_path = build!(project, sdk, arch, scheme)
9
+ if !output_path
10
+ return []
11
+ end
12
+
13
+ output_paths += [output_path + product_name]
14
+ end
15
+
16
+ output_paths
17
+ end
18
+
19
+ def self.build_iphoneos!(project, scheme, product_name)
20
+ output_paths = []
21
+ sdk = 'iphoneos'
22
+ archs = %w(arm64 armv7 armv7s)
23
+ archs.each do |arch|
24
+ output_path = build!(project, sdk, arch, scheme)
25
+ if !output_path
26
+ return []
27
+ end
28
+
29
+ output_paths += [output_path + product_name]
30
+ end
31
+
32
+ output_paths
33
+ end
34
+
35
+ def self.build_macos!
36
+ # todo
37
+ end
38
+
39
+ def self.build_tvos!
40
+ # todo
41
+ end
42
+
43
+ def self.build_watchos!
44
+ # todo
45
+ end
46
+
47
+ def self.build!(project, sdk, arch, scheme)
48
+ begin
49
+ output_path = Dir.randdir
50
+ args = %W(-project #{project.to_s} -scheme #{scheme} -configuration Release CONFIGURATION_BUILD_DIR=#{output_path.to_s} -sdk #{sdk} -derivedDataPath #{Dir.randdir.to_s} -arch #{arch} clean build)
51
+ Pod::Executable.execute_command("xcodebuild", args, true)
52
+ # Pod::UI.puts "#{scheme} #{sdk} #{arch} xcodebuild succeed!"
53
+ return output_path
54
+ rescue => e
55
+ # Pod::UI.puts "#{scheme} #{sdk} #{arch} xcodebuild failed! #{e}"
56
+ return nil
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ require 'cocoapods-freezer/freezer'
2
+ require 'cocoapods-freezer/dir'
3
+ require 'cocoapods-freezer/config'
4
+ require 'cocoapods-freezer/installer'
5
+ require 'cocoapods-freezer/xcodebuild'
6
+ require 'cocoapods-freezer/lipo'
7
+ require 'cocoapods-freezer/specification'
8
+ require 'cocoapods-freezer/sandbox'
9
+ require 'cocoapods-freezer/lockfile'
10
+ require 'cocoapods-freezer/command'
11
+
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::Freeze do
5
+ describe 'CLAide' do
6
+ it 'registers it self' do
7
+ Command.parse(%w{ freeze }).should.be.instance_of Command::Freezer
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-freezer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - ''
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cocoapods
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.5.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.5.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A short description of cocoapods-freezer.
56
+ email:
57
+ - ''
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - README_CH.md
67
+ - Rakefile
68
+ - cocoapods-freezer.gemspec
69
+ - lib/cocoapods-freezer.rb
70
+ - lib/cocoapods-freezer/command.rb
71
+ - lib/cocoapods-freezer/command/freeze.rb
72
+ - lib/cocoapods-freezer/command/install.rb
73
+ - lib/cocoapods-freezer/command/options/use_freezer.rb
74
+ - lib/cocoapods-freezer/config.rb
75
+ - lib/cocoapods-freezer/dir.rb
76
+ - lib/cocoapods-freezer/freezer.rb
77
+ - lib/cocoapods-freezer/gem_version.rb
78
+ - lib/cocoapods-freezer/installer.rb
79
+ - lib/cocoapods-freezer/lipo.rb
80
+ - lib/cocoapods-freezer/lockfile.rb
81
+ - lib/cocoapods-freezer/sandbox.rb
82
+ - lib/cocoapods-freezer/specification.rb
83
+ - lib/cocoapods-freezer/xcodebuild.rb
84
+ - lib/cocoapods_plugin.rb
85
+ - spec/command/freeze_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: https://github.com/EXAMPLE/cocoapods-freezer
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.5.2.3
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: A longer description of cocoapods-freezer.
111
+ test_files:
112
+ - spec/command/freeze_spec.rb
113
+ - spec/spec_helper.rb