Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specification refactor #253

Merged
merged 48 commits into from
May 23, 2012
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ea9b181
WIP Specification refactor.
fabiopelosin May 9, 2012
87778d8
Small clean up.
fabiopelosin May 9, 2012
99d2042
Simplified resolution process and implemented `main_subspec' substitu…
fabiopelosin May 9, 2012
8b50589
Automatically decorate Informatives.
fabiopelosin May 10, 2012
0c5c43c
Speficiation#activate_for_platform and collateral improvements.
fabiopelosin May 10, 2012
a1286c7
Merge branch 'master' into spec-refactor
fabiopelosin May 10, 2012
607b833
[Pod::Informative] Minor fix.
fabiopelosin May 10, 2012
3364111
[Spec::Linter] Minor tweaks.
fabiopelosin May 10, 2012
6522113
[LocalPod] Cluster specifications.
fabiopelosin May 10, 2012
b568f82
[Specification] Inherith dependencies from the parent.
fabiopelosin May 10, 2012
1d7b4e7
[LocalPod] Clean all the unused files.
fabiopelosin May 11, 2012
77c1f0b
[Specification] Clean up.
fabiopelosin May 11, 2012
22de372
[Specification#preferred_dependency] Implementation.
fabiopelosin May 11, 2012
7162c5a
Completed Pod::Specification refactor.
fabiopelosin May 14, 2012
3876515
[Pod::Executable] Show woking dir in output.
fabiopelosin May 14, 2012
8ecd4bc
Integration of Specificaiton refactor.
fabiopelosin May 14, 2012
e2867da
Updated master repo in fixtures.
fabiopelosin May 14, 2012
ebc4b15
Minor fixes related to master repo update.
fabiopelosin May 14, 2012
8bdb41f
Merge branch 'master' into spec-refactor
fabiopelosin May 14, 2012
462d6a1
Minor bug fixes.
fabiopelosin May 14, 2012
6bbbdba
Prevernt Xcodeproj from generating unecessary whitespace
fabiopelosin May 14, 2012
d35acab
[LocalPod] Cleaning fixes and code clean up.
fabiopelosin May 15, 2012
9027f20
[Specification] Improve handling of headers mappings.
fabiopelosin May 15, 2012
68b6381
Fix incorrect name for specs with preferred dependency in podfile.lock
fabiopelosin May 15, 2012
b863ece
[LocalPod] Resolve compiler flags per specification.
fabiopelosin May 15, 2012
cac18c8
LocalPod clean up.
fabiopelosin May 15, 2012
98d0fb0
Fine tuning console output.
fabiopelosin May 15, 2012
59a035f
[Spec::Linter] Adapted for Specification refactoring.
fabiopelosin May 15, 2012
b263097
[Documentation] Adapted for Specification refactoring.
fabiopelosin May 15, 2012
778fa15
[Specification::Linter] Minor fix.
fabiopelosin May 16, 2012
4973069
[LocalPod] Minor fix.
fabiopelosin May 16, 2012
139d009
[Generator::Documentation] Use relative paths for output readability.
fabiopelosin May 16, 2012
d59409f
[Specs] Cleaning up temporary repos helper.
fabiopelosin May 16, 2012
9323fba
[Specs] Fix for reinitialization of constant.
fabiopelosin May 16, 2012
fe46195
[Specs] Minor clean up and cosmetic fixes.
fabiopelosin May 16, 2012
2426f95
[Specs] Improved output.
fabiopelosin May 16, 2012
cb2942f
[Specs] Adapting existing specs for recent changes.
fabiopelosin May 16, 2012
59104c8
[Specs] Minor cosmetic fixes.
fabiopelosin May 16, 2012
572ac97
[Specs] Patch bacon to reset Pod::Config::Instance.
fabiopelosin May 17, 2012
b9ea515
[Executable] Remove original white space formatting from the output.
fabiopelosin May 17, 2012
85f0aef
[Documentation] Process only header files.
fabiopelosin May 17, 2012
638d78e
[Specs] Oops... forgot to update for documentation changes.
fabiopelosin May 17, 2012
b3942bd
[Presenter::CocoaPod] Robustness against nil last activity.
fabiopelosin May 17, 2012
74b38c8
TODO comments.
fabiopelosin May 23, 2012
34dac29
[Specification] Rename exclude_headers to exclude_header_search_paths.
fabiopelosin May 23, 2012
5e57791
[Config] Remove #force_doc.
fabiopelosin May 23, 2012
2c462d1
[Specs] Only print the count of the disabled specs in the summary.
fabiopelosin May 23, 2012
9511cc4
[Specs] Placeholder for LocalPod and TODOs.
fabiopelosin May 23, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/cocoapods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ module Pod
VERSION = '0.6.0rc1'

class Informative < StandardError
def message
#TODO: remove formatting from raise calls and remove conditional
super !~ /\[!\]/ ? "[!] #{super}\n".red : super
end
end

autoload :Command, 'cocoapods/command'
Expand Down
4 changes: 2 additions & 2 deletions lib/cocoapods/command/presenter/cocoa_pod.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def versions

# specification information
def spec
@spec ||= @set.specification.part_of_other_pod? ? @set.specification.part_of_specification : @set.specification
@set.specification
end

def authors
Expand All @@ -47,7 +47,7 @@ def source_url
end

def platform
spec.platform.to_s
spec.available_platforms.sort { |a,b| a.to_s.downcase <=> b.to_s.downcase }.join(' - ')
end

def license
Expand Down
284 changes: 130 additions & 154 deletions lib/cocoapods/command/spec.rb

Large diffs are not rendered by default.

31 changes: 13 additions & 18 deletions lib/cocoapods/dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ module Gem

module Pod
class Dependency < Gem::Dependency
attr_accessor :only_part_of_other_pod
alias_method :only_part_of_other_pod?, :only_part_of_other_pod

attr_reader :external_source
attr_accessor :specification
Expand All @@ -27,23 +25,20 @@ def initialize(*name_and_version_requirements, &block)
raise Informative, "A dependency needs either a name and version requirements, " \
"a source hash, or a block which defines a podspec."
end
@only_part_of_other_pod = false
end

def ==(other)
super &&
@only_part_of_other_pod == other.only_part_of_other_pod &&
(@specification ? @specification == other.specification : @external_source == other.external_source)
super && (@specification ? @specification == other.specification : @external_source == other.external_source)
end

def subspec_dependency?
@name.include?('/')
end

def inline?
@inline_podspec
end

def external?
!@external_source.nil?
end
Expand Down Expand Up @@ -75,7 +70,7 @@ def to_s
end
version.empty? ? @name : "#{@name} (#{version})"
end

def specification_from_sandbox(sandbox, platform)
@external_source.specification_from_sandbox(sandbox, platform)
end
Expand Down Expand Up @@ -126,33 +121,33 @@ def self.from_params(name, params)
raise Informative, "Unknown external source parameters for #{name}: #{params}"
end
end

class AbstractExternalSource
include Config::Mixin

attr_reader :name, :params

def initialize(name, params)
@name, @params = name, params
end

def specification_from_sandbox(sandbox, platform)
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.specification
local_pod.top_specification
else
copy_external_source_into_sandbox(sandbox)
local_pod = sandbox.installed_pod_named(name, platform)
local_pod.clean if config.clean?
local_pod.specification
local_pod.top_specification
end
end

def ==(other_source)
return if other_source.nil?
name == other_source.name && params == other_source.params
end
end

class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox)
puts " * Pre-downloading: '#{name}'" unless config.silent?
Expand All @@ -161,7 +156,7 @@ def copy_external_source_into_sandbox(sandbox)
downloader.clean if config.clean?
end
end

def description
"from `#{@params[:git]}'".tap do |description|
description << ", commit `#{@params[:commit]}'" if @params[:commit]
Expand All @@ -180,7 +175,7 @@ def copy_external_source_into_sandbox(sandbox)
output_path.open('w') { |f| f << io.read }
end
end

def description
"from `#{@params[:podspec]}'"
end
Expand Down
3 changes: 1 addition & 2 deletions lib/cocoapods/downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ class Downloader
extend Executable

def self.for_pod(pod)
spec = pod.specification
spec = spec.part_of_specification if spec.part_of_other_pod?
spec = pod.top_specification
for_target(pod.root, spec.source.dup)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/cocoapods/executable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def executable(name)
raise Informative, "Unable to locate the executable `#{name}'"
end
if Config.instance.verbose?
puts "-> #{bin} #{command}"
puts "-> [#{Dir.pwd}] $ #{bin} #{command}"
`#{bin} #{command} 1>&2`
else
`#{bin} #{command} 2> /dev/null`
Expand Down
6 changes: 3 additions & 3 deletions lib/cocoapods/generator/documentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class Documentation

def initialize(pod)
@pod = pod
@specification = pod.specification
@specification = pod.top_specification
@target_path = pod.sandbox.root + 'Documentation' + pod.name
@options = pod.specification.documentation || {}
@options = @specification.documentation || {}
end

def name
Expand Down Expand Up @@ -42,7 +42,7 @@ def docs_id
end

def files
@pod.absolute_source_files.map(&:to_s)
@pod.source_files(false).map(&:to_s)
end

def index_file
Expand Down
108 changes: 43 additions & 65 deletions lib/cocoapods/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def project
return @project if @project
@project = Pod::Project.new
@project.user_build_configurations = @podfile.user_build_configurations
activated_pods.each do |pod|
pods.each do |pod|
# Add all source files to the project grouped by pod
group = @project.add_pod_group(pod.name)
pod.source_files.each do |path|
Expand All @@ -45,33 +45,33 @@ def target_installers
end

def install_dependencies!
activated_pods.each do |pod|
marker = config.verbose ? "\n-> ".green : ''

