Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 18ef8bf8e1
Fetching contributors…

Cannot retrieve contributors at this time

184 lines (159 sloc) 6.84 kb
module Pod
class Installer
autoload :TargetInstaller, 'cocoapods/installer/target_installer'
module Shared
def dependent_specifications
@dependent_specifications ||= Resolver.new(@podfile, @definition ? @definition.dependencies : nil).resolve
end
def build_specifications
dependent_specifications.reject do |spec|
spec.wrapper? || spec.defined_in_set.only_part_of_other_pod?
end
end
def download_only_specifications
dependent_specifications - build_specifications
end
end
include Config::Mixin
include Shared
def initialize(podfile)
@podfile = podfile
end
def lock_file
config.project_root + 'Podfile.lock'
end
def project
return @project if @project
@project = Xcodeproj::Project.for_platform(@podfile.platform)
# First we need to resolve dependencies across *all* targets, so that the
# same correct versions of pods are being used for all targets. This
# happens when we call `build_specifications'.
build_specifications.each do |spec|
# Add all source files to the project grouped by pod
group = @project.add_pod_group(spec.name)
spec.expanded_source_files.each do |path|
group.children.new('path' => path.to_s)
end
end
# Add a group to hold all the target support files
@project.main_group.groups.new('name' => 'Targets Support Files')
@project
end
def target_installers
@target_installers ||= @podfile.target_definitions.values.map do |definition|
TargetInstaller.new(@podfile, project, definition) unless definition.empty?
end.compact
end
def install_dependencies!
build_specifications.each do |spec|
if spec.pod_destroot.exist? || spec.local?
message = "Using #{spec}"
message += " [LOCAL]" if spec.local?
puts message unless config.silent?
else
puts "Installing #{spec}" unless config.silent?
spec = spec.part_of_specification if spec.part_of_other_pod?
downloader = Downloader.for_source(spec.pod_destroot, spec.source)
downloader.download
# TODO move cleaning into the installer as well
downloader.clean(spec.expanded_clean_paths) if config.clean
end
end
end
def install!
puts "Installing dependencies of: #{@podfile.defined_in_file}" if config.verbose?
install_dependencies!
root = config.project_pods_root
headers_symlink_root = config.headers_symlink_root
# Clean old header symlinks
FileUtils.rm_r(headers_symlink_root, :secure => true) if File.exists?(headers_symlink_root)
puts "Generating support files" unless config.silent?
target_installers.each do |target_installer|
target_installer.install!
target_installer.create_files_in(root)
end
generate_lock_file!
puts "* Running post install hooks" if config.verbose?
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
target_installers.each do |target_installer|
target_installer.build_specifications.each { |spec| spec.post_install(target_installer) }
end
@podfile.post_install!(self)
projpath = File.join(root, 'Pods.xcodeproj')
puts "* Writing Xcode project file to `#{projpath}'" if config.verbose?
project.save_as(projpath)
end
def generate_lock_file!
lock_file.open('w') do |file|
file.puts "PODS:"
pods = build_specifications.map do |spec|
[spec.to_s, spec.dependencies.map(&:to_s).sort]
end.sort_by(&:first).each do |name, deps|
if deps.empty?
file.puts " - #{name}"
else
file.puts " - #{name}:"
deps.each { |dep| file.puts " - #{dep}" }
end
end
unless download_only_specifications.empty?
file.puts
file.puts "DOWNLOAD_ONLY:"
download_only_specifications.map(&:to_s).sort.each do |name|
file.puts " - #{name}"
end
end
file.puts
file.puts "DEPENDENCIES:"
@podfile.dependencies.map(&:to_s).sort.each do |dep|
file.puts " - #{dep}"
end
end
end
# For now this assumes just one pods target, i.e. only libPods.a.
# Not sure yet if we should try to be smart with apps that have multiple
# targets and try to map pod targets to those app targets.
#
# Possible options are:
# 1. Only cater to the most simple setup
# 2. Try to automagically figure it out by name. For example, a pod target
# called `:some_target' could map to an app target called `SomeTarget'.
# (A variation would be to not even camelize the target name, but simply
# let the user specify it with the proper case.)
# 3. Let the user specify the app target name as an extra argument, but this
# seems to be a less good version of the variation on #2.
def configure_project(projpath)
# TODO use more of Pathname’s API here
root = File.dirname(projpath)
xcworkspace = File.join(root, File.basename(projpath, '.xcodeproj') + '.xcworkspace')
workspace = Xcodeproj::Workspace.new_from_xcworkspace(xcworkspace)
pods_projpath = File.join(config.project_pods_root, 'Pods.xcodeproj')
root = Pathname.new(root).expand_path
[projpath, pods_projpath].each do |path|
path = Pathname.new(path).expand_path.relative_path_from(root).to_s
workspace << path unless workspace.include? path
end
workspace.save_as(xcworkspace)
app_project = Xcodeproj::Project.new(projpath)
return if app_project.files.find { |file| file.path =~ /libPods\.a$/ }
configfile = app_project.files.new('path' => 'Pods/Pods.xcconfig')
app_project.targets.each do |target|
target.buildConfigurations.each do |config|
config.baseConfiguration = configfile
end
end
libfile = app_project.files.new_static_library('Pods')
libfile.group = app_project.main_group.groups.find { |g| g.name == 'Frameworks' }
app_project.objects.select_by_class(Xcodeproj::Project::PBXFrameworksBuildPhase).each do |build_phase|
build_phase.files << libfile.buildFiles.new
end
copy_resources = app_project.add_shell_script_build_phase('Copy Pods Resources',
%{"${PODS_ROOT}/Pods-resources.sh"\n})
app_project.targets.each { |target| target.buildPhases << copy_resources }
app_project.save_as(projpath)
unless config.silent?
puts "[!] From now on use `#{File.basename(xcworkspace)}' instead of `#{File.basename(projpath)}'."
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.