cocoapods-jiffy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cocoapods-jiffy.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'bacon'
8
+ end
@@ -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
@@ -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.
@@ -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
+ ```
@@ -0,0 +1,12 @@
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
@@ -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,3 @@
1
+ module CocoapodsJiffy
2
+ VERSION = '0.1.0'.freeze
3
+ 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
@@ -0,0 +1,3 @@
1
+ require 'cocoapods-jiffy/post_install'
2
+ require 'cocoapods-jiffy/pre_install'
3
+ require 'cocoapods-jiffy'
@@ -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: