cocoapods-jiffy 0.1.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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +23 -0
- data/README.md +71 -0
- data/Rakefile +12 -0
- data/cocoapods-jiffy.gemspec +25 -0
- data/lib/cocoapods-jiffy.rb +211 -0
- data/lib/cocoapods-jiffy/gem_version.rb +3 -0
- data/lib/cocoapods-jiffy/post_install.rb +177 -0
- data/lib/cocoapods-jiffy/pre_install.rb +11 -0
- data/lib/cocoapods_plugin.rb +3 -0
- data/spec/spec_helper.rb +44 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bca41e78c4405209109d669d5e046fdb060e6101
|
4
|
+
data.tar.gz: 0329753fb6a89cf47c97ce86e48653cd75dd73ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd40804d0a12220c02cd165559a1472ad92d17bacc509631bb0161594da54cce2681a7cbfc96bb306ca61f169aff20c3aeaa54622da01cf1d8bcb383bf6f8c20
|
7
|
+
data.tar.gz: 5d8ec0b70da8488fba4bbce0aa7bbc53669aa9349ef2d3d04d290b6c853a4384b6e47870b6850654bf5a1aaf1c082a158be7496a4fab0d9f53a874c0919c5801
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cocoapods-rome (0.7.0)
|
5
|
+
cocoapods (>= 1.1.0.beta.1, < 2.0)
|
6
|
+
fourflusher (~> 1.0.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (4.2.7)
|
12
|
+
i18n (~> 0.7)
|
13
|
+
json (~> 1.7, >= 1.7.7)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
bacon (1.2.0)
|
18
|
+
claide (1.0.0)
|
19
|
+
cocoapods (1.1.0.beta.1)
|
20
|
+
activesupport (>= 4.0.2, < 5)
|
21
|
+
claide (>= 1.0.0, < 2.0)
|
22
|
+
cocoapods-core (= 1.1.0.beta.1)
|
23
|
+
cocoapods-deintegrate (>= 1.0.0, < 2.0)
|
24
|
+
cocoapods-downloader (>= 1.1.0, < 2.0)
|
25
|
+
cocoapods-plugins (>= 1.0.0, < 2.0)
|
26
|
+
cocoapods-search (>= 1.0.0, < 2.0)
|
27
|
+
cocoapods-stats (>= 1.0.0, < 2.0)
|
28
|
+
cocoapods-trunk (>= 1.0.0, < 2.0)
|
29
|
+
cocoapods-try (>= 1.1.0, < 2.0)
|
30
|
+
colored (~> 1.2)
|
31
|
+
escape (~> 0.0.4)
|
32
|
+
fourflusher (~> 1.0.1)
|
33
|
+
gh_inspector (~> 1.0)
|
34
|
+
molinillo (~> 0.5.0)
|
35
|
+
nap (~> 1.0)
|
36
|
+
xcodeproj (>= 1.2.0, < 2.0)
|
37
|
+
cocoapods-core (1.1.0.beta.1)
|
38
|
+
activesupport (>= 4.0.2)
|
39
|
+
fuzzy_match (~> 2.0.4)
|
40
|
+
nap (~> 1.0)
|
41
|
+
cocoapods-deintegrate (1.0.0)
|
42
|
+
cocoapods-downloader (1.1.0)
|
43
|
+
cocoapods-plugins (1.0.0)
|
44
|
+
nap
|
45
|
+
cocoapods-search (1.0.0)
|
46
|
+
cocoapods-stats (1.0.0)
|
47
|
+
cocoapods-trunk (1.0.0)
|
48
|
+
nap (>= 0.8, < 2.0)
|
49
|
+
netrc (= 0.7.8)
|
50
|
+
cocoapods-try (1.1.0)
|
51
|
+
colored (1.2)
|
52
|
+
escape (0.0.4)
|
53
|
+
fourflusher (1.0.1)
|
54
|
+
fuzzy_match (2.0.4)
|
55
|
+
gh_inspector (1.0.2)
|
56
|
+
i18n (0.7.0)
|
57
|
+
json (1.8.3)
|
58
|
+
minitest (5.9.0)
|
59
|
+
molinillo (0.5.0)
|
60
|
+
nap (1.1.0)
|
61
|
+
netrc (0.7.8)
|
62
|
+
rake (11.2.2)
|
63
|
+
thread_safe (0.3.5)
|
64
|
+
tzinfo (1.2.2)
|
65
|
+
thread_safe (~> 0.1)
|
66
|
+
xcodeproj (1.2.0)
|
67
|
+
activesupport (>= 3)
|
68
|
+
claide (>= 1.0.0, < 2.0)
|
69
|
+
colored (~> 1.2)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
bacon
|
76
|
+
bundler (~> 1.3)
|
77
|
+
cocoapods-rome!
|
78
|
+
rake
|
79
|
+
|
80
|
+
BUNDLED WITH
|
81
|
+
1.12.5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2015 Boris Bügling <boris@icculus.org>
|
2
|
+
Copyright (c) 2016 Krunoslav Zaher <krunoslav.zaher@gmail.com>
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# cocoapods-jiffy
|
2
|
+
|
3
|
+
Builds your CocoaPods dependencies in a jiffy.
|
4
|
+
|
5
|
+
It creates dynamic frameworks and caches them locally per xcode version, git commit, platform and configuration.
|
6
|
+
|
7
|
+
Built libraries are cached in `~/.cocoapods/jiffy-cache`.
|
8
|
+
|
9
|
+
This is a fork of [CocoaPods Rome](https://github.com/CocoaPods/Rome) plugin.
|
10
|
+
|
11
|
+
It's just some code that helped me to optimize build speed for my projects. If have some issue with it, please make a PR,
|
12
|
+
entire code base is ~200 lines, so it's not hard to figure out what went wrong.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ gem install cocoapods-jiffy
|
18
|
+
```
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Write a simple Podfile like this:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
platform :ios, '9.0' # this will be used as platform for caching
|
26
|
+
|
27
|
+
plugin 'cocoapods-jiify'
|
28
|
+
|
29
|
+
target 'CoolApp' do
|
30
|
+
# just specify targets should be cached by using `cachedpod` instead of `pod`
|
31
|
+
# targets will be cached locally per xcode version, commit and configuration (debug/release)
|
32
|
+
cachedpod 'RxSwift'
|
33
|
+
cachedpod 'RxCocoa'
|
34
|
+
cachedpod 'RxDataSources' # if one dependency is meant to be cached, then all of it's dependencies
|
35
|
+
# will also be cached, so don't list them again using `pod` or it will be
|
36
|
+
# error
|
37
|
+
|
38
|
+
# for other targets just use normal `pod` definition
|
39
|
+
pod 'R.swift' # this is a tool
|
40
|
+
pod 'Crashlytics' # this has already built vendored framework
|
41
|
+
pod 'Fabric'
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
then run this:
|
46
|
+
|
47
|
+
```bash
|
48
|
+
BUILD_JIFFY=1 pod install && USE_JIFFY=1 pod install
|
49
|
+
```
|
50
|
+
|
51
|
+
... have no idea can this be done more nicely, so if you can figure out it can be, please shoot me a PR.
|
52
|
+
|
53
|
+
and you will end up with optimized Pods directory:
|
54
|
+
|
55
|
+
```
|
56
|
+
$ tree Pods/
|
57
|
+
├── R.swift
|
58
|
+
│ ├── License
|
59
|
+
│ └── rswift
|
60
|
+
├── Release
|
61
|
+
│ └── iphoneos
|
62
|
+
│ ├── RxCocoa
|
63
|
+
│ │ ├── RxCocoa.Release.podspec
|
64
|
+
│ │ └── RxCocoa.framework
|
65
|
+
│ ├── RxDataSources
|
66
|
+
│ │ ├── RxDataSources.Release.podspec
|
67
|
+
│ │ └── RxDataSources.framework
|
68
|
+
│ ├── RxSwift
|
69
|
+
│ │ ├── RxSwift.Release.podspec
|
70
|
+
│ │ └── RxSwift.framework
|
71
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cocoapods-jiffy/gem_version.rb'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'cocoapods-jiffy'
|
8
|
+
spec.version = CocoapodsJiffy::VERSION
|
9
|
+
spec.authors = ['Krunoslav Zaher']
|
10
|
+
spec.email = ['krunoslav.zaher@gmail.com']
|
11
|
+
spec.summary = 'Builds your CocoaPods dependencies in a jiffy by building them as dynamic frameworks and caches them locally per xcode version, git commit, platform and configuration.'
|
12
|
+
spec.homepage = 'https://github.com/kzaher/Jiffy'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'cocoapods', '>= 1.1.0.beta.1', '< 2.0'
|
21
|
+
spec.add_dependency 'fourflusher', '~> 1.0.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'cocoapods-jiffy/gem_version'
|
2
|
+
require 'cocoapods'
|
3
|
+
|
4
|
+
module CocoapodsJiffy
|
5
|
+
PLATFORMS = { 'iphonesimulator' => 'iOS',
|
6
|
+
'appletvsimulator' => 'tvOS',
|
7
|
+
'watchsimulator' => 'watchOS' }.freeze
|
8
|
+
|
9
|
+
PLATFORM_SYMBOL_HASH = {
|
10
|
+
ios: 'iphoneos',
|
11
|
+
osx: 'osx',
|
12
|
+
tvos: 'appletvos',
|
13
|
+
watchos: 'watchos'
|
14
|
+
}.freeze
|
15
|
+
JIFFY_PODFILE_LOCK = 'Podfile.jiffy.lock'.freeze
|
16
|
+
PODFILE_LOCK = 'Podfile.lock'.freeze
|
17
|
+
XCODE_OUTPUT = `xcodebuild -version`.lines
|
18
|
+
BUILD_TOOLS_VERSION = XCODE_OUTPUT[0].strip + ' ' + XCODE_OUTPUT[1].strip.split(' ').last
|
19
|
+
|
20
|
+
CONFIGURATIONS = %w(Debug Release).freeze
|
21
|
+
|
22
|
+
def self.create_lockfile(installer_context, name = PODFILE_LOCK)
|
23
|
+
create_lockfile_for_path(installer_context.sandbox_root + "/../#{name}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.create_lockfile_for_path(path)
|
27
|
+
lockfile_path = Pathname.new(path)
|
28
|
+
lockfile = Pod::Lockfile.from_file(lockfile_path)
|
29
|
+
lockfile
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module CocoapodsJiffy
|
34
|
+
@@build_jiffy = ENV['BUILD_JIFFY'].to_i == 1
|
35
|
+
@@use_jiffy = ENV['USE_JIFFY'].to_i == 1
|
36
|
+
|
37
|
+
@@dependencies_per_pod = nil
|
38
|
+
@@podfile_path = nil
|
39
|
+
|
40
|
+
def self.build_jiffy
|
41
|
+
@@build_jiffy
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.build_jiffy=(v)
|
45
|
+
@@build_jiffy = v
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.use_jiffy
|
49
|
+
@@use_jiffy
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.use_jiffy=(v)
|
53
|
+
@@use_jiffy = v
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.dependencies_per_pod
|
57
|
+
@@dependencies_per_pod
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.dependencies_per_pod=(v)
|
61
|
+
@@dependencies_per_pod = v
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.podfile_path
|
65
|
+
@@podfile_path
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.podfile_path=(v)
|
69
|
+
@@podfile_path = v
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.generate_configuration_mappings
|
73
|
+
configuration_mappings = { 'Debug' => 'Debug', 'Release' => 'Release' }
|
74
|
+
env_configurations = ''
|
75
|
+
env_configurations = ENV['CONFIGURATIONS_JIFFY'] unless ENV['CONFIGURATIONS_JIFFY'].nil?
|
76
|
+
environment_configuration_mappings = env_configurations.split(',').collect do |pair|
|
77
|
+
parts = pair.split('=')
|
78
|
+
result = [parts[0].strip, parts[1].strip]
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
environment_configuration_mappings.each do |project_config, jiffy_prebuilt_config|
|
83
|
+
configuration_mappings[project_config] = jiffy_prebuilt_config
|
84
|
+
end
|
85
|
+
configuration_mappings
|
86
|
+
end
|
87
|
+
|
88
|
+
CONFIGURATION_MAPPINGS = generate_configuration_mappings
|
89
|
+
end
|
90
|
+
|
91
|
+
module CocoapodsJiffy
|
92
|
+
def self.collect_dependencies(name)
|
93
|
+
dependencies = CocoapodsJiffy.dependencies_per_pod[name]
|
94
|
+
return [name] if dependencies.nil? || dependencies.length.zero?
|
95
|
+
|
96
|
+
all_dependencies = [[name]] + dependencies.collect do |dep|
|
97
|
+
collect_dependencies(dep)
|
98
|
+
end
|
99
|
+
|
100
|
+
# exclude subspecs, we know it's a subspec if it contains "/"
|
101
|
+
calculated_dependencies = all_dependencies.flatten.uniq.select { |x| !x.include? '/' }
|
102
|
+
calculated_dependencies
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.parse_name_from_name_version(name_version)
|
106
|
+
# Pod::Spec.name_and_version_from_string(
|
107
|
+
name_version.split(' ').first
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.parse_dependencies(jiffy_lockfile_path)
|
111
|
+
raise "#{jiffy_lockfile_path} is missing, please run `BUILD_JIFFY pod install` first" unless File.exist?(jiffy_lockfile_path)
|
112
|
+
lockfile = create_lockfile_for_path(jiffy_lockfile_path)
|
113
|
+
|
114
|
+
dependencies_per_pod = {}
|
115
|
+
|
116
|
+
lockfile.to_hash['PODS'].each do |pod|
|
117
|
+
pod_name_version = pod.is_a?(String) ? pod : pod.keys.first
|
118
|
+
dependencies = []
|
119
|
+
unless pod.is_a?(String)
|
120
|
+
dependencies = pod.values.first.collect do |dep|
|
121
|
+
dependency_name = parse_name_from_name_version(dep)
|
122
|
+
dependency_name
|
123
|
+
end
|
124
|
+
end
|
125
|
+
pod_name = parse_name_from_name_version(pod_name_version)
|
126
|
+
dependencies_per_pod[pod_name] = dependencies
|
127
|
+
end
|
128
|
+
|
129
|
+
@@dependencies_per_pod = dependencies_per_pod
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.ensure_podfile_jiffy_loaded(podfile_path)
|
133
|
+
unless dependencies_per_pod.nil?
|
134
|
+
if podfile_path != podfile_path
|
135
|
+
raise "Podfiles differ #{podfile_path} != @{podfile_path}"
|
136
|
+
end
|
137
|
+
return
|
138
|
+
end
|
139
|
+
|
140
|
+
parse_dependencies(File.join(podfile_path.parent.to_s, JIFFY_PODFILE_LOCK))
|
141
|
+
end
|
142
|
+
|
143
|
+
@@cached_dependencies = []
|
144
|
+
@@normal_dependencies = []
|
145
|
+
|
146
|
+
def self.register_cached_dependency(dependency_name, included_as_a_dependency_of)
|
147
|
+
@@cached_dependencies << [dependency_name, included_as_a_dependency_of]
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.register_normal_dependency(dependency_name, included_as_a_dependency_of)
|
151
|
+
@@normal_dependencies << [dependency_name, included_as_a_dependency_of]
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.ensure_dependencies_exclusive
|
155
|
+
intersection = @@cached_dependencies.collect { |x| x[0] } & @@normal_dependencies.collect { |x| x[0] }
|
156
|
+
|
157
|
+
unless intersection.empty?
|
158
|
+
cached_dependencies_causing_issues = @@cached_dependencies.select { |dependency_name, _| intersection.include? dependency_name } .uniq
|
159
|
+
normal_dependencies_causing_issues = @@normal_dependencies.select { |dependency_name, _| intersection.include? dependency_name } .uniq
|
160
|
+
|
161
|
+
extract_description = lambda do |dependency_name, included_as_a_dependency_of|
|
162
|
+
if dependency_name == included_as_a_dependency_of
|
163
|
+
result = " #{dependency_name}"
|
164
|
+
else
|
165
|
+
result = " #{dependency_name} included as a dependency of #{included_as_a_dependency_of}"
|
166
|
+
end
|
167
|
+
|
168
|
+
result
|
169
|
+
end
|
170
|
+
|
171
|
+
cached_dependencies_causing_issues = cached_dependencies_causing_issues.collect(&extract_description)
|
172
|
+
normal_dependencies_causing_issues = normal_dependencies_causing_issues.collect(&extract_description)
|
173
|
+
|
174
|
+
cached_description = " >> dependencies causing issues that were included using `cachedpod`\n" + cached_dependencies_causing_issues.join("\n")
|
175
|
+
normal_description = " >> dependencies causing issues that were included using `pod`\n" + normal_dependencies_causing_issues.join("\n")
|
176
|
+
raise 'Found dependencies that were included as both `cachedpod` and `pod`.' + cached_description + "\n" + normal_description
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
module Pod
|
182
|
+
class Podfile
|
183
|
+
alias _pod pod
|
184
|
+
|
185
|
+
def pod(name, *args)
|
186
|
+
unless CocoapodsJiffy.build_jiffy
|
187
|
+
_pod(name, *args)
|
188
|
+
for dependency_name in CocoapodsJiffy.collect_dependencies(name)
|
189
|
+
CocoapodsJiffy.register_normal_dependency(dependency_name, name)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def cachedpod(name, *args)
|
195
|
+
if CocoapodsJiffy.use_jiffy
|
196
|
+
CocoapodsJiffy.ensure_podfile_jiffy_loaded(defined_in_file)
|
197
|
+
|
198
|
+
platform = CocoapodsJiffy::PLATFORM_SYMBOL_HASH[current_target_definition.platform.name]
|
199
|
+
dependencies = CocoapodsJiffy.collect_dependencies(name)
|
200
|
+
for dependency_name in dependencies
|
201
|
+
CocoapodsJiffy.register_cached_dependency(dependency_name, name)
|
202
|
+
CocoapodsJiffy::CONFIGURATION_MAPPINGS.each do |project_configuration, jiffy_configuration|
|
203
|
+
_pod "#{dependency_name}.#{jiffy_configuration}", path: File.join("Pods/#{jiffy_configuration}/#{platform}/#{dependency_name}"), integrate_target: false, configuration: [project_configuration]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
else
|
207
|
+
_pod(name, *args)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'fourflusher'
|
2
|
+
require 'cocoapods-jiffy'
|
3
|
+
require 'cocoapods-core/lockfile'
|
4
|
+
|
5
|
+
module CocoapodsJiffy
|
6
|
+
def self.cache_dir(podspec, device, configuration, commit)
|
7
|
+
home = ENV['HOME']
|
8
|
+
raise "Home doesn't exist" unless Dir.exist?(home)
|
9
|
+
File.join(home, '.cocoapods', 'jiffy-cache', BUILD_TOOLS_VERSION, podspec, commit, device, configuration)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.build_all_configurations_for_iosish_platform(sandbox, build_dir, target, device, simulator, destination, lockfile)
|
13
|
+
for configuration in CONFIGURATIONS
|
14
|
+
build_for_iosish_platform(sandbox, build_dir, target, device, simulator, configuration, destination, lockfile)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.build_all_configurations_for_osx(sandbox, target, _destination)
|
19
|
+
for configuration in CONFIGURATIONS
|
20
|
+
xcodebuild(sandbox, target, 'macosx', nil, configuration)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.commit_for_pod(lockfile, pod_name)
|
25
|
+
checkout_options = lockfile.checkout_options_for_pod_named(pod_name)
|
26
|
+
checksum = lockfile.checksum(pod_name)
|
27
|
+
commit = if !checkout_options.nil?
|
28
|
+
checkout_options[:commit]
|
29
|
+
elsif !checksum.nil?
|
30
|
+
checksum
|
31
|
+
else
|
32
|
+
raise "Commit not found for #{pod_name}" if checkout_options.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
commit
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.build_for_iosish_platform(sandbox, build_dir, target, device, simulator, configuration, destination, lockfile)
|
39
|
+
deployment_target = target.platform_deployment_target
|
40
|
+
target_label = target.cocoapods_target_label
|
41
|
+
|
42
|
+
spec_names = target.specs.map { |spec| [spec.root.name, spec.root.module_name] }.uniq
|
43
|
+
|
44
|
+
spec_names.each do |root_name, module_name|
|
45
|
+
commit = commit_for_pod(lockfile, root_name)
|
46
|
+
|
47
|
+
cache_path = cache_dir(root_name, device, configuration, commit)
|
48
|
+
destination_for_configuration = File.join(destination, configuration, device, root_name)
|
49
|
+
if Dir.exist?(cache_path)
|
50
|
+
puts "Skipping #{root_name} - #{device}"
|
51
|
+
else
|
52
|
+
begin
|
53
|
+
puts "Building #{root_name.green} - #{device.green}"
|
54
|
+
xcodebuild(sandbox, root_name, device, deployment_target, configuration, 'arm64 armv7 armv7s')
|
55
|
+
xcodebuild(sandbox, root_name, simulator, deployment_target, configuration, 'i386 x86_64')
|
56
|
+
rescue => exception
|
57
|
+
puts "Error building #{root_name.red}"
|
58
|
+
puts exception.to_s
|
59
|
+
puts exception.backtrace
|
60
|
+
end
|
61
|
+
executable_path = "#{build_dir}/#{root_name}"
|
62
|
+
device_lib = "#{build_dir}/#{configuration}-#{device}/#{root_name}/#{module_name}.framework/#{module_name}"
|
63
|
+
device_framework_lib = File.dirname(device_lib)
|
64
|
+
simulator_lib = "#{build_dir}/#{configuration}-#{simulator}/#{root_name}/#{module_name}.framework/#{module_name}"
|
65
|
+
simulator_framework_lib = File.dirname(simulator_lib)
|
66
|
+
license_path = File.join(device_framework_lib, 'LICENSE.md')
|
67
|
+
podfile_path = File.join(cache_path, "#{root_name}.#{configuration}.podspec")
|
68
|
+
|
69
|
+
next unless File.file?(device_lib) && File.file?(simulator_lib)
|
70
|
+
|
71
|
+
lipo_log = `lipo -create -output #{executable_path} #{device_lib} #{simulator_lib}`
|
72
|
+
puts lipo_log unless File.exist?(executable_path)
|
73
|
+
|
74
|
+
FileUtils.cp_r File.join(simulator_framework_lib, '.'), device_framework_lib
|
75
|
+
FileUtils.mv executable_path, device_lib
|
76
|
+
begin
|
77
|
+
FileUtils.mkdir_p cache_path
|
78
|
+
puts "Writing dummy LICENSE.md -> #{license_path}"
|
79
|
+
File.open(license_path, 'w') do |file|
|
80
|
+
file.write('')
|
81
|
+
end
|
82
|
+
FileUtils.cp_r device_framework_lib, cache_path, remove_destination: true
|
83
|
+
podspec_content = podspec_content(root_name, module_name, configuration)
|
84
|
+
File.open(podfile_path, 'w') do |file|
|
85
|
+
file.write(podspec_content)
|
86
|
+
end
|
87
|
+
rescue
|
88
|
+
puts "Failed to copy #{device_framework_lib} #{cache_path}"
|
89
|
+
end
|
90
|
+
|
91
|
+
# FileUtils.rm simulator_lib if File.file?(simulator_lib)
|
92
|
+
# FileUtils.rm device_lib if File.file?(device_lib)
|
93
|
+
end
|
94
|
+
|
95
|
+
puts "Copying #{cache_path} -> #{destination_for_configuration}"
|
96
|
+
FileUtils.mkdir_p destination_for_configuration
|
97
|
+
FileUtils.cp_r File.join(cache_path, '.'), destination_for_configuration, remove_destination: true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.xcodebuild(sandbox, target, sdk = 'macosx', deployment_target = nil, configuration, _arch)
|
102
|
+
puts sandbox.project_path
|
103
|
+
args = %W(-project #{sandbox.project_path} -scheme #{target} -configuration #{configuration} -sdk #{sdk}) + ['ONLY_ACTIVE_ARCH=NO', 'BITCODE_GENERATION_MODE=bitcode', 'CODE_SIGNING_REQUIRED=NO', 'CODE_SIGN_IDENTITY=']
|
104
|
+
platform = PLATFORMS[sdk]
|
105
|
+
args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil?
|
106
|
+
Pod::Executable.execute_command 'xcodebuild', args, true
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.build_dependencies(installer_context, lockfile, sandbox, build_dir, destination)
|
110
|
+
targets = installer_context.umbrella_targets.select { |t| t.specs.any? }
|
111
|
+
targets.each do |target|
|
112
|
+
puts "Processing #{target.cocoapods_target_label.green}"
|
113
|
+
|
114
|
+
case target.platform_name
|
115
|
+
when :ios then build_all_configurations_for_iosish_platform(sandbox, build_dir, target, 'iphoneos', 'iphonesimulator', destination, lockfile)
|
116
|
+
when :osx then build_all_configurations_for_osx(sandbox, target.cocoapods_target_label, destination, lockfile)
|
117
|
+
when :tvos then build_all_configurations_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator', destination, lockfile)
|
118
|
+
when :watchos then build_all_configurations_for_iosish_platform(sandbox, build_dir, target, 'watchos', 'watchsimulator', destination, lockfile)
|
119
|
+
else raise "Unknown platform '#{target.platform_name}'" end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.podspec_content(pod_name, module_name, configuration)
|
124
|
+
<<-DESC
|
125
|
+
Pod::Spec.new do |s|
|
126
|
+
s.name = "#{pod_name}.#{configuration}"
|
127
|
+
s.version = "1.0.0"
|
128
|
+
s.summary = "Caching podspec for #{pod_name}"
|
129
|
+
s.description = "Caching podspec for #{pod_name}"
|
130
|
+
s.homepage = "https://localhost.com/.cocoapods/cache/#{pod_name}"
|
131
|
+
s.license = 'MIT'
|
132
|
+
s.author = { "Krunoslav Zaher" => "krunoslav.zaher@gmail.com" }
|
133
|
+
s.source = { :path => "." }
|
134
|
+
|
135
|
+
s.requires_arc = true
|
136
|
+
|
137
|
+
s.source_files = '*.nothing'
|
138
|
+
s.frameworks = '#{module_name}'
|
139
|
+
s.vendored_frameworks = '#{module_name}.framework'
|
140
|
+
end
|
141
|
+
DESC
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.post_install(installer_context)
|
145
|
+
return unless CocoapodsJiffy.build_jiffy
|
146
|
+
sandbox_root = Pathname(installer_context.sandbox_root)
|
147
|
+
sandbox = Pod::Sandbox.new(sandbox_root)
|
148
|
+
|
149
|
+
build_dir = sandbox_root.parent + 'build'
|
150
|
+
destination = sandbox_root.parent + 'Pods'
|
151
|
+
|
152
|
+
Pod::UI.puts 'Building frameworks'
|
153
|
+
|
154
|
+
for configuration in CONFIGURATIONS
|
155
|
+
destination_for_configuration = File.join(destination, configuration)
|
156
|
+
Pod::UI.puts "Cleaning #{destination_for_configuration}"
|
157
|
+
|
158
|
+
FileUtils.rm_r destination_for_configuration, force: true
|
159
|
+
FileUtils.mkdir_p destination_for_configuration
|
160
|
+
end
|
161
|
+
|
162
|
+
puts 'SANDBOX parent: ' + sandbox_root.parent.to_s
|
163
|
+
|
164
|
+
Dir.chdir(sandbox.project_path.dirname) do
|
165
|
+
lockfile = create_lockfile(installer_context)
|
166
|
+
build_dependencies(installer_context, lockfile, sandbox, build_dir, destination)
|
167
|
+
end
|
168
|
+
|
169
|
+
# to be able to figure out what were original dependencies
|
170
|
+
puts 'Persisting lockfile Podfile.lock -> Podfile.jiffy.lock'
|
171
|
+
FileUtils.cp PODFILE_LOCK, JIFFY_PODFILE_LOCK
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
Pod::HooksManager.register('cocoapods-jiffy', :post_install) do |installer_context|
|
176
|
+
CocoapodsJiffy.post_install installer_context
|
177
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'cocoapods-jiffy'
|
2
|
+
|
3
|
+
Pod::HooksManager.register('cocoapods-jiffy', :pre_install) do |installer_context|
|
4
|
+
podfile = installer_context.podfile
|
5
|
+
podfile.use_frameworks!
|
6
|
+
if CocoapodsJiffy.build_jiffy
|
7
|
+
podfile.install!('cocoapods', podfile.installation_method.last.merge(integrate_targets: false))
|
8
|
+
end
|
9
|
+
|
10
|
+
CocoapodsJiffy.ensure_dependencies_exclusive if CocoapodsJiffy.use_jiffy
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
ROOT = Pathname.new(File.expand_path('../../', __FILE__))
|
3
|
+
$LOAD_PATH.unshift((ROOT + 'lib').to_s)
|
4
|
+
$LOAD_PATH.unshift((ROOT + 'spec').to_s)
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'bacon'
|
8
|
+
require 'cocoapods'
|
9
|
+
|
10
|
+
require 'cocoapods_plugin'
|
11
|
+
|
12
|
+
#-----------------------------------------------------------------------------#
|
13
|
+
|
14
|
+
module Pod
|
15
|
+
# Disable the wrapping so the output is deterministic in the tests.
|
16
|
+
#
|
17
|
+
UI.disable_wrap = true
|
18
|
+
|
19
|
+
# Redirects the messages to an internal store.
|
20
|
+
#
|
21
|
+
module UI
|
22
|
+
@output = ''
|
23
|
+
@warnings = ''
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_accessor :output
|
27
|
+
attr_accessor :warnings
|
28
|
+
|
29
|
+
def puts(message = '')
|
30
|
+
@output << "#{message}\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def warn(message = '', _actions = [])
|
34
|
+
@warnings << "#{message}\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def print(message)
|
38
|
+
@output << message
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#-----------------------------------------------------------------------------#
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cocoapods-jiffy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Krunoslav Zaher
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-01 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.1.0.beta.1
|
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.1.0.beta.1
|
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: 1.0.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.0.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:
|
76
|
+
email:
|
77
|
+
- krunoslav.zaher@gmail.com
|
78
|
+
executables: []
|
79
|
+
extensions: []
|
80
|
+
extra_rdoc_files: []
|
81
|
+
files:
|
82
|
+
- ".gitignore"
|
83
|
+
- Gemfile
|
84
|
+
- Gemfile.lock
|
85
|
+
- LICENSE.txt
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- cocoapods-jiffy.gemspec
|
89
|
+
- lib/cocoapods-jiffy.rb
|
90
|
+
- lib/cocoapods-jiffy/gem_version.rb
|
91
|
+
- lib/cocoapods-jiffy/post_install.rb
|
92
|
+
- lib/cocoapods-jiffy/pre_install.rb
|
93
|
+
- lib/cocoapods_plugin.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
homepage: https://github.com/kzaher/Jiffy
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.5.1
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Builds your CocoaPods dependencies in a jiffy by building them as dynamic
|
119
|
+
frameworks and caches them locally per xcode version, git commit, platform and configuration.
|
120
|
+
test_files:
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
has_rdoc:
|