unless should_install = !pod.exists? && !pod.specification.local?
puts marker + "Using #{pod}" unless config.silent?
else
puts marker + "Installing #{pod.specification}".green unless config.silent?
pods.each do |pod|
unless config.silent?
marker = config.verbose ? "\n-> ".green : ''
puts marker << ( pod.exists? ? "Using #{pod}" : "Installing #{pod}".green )
end

should_install = !pod.exists?
if should_install
downloader = Downloader.for_pod(pod)
downloader.download

if config.clean
downloader.clean
pod.clean
end
end

if (should_install && config.generate_docs?) || config.force_doc?
doc_generator = Generator::Documentation.new(pod)
if doc_generator.already_installed?
puts "Using Existing Documentation for #{pod.specification}".green if config.verbose?
else
puts "Installing Documentation for #{pod.specification}".green if config.verbose?
doc_generator.generate(config.doc_install?)
end
end
generate_docs(pod)
pod.clean if config.clean && should_install
end
end

#TODO: move to generator ?
def generate_docs(pod)
doc_generator = Generator::Documentation.new(pod)
if ( config.generate_docs? && !doc_generator.already_installed? ) || config.force_doc?
message = "Installing documentation"
doc_generator.generate(config.doc_install?)
else
message = "Using existing documentation"
end
puts "-> ".green << message << " for #{pod.name} (#{pod.top_specification.version})" if config.verbose?
end

def install!
Expand All @@ -83,14 +83,13 @@ def install!
print_title "Installing dependencies"
install_dependencies!

pods = activated_pods
print_title("Generating support files\n", false)
target_installers.each do |target_installer|
pods_for_target = activated_pods_by_target[target_installer.target_definition]
pods_for_target = pods_by_target[target_installer.target_definition]
target_installer.install!(pods_for_target, @sandbox)
end

generate_lock_file!(pods)
generate_lock_file!(specifications)
generate_dummy_source

puts "* Running post install hooks" if config.verbose?
Expand All @@ -107,36 +106,36 @@ def run_post_install_hooks
# we loop over target installers instead of pods, because we yield the target installer
# to the spec post install hook.
target_installers.each do |target_installer|
activated_specifications_for_target(target_installer.target_definition).each do |spec|
specs_by_target[target_installer.target_definition].each do |spec|
spec.post_install(target_installer)
end
end

@podfile.post_install!(self)
end

def generate_lock_file!(pods)
def generate_lock_file!(specs)
lock_file.open('w') do |file|
file.puts "PODS:"

# Get list of [name, dependencies] pairs.
activated_pods = pods.map do |pod|
[pod.specification.to_s, pod.dependencies.map(&:to_s).sort]
pod_and_deps = specs.map do |spec|
[spec.to_s, spec.dependencies.map(&:to_s).sort]
end.uniq

# Merge dependencies of ios and osx version of the same pod.
tmp = {}
activated_pods.each do |name, deps|
pod_and_deps.each do |name, deps|
if tmp[name]
tmp[name].concat(deps).uniq!
else
tmp[name] = deps
end
end
activated_pods = tmp
pod_and_deps = tmp

# Sort by name and print
activated_pods.sort_by(&:first).each do |name, deps|
pod_and_deps.sort_by(&:first).each do |name, deps|
if deps.empty?
file.puts " - #{name}"
else
Expand All @@ -145,14 +144,6 @@ def generate_lock_file!(pods)
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|
Expand All @@ -179,49 +170,36 @@ def specs_by_target
end

# @return [Array<Specification>] All dependencies that have been resolved.
def dependency_specifications
def specifications
specs_by_target.values.flatten
end

# @return [Array<LocalPod>] A list of LocalPod instances for each
# dependency that is not a download-only one.
def activated_pods
activated_pods_by_target.values.flatten
def pods
pods_by_target.values.flatten
end

def activated_pods_by_target
def pods_by_target
@pods_by_spec = {}
result = {}
specs_by_target.each do |target_definition, specs|
@pods_by_spec[target_definition.platform] = {}
result[target_definition] = specs.map do |spec|
LocalPod.new(spec, @sandbox, target_definition.platform) if activated_spec?(spec)
end.compact
pod = pod_for_spec(spec, target_definition.platform)
pod.add_specification(spec)
pod
end.uniq.compact
end
result
end

# @return [Array<Specification>] A list of specifications for each
# dependency that is not a download-only
# one.
def activated_specifications
dependency_specifications.select { |spec| activated_spec?(spec) }
end

def activated_specifications_for_target(target_definition)
specs_by_target[target_definition].select { |spec| activated_spec?(spec) }
end

def download_only_specifications
dependency_specifications - activated_specifications
def pod_for_spec(spec, platform)
@pods_by_spec[platform][spec.top_level_parent.name] ||= LocalPod.new(spec, @sandbox, platform)
end

private

def activated_spec?(spec)
# Don't activate specs which are only wrappers of subspecs, or share
# source with another pod but aren't activated themselves.
!spec.wrapper? && !@resolver.cached_sets[spec.name].only_part_of_other_pod?
end

def print_title(title, only_verbose = true)
if config.verbose?
puts "\n" + title.yellow
Expand Down
Loading