Skip to content

Commit

Permalink
chore(*): Restructure and separate code outputs build products
Browse files Browse the repository at this point in the history
  • Loading branch information
bangnguyengrab committed Dec 30, 2019
1 parent 66733bb commit 8e610ce
Show file tree
Hide file tree
Showing 37 changed files with 418 additions and 328 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1 +1,2 @@
.DS_Store
**/*/__pycache__
2 changes: 0 additions & 2 deletions PodBinaryCacheExample/.bundle/config

This file was deleted.

11 changes: 7 additions & 4 deletions PodBinaryCacheExample/.gitignore
@@ -1,4 +1,7 @@
build
DerivedData
Pods
!*.xcodeproj/xcshareddata/
/build
/DerivedData
/Pods
/.bundle
__pycache__/
xcshareddata/
xcuserdata/
2 changes: 1 addition & 1 deletion PodBinaryCacheExample/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
cocoapods-binary-cache (0.4.4)
cocoapods-binary-cache (0.0.1)
cocoapods (>= 1.5.0)
fourflusher (~> 2.0)
xcpretty (~> 0.3.0)
Expand Down
Binary file not shown.

This file was deleted.

Binary file not shown.
4 changes: 2 additions & 2 deletions cocoapods-binary-cache.gemspec
Expand Up @@ -5,8 +5,8 @@ require 'cocoapods-binary-cache/gem_version.rb'

Gem::Specification.new do |spec|
spec.name = 'cocoapods-binary-cache'
spec.version = CocoapodsBinary::VERSION
spec.authors = ['bang nguyen']
spec.version = CocoapodsBinaryCache::VERSION
spec.authors = ['Bang Nguyen']
spec.email = ['bang.nguyen@grabtaxi.com']
spec.description = %q{Reduce build time by building pod frameworks and cache to remote storage, reuse on multiple machines}
spec.summary = %q{Reduce build time by building pod frameworks and cache to remote storage, reuse on multiple machines}
Expand Down
242 changes: 6 additions & 236 deletions lib/cocoapods-binary-cache/Main.rb
@@ -1,238 +1,8 @@
# encoding: UTF-8
require_relative 'helper/podfile_options'
require_relative 'tool/tool'
require_relative 'helper/benchmark_show'
require_relative 'helper/passer'
require_relative 'PrebuildCache'
require_relative 'SchemeEditor'
# Copyright 2019 Grabtaxi Holdings PTE LTE (GRAB), All rights reserved.
# Use of this source code is governed by an MIT-style license that can be found in the LICENSE file

module Pod
class Podfile
module DSL

# Enable prebuiding for all pods
# it has a lower priority to other binary settings
def all_binary!
DSL.prebuild_all = true
end
# Provide DSL options to set from Podfile
require_relative 'pod-binary/prebuild_dsl'

# Enable bitcode for prebuilt frameworks
def enable_bitcode_for_prebuilt_frameworks!
DSL.bitcode_enabled = true
end

# Don't remove source code of prebuilt pods
# It may speed up the pod install if git didn't
# include the `Pods` folder
def keep_source_code_for_prebuilt_frameworks!
DSL.dont_remove_source_code = true
end

# Add custom xcodebuild option to the prebuilding action
#
# You may use this for your special demands. For example: the default archs in dSYMs
# of prebuilt frameworks is 'arm64 armv7 x86_64', and no 'i386' for 32bit simulator.
# It may generate a warning when building for a 32bit simulator. You may add following
# to your podfile
#
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks :simulator => "ARCHS=$(ARCHS_STANDARD)" `
#
# Another example to disable the generating of dSYM file:
#
# ` set_custom_xcodebuild_options_for_prebuilt_frameworks "DEBUG_INFORMATION_FORMAT=dwarf"`
#
#
# @param [String or Hash] options
#
# If is a String, it will apply for device and simulator. Use it just like in the commandline.
# If is a Hash, it should be like this: { :device => "XXXXX", :simulator => "XXXXX" }
#
def set_custom_xcodebuild_options_for_prebuilt_frameworks(options)
if options.kind_of? Hash
DSL.custom_build_options = [ options[:device] ] unless options[:device].nil?
DSL.custom_build_options_simulator = [ options[:simulator] ] unless options[:simulator].nil?
elsif options.kind_of? String
DSL.custom_build_options = [options]
DSL.custom_build_options_simulator = [options]
else
raise "Wrong type."
end
end

def enable_devpod_prebuild
DSL.enable_prebuild_dev_pod = true
end

def set_unbuilt_dev_pods(list)
DSL.unbuilt_dev_pods = Set.new(list)
DSL.unbuilt_pods = DSL.unbuilt_vendor_pods.merge(DSL.unbuilt_dev_pods)
end

def set_is_prebuild_job(flag)
DSL.is_prebuild_job = flag
end

def set_unbuilt_vendor_pods(list)
DSL.unbuilt_vendor_pods = Set.new(list)
DSL.unbuilt_pods = DSL.unbuilt_vendor_pods.merge(DSL.unbuilt_dev_pods)
end

private
def self.add_unbuilt_pods(list)
DSL.unbuilt_pods = DSL.unbuilt_pods.merge(list)
end

private
class_attr_accessor :prebuild_all
prebuild_all = false

class_attr_accessor :bitcode_enabled
bitcode_enabled = false

class_attr_accessor :dont_remove_source_code
dont_remove_source_code = false

class_attr_accessor :custom_build_options
class_attr_accessor :custom_build_options_simulator
self.custom_build_options = []
self.custom_build_options_simulator = []

private
class_attr_accessor :enable_prebuild_dev_pod
self.enable_prebuild_dev_pod = false

private
class_attr_accessor :unbuilt_dev_pods
self.unbuilt_dev_pods = Set[]

private
class_attr_accessor :unbuilt_vendor_pods
self.unbuilt_vendor_pods = Set[]

private
class_attr_accessor :unbuilt_pods
self.unbuilt_pods = Set[]

private
class_attr_accessor :is_prebuild_job
self.is_prebuild_job = false
end
end
end

Pod::HooksManager.register('cocoapods-binary-cache', :pre_install) do |installer_context|

require_relative 'helper/feature_switches'
if Pod.is_prebuild_stage
next
end

# [Check Environment]
# check user_framework is on
podfile = installer_context.podfile
podfile.target_definition_list.each do |target_definition|
next if target_definition.prebuild_framework_pod_names.empty?
if not target_definition.uses_frameworks?
STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
exit
end
end


# -- step 1: prebuild framework ---
# Execute a sperated pod install, to generate targets for building framework,
# then compile them to framework files.
require_relative 'helper/prebuild_sandbox'
require_relative 'Prebuild'

Pod::UI.puts "🚀 Prebuild frameworks"

# Fetch original installer (which is running this pre-install hook) options,
# then pass them to our installer to perform update if needed
# Looks like this is the most appropriate way to figure out that something should be updated

update = nil
repo_update = nil

include ObjectSpace
ObjectSpace.each_object(Pod::Installer) { |installer|
update = installer.update
repo_update = installer.repo_update
}

# control features
Pod::UI.puts "control features"
Pod.is_prebuild_stage = true
Pod::Podfile::DSL.enable_prebuild_patch true # enable sikpping for prebuild targets
Pod::Installer.force_disable_integration true # don't integrate targets
Pod::Config.force_disable_write_lockfile true # disbale write lock file for perbuild podfile
Pod::Installer.disable_install_complete_message true # disable install complete message

# make another custom sandbox
Pod::UI.puts "make another custom sandbox"
standard_sandbox = installer_context.sandbox
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)

# get the podfile for prebuild
Pod::UI.puts "get the podfile for prebuild"
prebuild_podfile = Pod::Podfile.from_ruby(podfile.defined_in_file)

# install
lockfile = installer_context.lockfile
binary_installer = Pod::Installer.new(prebuild_sandbox, prebuild_podfile, lockfile)

# Verify Vendor pod cache
manifest_path = prebuild_sandbox.root + 'Manifest.lock'
prebuilt_lockfile = Pod::Lockfile.from_file Pathname.new(manifest_path)
missed_vendor_pods = PodCacheValidator.verify_prebuilt_vendor_pods(lockfile, prebuilt_lockfile)
if !Pod::Podfile::DSL.is_prebuild_job
Pod::Podfile::DSL.add_unbuilt_pods(missed_vendor_pods)
end

# Verify Dev pod cache
if Pod::Podfile::DSL.enable_prebuild_dev_pod
BenchmarkShow.benchmark { PodCacheValidator.verify_devpod_checksum(prebuild_sandbox, lockfile) }
if !Pod::Podfile::DSL.is_prebuild_job
Pod::Podfile::DSL.add_unbuilt_pods(Pod::Prebuild::CacheInfo.cache_miss_local_pods)
end
end

binary_installer.clean_delta_file
Pod::UI.puts "Pod update = #{update}"
if binary_installer.have_exact_prebuild_cache? && !update
Pod::UI.puts "cache hit"
binary_installer.install_when_cache_hit!
else
Pod::UI.puts "cache miss -> need to update"
binary_installer.update = update
binary_installer.repo_update = repo_update
binary_installer.install!
end


# reset the environment
Pod.is_prebuild_stage = false
Pod::Installer.force_disable_integration false
Pod::Podfile::DSL.enable_prebuild_patch false
Pod::Config.force_disable_write_lockfile false
Pod::Installer.disable_install_complete_message false
Pod::UserInterface.warnings = [] # clean the warning in the prebuild step, it's duplicated.


# -- step 2: pod install ---
# install
Pod::UI.puts "\n"
Pod::UI.puts "🤖 Pod Install"
require_relative 'Integration'
# go on the normal install step ...
end

Pod::HooksManager.register('cocoapods-binary-cache', :post_install) do |installer_context|
next unless Pod::Podfile::DSL.enable_prebuild_dev_pod and installer_context.sandbox.instance_of?(Pod::PrebuildSandbox)

# Modify pods scheme to support code coverage
# If we don't prebuild dev pod -> no need to care about this in Pod project because we setup in the main project. Eg. DriverCI scheme
if Pod.is_prebuild_stage
SchemeEditor.edit_to_support_code_coverage(installer_context.sandbox)
end
end
# Hook cocoapods pre-install and post-install to do prebuild, caching stuffs
require_relative 'pod-binary/prebuild_hook'
7 changes: 5 additions & 2 deletions lib/cocoapods-binary-cache/gem_version.rb
@@ -1,3 +1,6 @@
module CocoapodsBinary
VERSION = "0.4.4"
# Copyright 2019 Grabtaxi Holdings PTE LTE (GRAB), All rights reserved.
# Use of this source code is governed by an MIT-style license that can be found in the LICENSE file

module CocoapodsBinaryCache
VERSION = "0.0.1"
end
8 changes: 8 additions & 0 deletions lib/cocoapods-binary-cache/helper/path_utils.rb
@@ -0,0 +1,8 @@
# Copyright 2019 Grabtaxi Holdings PTE LTE (GRAB), All rights reserved.
# Use of this source code is governed by an MIT-style license that can be found in the LICENSE file

class PathUtils
def self.remove_last_path_component(path, num_components=1)
path.split('/')[0...-num_components].join('/')
end
end
File renamed without changes.
22 changes: 22 additions & 0 deletions lib/cocoapods-binary-cache/pod-binary/LICENSE.txt
@@ -0,0 +1,22 @@
Copyright (c) 2018 leavez <gaojiji@gmail.com>

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

0 comments on commit 8e610ce

Please sign in to comment.