Commit 8453f585 authored by Eloy Duran's avatar Eloy Duran

Podfile#xcodeproj now also takes a hash of custom configurations that the user's project contains.

parent 42cc83a1
...@@ -34,13 +34,13 @@ module Pod ...@@ -34,13 +34,13 @@ module Pod
end.compact end.compact
end end
def user_projects def user_project_paths
@podfile.target_definitions.values.map(&:xcodeproj) @podfile.target_definitions.values.map { |td| td.user_project.path }
end end
def create_workspace! def create_workspace!
workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path) workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
[pods_project_path, *user_projects].each do |project_path| [pods_project_path, *user_project_paths].each do |project_path|
project_path = project_path.relative_path_from(config.project_root).to_s project_path = project_path.relative_path_from(config.project_root).to_s
workspace << project_path unless workspace.include?(project_path) workspace << project_path unless workspace.include?(project_path)
end end
...@@ -74,11 +74,11 @@ module Pod ...@@ -74,11 +74,11 @@ module Pod
add_xcconfig_base_configuration add_xcconfig_base_configuration
add_pods_library add_pods_library
add_copy_resources_script_phase add_copy_resources_script_phase
user_project.save_as(@target_definition.xcodeproj) user_project.save_as(@target_definition.user_project.path)
end end
def user_project_path def user_project_path
if path = @target_definition.xcodeproj if path = @target_definition.user_project.path
unless path.exist? unless path.exist?
raise Informative, "The Xcode project `#{path}' does not exist." raise Informative, "The Xcode project `#{path}' does not exist."
end end
......
module Pod module Pod
class Podfile class Podfile
class UserProject
include Config::Mixin
DEFAULT_CONFIGURATIONS = { 'Debug' => :debug, 'Release' => :release }.freeze
attr_reader :configurations
def initialize(path = nil, configurations = {})
self.path = path if path
@configurations = configurations.merge(DEFAULT_CONFIGURATIONS)
end
def path=(path)
path = path.to_s
@path = config.project_root + (File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj")
end
def path
if @path
@path
else
xcodeprojs = config.project_root.glob('*.xcodeproj')
if xcodeprojs.size == 1
@path = xcodeprojs.first
end
end
end
end
class TargetDefinition class TargetDefinition
include Config::Mixin include Config::Mixin
attr_reader :name, :target_dependencies attr_reader :name, :target_dependencies
attr_accessor :xcodeproj, :link_with, :platform, :parent, :exclusive attr_accessor :user_project, :link_with, :platform, :parent, :exclusive
def initialize(name, options = {}) def initialize(name, options = {})
@name, @target_dependencies = name, [] @name, @target_dependencies = name, []
...@@ -27,20 +56,8 @@ module Pod ...@@ -27,20 +56,8 @@ module Pod
end end
alias_method :exclusive?, :exclusive alias_method :exclusive?, :exclusive
def xcodeproj=(path) def user_project
path = path.to_s @user_project || @parent.user_project
@xcodeproj = config.project_root + (File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj")
end
def xcodeproj
if @xcodeproj
@xcodeproj
elsif @parent
@parent.xcodeproj
else
xcodeprojs = config.project_root.glob('*.xcodeproj')
@xcodeproj = xcodeprojs.first if xcodeprojs.size == 1
end
end end
def link_with=(targets) def link_with=(targets)
...@@ -64,8 +81,13 @@ module Pod ...@@ -64,8 +81,13 @@ module Pod
# Returns a path, which is relative to the project_root, relative to the # Returns a path, which is relative to the project_root, relative to the
# `$(SRCROOT)` of the user's project. # `$(SRCROOT)` of the user's project.
def relative_to_srcroot(path) def relative_to_srcroot(path)
raise Informative, "[!] Unable to find an Xcode project to integrate".red unless xcodeproj || !config.integrate_targets if user_project.path.nil?
xcodeproj ? (config.project_root + path).relative_path_from(xcodeproj.dirname) : path # TODO this is not in the right place
raise Informative, "[!] Unable to find an Xcode project to integrate".red if config.integrate_targets
path
else
(config.project_root + path).relative_path_from(user_project.path.dirname)
end
end end
def relative_pods_root def relative_pods_root
...@@ -123,7 +145,9 @@ module Pod ...@@ -123,7 +145,9 @@ module Pod
include Config::Mixin include Config::Mixin
def initialize(&block) def initialize(&block)
@target_definitions = { :default => (@target_definition = TargetDefinition.new(:default, :exclusive => true)) } @target_definition = TargetDefinition.new(:default, :exclusive => true)
@target_definition.user_project = UserProject.new
@target_definitions = { :default => @target_definition }
instance_eval(&block) instance_eval(&block)
end end
...@@ -159,8 +183,8 @@ module Pod ...@@ -159,8 +183,8 @@ module Pod
elsif @workspace elsif @workspace
@workspace @workspace
else else
projects = @target_definitions.map { |_, td| td.xcodeproj }.uniq projects = @target_definitions.map { |_, td| td.user_project.path }.uniq
if projects.size == 1 && (xcodeproj = @target_definitions[:default].xcodeproj) if projects.size == 1 && (xcodeproj = @target_definitions[:default].user_project.path)
config.project_root + "#{xcodeproj.basename('.xcodeproj')}.xcworkspace" config.project_root + "#{xcodeproj.basename('.xcodeproj')}.xcworkspace"
end end
end end
...@@ -184,8 +208,8 @@ module Pod ...@@ -184,8 +208,8 @@ module Pod
# xcodeproj 'TestProject' # xcodeproj 'TestProject'
# end # end
# #
def xcodeproj(path) def xcodeproj(path, configurations = {})
@target_definition.xcodeproj = path @target_definition.user_project = UserProject.new(path, configurations)
end end
# Specifies the target(s) in the user’s project that this Pods library # Specifies the target(s) in the user’s project that this Pods library
......
...@@ -288,6 +288,101 @@ ...@@ -288,6 +288,101 @@
}; };
name = Release; name = Release;
}; };
517F031C154C379000D46FE2 /* Test */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
SDKROOT = iphoneos;
};
name = Test;
};
517F031D154C379000D46FE2 /* Test */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SampleProject/SampleProject-Prefix.pch";
INFOPLIST_FILE = "SampleProject/SampleProject-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Test;
};
517F031E154C379000D46FE2 /* Test */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "TestRunner/TestRunner-Prefix.pch";
INFOPLIST_FILE = "TestRunner/TestRunner-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = Test;
};
517F0320154C379700D46FE2 /* App Store */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = "App Store";
};
517F0321154C379700D46FE2 /* App Store */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SampleProject/SampleProject-Prefix.pch";
INFOPLIST_FILE = "SampleProject/SampleProject-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = "App Store";
};
517F0322154C379700D46FE2 /* App Store */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "TestRunner/TestRunner-Prefix.pch";
INFOPLIST_FILE = "TestRunner/TestRunner-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.1;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = "App Store";
};
A346498314F9BE9A0080D870 /* Debug */ = { A346498314F9BE9A0080D870 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
...@@ -362,15 +457,20 @@ ...@@ -362,15 +457,20 @@
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
51075D5C1521D0C100E39B41 /* Debug */, 51075D5C1521D0C100E39B41 /* Debug */,
517F031E154C379000D46FE2 /* Test */,
51075D5D1521D0C100E39B41 /* Release */, 51075D5D1521D0C100E39B41 /* Release */,
517F0322154C379700D46FE2 /* App Store */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
A346496714F9BE990080D870 /* Build configuration list for PBXProject "SampleProject" */ = { A346496714F9BE990080D870 /* Build configuration list for PBXProject "SampleProject" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
A346498314F9BE9A0080D870 /* Debug */, A346498314F9BE9A0080D870 /* Debug */,
517F031C154C379000D46FE2 /* Test */,
A346498414F9BE9A0080D870 /* Release */, A346498414F9BE9A0080D870 /* Release */,
517F0320154C379700D46FE2 /* App Store */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
...@@ -379,7 +479,9 @@ ...@@ -379,7 +479,9 @@
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
A346498614F9BE9A0080D870 /* Debug */, A346498614F9BE9A0080D870 /* Debug */,
517F031D154C379000D46FE2 /* Test */,
A346498714F9BE9A0080D870 /* Release */, A346498714F9BE9A0080D870 /* Release */,
517F0321154C379700D46FE2 /* App Store */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
......
...@@ -4,6 +4,7 @@ describe Pod::Installer::UserProjectIntegrator do ...@@ -4,6 +4,7 @@ describe Pod::Installer::UserProjectIntegrator do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
before do before do
config.silent = true
@sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject') @sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
config.project_root = @sample_project_path.dirname config.project_root = @sample_project_path.dirname
...@@ -11,7 +12,7 @@ describe Pod::Installer::UserProjectIntegrator do ...@@ -11,7 +12,7 @@ describe Pod::Installer::UserProjectIntegrator do
@podfile = Pod::Podfile.new do @podfile = Pod::Podfile.new do
platform :ios platform :ios
xcodeproj sample_project_path xcodeproj sample_project_path, 'Test' => :debug
link_with 'SampleProject' # this is an app target! link_with 'SampleProject' # this is an app target!
dependency 'JSONKit' dependency 'JSONKit'
......
...@@ -52,12 +52,12 @@ describe Pod::Installer::UserProjectIntegrator do ...@@ -52,12 +52,12 @@ describe Pod::Installer::UserProjectIntegrator do
end end
it "raises if no project could be selected" do it "raises if no project could be selected" do
@target_integrator.target_definition.stubs(:xcodeproj).returns(nil) @target_integrator.target_definition.user_project.stubs(:path).returns(nil)
lambda { @target_integrator.user_project_path }.should.raise Pod::Informative lambda { @target_integrator.user_project_path }.should.raise Pod::Informative
end end
it "raises if the project path doesn't exist" do it "raises if the project path doesn't exist" do
@target_integrator.target_definition.xcodeproj.stubs(:exist?).returns(false) @target_integrator.target_definition.user_project.path.stubs(:exist?).returns(false)
lambda { @target_integrator.user_project_path }.should.raise Pod::Informative lambda { @target_integrator.user_project_path }.should.raise Pod::Informative
end end
......
...@@ -71,8 +71,8 @@ describe "Pod::Podfile" do ...@@ -71,8 +71,8 @@ describe "Pod::Podfile" do
path = config.project_root + 'MyProject.xcodeproj' path = config.project_root + 'MyProject.xcodeproj'
config.project_root.expects(:glob).with('*.xcodeproj').returns([path]) config.project_root.expects(:glob).with('*.xcodeproj').returns([path])
podfile.target_definitions[:default].xcodeproj.should == path podfile.target_definitions[:default].user_project.path.should == path
podfile.target_definitions[:another_target].xcodeproj.should == path podfile.target_definitions[:another_target].user_project.path.should == path
end end
it "assumes the basename of the workspace is the same as the default target's project basename" do it "assumes the basename of the workspace is the same as the default target's project basename" do
...@@ -117,7 +117,7 @@ describe "Pod::Podfile" do ...@@ -117,7 +117,7 @@ describe "Pod::Podfile" do
before do before do
@podfile = Pod::Podfile.new do @podfile = Pod::Podfile.new do
platform :ios platform :ios
xcodeproj 'iOS Project' xcodeproj 'iOS Project', 'iOS App Store' => :release, 'Test' => :debug
target :debug do target :debug do
dependency 'SSZipArchive' dependency 'SSZipArchive'
...@@ -133,7 +133,7 @@ describe "Pod::Podfile" do ...@@ -133,7 +133,7 @@ describe "Pod::Podfile" do
target :osx_target do target :osx_target do
platform :osx platform :osx
xcodeproj 'OSX Project.xcodeproj' xcodeproj 'OSX Project.xcodeproj', 'Mac App Store' => :release, 'Test' => :debug
link_with 'OSXTarget' link_with 'OSXTarget'
dependency 'ASIHTTPRequest' dependency 'ASIHTTPRequest'
target :nested_osx_target do target :nested_osx_target do
...@@ -178,26 +178,24 @@ describe "Pod::Podfile" do ...@@ -178,26 +178,24 @@ describe "Pod::Podfile" do
it "returns the Xcode project that contains the target to link with" do it "returns the Xcode project that contains the target to link with" do
[:default, :debug, :test, :subtarget].each do |target_name| [:default, :debug, :test, :subtarget].each do |target_name|
target = @podfile.target_definitions[target_name] target = @podfile.target_definitions[target_name]
target.xcodeproj.should == config.project_root + 'iOS Project.xcodeproj' target.user_project.path.should == config.project_root + 'iOS Project.xcodeproj'
end end
[:osx_target, :nested_osx_target].each do |target_name| [:osx_target, :nested_osx_target].each do |target_name|
target = @podfile.target_definitions[target_name] target = @podfile.target_definitions[target_name]
target.xcodeproj.should == config.project_root + 'OSX Project.xcodeproj' target.user_project.path.should == config.project_root + 'OSX Project.xcodeproj'
end end
end end
it "returns a Xcode project found in the working dir when no explicit project is specified" do it "returns a Xcode project found in the working dir when no explicit project is specified" do
xcodeproj1 = config.project_root + '1.xcodeproj' xcodeproj1 = config.project_root + '1.xcodeproj'
target = Pod::Podfile::TargetDefinition.new(:implicit)
config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1]) config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1])
target.xcodeproj.should == xcodeproj1 Pod::Podfile::UserProject.new.path.should == xcodeproj1
end end
it "returns `nil' if more than one Xcode project was found in the working when no explicit project is specified" do it "returns `nil' if more than one Xcode project was found in the working when no explicit project is specified" do
xcodeproj1, xcodeproj2 = config.project_root + '1.xcodeproj', config.project_root + '2.xcodeproj' xcodeproj1, xcodeproj2 = config.project_root + '1.xcodeproj', config.project_root + '2.xcodeproj'
target = Pod::Podfile::TargetDefinition.new(:implicit)
config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1, xcodeproj2]) config.project_root.expects(:glob).with('*.xcodeproj').returns([xcodeproj1, xcodeproj2])
target.xcodeproj.should == nil Pod::Podfile::UserProject.new.path.should == nil
end end
it "leaves the name of the target, to link with, to be automatically resolved" do it "leaves the name of the target, to link with, to be automatically resolved" do
...@@ -250,10 +248,18 @@ describe "Pod::Podfile" do ...@@ -250,10 +248,18 @@ describe "Pod::Podfile" do
@podfile.target_definitions[:nested_osx_target].should.not.be.exclusive @podfile.target_definitions[:nested_osx_target].should.not.be.exclusive
end end
it "returns the custom configurations, that the user's project contains, and wether it should be based on a debug or a release build" do
all = { 'Release' => :release, 'Debug' => :debug, 'Test' => :debug }
@podfile.target_definitions[:default].user_project.configurations.should == all.merge('iOS App Store' => :release)
@podfile.target_definitions[:test].user_project.configurations.should == all.merge('iOS App Store' => :release)
@podfile.target_definitions[:osx_target].user_project.configurations.should == all.merge('Mac App Store' => :release)
@podfile.target_definitions[:nested_osx_target].user_project.configurations.should == all.merge('Mac App Store' => :release)
end
describe "with an Xcode project that's not in the project_root" do describe "with an Xcode project that's not in the project_root" do
before do before do
@target_definition = @podfile.target_definitions[:default] @target_definition = @podfile.target_definitions[:default]
@target_definition.stubs(:xcodeproj).returns(config.project_root + 'subdir/iOS Project.xcodeproj') @target_definition.user_project.stubs(:path).returns(config.project_root + 'subdir/iOS Project.xcodeproj')
end end
it "returns the $(PODS_ROOT) relative to the project's $(SRCROOT)" do it "returns the $(PODS_ROOT) relative to the project's $(SRCROOT)" do
...@@ -264,7 +270,7 @@ describe "Pod::Podfile" do ...@@ -264,7 +270,7 @@ describe "Pod::Podfile" do
config.integrate_targets.should.equal true config.integrate_targets.should.equal true
config.integrate_targets = false config.integrate_targets = false
@target_definition.relative_pods_root.should == '${SRCROOT}/../Pods' @target_definition.relative_pods_root.should == '${SRCROOT}/../Pods'
@target_definition.stubs(:xcodeproj).returns(nil) @target_definition.user_project.stubs(:path).returns(nil)
@target_definition.relative_pods_root.should == '${SRCROOT}/Pods' @target_definition.relative_pods_root.should == '${SRCROOT}/Pods'
config.integrate_targets = true config.integrate_targets = true
end end
...@@ -282,9 +288,9 @@ describe "Pod::Podfile" do ...@@ -282,9 +288,9 @@ describe "Pod::Podfile" do
describe "concerning validations" do describe "concerning validations" do
it "raises if it should integrate and can't find an xcodeproj" do it "raises if it should integrate and can't find an xcodeproj" do
config.integrate_targets.should.equal true config.integrate_targets = true
target_definition = Pod::Podfile.new {}.target_definitions[:default] target_definition = Pod::Podfile.new {}.target_definitions[:default]
target_definition.stubs(:xcodeproj).returns(nil) target_definition.user_project.stubs(:path).returns(nil)
exception = lambda { exception = lambda {
target_definition.relative_pods_root target_definition.relative_pods_root
}.should.raise Pod::Informative }.should.raise Pod::Informative
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment