cocoapods-binary 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +21 -0
- data/Rakefile +13 -0
- data/cocoapods-binary.gemspec +26 -0
- data/lib/cocoapods-binary.rb +1 -0
- data/lib/cocoapods-binary/Integration.rb +111 -0
- data/lib/cocoapods-binary/Main.rb +74 -0
- data/lib/cocoapods-binary/Prebuild.rb +118 -0
- data/lib/cocoapods-binary/feature_switches.rb +85 -0
- data/lib/cocoapods-binary/gem_version.rb +3 -0
- data/lib/cocoapods-binary/podfile_options.rb +71 -0
- data/lib/cocoapods-binary/prebuild_sandbox.rb +34 -0
- data/lib/cocoapods-binary/rome/build_framework.rb +117 -0
- data/lib/cocoapods-binary/tool/tool.rb +12 -0
- data/lib/cocoapods_plugin.rb +9 -0
- data/spec/spec_helper.rb +50 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 95712d26a28d3618a331d08eaea667111f35dab7
|
4
|
+
data.tar.gz: 034e10124db90aa532cdbd086154a44c210916e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf25edfb16bd288a3ed6c0e61bbfa76412109d8541a13213cf3c513248fe9fd94d716b6d3d533adad3eadd5a60f388adf6b72effb2ab9b3ff95edf80bcfb21b3
|
7
|
+
data.tar.gz: f9e055f09c36ef39538329ecdb3f5eeb7db867fcdbf93c629cccc93c828685ac925d3a8198b9990aea5a97a7bf71dccb2439608c0a34a97f164e72b166fae806
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2018 leavez <gaojiji@gmail.com>
|
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,21 @@
|
|
1
|
+
# cocoapods-binary
|
2
|
+
|
3
|
+
A cocoapods plugin that enables to integrate pod in form of prebuilt framework, not source code, with **just one flag** in podfile. This can dramatically speed up your compile time.
|
4
|
+
|
5
|
+
(This project is still in early stage.)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install cocoapods-binary
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Add this in the podfile:
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
plugin 'cocoapods-binary'
|
17
|
+
|
18
|
+
target "HP" do
|
19
|
+
pod "ExpectoPatronum", :binary => true
|
20
|
+
end
|
21
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cocoapods-binary/gem_version.rb'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'cocoapods-binary'
|
8
|
+
spec.version = CocoapodsBinary::VERSION
|
9
|
+
spec.authors = ['leavez']
|
10
|
+
spec.email = ['gaojiji@gmail.com']
|
11
|
+
spec.description = %q{A short description of cocoapods-binary.}
|
12
|
+
spec.summary = %q{A longer description of cocoapods-binary.}
|
13
|
+
spec.homepage = 'https://github.com/EXAMPLE/cocoapods-binary'
|
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.4.0", "< 2.0"
|
22
|
+
spec.add_dependency "fourflusher", "~> 2.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cocoapods-binary/gem_version'
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require_relative 'podfile_options'
|
2
|
+
require_relative 'feature_switches'
|
3
|
+
require_relative 'prebuild_sandbox'
|
4
|
+
|
5
|
+
# Provide a special "download" process for prebuilded pods.
|
6
|
+
#
|
7
|
+
# As the frameworks is already exsited in local folder. We
|
8
|
+
# just create a symlink to the original target folder.
|
9
|
+
#
|
10
|
+
module Pod
|
11
|
+
class Installer
|
12
|
+
class PodSourceInstaller
|
13
|
+
|
14
|
+
def install_for_prebuild!(standard_sanbox)
|
15
|
+
# make a symlink to target folder
|
16
|
+
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sanbox)
|
17
|
+
source = prebuild_sandbox.framework_path_for_pod_name self.name
|
18
|
+
|
19
|
+
target_folder = standard_sanbox.pod_dir(self.name)
|
20
|
+
return if standard_sanbox.local? self.name
|
21
|
+
|
22
|
+
target_folder.rmtree if target_folder.exist?
|
23
|
+
target_folder.mkdir unless target_folder.exist?
|
24
|
+
target = target_folder + "#{self.name}.framework"
|
25
|
+
File.symlink(source, target)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# Let cocoapods use the prebuild framework files in install process.
|
34
|
+
#
|
35
|
+
# the code only effect the second pod install process.
|
36
|
+
#
|
37
|
+
module Pod
|
38
|
+
class Installer
|
39
|
+
|
40
|
+
# Remove the old target files if prebuild frameworks changed
|
41
|
+
def remove_target_files_if_needed
|
42
|
+
|
43
|
+
changes = Pod::Prebuild.framework_changes
|
44
|
+
return if changes == nil
|
45
|
+
added = changes[:added] || []
|
46
|
+
changed = changes[:changed] || []
|
47
|
+
deleted = changes[:removed] || []
|
48
|
+
|
49
|
+
(added + changed + deleted).each do |name|
|
50
|
+
root_name = Specification.root_name(name)
|
51
|
+
next if self.sandbox.local?(root_name)
|
52
|
+
|
53
|
+
# delete the cached files
|
54
|
+
target_path = self.sandbox.pod_dir(root_name)
|
55
|
+
target_path.rmtree if target_path.exist?
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# Modify specification to use only the prebuild framework after analyzing
|
62
|
+
old_method2 = instance_method(:resolve_dependencies)
|
63
|
+
define_method(:resolve_dependencies) do
|
64
|
+
|
65
|
+
if Pod.is_prebuild_stage
|
66
|
+
old_method2.bind(self).()
|
67
|
+
else
|
68
|
+
# Remove the old target files, else it will not notice file changes
|
69
|
+
self.remove_target_files_if_needed
|
70
|
+
old_method2.bind(self).()
|
71
|
+
|
72
|
+
self.analysis_result.specifications.each do |spec|
|
73
|
+
next unless self.prebuild_pod_names.include? spec.name
|
74
|
+
spec.attributes_hash["vendored_frameworks"] = "#{spec.name}.framework"
|
75
|
+
spec.attributes_hash["source_files"] = []
|
76
|
+
|
77
|
+
# to avoid the warning of missing license
|
78
|
+
spec.attributes_hash["license"] = {}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Override the download step to skip download and prepare file in target folder
|
86
|
+
old_method = instance_method(:install_source_of_pod)
|
87
|
+
define_method(:install_source_of_pod) do |pod_name|
|
88
|
+
|
89
|
+
if Pod.is_prebuild_stage
|
90
|
+
return old_method.bind(self).(pod_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
# copy from original
|
94
|
+
pod_installer = create_pod_installer(pod_name)
|
95
|
+
# \copy from original
|
96
|
+
|
97
|
+
if self.prebuild_pod_names.include? pod_name
|
98
|
+
pod_installer.install_for_prebuild!(self.sandbox)
|
99
|
+
else
|
100
|
+
pod_installer.install!
|
101
|
+
end
|
102
|
+
|
103
|
+
# copy from original
|
104
|
+
@installed_specs.concat(pod_installer.specs_by_platform.values.flatten.uniq)
|
105
|
+
# \copy from original
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'feature_switches'
|
4
|
+
require_relative 'prebuild_sandbox'
|
5
|
+
|
6
|
+
Pod::HooksManager.register('cocoapods-binary', :pre_install) do |installer_context|
|
7
|
+
|
8
|
+
# check user_framework is on
|
9
|
+
podfile = installer_context.podfile
|
10
|
+
podfile.target_definition_list.each do |target_definition|
|
11
|
+
next if target_definition.prebuild_framework_names.empty?
|
12
|
+
if not target_definition.uses_frameworks?
|
13
|
+
STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# hook the install command to install twice (first for the prebuilding)
|
20
|
+
module Pod
|
21
|
+
class Config
|
22
|
+
attr_writer :sandbox
|
23
|
+
attr_writer :lockfile
|
24
|
+
end
|
25
|
+
|
26
|
+
class Command
|
27
|
+
class Install
|
28
|
+
|
29
|
+
|
30
|
+
# --- patch ---
|
31
|
+
old_method = instance_method(:run)
|
32
|
+
|
33
|
+
define_method(:run) do
|
34
|
+
|
35
|
+
# -- step 1: prebuild framework ---
|
36
|
+
|
37
|
+
# control features
|
38
|
+
Pod.is_prebuild_stage = true
|
39
|
+
Pod::Podfile::DSL.enable_prebuild_patch true # enable sikpping for prebuild targets
|
40
|
+
Pod::Installer.force_disable_integration true # don't integrate targets
|
41
|
+
Pod::Config.force_disable_write_lockfile true # disbale write lock file for perbuild podfile
|
42
|
+
Pod::Installer.disable_install_complete_message true # disable install complete message
|
43
|
+
|
44
|
+
# make another custom sandbox
|
45
|
+
standard_sandbox = self.config.sandbox
|
46
|
+
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
|
47
|
+
self.config.sandbox = prebuild_sandbox
|
48
|
+
|
49
|
+
# install
|
50
|
+
Pod::UI.puts "✔️ Prebuild frameworks"
|
51
|
+
old_method.bind(self).()
|
52
|
+
|
53
|
+
|
54
|
+
# -- step 2: prebuild framework ---
|
55
|
+
|
56
|
+
# reset the environment
|
57
|
+
self.config.podfile = nil
|
58
|
+
self.config.lockfile = nil
|
59
|
+
self.config.sandbox = standard_sandbox
|
60
|
+
Pod.is_prebuild_stage = false
|
61
|
+
Pod::Installer.force_disable_integration false
|
62
|
+
Pod::Podfile::DSL.enable_prebuild_patch false
|
63
|
+
Pod::Config.force_disable_write_lockfile false
|
64
|
+
Pod::Installer.disable_install_complete_message false
|
65
|
+
|
66
|
+
# install
|
67
|
+
Pod::UI.puts "\n"
|
68
|
+
Pod::UI.puts "✔️ Pod Install"
|
69
|
+
old_method.bind(self).()
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative 'rome/build_framework'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Prebuild
|
5
|
+
class_attr_accessor :framework_changes
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# patch prebuild ability
|
10
|
+
module Pod
|
11
|
+
|
12
|
+
class_attr_accessor :old_manifest_lock_file
|
13
|
+
|
14
|
+
class Installer
|
15
|
+
|
16
|
+
def prebuild_frameworks
|
17
|
+
|
18
|
+
local_manifest = Pod.old_manifest_lock_file
|
19
|
+
sandbox_path = sandbox.root
|
20
|
+
existed_framework_folder = sandbox.generate_framework_path
|
21
|
+
|
22
|
+
if local_manifest != nil
|
23
|
+
|
24
|
+
changes = local_manifest.detect_changes_with_podfile(podfile)
|
25
|
+
Pod::Prebuild.framework_changes = changes # save the chagnes info for later stage
|
26
|
+
added = changes[:added] || []
|
27
|
+
changed = changes[:changed] || []
|
28
|
+
unchanged = changes[:unchanged] || []
|
29
|
+
deleted = changes[:removed] || []
|
30
|
+
|
31
|
+
existed_framework_folder.mkdir unless existed_framework_folder.exist?
|
32
|
+
exsited_framework_names = sandbox.exsited_framework_names
|
33
|
+
|
34
|
+
# deletions
|
35
|
+
# remove all frameworks except ones to remain
|
36
|
+
unchange_framework_names = added + unchanged
|
37
|
+
to_delete = exsited_framework_names.select do |framework_name|
|
38
|
+
not unchange_framework_names.include?(framework_name)
|
39
|
+
end
|
40
|
+
to_delete.each do |framework_name|
|
41
|
+
path = existed_framework_folder + (framework_name + ".framework")
|
42
|
+
path.rmtree if path.exist?
|
43
|
+
end
|
44
|
+
|
45
|
+
# additions
|
46
|
+
missing = unchanged.select do |pod_name|
|
47
|
+
not exsited_framework_names.include?(pod_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
targets = (added + changed + missing).map do |pod_name|
|
51
|
+
self.pod_targets.find do |pod_target|
|
52
|
+
pod_target.root_spec.name == pod_name
|
53
|
+
end
|
54
|
+
end
|
55
|
+
Pod::Prebuild.build(sandbox_path, existed_framework_folder, targets)
|
56
|
+
|
57
|
+
else
|
58
|
+
Pod::Prebuild.framework_changes = nil
|
59
|
+
Pod::Prebuild.build(sandbox_path, existed_framework_folder, self.pod_targets)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Remove useless files
|
63
|
+
# only keep manifest.lock and framework folder
|
64
|
+
to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
|
65
|
+
to_delete_files = sandbox_path.children.select do |file|
|
66
|
+
filename = File.basename(file)
|
67
|
+
not to_remain_files.include?(filename)
|
68
|
+
end
|
69
|
+
to_delete_files.each do |path|
|
70
|
+
path.rmtree if path.exist?
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# check if need to prebuild
|
76
|
+
old_method = instance_method(:install!)
|
77
|
+
define_method(:install!) do
|
78
|
+
return old_method.bind(self).() unless Pod.is_prebuild_stage
|
79
|
+
|
80
|
+
# check if need build frameworks
|
81
|
+
local_manifest = self.sandbox.manifest
|
82
|
+
changes = local_manifest.detect_changes_with_podfile(podfile)
|
83
|
+
added = changes[:added] || []
|
84
|
+
changed = changes[:changed] || []
|
85
|
+
unchanged = changes[:unchanged] || []
|
86
|
+
|
87
|
+
unchange_framework_names = added + unchanged
|
88
|
+
exsited_framework_names = sandbox.exsited_framework_names
|
89
|
+
missing = unchanged.select do |pod_name|
|
90
|
+
not exsited_framework_names.include?(pod_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
if (added + changed + missing).empty?
|
94
|
+
# don't do the install
|
95
|
+
exsited_framework_names.each do |name|
|
96
|
+
UI.puts "Using #{name}"
|
97
|
+
end
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
# normal install
|
102
|
+
# Save manifest before generate a new one
|
103
|
+
Pod.old_manifest_lock_file = local_manifest
|
104
|
+
old_method.bind(self).()
|
105
|
+
end
|
106
|
+
|
107
|
+
# patch the post install hook
|
108
|
+
old_method2 = instance_method(:run_plugins_post_install_hooks)
|
109
|
+
define_method(:run_plugins_post_install_hooks) do
|
110
|
+
old_method2.bind(self).()
|
111
|
+
if Pod::is_prebuild_stage
|
112
|
+
self.prebuild_frameworks
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# a flag that indicate stages
|
4
|
+
class_attr_accessor :is_prebuild_stage
|
5
|
+
|
6
|
+
|
7
|
+
# a switch for the `pod` DSL to make it only valid for ':binary => true'
|
8
|
+
class Podfile
|
9
|
+
module DSL
|
10
|
+
|
11
|
+
@@enable_prebuild_patch = false
|
12
|
+
|
13
|
+
# when enable, `pod` function will skip all pods without 'prebuild => true'
|
14
|
+
def self.enable_prebuild_patch(value)
|
15
|
+
@@enable_prebuild_patch = value
|
16
|
+
end
|
17
|
+
|
18
|
+
# --- patch ---
|
19
|
+
old_method = instance_method(:pod)
|
20
|
+
|
21
|
+
define_method(:pod) do |name, *args|
|
22
|
+
if !@@enable_prebuild_patch
|
23
|
+
old_method.bind(self).(name, *args)
|
24
|
+
return
|
25
|
+
end
|
26
|
+
options = args.last
|
27
|
+
return unless options.is_a?(Hash)
|
28
|
+
prebuild = options[Pod::Prebuild.keyword]
|
29
|
+
if prebuild
|
30
|
+
old_method.bind(self).(name, *args)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# a force disable option for integral
|
38
|
+
class Installer
|
39
|
+
def self.force_disable_integration(value)
|
40
|
+
@@force_disable_integration = value
|
41
|
+
end
|
42
|
+
|
43
|
+
old_method = instance_method(:integrate_user_project)
|
44
|
+
define_method(:integrate_user_project) do
|
45
|
+
if @@force_disable_integration
|
46
|
+
return
|
47
|
+
end
|
48
|
+
old_method.bind(self).()
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# a option to disable install complete message
|
53
|
+
class Installer
|
54
|
+
def self.disable_install_complete_message(value)
|
55
|
+
@@disable_install_complete_message = value
|
56
|
+
end
|
57
|
+
|
58
|
+
old_method = instance_method(:print_post_install_message)
|
59
|
+
define_method(:print_post_install_message) do
|
60
|
+
if @@disable_install_complete_message
|
61
|
+
return
|
62
|
+
end
|
63
|
+
old_method.bind(self).()
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# option to disable write lockfiles
|
68
|
+
class Config
|
69
|
+
|
70
|
+
@@force_disable_write_lockfile
|
71
|
+
def self.force_disable_write_lockfile(value)
|
72
|
+
@@force_disable_write_lockfile = value
|
73
|
+
end
|
74
|
+
|
75
|
+
old_method = instance_method(:lockfile_path)
|
76
|
+
define_method(:lockfile_path) do
|
77
|
+
if @@force_disable_write_lockfile
|
78
|
+
return self.sandbox.root + 'Manifest.lock.bak'
|
79
|
+
else
|
80
|
+
return old_method.bind(self).()
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
class Prebuild
|
4
|
+
def self.keyword
|
5
|
+
:binary
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Podfile
|
10
|
+
class TargetDefinition
|
11
|
+
|
12
|
+
## --- option for setting using prebuild framework ---
|
13
|
+
def parse_prebuild_framework(name, requirements)
|
14
|
+
options = requirements.last
|
15
|
+
return requirements unless options.is_a?(Hash)
|
16
|
+
|
17
|
+
should_prebuild_framework = options.delete(Pod::Prebuild.keyword)
|
18
|
+
pod_name = Specification.root_name(name)
|
19
|
+
set_prebuild_for_pod(pod_name, should_prebuild_framework)
|
20
|
+
requirements.pop if options.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_prebuild_for_pod(pod_name, should_prebuild)
|
24
|
+
return unless should_prebuild == true
|
25
|
+
@prebuild_framework_names ||= []
|
26
|
+
@prebuild_framework_names.push pod_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def prebuild_framework_names
|
30
|
+
@prebuild_framework_names || []
|
31
|
+
end
|
32
|
+
|
33
|
+
# ---- patch method ----
|
34
|
+
# We want modify `store_pod` method, but it's hard to insert a line in the
|
35
|
+
# implementation. So we patch a method called in `store_pod`.
|
36
|
+
old_method = instance_method(:parse_inhibit_warnings)
|
37
|
+
|
38
|
+
define_method(:parse_inhibit_warnings) do |name, requirements|
|
39
|
+
parse_prebuild_framework(name, requirements)
|
40
|
+
old_method.bind(self).(name, requirements)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
module Pod
|
49
|
+
class Installer
|
50
|
+
def prebuild_pod_names
|
51
|
+
@prebuild_pod_names ||= self.podfile.target_definition_list.map(&:prebuild_framework_names).flatten.uniq
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Pod
|
57
|
+
class AggregateTarget
|
58
|
+
|
59
|
+
def have_prebuild_pod_targets?
|
60
|
+
prebuild_framework_names = self.target_definition.prebuild_framework_names
|
61
|
+
return (prebuild_framework_names != nil and !prebuild_framework_names.empty?)
|
62
|
+
end
|
63
|
+
|
64
|
+
def prebuild_pod_targets
|
65
|
+
prebuild_framework_names = self.target_definition.prebuild_framework_names
|
66
|
+
pod_targets = self.pod_targets.select { |pod_target| prebuild_framework_names.include?(pod_target.pod_name) }
|
67
|
+
return pod_targets
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pod
|
2
|
+
class PrebuildSandbox < Sandbox
|
3
|
+
|
4
|
+
# [String] standard_sandbox_path
|
5
|
+
def self.from_standard_sanbox_path(path)
|
6
|
+
prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
|
7
|
+
self.new(prebuild_sandbox_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_standard_sandbox(sandbox)
|
11
|
+
self.from_standard_sanbox_path(sandbox.root)
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_framework_path
|
15
|
+
self.root + "Frameworks"
|
16
|
+
end
|
17
|
+
|
18
|
+
def framework_path_for_pod_name(name)
|
19
|
+
self.generate_framework_path + "#{name}.framework"
|
20
|
+
end
|
21
|
+
|
22
|
+
def exsited_framework_names
|
23
|
+
[] unless generate_framework_path.exist?
|
24
|
+
generate_framework_path.children.map do |framework_name|
|
25
|
+
extension = File.extname(framework_name)
|
26
|
+
if extension == ".framework"
|
27
|
+
File.basename(framework_name, extension)
|
28
|
+
else
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
end.reject(&:nil?)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'fourflusher'
|
2
|
+
require_relative '../feature_switches'
|
3
|
+
|
4
|
+
|
5
|
+
CONFIGURATION = "Release"
|
6
|
+
PLATFORMS = { 'iphonesimulator' => 'iOS',
|
7
|
+
'appletvsimulator' => 'tvOS',
|
8
|
+
'watchsimulator' => 'watchOS' }
|
9
|
+
|
10
|
+
# Build specific target to framework file
|
11
|
+
# @param [PodTarget] target
|
12
|
+
# a specific pod target
|
13
|
+
#
|
14
|
+
def build_for_iosish_platform(sandbox, build_dir, target, device, simulator)
|
15
|
+
deployment_target = target.platform.deployment_target.to_s
|
16
|
+
|
17
|
+
target_label = target.label
|
18
|
+
Pod::UI.puts "Prebuilding #{target_label}..."
|
19
|
+
xcodebuild(sandbox, target_label, device, deployment_target)
|
20
|
+
xcodebuild(sandbox, target_label, simulator, deployment_target)
|
21
|
+
|
22
|
+
root_name = target.pod_name
|
23
|
+
module_name = target.product_module_name
|
24
|
+
|
25
|
+
executable_path = "#{build_dir}/#{root_name}"
|
26
|
+
device_lib = "#{build_dir}/#{CONFIGURATION}-#{device}/#{root_name}/#{module_name}.framework/#{module_name}"
|
27
|
+
device_framework_lib = File.dirname(device_lib)
|
28
|
+
simulator_lib = "#{build_dir}/#{CONFIGURATION}-#{simulator}/#{root_name}/#{module_name}.framework/#{module_name}"
|
29
|
+
|
30
|
+
return unless File.file?(device_lib) && File.file?(simulator_lib)
|
31
|
+
|
32
|
+
lipo_log = `lipo -create -output #{executable_path} #{device_lib} #{simulator_lib}`
|
33
|
+
puts lipo_log unless File.exist?(executable_path)
|
34
|
+
|
35
|
+
FileUtils.mv executable_path, device_lib, :force => true
|
36
|
+
FileUtils.mv device_framework_lib, build_dir, :force => true
|
37
|
+
FileUtils.rm simulator_lib if File.file?(simulator_lib)
|
38
|
+
FileUtils.rm device_lib if File.file?(device_lib)
|
39
|
+
end
|
40
|
+
|
41
|
+
def xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil)
|
42
|
+
args = %W(-project #{sandbox.project_path.realdirpath} -scheme #{target} -configuration #{CONFIGURATION} -sdk #{sdk})
|
43
|
+
platform = PLATFORMS[sdk]
|
44
|
+
args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
|
45
|
+
Pod::Executable.execute_command 'xcodebuild', args, true
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
module Pod
|
51
|
+
class Prebuild
|
52
|
+
|
53
|
+
# Build the frameworks with sandbox and targets
|
54
|
+
#
|
55
|
+
# @param [String] sandbox_root_path
|
56
|
+
# The sandbox root path where the targets project place
|
57
|
+
#
|
58
|
+
# [Pathname] output_path
|
59
|
+
# output path for generated frameworks
|
60
|
+
#
|
61
|
+
# [Array<PodTarget>] targets
|
62
|
+
# The pod targets to build
|
63
|
+
#
|
64
|
+
def self.build(sandbox_root_path, output_path, targets)
|
65
|
+
|
66
|
+
return unless not targets.empty?
|
67
|
+
|
68
|
+
sandbox_root = Pathname(sandbox_root_path)
|
69
|
+
sandbox = Pod::Sandbox.new(sandbox_root)
|
70
|
+
|
71
|
+
build_dir = sandbox_root.parent + 'build'
|
72
|
+
destination = output_path
|
73
|
+
|
74
|
+
build_dir.rmtree if build_dir.directory?
|
75
|
+
|
76
|
+
|
77
|
+
Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
|
78
|
+
|
79
|
+
targets.each do |target|
|
80
|
+
case target.platform.name
|
81
|
+
when :ios then build_for_iosish_platform(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator')
|
82
|
+
when :osx then xcodebuild(sandbox, target.label)
|
83
|
+
when :tvos then nil
|
84
|
+
when :watchos then nil
|
85
|
+
# when :tvos then build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator')
|
86
|
+
# when :watchos then build_for_iosish_platform(sandbox, build_dir, target, 'watchos', 'watchsimulator')
|
87
|
+
else raise "Unknown platform '#{target.platform.name}'" end
|
88
|
+
end
|
89
|
+
|
90
|
+
raise Pod::Informative, 'The build directory was not found in the expected location.' unless build_dir.directory?
|
91
|
+
|
92
|
+
# Make sure the device target overwrites anything in the simulator build, otherwise iTunesConnect
|
93
|
+
# can get upset about Info.plist containing references to the simulator SDK
|
94
|
+
frameworks = build_dir.children.select{ |path| File.extname(path) == ".framework" }
|
95
|
+
Pod::UI.puts "Built #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)}"
|
96
|
+
|
97
|
+
targets.each do |pod_target|
|
98
|
+
consumer = pod_target.root_spec.consumer(pod_target.platform.name)
|
99
|
+
file_accessor = Pod::Sandbox::FileAccessor.new(sandbox.pod_dir(pod_target.pod_name), consumer)
|
100
|
+
frameworks += file_accessor.vendored_libraries
|
101
|
+
frameworks += file_accessor.vendored_frameworks
|
102
|
+
end
|
103
|
+
frameworks.uniq!
|
104
|
+
|
105
|
+
Pod::UI.puts "Copying #{frameworks.count} #{'frameworks'.pluralize(frameworks.count)} " \
|
106
|
+
"to `#{destination.relative_path_from Pathname.pwd}`"
|
107
|
+
|
108
|
+
frameworks.each do |framework|
|
109
|
+
FileUtils.mkdir_p destination
|
110
|
+
FileUtils.cp_r framework, destination, :remove_destination => true
|
111
|
+
end
|
112
|
+
build_dir.rmtree if build_dir.directory?
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -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,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cocoapods-binary
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- leavez
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-24 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.4.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: fourflusher
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.3'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rake
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
description: A short description of cocoapods-binary.
|
76
|
+
email:
|
77
|
+
- gaojiji@gmail.com
|
78
|
+
executables: []
|
79
|
+
extensions: []
|
80
|
+
extra_rdoc_files: []
|
81
|
+
files:
|
82
|
+
- ".gitignore"
|
83
|
+
- Gemfile
|
84
|
+
- LICENSE.txt
|
85
|
+
- README.md
|
86
|
+
- Rakefile
|
87
|
+
- cocoapods-binary.gemspec
|
88
|
+
- lib/cocoapods-binary.rb
|
89
|
+
- lib/cocoapods-binary/Integration.rb
|
90
|
+
- lib/cocoapods-binary/Main.rb
|
91
|
+
- lib/cocoapods-binary/Prebuild.rb
|
92
|
+
- lib/cocoapods-binary/feature_switches.rb
|
93
|
+
- lib/cocoapods-binary/gem_version.rb
|
94
|
+
- lib/cocoapods-binary/podfile_options.rb
|
95
|
+
- lib/cocoapods-binary/prebuild_sandbox.rb
|
96
|
+
- lib/cocoapods-binary/rome/build_framework.rb
|
97
|
+
- lib/cocoapods-binary/tool/tool.rb
|
98
|
+
- lib/cocoapods_plugin.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
homepage: https://github.com/EXAMPLE/cocoapods-binary
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.4.8
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: A longer description of cocoapods-binary.
|
124
|
+
test_files:
|
125
|
+
- spec/spec_helper.rb
|