Commit 813bdac9 authored by Luke Redpath's avatar Luke Redpath

In preparation for further refactoring, extract integration with the user's project into a class

of it's own, and cover it's functionality with some specs.
parent 4bd63675
Subproject commit c874b109de3523829ef234a0e53a8c7c0ab1fc33
Subproject commit 7a771d9cba7eeea0515ebeac84a9155a3d7c4988
......@@ -15,6 +15,7 @@ module Pod
autoload :Platform, 'cocoapods/platform'
autoload :Podfile, 'cocoapods/podfile'
autoload :Project, 'cocoapods/project'
autoload :ProjectIntegration, 'cocoapods/project_integration'
autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox'
autoload :Source, 'cocoapods/source'
......
......@@ -123,56 +123,8 @@ module Pod
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 = Pod::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',
%{"${SRCROOT}/Pods/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
ProjectIntegration.integrate_with_project(projpath)
end
def dependent_specifications
......
require 'xcodeproj/workspace'
require 'xcodeproj/project'
module Pod
class ProjectIntegration
extend Pod::Config::Mixin
# 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 self.integrate_with_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::Object::PBXFrameworksBuildPhase).each do |build_phase|
build_phase.files << libfile.buildFiles.new
end
copy_resources = app_project.add_shell_script_build_phase('Copy Pods Resources',
%{"${SRCROOT}/Pods/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
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497114F9BE9A0080D870 /* UIKit.framework */; };
A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497314F9BE9A0080D870 /* Foundation.framework */; };
A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497514F9BE9A0080D870 /* CoreGraphics.framework */; };
A346497C14F9BE9A0080D870 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A346497A14F9BE9A0080D870 /* InfoPlist.strings */; };
A346497E14F9BE9A0080D870 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A346497D14F9BE9A0080D870 /* main.m */; };
A346498214F9BE9A0080D870 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A346498114F9BE9A0080D870 /* AppDelegate.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
A346496D14F9BE9A0080D870 /* SampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
A346497114F9BE9A0080D870 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
A346497314F9BE9A0080D870 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
A346497514F9BE9A0080D870 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
A346497914F9BE9A0080D870 /* SampleProject-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SampleProject-Info.plist"; sourceTree = "<group>"; };
A346497B14F9BE9A0080D870 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
A346497D14F9BE9A0080D870 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
A346497F14F9BE9A0080D870 /* SampleProject-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SampleProject-Prefix.pch"; sourceTree = "<group>"; };
A346498014F9BE9A0080D870 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
A346498114F9BE9A0080D870 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
A346496A14F9BE9A0080D870 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */,
A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */,
A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
A346496214F9BE990080D870 = {
isa = PBXGroup;
children = (
A346497714F9BE9A0080D870 /* SampleProject */,
A346497014F9BE9A0080D870 /* Frameworks */,
A346496E14F9BE9A0080D870 /* Products */,
);
sourceTree = "<group>";
};
A346496E14F9BE9A0080D870 /* Products */ = {
isa = PBXGroup;
children = (
A346496D14F9BE9A0080D870 /* SampleProject.app */,
);
name = Products;
sourceTree = "<group>";
};
A346497014F9BE9A0080D870 /* Frameworks */ = {
isa = PBXGroup;
children = (
A346497114F9BE9A0080D870 /* UIKit.framework */,
A346497314F9BE9A0080D870 /* Foundation.framework */,
A346497514F9BE9A0080D870 /* CoreGraphics.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
A346497714F9BE9A0080D870 /* SampleProject */ = {
isa = PBXGroup;
children = (
A346498014F9BE9A0080D870 /* AppDelegate.h */,
A346498114F9BE9A0080D870 /* AppDelegate.m */,
A346497814F9BE9A0080D870 /* Supporting Files */,
);
path = SampleProject;
sourceTree = "<group>";
};
A346497814F9BE9A0080D870 /* Supporting Files */ = {
isa = PBXGroup;
children = (
A346497914F9BE9A0080D870 /* SampleProject-Info.plist */,
A346497A14F9BE9A0080D870 /* InfoPlist.strings */,
A346497D14F9BE9A0080D870 /* main.m */,
A346497F14F9BE9A0080D870 /* SampleProject-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
A346496C14F9BE9A0080D870 /* SampleProject */ = {
isa = PBXNativeTarget;
buildConfigurationList = A346498514F9BE9A0080D870 /* Build configuration list for PBXNativeTarget "SampleProject" */;
buildPhases = (
A346496914F9BE9A0080D870 /* Sources */,
A346496A14F9BE9A0080D870 /* Frameworks */,
A346496B14F9BE9A0080D870 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = SampleProject;
productName = SampleProject;
productReference = A346496D14F9BE9A0080D870 /* SampleProject.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
A346496414F9BE990080D870 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
ORGANIZATIONNAME = "LJR Software Limited";
};
buildConfigurationList = A346496714F9BE990080D870 /* Build configuration list for PBXProject "SampleProject" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = A346496214F9BE990080D870;
productRefGroup = A346496E14F9BE9A0080D870 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
A346496C14F9BE9A0080D870 /* SampleProject */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
A346496B14F9BE9A0080D870 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A346497C14F9BE9A0080D870 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
A346496914F9BE9A0080D870 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A346497E14F9BE9A0080D870 /* main.m in Sources */,
A346498214F9BE9A0080D870 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
A346497A14F9BE9A0080D870 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
A346497B14F9BE9A0080D870 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
A346498314F9BE9A0080D870 /* Debug */ = {
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 = Debug;
};
A346498414F9BE9A0080D870 /* Release */ = {
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 = Release;
};
A346498614F9BE9A0080D870 /* Debug */ = {
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 = Debug;
};
A346498714F9BE9A0080D870 /* Release */ = {
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 = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
A346496714F9BE990080D870 /* Build configuration list for PBXProject "SampleProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A346498314F9BE9A0080D870 /* Debug */,
A346498414F9BE9A0080D870 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A346498514F9BE9A0080D870 /* Build configuration list for PBXNativeTarget "SampleProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A346498614F9BE9A0080D870 /* Debug */,
A346498714F9BE9A0080D870 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = A346496414F9BE990080D870 /* Project object */;
}
//
// AppDelegate.h
// SampleProject
//
// Created by Luke Redpath on 26/02/2012.
// Copyright (c) 2012 LJR Software Limited. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//
// AppDelegate.m
// SampleProject
//
// Created by Luke Redpath on 26/02/2012.
// Copyright (c) 2012 LJR Software Limited. All rights reserved.
//
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>co.uk.lukeredpath.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
//
// Prefix header for all source files of the 'SampleProject' target in the 'SampleProject' project
//
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
//
// main.m
// SampleProject
//
// Created by Luke Redpath on 26/02/2012.
// Copyright (c) 2012 LJR Software Limited. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
......@@ -3,6 +3,14 @@ module SpecHelper
Fixture.fixture(name)
end
def self.create_sample_app_copy_from_fixture(fixture_name)
tmp_dir = Pathname.new(Dir.mktmpdir)
fixture_path = ROOT + "spec/fixtures/#{fixture_name}"
fixture_copy_path = tmp_dir + fixture_name
FileUtils.cp_r(fixture_path, tmp_dir)
fixture_copy_path + "#{fixture_name}.xcodeproj"
end
module Fixture
ROOT = ::ROOT + 'spec/fixtures'
......
require File.expand_path('../../spec_helper', __FILE__)
describe Pod::ProjectIntegration do
before do
@sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
Pod::ProjectIntegration.integrate_with_project(@sample_project_path)
@sample_project = Xcodeproj::Project.new(@sample_project_path)
end
it 'creates a workspace with a name matching the project' do
workspace_path = @sample_project_path.dirname + "SampleProject.xcworkspace"
workspace_path.should.exist
end
it 'adds the project being integrated to the workspace' do
workspace = Xcodeproj::Workspace.new_from_xcworkspace(@sample_project_path.dirname + "SampleProject.xcworkspace")
workspace.should.include?("SampleProject.xcodeproj")
end
it 'adds the Pods project to the workspace' do
workspace = Xcodeproj::Workspace.new_from_xcworkspace(@sample_project_path.dirname + "SampleProject.xcworkspace")
workspace.projpaths.find { |path| path =~ /Pods.xcodeproj/ }.should.not.be.nil
end
it 'adds the Pods xcconfig file to the project' do
@sample_project.files.where(:path => "Pods/Pods.xcconfig").should.not.be.nil
end
it 'sets the Pods xcconfig as the base config for each build configuration' do
xcconfig_file = @sample_project.files.where(:path => "Pods/Pods.xcconfig")
@sample_project.targets.each do |target|
target.buildConfigurations.each do |config|
config.baseConfiguration.should == xcconfig_file
end
end
end
it 'adds a reference to the libPods static library' do
static_lib = @sample_project.files.where(:name => "libPods.a")
static_lib.should.not.be.nil
end
it 'adds the libPods static library to the "Link binary with libraries" build phase of each target' do
@sample_project.targets.each do |target|
framework_build_phase = target.frameworks_build_phases.first
framework_build_phase.files.where(:file => {:name => 'libPods.a'}).should.not.be.nil
end
end
it 'adds a Copy Pods Resources build phase to each target' do
@sample_project.targets.each do |target|
expected_phase = target.shell_script_build_phases.where(:name => "Copy Pods Resources")
expected_phase.shellScript.strip.should == "\"${SRCROOT}/Pods/Pods-resources.sh\"".strip
end
end
end
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