Commit ee854c16 authored by Fabio Pelosin's avatar Fabio Pelosin

Merge branch 'core-extraction' into installer_clean_up

* core-extraction: (92 commits)
  Minor fixes.
  [Changelog]
  [SpecHelper] More refinement for bacon support.
  [TargetInstaller] Extracted XCConfig generation to Generator::XCConfing.
  Release 0.16.0
  [RakeFile] More fixes for release task.
  [Gemspec] Require xcodeproj 0.4.0.
  [RakeFile] Minor fix for release task.
  [TargetInstaller] Fixed spec.
  [Command::Search] Catch DSL errors and present a warning.
  [UI] Minor adaptation for Core extraction.
  [List] Adapted for Core extraction.
  [Gemfile] Updated bundle.
  [Sandbox] Adapted for changes in Core.
  [LocalPod] Adapted for Core extraction.
  [Fixtures] Updates.
  [SpecHelper] Improved bacon support.
  [Sandobox] Adapted for Core extraction.
  [Resolver] adapted for Core extraction
  [Linter] Adoped Core Linter and renamed to DeepLinter (WIP).
  ...

Conflicts:
	lib/cocoapods/command/install.rb
	lib/cocoapods/command/linter.rb
	lib/cocoapods/installer.rb
	lib/cocoapods/lockfile.rb
	lib/cocoapods/resolver.rb
	spec/unit/installer_spec.rb
parents 697f8bd1 908790f5
...@@ -2,8 +2,21 @@ language: ruby ...@@ -2,8 +2,21 @@ language: ruby
rvm: rvm:
- 1.8.7 - 1.8.7
- 1.9.3 - 1.9.3
# Not in Travis non-pro yet
#- 2.0.0
# Rubinius in 1.8 mode on Travis does not work. It complains about st_data_t etc in Xcodeproj. # Rubinius in 1.8 mode on Travis does not work. It complains about st_data_t etc in Xcodeproj.
#- rbx-18mode #- rbx-18mode
- rbx-19mode - rbx-19mode
matrix:
allow_failures:
- rvm: rbx-19mode
#- rvm: 2.0.0
install: NOEXEC=skip rake travis:setup install: NOEXEC=skip rake travis:setup
script: bundle exec rake spec script: bundle exec rake spec
notifications:
# email: false
campfire:
on_success: change
on_failure: always
rooms:
- secure: "qOE5zmgaHe/qQu3W9rmj7wygA5Ivl+cx50fqWGag2bdRl8ly5yj1NVoOKk/O\nZmQc4Lze+301uvTXi+r5v8A/tF6W1kUZw7yBiKuXoYFUGmDiVR9o2I/FPwkL\ngSzPJttrXTQfkQ4PbnrkX+JO+5bLWrKaO0hKXT4B2yUu4UXLVk0="
## Master ## Branch 0.17
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.2...master)[Xcodeproj](https://github.com/CocoaPods/Xcodeproj/compare/0.3.5...master) ###### DSL Changes
- Deprecated header_mappings hook for specifications.
- `preferred_dependency` has been renamed to `default_subspec`.
- Added `s.exclude_source_files` and related attributes to the specification class.
- Added support for prefix_header_file in subspecs
- Added support for prefix_header_contents in subspecs
- Removed exclude_header_search_paths
- Added screenshot attribute
- Renamed preferred_dependency
###### Enhancements
- Extracted command-line command & option handling into
[CLAide](https://github.com/CocoaPods/CLAide).
- Added PathList class.
- Added Podfile to the Pods project.
[#476](https://github.com/CocoaPods/CocoaPods/issues/476)
## 0.16.0
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.16.0.rc5...master)
###### Enhancements
- Use Rake 0.9.4
[#657](https://github.com/CocoaPods/CocoaPods/issues/657)
## 0.16.0.rc5
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.16.0.rc4...0.16.0.rc5)
###### Deprecated
- The usage of specifications defined in a Podfile is deprecated. Use the
`:podspec` option with a file path instead. Complete removal will most
probably happen in 0.17.0.
[#549](https://github.com/CocoaPods/CocoaPods/issues/549)
[#616](https://github.com/CocoaPods/CocoaPods/issues/616)
[#525](https://github.com/CocoaPods/CocoaPods/issues/525)
###### Bug fixes
- Always consider inline podspecs as needing installation.
- Fix detection when the lib has already been integrated with the user’s target.
[#643](https://github.com/CocoaPods/CocoaPods/issues/643)
[#614](https://github.com/CocoaPods/CocoaPods/issues/614)
[#613](https://github.com/CocoaPods/CocoaPods/issues/613)
## 0.16.0.rc4
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.16.0.rc3...0.16.0.rc4)
###### Bug fixes
- Fix for Rake 0.9.3
[#657](https://github.com/CocoaPods/CocoaPods/issues/657)
## 0.16.0.rc3
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.16.0.rc2...0.16.0.rc3)[Xcodeproj](https://github.com/CocoaPods/Xcodeproj/compare/0.4.0.rc1...0.4.0.rc6)
###### Enhancements
- Added support for copying frameworks to the app bundle.
[#597](https://github.com/CocoaPods/CocoaPods/pull/597)
###### Bug fixes
- Ignore PBXReferenceProxy while integrating into user project.
[#626](https://github.com/CocoaPods/CocoaPods/issues/626)
- Added support for PBXAggregateTarget and PBXLegacyTarget.
[#615](https://github.com/CocoaPods/CocoaPods/issues/615)
- Added support for PBXReferenceProxy.
[#612](https://github.com/CocoaPods/CocoaPods/issues/612)
## 0.16.0.rc2
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.16.0.rc1...0.16.0.rc2)
###### Bug fixes
- Fix for uninitialized constant Xcodeproj::Constants error.
## 0.16.0.rc1
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.15.2...0.16.0.rc1)[Xcodeproj](https://github.com/CocoaPods/Xcodeproj/compare/0.3.5...0.4.0.rc1)
###### Enhancements
- Xcodeproj partial rewrite. - Xcodeproj partial rewrite.
[#576](https://github.com/CocoaPods/CocoaPods/pull/576) [#565](https://github.com/CocoaPods/CocoaPods/issues/565)
- Performance improvements in the `Generating supporting files` phase. [#561](https://github.com/CocoaPods/CocoaPods/pull/561)
- Performance improvements in the `Generating support files` phase.
- Better support for editing existing projects and sorting groups. - Better support for editing existing projects and sorting groups.
## 0.15.2 ## 0.15.2
...@@ -156,6 +241,7 @@ ...@@ -156,6 +241,7 @@
- The subversion downloader now does an export instead of a checkout, which - The subversion downloader now does an export instead of a checkout, which
makes it play nicer with SCMs that store metadata in each directory. makes it play nicer with SCMs that store metadata in each directory.
[#245](https://github.com/CocoaPods/CocoaPods/issues/245) [#245](https://github.com/CocoaPods/CocoaPods/issues/245)
- Now the Podfile is added to the Pods project for convenient editing.
###### Bug fixes ###### Bug fixes
......
...@@ -3,7 +3,8 @@ source "http://rubygems.org" ...@@ -3,7 +3,8 @@ source "http://rubygems.org"
gemspec gemspec
group :development do group :development do
gem "xcodeproj", :git => "git://github.com/CocoaPods/Xcodeproj.git", :branch => "refactor" gem "cocoapods-core", :git => "git://github.com/CocoaPods/Core.git"
gem "xcodeproj", :git => "git://github.com/CocoaPods/Xcodeproj.git"
gem "mocha", "~> 0.11.4" gem "mocha", "~> 0.11.4"
gem "bacon" gem "bacon"
gem "mocha-on-bacon" gem "mocha-on-bacon"
......
GIT
remote: git://github.com/CocoaPods/Core.git
revision: e41f3c851003589aaddde533dd6e90a81d095621
specs:
cocoapods-core (0.16.0.rc2)
activesupport (~> 3.2.6)
faraday (~> 0.8.1)
octokit (~> 1.7)
GIT GIT
remote: git://github.com/CocoaPods/Xcodeproj.git remote: git://github.com/CocoaPods/Xcodeproj.git
revision: 280a500ed5ee5a5f6bb4e3c5edcfef0240fa427b revision: d599d4ed17763aa5eb03382a17a6243e11beda2e
branch: refactor
specs: specs:
xcodeproj (0.3.5) xcodeproj (0.4.0)
activesupport (~> 3.2.6) activesupport (~> 3.2.6)
colored (~> 1.2)
GIT GIT
remote: https://github.com/alloy/kicker.git remote: https://github.com/alloy/kicker.git
...@@ -18,46 +27,49 @@ GIT ...@@ -18,46 +27,49 @@ GIT
PATH PATH
remote: . remote: .
specs: specs:
cocoapods (0.15.2) cocoapods (0.17.0.alpha)
activesupport (~> 3.2.6) activesupport (~> 3.2.6)
claide (~> 0.1)
cocoapods-core
colored (~> 1.2) colored (~> 1.2)
escape (~> 0.0.4) escape (~> 0.0.4)
faraday (~> 0.8.1) faraday (~> 0.8.1)
json (~> 1.7.3) json (~> 1.7.3)
octokit (~> 1.7) octokit (~> 1.7)
open4 (~> 1.3.0) open4 (~> 1.3.0)
rake (~> 0.9.0) rake (~> 0.9.4)
xcodeproj (~> 0.3.5) xcodeproj (~> 0.4.0)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
activesupport (3.2.8) activesupport (3.2.9)
i18n (~> 0.6) i18n (~> 0.6)
multi_json (~> 1.0) multi_json (~> 1.0)
addressable (2.3.2) addressable (2.3.2)
awesome_print (1.1.0) awesome_print (1.1.0)
bacon (1.1.0) bacon (1.1.0)
claide (0.2.0)
coderay (1.0.8) coderay (1.0.8)
colored (1.2) colored (1.2)
crack (0.3.1) crack (0.3.1)
escape (0.0.4) escape (0.0.4)
faraday (0.8.4) faraday (0.8.4)
multipart-post (~> 1.1) multipart-post (~> 1.1)
faraday_middleware (0.8.8) faraday_middleware (0.9.0)
faraday (>= 0.7.4, < 0.9) faraday (>= 0.7.4, < 0.9)
github-markup (0.7.4) github-markup (0.7.4)
hashie (1.2.0) hashie (1.2.0)
i18n (0.6.1) i18n (0.6.1)
json (1.7.5) json (1.7.5)
listen (0.5.3) listen (0.6.0)
metaclass (0.0.1) metaclass (0.0.1)
method_source (0.8.1) method_source (0.8.1)
mocha (0.11.4) mocha (0.11.4)
metaclass (~> 0.0.1) metaclass (~> 0.0.1)
mocha-on-bacon (0.2.1) mocha-on-bacon (0.2.1)
mocha (>= 0.9.8) mocha (>= 0.9.8)
multi_json (1.3.6) multi_json (1.3.7)
multipart-post (1.1.5) multipart-post (1.1.5)
octokit (1.18.0) octokit (1.18.0)
addressable (~> 2.2) addressable (~> 2.2)
...@@ -70,13 +82,13 @@ GEM ...@@ -70,13 +82,13 @@ GEM
coderay (~> 1.0.5) coderay (~> 1.0.5)
method_source (~> 0.8) method_source (~> 0.8)
slop (~> 3.3.1) slop (~> 3.3.1)
rake (0.9.2.2) rake (0.9.5)
rb-fsevent (0.9.2) rb-fsevent (0.9.2)
redcarpet (2.2.2) redcarpet (2.2.2)
slop (3.3.3) slop (3.3.3)
terminal-notifier (1.4.2) terminal-notifier (1.4.2)
vcr (2.2.5) vcr (2.3.0)
webmock (1.8.11) webmock (1.9.0)
addressable (>= 2.2.7) addressable (>= 2.2.7)
crack (>= 0.1.7) crack (>= 0.1.7)
yard (0.8.3) yard (0.8.3)
...@@ -88,6 +100,7 @@ DEPENDENCIES ...@@ -88,6 +100,7 @@ DEPENDENCIES
awesome_print awesome_print
bacon bacon
cocoapods! cocoapods!
cocoapods-core!
github-markup github-markup
kicker! kicker!
mocha (~> 0.11.4) mocha (~> 0.11.4)
......
...@@ -108,9 +108,9 @@ namespace :gem do ...@@ -108,9 +108,9 @@ namespace :gem do
required_xcodeproj_version = xcodeproj.requirement.requirements.first.last.to_s required_xcodeproj_version = xcodeproj.requirement.requirements.first.last.to_s
puts "* Checking if xcodeproj #{required_xcodeproj_version} exists on the gem host" puts "* Checking if xcodeproj #{required_xcodeproj_version} exists on the gem host"
search_result = silent_sh("gem search --remote xcodeproj") search_result = silent_sh("gem search --all --remote xcodeproj")
remote_xcodeproj_version = search_result.match(/xcodeproj \(([\d\.]+)\)/m)[1] remote_xcodeproj_versions = search_result.match(/xcodeproj \((.*)\)/m)[1].split(', ')
unless Gem::Version.new(required_xcodeproj_version) <= Gem::Version.new(remote_xcodeproj_version) unless remote_xcodeproj_versions.include?(required_xcodeproj_version)
$stderr.puts "[!] The Xcodeproj version `#{required_xcodeproj_version}' required by " \ $stderr.puts "[!] The Xcodeproj version `#{required_xcodeproj_version}' required by " \
"this version of CocoaPods does not exist on the gem host. " \ "this version of CocoaPods does not exist on the gem host. " \
"Either push that first, or fix the version requirement." "Either push that first, or fix the version requirement."
...@@ -211,7 +211,7 @@ namespace :spec do ...@@ -211,7 +211,7 @@ namespace :spec do
tarballs = FileList['spec/fixtures/**/*.tar.gz'] tarballs = FileList['spec/fixtures/**/*.tar.gz']
tarballs.each do |tarball| tarballs.each do |tarball|
basename = File.basename(tarball) basename = File.basename(tarball)
sh "cd #{File.dirname(tarball)} && rm #{basename} && tar -zcf #{basename} #{basename[0..-8]}" sh "cd #{File.dirname(tarball)} && rm #{basename} && env COPYFILE_DISABLE=1 tar -zcf #{basename} #{basename[0..-8]}"
end end
end end
......
...@@ -13,4 +13,4 @@ end ...@@ -13,4 +13,4 @@ end
require 'cocoapods' require 'cocoapods'
Pod::Command.run(*ARGV) Pod::Command.run(ARGV)
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
$:.unshift File.expand_path('../lib', __FILE__) $:.unshift File.expand_path('../lib', __FILE__)
require 'cocoapods' require 'cocoapods/version'
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "cocoapods" s.name = "cocoapods"
...@@ -26,7 +26,9 @@ Gem::Specification.new do |s| ...@@ -26,7 +26,9 @@ Gem::Specification.new do |s|
s.executables = %w{ pod } s.executables = %w{ pod }
s.require_paths = %w{ lib } s.require_paths = %w{ lib }
s.add_runtime_dependency 'xcodeproj', '~> 0.3.5' s.add_runtime_dependency 'cocoapods-core'
s.add_runtime_dependency 'claide', '~> 0.1'
s.add_runtime_dependency 'xcodeproj', '~> 0.4.0'
s.add_runtime_dependency 'faraday', '~> 0.8.1' s.add_runtime_dependency 'faraday', '~> 0.8.1'
s.add_runtime_dependency 'octokit', '~> 1.7' s.add_runtime_dependency 'octokit', '~> 1.7'
...@@ -34,7 +36,7 @@ Gem::Specification.new do |s| ...@@ -34,7 +36,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'escape', '~> 0.0.4' s.add_runtime_dependency 'escape', '~> 0.0.4'
s.add_runtime_dependency 'json', '~> 1.7.3' s.add_runtime_dependency 'json', '~> 1.7.3'
s.add_runtime_dependency 'open4', '~> 1.3.0' s.add_runtime_dependency 'open4', '~> 1.3.0'
s.add_runtime_dependency 'rake', '~> 0.9.0' s.add_runtime_dependency 'rake', '~> 0.9.4'
s.add_runtime_dependency 'activesupport', '~> 3.2.6' s.add_runtime_dependency 'activesupport', '~> 3.2.6'
s.add_development_dependency 'bacon', '~> 1.1' s.add_development_dependency 'bacon', '~> 1.1'
......
// !$*UTF8*$! <?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">
archiveVersion = 1; <plist version="1.0">
classes = { <dict>
}; <key>archiveVersion</key>
objectVersion = 46; <string>1</string>
objects = { <key>classes</key>
<dict/>
/* Begin PBXBuildFile section */ <key>objectVersion</key>
11B1743F89354E14AD85E930 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8611E331022F4C3AA09890CC /* libPods.a */; }; <string>46</string>
F87A15CD1444A30800318955 /* AFGowallaAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15C61444A30800318955 /* AFGowallaAPIClient.m */; }; <key>objects</key>
F87A15CE1444A30800318955 /* NearbySpotsController.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15C91444A30800318955 /* NearbySpotsController.m */; }; <dict>
F87A15CF1444A30800318955 /* Spot.m in Sources */ = {isa = PBXBuildFile; fileRef = F87A15CC1444A30800318955 /* Spot.m */; }; <key>11B1743F89354E14AD85E930</key>
F87A15D11444A3EB00318955 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F87A15D01444A3EB00318955 /* CoreLocation.framework */; }; <dict>
F87A15DD1444A86600318955 /* placeholder-stamp.png in Resources */ = {isa = PBXBuildFile; fileRef = F87A15DB1444A86600318955 /* placeholder-stamp.png */; }; <key>fileRef</key>
F8A27AC7142CFE1300F5E0D6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8A27AB2142CFE1300F5E0D6 /* AppDelegate.m */; }; <string>8611E331022F4C3AA09890CC</string>
F8A27AC8142CFE1300F5E0D6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F8A27AB3142CFE1300F5E0D6 /* main.m */; }; <key>isa</key>
F8A27AC9142CFE1300F5E0D6 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = F8A27AB9142CFE1300F5E0D6 /* Credits.rtf */; }; <string>PBXBuildFile</string>
F8A27ACA142CFE1300F5E0D6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F8A27ABB142CFE1300F5E0D6 /* MainMenu.xib */; }; </dict>
F8CEEB6F142CEC6E00247B03 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8CEEB6E142CEC6E00247B03 /* Cocoa.framework */; }; <key>421D23439A244A868D6E03C7</key>
/* End PBXBuildFile section */ <dict>
<key>fileRef</key>
/* Begin PBXFileReference section */ <string>D30A9AFA1D134BD896376B60</string>
7F444671037A4EAEBDA542D6 /* Pods.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; <key>isa</key>
8611E331022F4C3AA09890CC /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; <string>PBXBuildFile</string>
F87A15C51444A30800318955 /* AFGowallaAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFGowallaAPIClient.h; sourceTree = "<group>"; }; <key>settings</key>
F87A15C61444A30800318955 /* AFGowallaAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFGowallaAPIClient.m; sourceTree = "<group>"; }; <dict/>
F87A15C81444A30800318955 /* NearbySpotsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NearbySpotsController.h; sourceTree = "<group>"; }; </dict>
F87A15C91444A30800318955 /* NearbySpotsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NearbySpotsController.m; sourceTree = "<group>"; }; <key>4796F62BE55948D5808E91C5</key>
F87A15CB1444A30800318955 /* Spot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spot.h; sourceTree = "<group>"; }; <dict>
F87A15CC1444A30800318955 /* Spot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Spot.m; sourceTree = "<group>"; }; <key>buildActionMask</key>
F87A15D01444A3EB00318955 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; <string>2147483647</string>
F87A15DB1444A86600318955 /* placeholder-stamp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "placeholder-stamp.png"; sourceTree = "<group>"; }; <key>files</key>
F8A27AB1142CFE1300F5E0D6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; <array/>
F8A27AB2142CFE1300F5E0D6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; <key>inputPaths</key>
F8A27AB3142CFE1300F5E0D6 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; <array/>
F8A27ABA142CFE1300F5E0D6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = Credits.rtf; sourceTree = "<group>"; }; <key>isa</key>
F8A27ABC142CFE1300F5E0D6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MainMenu.xib; sourceTree = "<group>"; }; <string>PBXShellScriptBuildPhase</string>
F8A27AC4142CFE1300F5E0D6 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = "<group>"; }; <key>name</key>
F8A27AC5142CFE1300F5E0D6 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; <string>Copy Pods Resources</string>
F8CEEB6A142CEC6E00247B03 /* AFNetworking Mac Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AFNetworking Mac Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; <key>outputPaths</key>
F8CEEB6E142CEC6E00247B03 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; <array/>
F8CEEB71142CEC6E00247B03 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; <key>runOnlyForDeploymentPostprocessing</key>
F8CEEB72142CEC6E00247B03 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; <string>0</string>
F8CEEB73142CEC6E00247B03 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; <key>shellPath</key>
/* End PBXFileReference section */ <string>/bin/sh</string>
<key>shellScript</key>
/* Begin PBXFrameworksBuildPhase section */ <string>"${SRCROOT}/Pods/Pods-resources.sh"
F8CEEB67142CEC6E00247B03 /* Frameworks */ = { </string>
isa = PBXFrameworksBuildPhase; </dict>
buildActionMask = 2147483647; <key>7F444671037A4EAEBDA542D6</key>
files = ( <dict>
F87A15D11444A3EB00318955 /* CoreLocation.framework in Frameworks */, <key>isa</key>
F8CEEB6F142CEC6E00247B03 /* Cocoa.framework in Frameworks */, <string>PBXFileReference</string>
11B1743F89354E14AD85E930 /* libPods.a in Frameworks */, <key>lastKnownFileType</key>
); <string>text.xcconfig</string>
runOnlyForDeploymentPostprocessing = 0; <key>name</key>
}; <string>Pods.xcconfig</string>
/* End PBXFrameworksBuildPhase section */ <key>path</key>
<string>Pods/Pods.xcconfig</string>
/* Begin PBXGroup section */ <key>sourceTree</key>
F87A15C41444A30800318955 /* Classes */ = { <string>SOURCE_ROOT</string>
isa = PBXGroup; </dict>
children = ( <key>7FE1FF99DC1B4295A4C8BD9E</key>
F87A15C51444A30800318955 /* AFGowallaAPIClient.h */, <dict>
F87A15C61444A30800318955 /* AFGowallaAPIClient.m */, <key>includeInIndex</key>
F87A15C71444A30800318955 /* Controllers */, <string>1</string>
F87A15CA1444A30800318955 /* Models */, <key>isa</key>
); <string>PBXFileReference</string>
path = Classes; <key>lastKnownFileType</key>
sourceTree = "<group>"; <string>text.xcconfig</string>
}; <key>name</key>
F87A15C71444A30800318955 /* Controllers */ = { <string>Pods.xcconfig</string>
isa = PBXGroup; <key>path</key>
children = ( <string>Pods/Pods.xcconfig</string>
F87A15C81444A30800318955 /* NearbySpotsController.h */, <key>sourceTree</key>
F87A15C91444A30800318955 /* NearbySpotsController.m */, <string>SOURCE_ROOT</string>
); </dict>
path = Controllers; <key>8611E331022F4C3AA09890CC</key>
sourceTree = "<group>"; <dict>
}; <key>explicitFileType</key>
F87A15CA1444A30800318955 /* Models */ = { <string>archive.ar</string>
isa = PBXGroup; <key>includeInIndex</key>
children = ( <string>0</string>
F87A15CB1444A30800318955 /* Spot.h */, <key>isa</key>
F87A15CC1444A30800318955 /* Spot.m */, <string>PBXFileReference</string>
); <key>path</key>
path = Models; <string>libPods.a</string>
sourceTree = "<group>"; <key>sourceTree</key>
}; <string>BUILT_PRODUCTS_DIR</string>
F87A15DA1444A86600318955 /* Images */ = { </dict>
isa = PBXGroup; <key>D30A9AFA1D134BD896376B60</key>
children = ( <dict>
F87A15DB1444A86600318955 /* placeholder-stamp.png */, <key>explicitFileType</key>
); <string>archive.ar</string>
path = Images; <key>includeInIndex</key>
sourceTree = "<group>"; <string>0</string>
}; <key>isa</key>
F8A27ACD142CFE3000F5E0D6 /* Supporting Files */ = { <string>PBXFileReference</string>
isa = PBXGroup; <key>name</key>
children = ( <string>libPods.a</string>
F8A27AB3142CFE1300F5E0D6 /* main.m */, <key>path</key>
F8A27AB1142CFE1300F5E0D6 /* Info.plist */, <string>libPods.a</string>
F8A27AB2142CFE1300F5E0D6 /* AppDelegate.m */, <key>sourceTree</key>
F8A27AC4142CFE1300F5E0D6 /* Prefix.pch */, <string>BUILT_PRODUCTS_DIR</string>
F8A27AC5142CFE1300F5E0D6 /* AppDelegate.h */, </dict>
F8A27AB9142CFE1300F5E0D6 /* Credits.rtf */, <key>EA4ACD0F68074D0289CD79E3</key>
F8A27ABB142CFE1300F5E0D6 /* MainMenu.xib */, <dict>
F87A15DA1444A86600318955 /* Images */, <key>buildActionMask</key>
); <string>2147483647</string>
name = "Supporting Files"; <key>files</key>
sourceTree = "<group>"; <array/>
}; <key>inputPaths</key>
F8CEEB5F142CEC6E00247B03 = { <array/>
isa = PBXGroup; <key>isa</key>
children = ( <string>PBXShellScriptBuildPhase</string>
F87A15C41444A30800318955 /* Classes */, <key>name</key>
F8A27ACD142CFE3000F5E0D6 /* Supporting Files */, <string>Copy Pods Resources</string>
F8CEEB6D142CEC6E00247B03 /* Frameworks */, <key>outputPaths</key>
F8CEEB6B142CEC6E00247B03 /* Products */, <array/>
7F444671037A4EAEBDA542D6 /* Pods.xcconfig */, <key>runOnlyForDeploymentPostprocessing</key>
); <string>0</string>
sourceTree = "<group>"; <key>shellPath</key>
}; <string>/bin/sh</string>
F8CEEB6B142CEC6E00247B03 /* Products */ = { <key>shellScript</key>
isa = PBXGroup; <string>"${SRCROOT}/Pods/Pods-resources.sh"
children = ( </string>
F8CEEB6A142CEC6E00247B03 /* AFNetworking Mac Example.app */, </dict>
); <key>F87A15C41444A30800318955</key>
name = Products; <dict>
sourceTree = "<group>"; <key>children</key>
}; <array>
F8CEEB6D142CEC6E00247B03 /* Frameworks */ = { <string>F87A15C51444A30800318955</string>
isa = PBXGroup; <string>F87A15C61444A30800318955</string>
children = ( <string>F87A15C71444A30800318955</string>
F87A15D01444A3EB00318955 /* CoreLocation.framework */, <string>F87A15CA1444A30800318955</string>
F8CEEB6E142CEC6E00247B03 /* Cocoa.framework */, </array>
F8CEEB70142CEC6E00247B03 /* Other Frameworks */, <key>isa</key>
8611E331022F4C3AA09890CC /* libPods.a */, <string>PBXGroup</string>
); <key>path</key>
name = Frameworks; <string>Classes</string>
sourceTree = "<group>"; <key>sourceTree</key>
}; <string>&lt;group&gt;</string>
F8CEEB70142CEC6E00247B03 /* Other Frameworks */ = { </dict>
isa = PBXGroup; <key>F87A15C51444A30800318955</key>
children = ( <dict>
F8CEEB71142CEC6E00247B03 /* AppKit.framework */, <key>fileEncoding</key>
F8CEEB72142CEC6E00247B03 /* CoreData.framework */, <string>4</string>
F8CEEB73142CEC6E00247B03 /* Foundation.framework */, <key>isa</key>
); <string>PBXFileReference</string>
name = "Other Frameworks"; <key>lastKnownFileType</key>
sourceTree = "<group>"; <string>sourcecode.c.h</string>
}; <key>path</key>
/* End PBXGroup section */ <string>AFGowallaAPIClient.h</string>
<key>sourceTree</key>
/* Begin PBXNativeTarget section */ <string>&lt;group&gt;</string>
F8CEEB69142CEC6E00247B03 /* AFNetworking Mac Example */ = { </dict>
isa = PBXNativeTarget; <key>F87A15C61444A30800318955</key>
buildConfigurationList = F8CEEB88142CEC6E00247B03 /* Build configuration list for PBXNativeTarget "AFNetworking Mac Example" */; <dict>
buildPhases = ( <key>fileEncoding</key>
F8CEEB66142CEC6E00247B03 /* Sources */, <string>4</string>
F8CEEB67142CEC6E00247B03 /* Frameworks */, <key>isa</key>
F8CEEB68142CEC6E00247B03 /* Resources */, <string>PBXFileReference</string>
EA4ACD0F68074D0289CD79E3 /* Copy Pods Resources */, <key>lastKnownFileType</key>
); <string>sourcecode.c.objc</string>
buildRules = ( <key>path</key>
); <string>AFGowallaAPIClient.m</string>
dependencies = ( <key>sourceTree</key>
); <string>&lt;group&gt;</string>
name = "AFNetworking Mac Example"; </dict>
productName = "AFNetworking Mac Example"; <key>F87A15C71444A30800318955</key>
productReference = F8CEEB6A142CEC6E00247B03 /* AFNetworking Mac Example.app */; <dict>
productType = "com.apple.product-type.application"; <key>children</key>
}; <array>
/* End PBXNativeTarget section */ <string>F87A15C81444A30800318955</string>
<string>F87A15C91444A30800318955</string>
/* Begin PBXProject section */ </array>
F8CEEB61142CEC6E00247B03 /* Project object */ = { <key>isa</key>
isa = PBXProject; <string>PBXGroup</string>
attributes = { <key>path</key>
LastUpgradeCheck = 0420; <string>Controllers</string>
ORGANIZATIONNAME = Gowalla; <key>sourceTree</key>
}; <string>&lt;group&gt;</string>
buildConfigurationList = F8CEEB64142CEC6E00247B03 /* Build configuration list for PBXProject "AFNetworking Mac Example" */; </dict>
compatibilityVersion = "Xcode 3.2"; <key>F87A15C81444A30800318955</key>
developmentRegion = English; <dict>
hasScannedForEncodings = 0; <key>fileEncoding</key>
knownRegions = ( <string>4</string>
en, <key>isa</key>
); <string>PBXFileReference</string>
mainGroup = F8CEEB5F142CEC6E00247B03; <key>lastKnownFileType</key>
productRefGroup = F8CEEB6B142CEC6E00247B03 /* Products */; <string>sourcecode.c.h</string>
projectDirPath = ""; <key>path</key>
projectRoot = ""; <string>NearbySpotsController.h</string>
targets = ( <key>sourceTree</key>
F8CEEB69142CEC6E00247B03 /* AFNetworking Mac Example */, <string>&lt;group&gt;</string>
); </dict>
}; <key>F87A15C91444A30800318955</key>
/* End PBXProject section */ <dict>
<key>fileEncoding</key>
/* Begin PBXResourcesBuildPhase section */ <string>4</string>
F8CEEB68142CEC6E00247B03 /* Resources */ = { <key>isa</key>
isa = PBXResourcesBuildPhase; <string>PBXFileReference</string>
buildActionMask = 2147483647; <key>lastKnownFileType</key>
files = ( <string>sourcecode.c.objc</string>
F8A27AC9142CFE1300F5E0D6 /* Credits.rtf in Resources */, <key>path</key>
F8A27ACA142CFE1300F5E0D6 /* MainMenu.xib in Resources */, <string>NearbySpotsController.m</string>
F87A15DD1444A86600318955 /* placeholder-stamp.png in Resources */, <key>sourceTree</key>
); <string>&lt;group&gt;</string>
runOnlyForDeploymentPostprocessing = 0; </dict>
}; <key>F87A15CA1444A30800318955</key>
/* End PBXResourcesBuildPhase section */ <dict>
<key>children</key>
/* Begin PBXShellScriptBuildPhase section */ <array>
EA4ACD0F68074D0289CD79E3 /* Copy Pods Resources */ = { <string>F87A15CB1444A30800318955</string>
isa = PBXShellScriptBuildPhase; <string>F87A15CC1444A30800318955</string>
buildActionMask = 2147483647; </array>
files = ( <key>isa</key>
); <string>PBXGroup</string>
inputPaths = ( <key>path</key>
); <string>Models</string>
name = "Copy Pods Resources"; <key>sourceTree</key>
outputPaths = ( <string>&lt;group&gt;</string>
); </dict>
runOnlyForDeploymentPostprocessing = 0; <key>F87A15CB1444A30800318955</key>
shellPath = /bin/sh; <dict>
shellScript = "\"${SRCROOT}/Pods/Pods-resources.sh\"\n"; <key>fileEncoding</key>
}; <string>4</string>
/* End PBXShellScriptBuildPhase section */ <key>isa</key>
<string>PBXFileReference</string>
/* Begin PBXSourcesBuildPhase section */ <key>lastKnownFileType</key>
F8CEEB66142CEC6E00247B03 /* Sources */ = { <string>sourcecode.c.h</string>
isa = PBXSourcesBuildPhase; <key>path</key>
buildActionMask = 2147483647; <string>Spot.h</string>
files = ( <key>sourceTree</key>
F8A27AC7142CFE1300F5E0D6 /* AppDelegate.m in Sources */, <string>&lt;group&gt;</string>
F8A27AC8142CFE1300F5E0D6 /* main.m in Sources */, </dict>
F87A15CD1444A30800318955 /* AFGowallaAPIClient.m in Sources */, <key>F87A15CC1444A30800318955</key>
F87A15CE1444A30800318955 /* NearbySpotsController.m in Sources */, <dict>
F87A15CF1444A30800318955 /* Spot.m in Sources */, <key>fileEncoding</key>
); <string>4</string>
runOnlyForDeploymentPostprocessing = 0; <key>isa</key>
}; <string>PBXFileReference</string>
/* End PBXSourcesBuildPhase section */ <key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
/* Begin PBXVariantGroup section */ <key>path</key>
F8A27AB9142CFE1300F5E0D6 /* Credits.rtf */ = { <string>Spot.m</string>
isa = PBXVariantGroup; <key>sourceTree</key>
children = ( <string>&lt;group&gt;</string>
F8A27ABA142CFE1300F5E0D6 /* en */, </dict>
); <key>F87A15CD1444A30800318955</key>
name = Credits.rtf; <dict>
path = en.lproj; <key>fileRef</key>
sourceTree = "<group>"; <string>F87A15C61444A30800318955</string>
}; <key>isa</key>
F8A27ABB142CFE1300F5E0D6 /* MainMenu.xib */ = { <string>PBXBuildFile</string>
isa = PBXVariantGroup; </dict>
children = ( <key>F87A15CE1444A30800318955</key>
F8A27ABC142CFE1300F5E0D6 /* en */, <dict>
); <key>fileRef</key>
name = MainMenu.xib; <string>F87A15C91444A30800318955</string>
path = en.lproj; <key>isa</key>
sourceTree = "<group>"; <string>PBXBuildFile</string>
}; </dict>
/* End PBXVariantGroup section */ <key>F87A15CF1444A30800318955</key>
<dict>
/* Begin XCBuildConfiguration section */ <key>fileRef</key>
F8CEEB86142CEC6E00247B03 /* Debug */ = { <string>F87A15CC1444A30800318955</string>
isa = XCBuildConfiguration; <key>isa</key>
buildSettings = { <string>PBXBuildFile</string>
ALWAYS_SEARCH_USER_PATHS = NO; </dict>
ARCHS = "$(ARCHS_STANDARD_64_BIT)"; <key>F87A15D01444A3EB00318955</key>
CLANG_ENABLE_OBJC_ARC = YES; <dict>
COPY_PHASE_STRIP = NO; <key>isa</key>
GCC_C_LANGUAGE_STANDARD = gnu99; <string>PBXFileReference</string>
GCC_DYNAMIC_NO_PIC = NO; <key>lastKnownFileType</key>
GCC_ENABLE_OBJC_EXCEPTIONS = YES; <string>wrapper.framework</string>
GCC_OPTIMIZATION_LEVEL = 0; <key>name</key>
GCC_PREPROCESSOR_DEFINITIONS = ( <string>CoreLocation.framework</string>
"DEBUG=1", <key>path</key>
"$(inherited)", <string>System/Library/Frameworks/CoreLocation.framework</string>
); <key>sourceTree</key>
GCC_SYMBOLS_PRIVATE_EXTERN = NO; <string>SDKROOT</string>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; </dict>
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; <key>F87A15D11444A3EB00318955</key>
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; <dict>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <key>fileRef</key>
GCC_WARN_UNUSED_VARIABLE = YES; <string>F87A15D01444A3EB00318955</string>
MACOSX_DEPLOYMENT_TARGET = 10.6; <key>isa</key>
ONLY_ACTIVE_ARCH = YES; <string>PBXBuildFile</string>
SDKROOT = macosx; </dict>
}; <key>F87A15DA1444A86600318955</key>
name = Debug; <dict>
}; <key>children</key>
F8CEEB87142CEC6E00247B03 /* Release */ = { <array>
isa = XCBuildConfiguration; <string>F87A15DB1444A86600318955</string>
buildSettings = { </array>
ALWAYS_SEARCH_USER_PATHS = NO; <key>isa</key>
ARCHS = "$(ARCHS_STANDARD_64_BIT)"; <string>PBXGroup</string>
CLANG_ENABLE_OBJC_ARC = YES; <key>path</key>
COPY_PHASE_STRIP = YES; <string>Images</string>
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; <key>sourceTree</key>
GCC_C_LANGUAGE_STANDARD = gnu99; <string>&lt;group&gt;</string>
GCC_ENABLE_OBJC_EXCEPTIONS = YES; </dict>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <key>F87A15DB1444A86600318955</key>
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; <dict>
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; <key>isa</key>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <string>PBXFileReference</string>
GCC_WARN_UNUSED_VARIABLE = YES; <key>lastKnownFileType</key>
MACOSX_DEPLOYMENT_TARGET = 10.6; <string>image.png</string>
SDKROOT = macosx; <key>path</key>
}; <string>placeholder-stamp.png</string>
name = Release; <key>sourceTree</key>
}; <string>&lt;group&gt;</string>
F8CEEB89142CEC6E00247B03 /* Debug */ = { </dict>
isa = XCBuildConfiguration; <key>F87A15DD1444A86600318955</key>
baseConfigurationReference = 7F444671037A4EAEBDA542D6 /* Pods.xcconfig */; <dict>
buildSettings = { <key>fileRef</key>
DSTROOT = /tmp/Pods.dst; <string>F87A15DB1444A86600318955</string>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>isa</key>
GCC_PREFIX_HEADER = Prefix.pch; <string>PBXBuildFile</string>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; </dict>
INFOPLIST_FILE = Info.plist; <key>F8A27AB1142CFE1300F5E0D6</key>
OTHER_LDFLAGS = ""; <dict>
PRODUCT_NAME = "$(TARGET_NAME)"; <key>fileEncoding</key>
SKIP_INSTALL = YES; <string>4</string>
WRAPPER_EXTENSION = app; <key>isa</key>
}; <string>PBXFileReference</string>
name = Debug; <key>lastKnownFileType</key>
}; <string>text.plist.xml</string>
F8CEEB8A142CEC6E00247B03 /* Release */ = { <key>path</key>
isa = XCBuildConfiguration; <string>Info.plist</string>
baseConfigurationReference = 7F444671037A4EAEBDA542D6 /* Pods.xcconfig */; <key>sourceTree</key>
buildSettings = { <string>&lt;group&gt;</string>
DSTROOT = /tmp/Pods.dst; </dict>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>F8A27AB2142CFE1300F5E0D6</key>
GCC_PREFIX_HEADER = Prefix.pch; <dict>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <key>fileEncoding</key>
INFOPLIST_FILE = Info.plist; <string>4</string>
OTHER_LDFLAGS = ""; <key>isa</key>
PRODUCT_NAME = "$(TARGET_NAME)"; <string>PBXFileReference</string>
SKIP_INSTALL = YES; <key>lastKnownFileType</key>
WRAPPER_EXTENSION = app; <string>sourcecode.c.objc</string>
}; <key>path</key>
name = Release; <string>AppDelegate.m</string>
}; <key>sourceTree</key>
/* End XCBuildConfiguration section */ <string>&lt;group&gt;</string>
</dict>
/* Begin XCConfigurationList section */ <key>F8A27AB3142CFE1300F5E0D6</key>
F8CEEB64142CEC6E00247B03 /* Build configuration list for PBXProject "AFNetworking Mac Example" */ = { <dict>
isa = XCConfigurationList; <key>fileEncoding</key>
buildConfigurations = ( <string>4</string>
F8CEEB86142CEC6E00247B03 /* Debug */, <key>isa</key>
F8CEEB87142CEC6E00247B03 /* Release */, <string>PBXFileReference</string>
); <key>lastKnownFileType</key>
defaultConfigurationIsVisible = 0; <string>sourcecode.c.objc</string>
defaultConfigurationName = Release; <key>path</key>
}; <string>main.m</string>
F8CEEB88142CEC6E00247B03 /* Build configuration list for PBXNativeTarget "AFNetworking Mac Example" */ = { <key>sourceTree</key>
isa = XCConfigurationList; <string>&lt;group&gt;</string>
buildConfigurations = ( </dict>
F8CEEB89142CEC6E00247B03 /* Debug */, <key>F8A27AB9142CFE1300F5E0D6</key>
F8CEEB8A142CEC6E00247B03 /* Release */, <dict>
); <key>children</key>
defaultConfigurationIsVisible = 0; <array>
defaultConfigurationName = Release; <string>F8A27ABA142CFE1300F5E0D6</string>
}; </array>
/* End XCConfigurationList section */ <key>isa</key>
}; <string>PBXVariantGroup</string>
rootObject = F8CEEB61142CEC6E00247B03 /* Project object */; <key>name</key>
} <string>Credits.rtf</string>
<key>path</key>
<string>en.lproj</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27ABA142CFE1300F5E0D6</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.rtf</string>
<key>name</key>
<string>en</string>
<key>path</key>
<string>Credits.rtf</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27ABB142CFE1300F5E0D6</key>
<dict>
<key>children</key>
<array>
<string>F8A27ABC142CFE1300F5E0D6</string>
</array>
<key>isa</key>
<string>PBXVariantGroup</string>
<key>name</key>
<string>MainMenu.xib</string>
<key>path</key>
<string>en.lproj</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27ABC142CFE1300F5E0D6</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>file.xib</string>
<key>name</key>
<string>en</string>
<key>path</key>
<string>MainMenu.xib</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27AC4142CFE1300F5E0D6</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>Prefix.pch</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27AC5142CFE1300F5E0D6</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>AppDelegate.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8A27AC7142CFE1300F5E0D6</key>
<dict>
<key>fileRef</key>
<string>F8A27AB2142CFE1300F5E0D6</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8A27AC8142CFE1300F5E0D6</key>
<dict>
<key>fileRef</key>
<string>F8A27AB3142CFE1300F5E0D6</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8A27AC9142CFE1300F5E0D6</key>
<dict>
<key>fileRef</key>
<string>F8A27AB9142CFE1300F5E0D6</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8A27ACA142CFE1300F5E0D6</key>
<dict>
<key>fileRef</key>
<string>F8A27ABB142CFE1300F5E0D6</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8A27ACD142CFE3000F5E0D6</key>
<dict>
<key>children</key>
<array>
<string>F8A27AB3142CFE1300F5E0D6</string>
<string>F8A27AB1142CFE1300F5E0D6</string>
<string>F8A27AB2142CFE1300F5E0D6</string>
<string>F8A27AC4142CFE1300F5E0D6</string>
<string>F8A27AC5142CFE1300F5E0D6</string>
<string>F8A27AB9142CFE1300F5E0D6</string>
<string>F8A27ABB142CFE1300F5E0D6</string>
<string>F87A15DA1444A86600318955</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Supporting Files</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8CEEB5F142CEC6E00247B03</key>
<dict>
<key>children</key>
<array>
<string>F87A15C41444A30800318955</string>
<string>F8A27ACD142CFE3000F5E0D6</string>
<string>F8CEEB6D142CEC6E00247B03</string>
<string>F8CEEB6B142CEC6E00247B03</string>
<string>7F444671037A4EAEBDA542D6</string>
<string>7FE1FF99DC1B4295A4C8BD9E</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8CEEB61142CEC6E00247B03</key>
<dict>
<key>attributes</key>
<dict>
<key>LastUpgradeCheck</key>
<string>0420</string>
<key>ORGANIZATIONNAME</key>
<string>Gowalla</string>
</dict>
<key>buildConfigurationList</key>
<string>F8CEEB64142CEC6E00247B03</string>
<key>compatibilityVersion</key>
<string>Xcode 3.2</string>
<key>developmentRegion</key>
<string>English</string>
<key>hasScannedForEncodings</key>
<string>0</string>
<key>isa</key>
<string>PBXProject</string>
<key>knownRegions</key>
<array>
<string>en</string>
</array>
<key>mainGroup</key>
<string>F8CEEB5F142CEC6E00247B03</string>
<key>productRefGroup</key>
<string>F8CEEB6B142CEC6E00247B03</string>
<key>projectDirPath</key>
<string></string>
<key>projectReferences</key>
<array/>
<key>projectRoot</key>
<string></string>
<key>targets</key>
<array>
<string>F8CEEB69142CEC6E00247B03</string>
</array>
</dict>
<key>F8CEEB64142CEC6E00247B03</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>F8CEEB86142CEC6E00247B03</string>
<string>F8CEEB87142CEC6E00247B03</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>F8CEEB66142CEC6E00247B03</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F8A27AC7142CFE1300F5E0D6</string>
<string>F8A27AC8142CFE1300F5E0D6</string>
<string>F87A15CD1444A30800318955</string>
<string>F87A15CE1444A30800318955</string>
<string>F87A15CF1444A30800318955</string>
</array>
<key>isa</key>
<string>PBXSourcesBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8CEEB67142CEC6E00247B03</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F87A15D11444A3EB00318955</string>
<string>F8CEEB6F142CEC6E00247B03</string>
<string>11B1743F89354E14AD85E930</string>
<string>421D23439A244A868D6E03C7</string>
</array>
<key>isa</key>
<string>PBXFrameworksBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8CEEB68142CEC6E00247B03</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F8A27AC9142CFE1300F5E0D6</string>
<string>F8A27ACA142CFE1300F5E0D6</string>
<string>F87A15DD1444A86600318955</string>
</array>
<key>isa</key>
<string>PBXResourcesBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8CEEB69142CEC6E00247B03</key>
<dict>
<key>buildConfigurationList</key>
<string>F8CEEB88142CEC6E00247B03</string>
<key>buildPhases</key>
<array>
<string>F8CEEB66142CEC6E00247B03</string>
<string>F8CEEB67142CEC6E00247B03</string>
<string>F8CEEB68142CEC6E00247B03</string>
<string>EA4ACD0F68074D0289CD79E3</string>
<string>4796F62BE55948D5808E91C5</string>
</array>
<key>buildRules</key>
<array/>
<key>dependencies</key>
<array/>
<key>isa</key>
<string>PBXNativeTarget</string>
<key>name</key>
<string>AFNetworking Mac Example</string>
<key>productName</key>
<string>AFNetworking Mac Example</string>
<key>productReference</key>
<string>F8CEEB6A142CEC6E00247B03</string>
<key>productType</key>
<string>com.apple.product-type.application</string>
</dict>
<key>F8CEEB6A142CEC6E00247B03</key>
<dict>
<key>explicitFileType</key>
<string>wrapper.application</string>
<key>includeInIndex</key>
<string>0</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>path</key>
<string>AFNetworking Mac Example.app</string>
<key>sourceTree</key>
<string>BUILT_PRODUCTS_DIR</string>
</dict>
<key>F8CEEB6B142CEC6E00247B03</key>
<dict>
<key>children</key>
<array>
<string>F8CEEB6A142CEC6E00247B03</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Products</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8CEEB6D142CEC6E00247B03</key>
<dict>
<key>children</key>
<array>
<string>F87A15D01444A3EB00318955</string>
<string>F8CEEB6E142CEC6E00247B03</string>
<string>F8CEEB70142CEC6E00247B03</string>
<string>8611E331022F4C3AA09890CC</string>
<string>D30A9AFA1D134BD896376B60</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Frameworks</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8CEEB6E142CEC6E00247B03</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>Cocoa.framework</string>
<key>path</key>
<string>System/Library/Frameworks/Cocoa.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8CEEB6F142CEC6E00247B03</key>
<dict>
<key>fileRef</key>
<string>F8CEEB6E142CEC6E00247B03</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8CEEB70142CEC6E00247B03</key>
<dict>
<key>children</key>
<array>
<string>F8CEEB71142CEC6E00247B03</string>
<string>F8CEEB72142CEC6E00247B03</string>
<string>F8CEEB73142CEC6E00247B03</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Other Frameworks</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8CEEB71142CEC6E00247B03</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>AppKit.framework</string>
<key>path</key>
<string>System/Library/Frameworks/AppKit.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8CEEB72142CEC6E00247B03</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>CoreData.framework</string>
<key>path</key>
<string>System/Library/Frameworks/CoreData.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8CEEB73142CEC6E00247B03</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>Foundation.framework</string>
<key>path</key>
<string>System/Library/Frameworks/Foundation.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8CEEB86142CEC6E00247B03</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ALWAYS_SEARCH_USER_PATHS</key>
<string>NO</string>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_64_BIT)</string>
<key>CLANG_ENABLE_OBJC_ARC</key>
<string>YES</string>
<key>COPY_PHASE_STRIP</key>
<string>NO</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>gnu99</string>
<key>GCC_DYNAMIC_NO_PIC</key>
<string>NO</string>
<key>GCC_ENABLE_OBJC_EXCEPTIONS</key>
<string>YES</string>
<key>GCC_OPTIMIZATION_LEVEL</key>
<string>0</string>
<key>GCC_PREPROCESSOR_DEFINITIONS</key>
<array>
<string>DEBUG=1</string>
<string>$(inherited)</string>
</array>
<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
<string>NO</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_MISSING_PROTOTYPES</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>MACOSX_DEPLOYMENT_TARGET</key>
<string>10.6</string>
<key>ONLY_ACTIVE_ARCH</key>
<string>YES</string>
<key>SDKROOT</key>
<string>macosx</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>F8CEEB87142CEC6E00247B03</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ALWAYS_SEARCH_USER_PATHS</key>
<string>NO</string>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_64_BIT)</string>
<key>CLANG_ENABLE_OBJC_ARC</key>
<string>YES</string>
<key>COPY_PHASE_STRIP</key>
<string>YES</string>
<key>DEBUG_INFORMATION_FORMAT</key>
<string>dwarf-with-dsym</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>gnu99</string>
<key>GCC_ENABLE_OBJC_EXCEPTIONS</key>
<string>YES</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_MISSING_PROTOTYPES</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>MACOSX_DEPLOYMENT_TARGET</key>
<string>10.6</string>
<key>SDKROOT</key>
<string>macosx</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
<key>F8CEEB88142CEC6E00247B03</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>F8CEEB89142CEC6E00247B03</string>
<string>F8CEEB8A142CEC6E00247B03</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>F8CEEB89142CEC6E00247B03</key>
<dict>
<key>baseConfigurationReference</key>
<string>7FE1FF99DC1B4295A4C8BD9E</string>
<key>buildSettings</key>
<dict>
<key>DSTROOT</key>
<string>/tmp/Pods.dst</string>
<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
<string>YES</string>
<key>GCC_PREFIX_HEADER</key>
<string>Prefix.pch</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>INFOPLIST_FILE</key>
<string>Info.plist</string>
<key>OTHER_LDFLAGS</key>
<string></string>
<key>PRODUCT_NAME</key>
<string>$(TARGET_NAME)</string>
<key>SKIP_INSTALL</key>
<string>YES</string>
<key>WRAPPER_EXTENSION</key>
<string>app</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>F8CEEB8A142CEC6E00247B03</key>
<dict>
<key>baseConfigurationReference</key>
<string>7FE1FF99DC1B4295A4C8BD9E</string>
<key>buildSettings</key>
<dict>
<key>DSTROOT</key>
<string>/tmp/Pods.dst</string>
<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
<string>YES</string>
<key>GCC_PREFIX_HEADER</key>
<string>Prefix.pch</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>INFOPLIST_FILE</key>
<string>Info.plist</string>
<key>OTHER_LDFLAGS</key>
<string></string>
<key>PRODUCT_NAME</key>
<string>$(TARGET_NAME)</string>
<key>SKIP_INSTALL</key>
<string>YES</string>
<key>WRAPPER_EXTENSION</key>
<string>app</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
</dict>
<key>rootObject</key>
<string>F8CEEB61142CEC6E00247B03</string>
</dict>
</plist>
COCOAPODS: 0.15.1 PODS:
- AFNetworking (0.7.0):
PODS:
- AFNetworking (0.7.0):
- JSONKit - JSONKit
- FormatterKit (1.0.0): - FormatterKit (1.0.0):
- FormatterKit/ArrayFormatter (= 1.0.0) - FormatterKit/ArrayFormatter (= 1.0.0)
- FormatterKit/LocationFormatter (= 1.0.0) - FormatterKit/LocationFormatter (= 1.0.0)
- FormatterKit/OrdinalNumberFormatter (= 1.0.0) - FormatterKit/OrdinalNumberFormatter (= 1.0.0)
...@@ -19,17 +17,19 @@ PODS: ...@@ -19,17 +17,19 @@ PODS:
- FormatterKit/UnitOfInformationFormatter (1.0.0) - FormatterKit/UnitOfInformationFormatter (1.0.0)
- JSONKit (1.5pre) - JSONKit (1.5pre)
SPEC CHECKSUMS: DEPENDENCIES:
FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 - AFNetworking (~> 0.7.0)
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 - FormatterKit
SPEC CHECKSUMS:
AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c
JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477 FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821 JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
DEPENDENCIES: COCOAPODS: 0.16.0.rc2
- AFNetworking (~> 0.7.0)
- FormatterKit
// !$*UTF8*$! <?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">
archiveVersion = 1; <plist version="1.0">
classes = { <dict>
}; <key>archiveVersion</key>
objectVersion = 46; <string>1</string>
objects = { <key>classes</key>
<dict/>
/* Begin PBXBuildFile section */ <key>objectVersion</key>
46CF19E6210948BCAA4F152C /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 242C9E9348A44970B9ECDCF5 /* libPods.a */; }; <string>46</string>
F8D0701B14310F4A00653FD3 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */; }; <key>objects</key>
F8D0701C14310F4F00653FD3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469E013957DF100DB05C8 /* Security.framework */; }; <dict>
F8D25D191396A9D300CF3BD6 /* placeholder-stamp.png in Resources */ = {isa = PBXBuildFile; fileRef = F8D25D171396A9D300CF3BD6 /* placeholder-stamp.png */; }; <key>0BBDA6CDB42C48EFB1B980BC</key>
F8D25D1A1396A9D300CF3BD6 /* placeholder-stamp@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F8D25D181396A9D300CF3BD6 /* placeholder-stamp@2x.png */; }; <dict>
F8DA09D21396ABED0057D0CC /* AFGowallaAPIClient.m in Sources */ = {isa = PBXBuildFile; fileRef = F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */; }; <key>explicitFileType</key>
F8DA09D41396ABED0057D0CC /* NearbySpotsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09C81396AB690057D0CC /* NearbySpotsViewController.m */; }; <string>archive.ar</string>
F8DA09D51396ABED0057D0CC /* Spot.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09CB1396AB690057D0CC /* Spot.m */; }; <key>includeInIndex</key>
F8DA09D61396ABED0057D0CC /* SpotTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09CE1396AB690057D0CC /* SpotTableViewCell.m */; }; <string>0</string>
F8DA09E41396AC040057D0CC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09E31396AC040057D0CC /* main.m */; }; <key>isa</key>
F8DA09E81396AC220057D0CC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F8DA09E71396AC220057D0CC /* AppDelegate.m */; }; <string>PBXFileReference</string>
F8E469651395739D00DB05C8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469641395739D00DB05C8 /* UIKit.framework */; }; <key>name</key>
F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469661395739D00DB05C8 /* Foundation.framework */; }; <string>libPods.a</string>
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469681395739D00DB05C8 /* CoreGraphics.framework */; }; <key>path</key>
F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8E469DE13957DD500DB05C8 /* CoreLocation.framework */; }; <string>libPods.a</string>
/* End PBXBuildFile section */ <key>sourceTree</key>
<string>BUILT_PRODUCTS_DIR</string>
/* Begin PBXFileReference section */ </dict>
242C9E9348A44970B9ECDCF5 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; <key>242C9E9348A44970B9ECDCF5</key>
391552C2BD5947DF9FEB5975 /* Pods.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; <dict>
F8D25D171396A9D300CF3BD6 /* placeholder-stamp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "placeholder-stamp.png"; path = "Images/placeholder-stamp.png"; sourceTree = SOURCE_ROOT; }; <key>explicitFileType</key>
F8D25D181396A9D300CF3BD6 /* placeholder-stamp@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "placeholder-stamp@2x.png"; path = "Images/placeholder-stamp@2x.png"; sourceTree = SOURCE_ROOT; }; <string>archive.ar</string>
F8D25D1B1396A9DE00CF3BD6 /* AFGowallaAPIClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFGowallaAPIClient.h; path = Classes/AFGowallaAPIClient.h; sourceTree = "<group>"; }; <key>includeInIndex</key>
F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFGowallaAPIClient.m; path = Classes/AFGowallaAPIClient.m; sourceTree = "<group>"; }; <string>0</string>
F8DA09C71396AB690057D0CC /* NearbySpotsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NearbySpotsViewController.h; sourceTree = "<group>"; }; <key>isa</key>
F8DA09C81396AB690057D0CC /* NearbySpotsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NearbySpotsViewController.m; sourceTree = "<group>"; }; <string>PBXFileReference</string>
F8DA09CA1396AB690057D0CC /* Spot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Spot.h; sourceTree = "<group>"; }; <key>path</key>
F8DA09CB1396AB690057D0CC /* Spot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Spot.m; sourceTree = "<group>"; }; <string>libPods.a</string>
F8DA09CD1396AB690057D0CC /* SpotTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpotTableViewCell.h; sourceTree = "<group>"; }; <key>sourceTree</key>
F8DA09CE1396AB690057D0CC /* SpotTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpotTableViewCell.m; sourceTree = "<group>"; }; <string>BUILT_PRODUCTS_DIR</string>
F8DA09E31396AC040057D0CC /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; </dict>
F8DA09E51396AC220057D0CC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; <key>391552C2BD5947DF9FEB5975</key>
F8DA09E61396AC220057D0CC /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = SOURCE_ROOT; }; <dict>
F8DA09E71396AC220057D0CC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; <key>isa</key>
F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AFNetworking iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; <string>PBXFileReference</string>
F8E469641395739D00DB05C8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; <key>lastKnownFileType</key>
F8E469661395739D00DB05C8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; <string>text.xcconfig</string>
F8E469681395739D00DB05C8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; <key>name</key>
F8E4696C1395739D00DB05C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; <string>Pods.xcconfig</string>
F8E469DE13957DD500DB05C8 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; <key>path</key>
F8E469E013957DF100DB05C8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; <string>Pods/Pods.xcconfig</string>
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; <key>sourceTree</key>
/* End PBXFileReference section */ <string>SOURCE_ROOT</string>
</dict>
/* Begin PBXFrameworksBuildPhase section */ <key>46CF19E6210948BCAA4F152C</key>
F8E4695D1395739C00DB05C8 /* Frameworks */ = { <dict>
isa = PBXFrameworksBuildPhase; <key>fileRef</key>
buildActionMask = 2147483647; <string>242C9E9348A44970B9ECDCF5</string>
files = ( <key>isa</key>
F8E469651395739D00DB05C8 /* UIKit.framework in Frameworks */, <string>PBXBuildFile</string>
F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */, </dict>
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */, <key>89DE83CBA1B145CEB0C1180C</key>
F8E469DF13957DD500DB05C8 /* CoreLocation.framework in Frameworks */, <dict>
F8D0701B14310F4A00653FD3 /* SystemConfiguration.framework in Frameworks */, <key>fileRef</key>
F8D0701C14310F4F00653FD3 /* Security.framework in Frameworks */, <string>0BBDA6CDB42C48EFB1B980BC</string>
46CF19E6210948BCAA4F152C /* libPods.a in Frameworks */, <key>isa</key>
); <string>PBXBuildFile</string>
runOnlyForDeploymentPostprocessing = 0; <key>settings</key>
}; <dict/>
/* End PBXFrameworksBuildPhase section */ </dict>
<key>8A3A8D61FF1041A3B3AA9C55</key>
/* Begin PBXGroup section */ <dict>
F8DA09C61396AB690057D0CC /* Controllers */ = { <key>buildActionMask</key>
isa = PBXGroup; <string>2147483647</string>
children = ( <key>files</key>
F8DA09C71396AB690057D0CC /* NearbySpotsViewController.h */, <array/>
F8DA09C81396AB690057D0CC /* NearbySpotsViewController.m */, <key>inputPaths</key>
); <array/>
name = Controllers; <key>isa</key>
path = Classes/Controllers; <string>PBXShellScriptBuildPhase</string>
sourceTree = SOURCE_ROOT; <key>name</key>
}; <string>Copy Pods Resources</string>
F8DA09C91396AB690057D0CC /* Models */ = { <key>outputPaths</key>
isa = PBXGroup; <array/>
children = ( <key>runOnlyForDeploymentPostprocessing</key>
F8DA09CA1396AB690057D0CC /* Spot.h */, <string>0</string>
F8DA09CB1396AB690057D0CC /* Spot.m */, <key>shellPath</key>
); <string>/bin/sh</string>
name = Models; <key>shellScript</key>
path = Classes/Models; <string>"${SRCROOT}/Pods/Pods-resources.sh"
sourceTree = SOURCE_ROOT; </string>
}; </dict>
F8DA09CC1396AB690057D0CC /* Views */ = { <key>C8C94222118242C297ED4081</key>
isa = PBXGroup; <dict>
children = ( <key>includeInIndex</key>
F8DA09CD1396AB690057D0CC /* SpotTableViewCell.h */, <string>1</string>
F8DA09CE1396AB690057D0CC /* SpotTableViewCell.m */, <key>isa</key>
); <string>PBXFileReference</string>
name = Views; <key>lastKnownFileType</key>
path = Classes/Views; <string>text.xcconfig</string>
sourceTree = SOURCE_ROOT; <key>name</key>
}; <string>Pods.xcconfig</string>
F8E469551395739C00DB05C8 = { <key>path</key>
isa = PBXGroup; <string>Pods/Pods.xcconfig</string>
children = ( <key>sourceTree</key>
F8E469B71395759C00DB05C8 /* Networking Extensions */, <string>SOURCE_ROOT</string>
F8E4696A1395739D00DB05C8 /* Classes */, </dict>
F8E469ED1395812A00DB05C8 /* Images */, <key>DD5E268688D543178A339BEB</key>
F8E469631395739D00DB05C8 /* Frameworks */, <dict>
F8E469611395739C00DB05C8 /* Products */, <key>buildActionMask</key>
391552C2BD5947DF9FEB5975 /* Pods.xcconfig */, <string>2147483647</string>
); <key>files</key>
sourceTree = "<group>"; <array/>
}; <key>inputPaths</key>
F8E469611395739C00DB05C8 /* Products */ = { <array/>
isa = PBXGroup; <key>isa</key>
children = ( <string>PBXShellScriptBuildPhase</string>
F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */, <key>name</key>
); <string>Copy Pods Resources</string>
name = Products; <key>outputPaths</key>
sourceTree = "<group>"; <array/>
}; <key>runOnlyForDeploymentPostprocessing</key>
F8E469631395739D00DB05C8 /* Frameworks */ = { <string>0</string>
isa = PBXGroup; <key>shellPath</key>
children = ( <string>/bin/sh</string>
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */, <key>shellScript</key>
F8E469E013957DF100DB05C8 /* Security.framework */, <string>"${SRCROOT}/Pods/Pods-resources.sh"
F8E469DE13957DD500DB05C8 /* CoreLocation.framework */, </string>
F8E469641395739D00DB05C8 /* UIKit.framework */, </dict>
F8E469661395739D00DB05C8 /* Foundation.framework */, <key>F8D0701B14310F4A00653FD3</key>
F8E469681395739D00DB05C8 /* CoreGraphics.framework */, <dict>
242C9E9348A44970B9ECDCF5 /* libPods.a */, <key>fileRef</key>
); <string>F8E469E213957DF700DB05C8</string>
name = Frameworks; <key>isa</key>
sourceTree = "<group>"; <string>PBXBuildFile</string>
}; </dict>
F8E4696A1395739D00DB05C8 /* Classes */ = { <key>F8D0701C14310F4F00653FD3</key>
isa = PBXGroup; <dict>
children = ( <key>fileRef</key>
F8DA09C61396AB690057D0CC /* Controllers */, <string>F8E469E013957DF100DB05C8</string>
F8DA09C91396AB690057D0CC /* Models */, <key>isa</key>
F8DA09CC1396AB690057D0CC /* Views */, <string>PBXBuildFile</string>
F8E4696B1395739D00DB05C8 /* Supporting Files */, </dict>
); <key>F8D25D171396A9D300CF3BD6</key>
name = Classes; <dict>
path = AFNetworkingExample; <key>isa</key>
sourceTree = "<group>"; <string>PBXFileReference</string>
}; <key>lastKnownFileType</key>
F8E4696B1395739D00DB05C8 /* Supporting Files */ = { <string>image.png</string>
isa = PBXGroup; <key>name</key>
children = ( <string>placeholder-stamp.png</string>
F8DA09E31396AC040057D0CC /* main.m */, <key>path</key>
F8DA09E61396AC220057D0CC /* Prefix.pch */, <string>Images/placeholder-stamp.png</string>
F8DA09E51396AC220057D0CC /* AppDelegate.h */, <key>sourceTree</key>
F8DA09E71396AC220057D0CC /* AppDelegate.m */, <string>SOURCE_ROOT</string>
F8E4696C1395739D00DB05C8 /* Info.plist */, </dict>
); <key>F8D25D181396A9D300CF3BD6</key>
name = "Supporting Files"; <dict>
sourceTree = "<group>"; <key>isa</key>
}; <string>PBXFileReference</string>
F8E469B71395759C00DB05C8 /* Networking Extensions */ = { <key>lastKnownFileType</key>
isa = PBXGroup; <string>image.png</string>
children = ( <key>name</key>
F8D25D1B1396A9DE00CF3BD6 /* AFGowallaAPIClient.h */, <string>placeholder-stamp@2x.png</string>
F8D25D1D1396A9DE00CF3BD6 /* AFGowallaAPIClient.m */, <key>path</key>
); <string>Images/placeholder-stamp@2x.png</string>
name = "Networking Extensions"; <key>sourceTree</key>
sourceTree = "<group>"; <string>SOURCE_ROOT</string>
}; </dict>
F8E469ED1395812A00DB05C8 /* Images */ = { <key>F8D25D191396A9D300CF3BD6</key>
isa = PBXGroup; <dict>
children = ( <key>fileRef</key>
F8D25D171396A9D300CF3BD6 /* placeholder-stamp.png */, <string>F8D25D171396A9D300CF3BD6</string>
F8D25D181396A9D300CF3BD6 /* placeholder-stamp@2x.png */, <key>isa</key>
); <string>PBXBuildFile</string>
name = Images; </dict>
path = AFNetworkingExample/Images; <key>F8D25D1A1396A9D300CF3BD6</key>
sourceTree = "<group>"; <dict>
}; <key>fileRef</key>
/* End PBXGroup section */ <string>F8D25D181396A9D300CF3BD6</string>
<key>isa</key>
/* Begin PBXNativeTarget section */ <string>PBXBuildFile</string>
F8E4695F1395739C00DB05C8 /* AFNetworking iOS Example */ = { </dict>
isa = PBXNativeTarget; <key>F8D25D1B1396A9DE00CF3BD6</key>
buildConfigurationList = F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworking iOS Example" */; <dict>
buildPhases = ( <key>fileEncoding</key>
F8E4695C1395739C00DB05C8 /* Sources */, <string>4</string>
F8E4695D1395739C00DB05C8 /* Frameworks */, <key>isa</key>
F8E4695E1395739C00DB05C8 /* Resources */, <string>PBXFileReference</string>
DD5E268688D543178A339BEB /* Copy Pods Resources */, <key>lastKnownFileType</key>
); <string>sourcecode.c.h</string>
buildRules = ( <key>name</key>
); <string>AFGowallaAPIClient.h</string>
dependencies = ( <key>path</key>
); <string>Classes/AFGowallaAPIClient.h</string>
name = "AFNetworking iOS Example"; <key>sourceTree</key>
productName = AFNetworkingExample; <string>&lt;group&gt;</string>
productReference = F8E469601395739C00DB05C8 /* AFNetworking iOS Example.app */; </dict>
productType = "com.apple.product-type.application"; <key>F8D25D1D1396A9DE00CF3BD6</key>
}; <dict>
/* End PBXNativeTarget section */ <key>fileEncoding</key>
<string>4</string>
/* Begin PBXProject section */ <key>isa</key>
F8E469571395739C00DB05C8 /* Project object */ = { <string>PBXFileReference</string>
isa = PBXProject; <key>lastKnownFileType</key>
attributes = { <string>sourcecode.c.objc</string>
LastUpgradeCheck = 0420; <key>name</key>
ORGANIZATIONNAME = Gowalla; <string>AFGowallaAPIClient.m</string>
}; <key>path</key>
buildConfigurationList = F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking iOS Example" */; <string>Classes/AFGowallaAPIClient.m</string>
compatibilityVersion = "Xcode 3.2"; <key>sourceTree</key>
developmentRegion = English; <string>&lt;group&gt;</string>
hasScannedForEncodings = 0; </dict>
knownRegions = ( <key>F8DA09C61396AB690057D0CC</key>
en, <dict>
); <key>children</key>
mainGroup = F8E469551395739C00DB05C8; <array>
productRefGroup = F8E469611395739C00DB05C8 /* Products */; <string>F8DA09C71396AB690057D0CC</string>
projectDirPath = ""; <string>F8DA09C81396AB690057D0CC</string>
projectRoot = ""; </array>
targets = ( <key>isa</key>
F8E4695F1395739C00DB05C8 /* AFNetworking iOS Example */, <string>PBXGroup</string>
); <key>name</key>
}; <string>Controllers</string>
/* End PBXProject section */ <key>path</key>
<string>Classes/Controllers</string>
/* Begin PBXResourcesBuildPhase section */ <key>sourceTree</key>
F8E4695E1395739C00DB05C8 /* Resources */ = { <string>SOURCE_ROOT</string>
isa = PBXResourcesBuildPhase; </dict>
buildActionMask = 2147483647; <key>F8DA09C71396AB690057D0CC</key>
files = ( <dict>
F8D25D191396A9D300CF3BD6 /* placeholder-stamp.png in Resources */, <key>fileEncoding</key>
F8D25D1A1396A9D300CF3BD6 /* placeholder-stamp@2x.png in Resources */, <string>4</string>
); <key>isa</key>
runOnlyForDeploymentPostprocessing = 0; <string>PBXFileReference</string>
}; <key>lastKnownFileType</key>
/* End PBXResourcesBuildPhase section */ <string>sourcecode.c.h</string>
<key>path</key>
/* Begin PBXShellScriptBuildPhase section */ <string>NearbySpotsViewController.h</string>
DD5E268688D543178A339BEB /* Copy Pods Resources */ = { <key>sourceTree</key>
isa = PBXShellScriptBuildPhase; <string>&lt;group&gt;</string>
buildActionMask = 2147483647; </dict>
files = ( <key>F8DA09C81396AB690057D0CC</key>
); <dict>
inputPaths = ( <key>fileEncoding</key>
); <string>4</string>
name = "Copy Pods Resources"; <key>isa</key>
outputPaths = ( <string>PBXFileReference</string>
); <key>lastKnownFileType</key>
runOnlyForDeploymentPostprocessing = 0; <string>sourcecode.c.objc</string>
shellPath = /bin/sh; <key>path</key>
shellScript = "\"${SRCROOT}/Pods/Pods-resources.sh\"\n"; <string>NearbySpotsViewController.m</string>
}; <key>sourceTree</key>
/* End PBXShellScriptBuildPhase section */ <string>&lt;group&gt;</string>
</dict>
/* Begin PBXSourcesBuildPhase section */ <key>F8DA09C91396AB690057D0CC</key>
F8E4695C1395739C00DB05C8 /* Sources */ = { <dict>
isa = PBXSourcesBuildPhase; <key>children</key>
buildActionMask = 2147483647; <array>
files = ( <string>F8DA09CA1396AB690057D0CC</string>
F8DA09D21396ABED0057D0CC /* AFGowallaAPIClient.m in Sources */, <string>F8DA09CB1396AB690057D0CC</string>
F8DA09D41396ABED0057D0CC /* NearbySpotsViewController.m in Sources */, </array>
F8DA09D51396ABED0057D0CC /* Spot.m in Sources */, <key>isa</key>
F8DA09D61396ABED0057D0CC /* SpotTableViewCell.m in Sources */, <string>PBXGroup</string>
F8DA09E41396AC040057D0CC /* main.m in Sources */, <key>name</key>
F8DA09E81396AC220057D0CC /* AppDelegate.m in Sources */, <string>Models</string>
); <key>path</key>
runOnlyForDeploymentPostprocessing = 0; <string>Classes/Models</string>
}; <key>sourceTree</key>
/* End PBXSourcesBuildPhase section */ <string>SOURCE_ROOT</string>
</dict>
/* Begin XCBuildConfiguration section */ <key>F8DA09CA1396AB690057D0CC</key>
F8E4697F1395739D00DB05C8 /* Debug */ = { <dict>
isa = XCBuildConfiguration; <key>fileEncoding</key>
buildSettings = { <string>4</string>
ARCHS = "$(ARCHS_STANDARD_32_BIT)"; <key>isa</key>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; <string>PBXFileReference</string>
GCC_C_LANGUAGE_STANDARD = gnu99; <key>lastKnownFileType</key>
GCC_OPTIMIZATION_LEVEL = 0; <string>sourcecode.c.h</string>
GCC_PREPROCESSOR_DEFINITIONS = DEBUG; <key>path</key>
GCC_SYMBOLS_PRIVATE_EXTERN = NO; <string>Spot.h</string>
GCC_VERSION = com.apple.compilers.llvmgcc42; <key>sourceTree</key>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <string>&lt;group&gt;</string>
GCC_WARN_UNUSED_VARIABLE = YES; </dict>
IPHONEOS_DEPLOYMENT_TARGET = 4.3; <key>F8DA09CB1396AB690057D0CC</key>
SDKROOT = iphoneos; <dict>
}; <key>fileEncoding</key>
name = Debug; <string>4</string>
}; <key>isa</key>
F8E469801395739D00DB05C8 /* Release */ = { <string>PBXFileReference</string>
isa = XCBuildConfiguration; <key>lastKnownFileType</key>
buildSettings = { <string>sourcecode.c.objc</string>
ARCHS = "$(ARCHS_STANDARD_32_BIT)"; <key>path</key>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; <string>Spot.m</string>
GCC_C_LANGUAGE_STANDARD = gnu99; <key>sourceTree</key>
GCC_VERSION = com.apple.compilers.llvmgcc42; <string>&lt;group&gt;</string>
GCC_WARN_ABOUT_RETURN_TYPE = YES; </dict>
GCC_WARN_UNUSED_VARIABLE = YES; <key>F8DA09CC1396AB690057D0CC</key>
IPHONEOS_DEPLOYMENT_TARGET = 4.3; <dict>
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; <key>children</key>
SDKROOT = iphoneos; <array>
}; <string>F8DA09CD1396AB690057D0CC</string>
name = Release; <string>F8DA09CE1396AB690057D0CC</string>
}; </array>
F8E469821395739D00DB05C8 /* Debug */ = { <key>isa</key>
isa = XCBuildConfiguration; <string>PBXGroup</string>
baseConfigurationReference = 391552C2BD5947DF9FEB5975 /* Pods.xcconfig */; <key>name</key>
buildSettings = { <string>Views</string>
ALWAYS_SEARCH_USER_PATHS = NO; <key>path</key>
COPY_PHASE_STRIP = NO; <string>Classes/Views</string>
DSTROOT = /tmp/Pods.dst; <key>sourceTree</key>
GCC_DYNAMIC_NO_PIC = NO; <string>SOURCE_ROOT</string>
GCC_PRECOMPILE_PREFIX_HEADER = YES; </dict>
GCC_PREFIX_HEADER = Prefix.pch; <key>F8DA09CD1396AB690057D0CC</key>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <dict>
GCC_WARN_SHADOW = YES; <key>fileEncoding</key>
GCC_WARN_SIGN_COMPARE = YES; <string>4</string>
GCC_WARN_UNUSED_PARAMETER = NO; <key>isa</key>
INFOPLIST_FILE = Info.plist; <string>PBXFileReference</string>
PRODUCT_NAME = "$(TARGET_NAME)"; <key>lastKnownFileType</key>
SKIP_INSTALL = YES; <string>sourcecode.c.h</string>
WRAPPER_EXTENSION = app; <key>path</key>
}; <string>SpotTableViewCell.h</string>
name = Debug; <key>sourceTree</key>
}; <string>&lt;group&gt;</string>
F8E469831395739D00DB05C8 /* Release */ = { </dict>
isa = XCBuildConfiguration; <key>F8DA09CE1396AB690057D0CC</key>
baseConfigurationReference = 391552C2BD5947DF9FEB5975 /* Pods.xcconfig */; <dict>
buildSettings = { <key>fileEncoding</key>
ALWAYS_SEARCH_USER_PATHS = NO; <string>4</string>
COPY_PHASE_STRIP = YES; <key>isa</key>
DSTROOT = /tmp/Pods.dst; <string>PBXFileReference</string>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>lastKnownFileType</key>
GCC_PREFIX_HEADER = Prefix.pch; <string>sourcecode.c.objc</string>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <key>path</key>
GCC_WARN_SHADOW = YES; <string>SpotTableViewCell.m</string>
GCC_WARN_SIGN_COMPARE = YES; <key>sourceTree</key>
GCC_WARN_UNUSED_PARAMETER = NO; <string>&lt;group&gt;</string>
INFOPLIST_FILE = Info.plist; </dict>
PRODUCT_NAME = "$(TARGET_NAME)"; <key>F8DA09D21396ABED0057D0CC</key>
SKIP_INSTALL = YES; <dict>
VALIDATE_PRODUCT = YES; <key>fileRef</key>
WRAPPER_EXTENSION = app; <string>F8D25D1D1396A9DE00CF3BD6</string>
}; <key>isa</key>
name = Release; <string>PBXBuildFile</string>
}; </dict>
/* End XCBuildConfiguration section */ <key>F8DA09D41396ABED0057D0CC</key>
<dict>
/* Begin XCConfigurationList section */ <key>fileRef</key>
F8E4695A1395739C00DB05C8 /* Build configuration list for PBXProject "AFNetworking iOS Example" */ = { <string>F8DA09C81396AB690057D0CC</string>
isa = XCConfigurationList; <key>isa</key>
buildConfigurations = ( <string>PBXBuildFile</string>
F8E4697F1395739D00DB05C8 /* Debug */, </dict>
F8E469801395739D00DB05C8 /* Release */, <key>F8DA09D51396ABED0057D0CC</key>
); <dict>
defaultConfigurationIsVisible = 0; <key>fileRef</key>
defaultConfigurationName = Release; <string>F8DA09CB1396AB690057D0CC</string>
}; <key>isa</key>
F8E469811395739D00DB05C8 /* Build configuration list for PBXNativeTarget "AFNetworking iOS Example" */ = { <string>PBXBuildFile</string>
isa = XCConfigurationList; </dict>
buildConfigurations = ( <key>F8DA09D61396ABED0057D0CC</key>
F8E469821395739D00DB05C8 /* Debug */, <dict>
F8E469831395739D00DB05C8 /* Release */, <key>fileRef</key>
); <string>F8DA09CE1396AB690057D0CC</string>
defaultConfigurationIsVisible = 0; <key>isa</key>
defaultConfigurationName = Release; <string>PBXBuildFile</string>
}; </dict>
/* End XCConfigurationList section */ <key>F8DA09E31396AC040057D0CC</key>
}; <dict>
rootObject = F8E469571395739C00DB05C8 /* Project object */; <key>fileEncoding</key>
} <string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>main.m</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>F8DA09E41396AC040057D0CC</key>
<dict>
<key>fileRef</key>
<string>F8DA09E31396AC040057D0CC</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8DA09E51396AC220057D0CC</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>AppDelegate.h</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>F8DA09E61396AC220057D0CC</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>Prefix.pch</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>F8DA09E71396AC220057D0CC</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>AppDelegate.m</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>F8DA09E81396AC220057D0CC</key>
<dict>
<key>fileRef</key>
<string>F8DA09E71396AC220057D0CC</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8E469551395739C00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8E469B71395759C00DB05C8</string>
<string>F8E4696A1395739D00DB05C8</string>
<string>F8E469ED1395812A00DB05C8</string>
<string>F8E469631395739D00DB05C8</string>
<string>F8E469611395739C00DB05C8</string>
<string>391552C2BD5947DF9FEB5975</string>
<string>C8C94222118242C297ED4081</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E469571395739C00DB05C8</key>
<dict>
<key>attributes</key>
<dict>
<key>LastUpgradeCheck</key>
<string>0420</string>
<key>ORGANIZATIONNAME</key>
<string>Gowalla</string>
</dict>
<key>buildConfigurationList</key>
<string>F8E4695A1395739C00DB05C8</string>
<key>compatibilityVersion</key>
<string>Xcode 3.2</string>
<key>developmentRegion</key>
<string>English</string>
<key>hasScannedForEncodings</key>
<string>0</string>
<key>isa</key>
<string>PBXProject</string>
<key>knownRegions</key>
<array>
<string>en</string>
</array>
<key>mainGroup</key>
<string>F8E469551395739C00DB05C8</string>
<key>productRefGroup</key>
<string>F8E469611395739C00DB05C8</string>
<key>projectDirPath</key>
<string></string>
<key>projectReferences</key>
<array/>
<key>projectRoot</key>
<string></string>
<key>targets</key>
<array>
<string>F8E4695F1395739C00DB05C8</string>
</array>
</dict>
<key>F8E4695A1395739C00DB05C8</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>F8E4697F1395739D00DB05C8</string>
<string>F8E469801395739D00DB05C8</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>F8E4695C1395739C00DB05C8</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F8DA09D21396ABED0057D0CC</string>
<string>F8DA09D41396ABED0057D0CC</string>
<string>F8DA09D51396ABED0057D0CC</string>
<string>F8DA09D61396ABED0057D0CC</string>
<string>F8DA09E41396AC040057D0CC</string>
<string>F8DA09E81396AC220057D0CC</string>
</array>
<key>isa</key>
<string>PBXSourcesBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8E4695D1395739C00DB05C8</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F8E469651395739D00DB05C8</string>
<string>F8E469671395739D00DB05C8</string>
<string>F8E469691395739D00DB05C8</string>
<string>F8E469DF13957DD500DB05C8</string>
<string>F8D0701B14310F4A00653FD3</string>
<string>F8D0701C14310F4F00653FD3</string>
<string>46CF19E6210948BCAA4F152C</string>
<string>89DE83CBA1B145CEB0C1180C</string>
</array>
<key>isa</key>
<string>PBXFrameworksBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8E4695E1395739C00DB05C8</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array>
<string>F8D25D191396A9D300CF3BD6</string>
<string>F8D25D1A1396A9D300CF3BD6</string>
</array>
<key>isa</key>
<string>PBXResourcesBuildPhase</string>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
</dict>
<key>F8E4695F1395739C00DB05C8</key>
<dict>
<key>buildConfigurationList</key>
<string>F8E469811395739D00DB05C8</string>
<key>buildPhases</key>
<array>
<string>F8E4695C1395739C00DB05C8</string>
<string>F8E4695D1395739C00DB05C8</string>
<string>F8E4695E1395739C00DB05C8</string>
<string>DD5E268688D543178A339BEB</string>
<string>8A3A8D61FF1041A3B3AA9C55</string>
</array>
<key>buildRules</key>
<array/>
<key>dependencies</key>
<array/>
<key>isa</key>
<string>PBXNativeTarget</string>
<key>name</key>
<string>AFNetworking iOS Example</string>
<key>productName</key>
<string>AFNetworkingExample</string>
<key>productReference</key>
<string>F8E469601395739C00DB05C8</string>
<key>productType</key>
<string>com.apple.product-type.application</string>
</dict>
<key>F8E469601395739C00DB05C8</key>
<dict>
<key>explicitFileType</key>
<string>wrapper.application</string>
<key>includeInIndex</key>
<string>0</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>path</key>
<string>AFNetworking iOS Example.app</string>
<key>sourceTree</key>
<string>BUILT_PRODUCTS_DIR</string>
</dict>
<key>F8E469611395739C00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8E469601395739C00DB05C8</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Products</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E469631395739D00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8E469E213957DF700DB05C8</string>
<string>F8E469E013957DF100DB05C8</string>
<string>F8E469DE13957DD500DB05C8</string>
<string>F8E469641395739D00DB05C8</string>
<string>F8E469661395739D00DB05C8</string>
<string>F8E469681395739D00DB05C8</string>
<string>242C9E9348A44970B9ECDCF5</string>
<string>0BBDA6CDB42C48EFB1B980BC</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Frameworks</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E469641395739D00DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>UIKit.framework</string>
<key>path</key>
<string>System/Library/Frameworks/UIKit.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469651395739D00DB05C8</key>
<dict>
<key>fileRef</key>
<string>F8E469641395739D00DB05C8</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8E469661395739D00DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>Foundation.framework</string>
<key>path</key>
<string>System/Library/Frameworks/Foundation.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469671395739D00DB05C8</key>
<dict>
<key>fileRef</key>
<string>F8E469661395739D00DB05C8</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8E469681395739D00DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>CoreGraphics.framework</string>
<key>path</key>
<string>System/Library/Frameworks/CoreGraphics.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469691395739D00DB05C8</key>
<dict>
<key>fileRef</key>
<string>F8E469681395739D00DB05C8</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8E4696A1395739D00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8DA09C61396AB690057D0CC</string>
<string>F8DA09C91396AB690057D0CC</string>
<string>F8DA09CC1396AB690057D0CC</string>
<string>F8E4696B1395739D00DB05C8</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Classes</string>
<key>path</key>
<string>AFNetworkingExample</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E4696B1395739D00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8DA09E31396AC040057D0CC</string>
<string>F8DA09E61396AC220057D0CC</string>
<string>F8DA09E51396AC220057D0CC</string>
<string>F8DA09E71396AC220057D0CC</string>
<string>F8E4696C1395739D00DB05C8</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Supporting Files</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E4696C1395739D00DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.plist.xml</string>
<key>path</key>
<string>Info.plist</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E4697F1395739D00DB05C8</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_32_BIT)</string>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>gnu99</string>
<key>GCC_OPTIMIZATION_LEVEL</key>
<string>0</string>
<key>GCC_PREPROCESSOR_DEFINITIONS</key>
<string>DEBUG</string>
<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
<string>NO</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvmgcc42</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>IPHONEOS_DEPLOYMENT_TARGET</key>
<string>4.3</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>F8E469801395739D00DB05C8</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_32_BIT)</string>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>gnu99</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvmgcc42</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>IPHONEOS_DEPLOYMENT_TARGET</key>
<string>4.3</string>
<key>OTHER_CFLAGS</key>
<string>-DNS_BLOCK_ASSERTIONS=1</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
<key>F8E469811395739D00DB05C8</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>F8E469821395739D00DB05C8</string>
<string>F8E469831395739D00DB05C8</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>F8E469821395739D00DB05C8</key>
<dict>
<key>baseConfigurationReference</key>
<string>C8C94222118242C297ED4081</string>
<key>buildSettings</key>
<dict>
<key>ALWAYS_SEARCH_USER_PATHS</key>
<string>NO</string>
<key>COPY_PHASE_STRIP</key>
<string>NO</string>
<key>DSTROOT</key>
<string>/tmp/Pods.dst</string>
<key>GCC_DYNAMIC_NO_PIC</key>
<string>NO</string>
<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
<string>YES</string>
<key>GCC_PREFIX_HEADER</key>
<string>Prefix.pch</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_SHADOW</key>
<string>YES</string>
<key>GCC_WARN_SIGN_COMPARE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_PARAMETER</key>
<string>NO</string>
<key>INFOPLIST_FILE</key>
<string>Info.plist</string>
<key>PRODUCT_NAME</key>
<string>$(TARGET_NAME)</string>
<key>SKIP_INSTALL</key>
<string>YES</string>
<key>WRAPPER_EXTENSION</key>
<string>app</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>F8E469831395739D00DB05C8</key>
<dict>
<key>baseConfigurationReference</key>
<string>C8C94222118242C297ED4081</string>
<key>buildSettings</key>
<dict>
<key>ALWAYS_SEARCH_USER_PATHS</key>
<string>NO</string>
<key>COPY_PHASE_STRIP</key>
<string>YES</string>
<key>DSTROOT</key>
<string>/tmp/Pods.dst</string>
<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
<string>YES</string>
<key>GCC_PREFIX_HEADER</key>
<string>Prefix.pch</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_SHADOW</key>
<string>YES</string>
<key>GCC_WARN_SIGN_COMPARE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_PARAMETER</key>
<string>NO</string>
<key>INFOPLIST_FILE</key>
<string>Info.plist</string>
<key>PRODUCT_NAME</key>
<string>$(TARGET_NAME)</string>
<key>SKIP_INSTALL</key>
<string>YES</string>
<key>VALIDATE_PRODUCT</key>
<string>YES</string>
<key>WRAPPER_EXTENSION</key>
<string>app</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
<key>F8E469B71395759C00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8D25D1B1396A9DE00CF3BD6</string>
<string>F8D25D1D1396A9DE00CF3BD6</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Networking Extensions</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>F8E469DE13957DD500DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>CoreLocation.framework</string>
<key>path</key>
<string>System/Library/Frameworks/CoreLocation.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469DF13957DD500DB05C8</key>
<dict>
<key>fileRef</key>
<string>F8E469DE13957DD500DB05C8</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F8E469E013957DF100DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>Security.framework</string>
<key>path</key>
<string>System/Library/Frameworks/Security.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469E213957DF700DB05C8</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>SystemConfiguration.framework</string>
<key>path</key>
<string>System/Library/Frameworks/SystemConfiguration.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>F8E469ED1395812A00DB05C8</key>
<dict>
<key>children</key>
<array>
<string>F8D25D171396A9D300CF3BD6</string>
<string>F8D25D181396A9D300CF3BD6</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Images</string>
<key>path</key>
<string>AFNetworkingExample/Images</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
</dict>
<key>rootObject</key>
<string>F8E469571395739C00DB05C8</string>
</dict>
</plist>
SPEC CHECKSUMS: PODS:
FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821 - AFNetworking (0.7.0):
AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c
JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
PODS:
- AFNetworking (0.7.0):
- JSONKit - JSONKit
- FormatterKit (1.0.0): - FormatterKit (1.0.0):
- FormatterKit/ArrayFormatter (= 1.0.0) - FormatterKit/ArrayFormatter (= 1.0.0)
- FormatterKit/LocationFormatter (= 1.0.0) - FormatterKit/LocationFormatter (= 1.0.0)
- FormatterKit/OrdinalNumberFormatter (= 1.0.0) - FormatterKit/OrdinalNumberFormatter (= 1.0.0)
...@@ -28,8 +17,19 @@ PODS: ...@@ -28,8 +17,19 @@ PODS:
- FormatterKit/UnitOfInformationFormatter (1.0.0) - FormatterKit/UnitOfInformationFormatter (1.0.0)
- JSONKit (1.5pre) - JSONKit (1.5pre)
COCOAPODS: 0.15.1 DEPENDENCIES:
DEPENDENCIES:
- AFNetworking (~> 0.7.0) - AFNetworking (~> 0.7.0)
- FormatterKit - FormatterKit
SPEC CHECKSUMS:
AFNetworking: 7bf22b0ed1d9068909cd67206db78204eb63dd2c
FormatterKit: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/ArrayFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/LocationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/OrdinalNumberFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/TimeIntervalFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/URLRequestFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
FormatterKit/UnitOfInformationFormatter: 12dea999a2df19e389f7b821962fc4088de8b821
JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
COCOAPODS: 0.16.0.rc2
DEPENDENCIES: PODS:
- MGSplitViewController (1.0.0)
DEPENDENCIES:
- MGSplitViewController (= 1.0.0) - MGSplitViewController (= 1.0.0)
SPEC CHECKSUMS: SPEC CHECKSUMS:
MGSplitViewController: e0b0bc01aa81e1559765c39e7a764c890dac373a MGSplitViewController: e0b0bc01aa81e1559765c39e7a764c890dac373a
PODS: COCOAPODS: 0.16.0.rc2
- MGSplitViewController (1.0.0)
COCOAPODS: 0.15.1
...@@ -37,10 +37,10 @@ DEPENDENCIES: ...@@ -37,10 +37,10 @@ DEPENDENCIES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
FileMD5Hash: c3b015e6fb293eea0a0c276747f61f20408c2644 FileMD5Hash: c3b015e6fb293eea0a0c276747f61f20408c2644
ISO8601DateFormatter: dc05a2481edf49668d85d3ff8c466c32eb544780 ISO8601DateFormatter: dc05a2481edf49668d85d3ff8c466c32eb544780
JSONKit: 3d4708953ea7ae399a49777372d8b060a43ddd27 JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
LibComponentLogging-Core: c80e88f2b7fb204554de7bec13374daf394097e8 LibComponentLogging-Core: 9c2914bc501a0656450860a136b0e8e52f3e16d4
LibComponentLogging-NSLog: d8f54e7eb65bb893f91cab5864ecf8e85ebd9359 LibComponentLogging-NSLog: a4bb0f6de612eef7b5fcdbd9cc96dc868ba1f2df
NSData+Base64: be7e201540fa7805ecedc1f38d456e008be259b2 NSData+Base64: 8b910cb8a64f45daec6fb15936c36a9a911c57ca
RestKit: a9f24f857c792183bcc656f891abe93d38e342ee RestKit: a9f24f857c792183bcc656f891abe93d38e342ee
RestKit/JSON: a9f24f857c792183bcc656f891abe93d38e342ee RestKit/JSON: a9f24f857c792183bcc656f891abe93d38e342ee
RestKit/Network: a9f24f857c792183bcc656f891abe93d38e342ee RestKit/Network: a9f24f857c792183bcc656f891abe93d38e342ee
...@@ -50,4 +50,4 @@ SPEC CHECKSUMS: ...@@ -50,4 +50,4 @@ SPEC CHECKSUMS:
SOCKit: 9d71b00c699cf5aa2989d6aa12f3392b048123db SOCKit: 9d71b00c699cf5aa2989d6aa12f3392b048123db
cocoa-oauth: 8f4c8b77c77ac660de37f8125557c4ec09b0118a cocoa-oauth: 8f4c8b77c77ac660de37f8125557c4ec09b0118a
COCOAPODS: 0.13.0 COCOAPODS: 0.16.0.rc2
// !$*UTF8*$! <?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">
archiveVersion = 1; <plist version="1.0">
classes = { <dict>
}; <key>archiveVersion</key>
objectVersion = 46; <string>1</string>
objects = { <key>classes</key>
<dict/>
/* Begin PBXBuildFile section */ <key>objectVersion</key>
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */; }; <string>46</string>
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; <key>objects</key>
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; <dict>
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; <key>080E96DDFE201D6D7F000001</key>
2538E811123419CA00ACB5D7 /* RKTUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E810123419CA00ACB5D7 /* RKTUser.m */; }; <dict>
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E813123419EC00ACB5D7 /* RKTStatus.m */; }; <key>children</key>
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; <array>
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */; }; <string>1D3623240D0F684500981E51</string>
3F3CE3FC125B9A6E0083FDCB /* listbg.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FA125B9A6E0083FDCB /* listbg.png */; }; <string>1D3623250D0F684500981E51</string>
3F3CE3FD125B9A6E0083FDCB /* listbg@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FB125B9A6E0083FDCB /* listbg@2x.png */; }; <string>28D7ACF60DDB3853001CB0EB</string>
3F3CE40E125B9B450083FDCB /* BG.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40A125B9B450083FDCB /* BG.png */; }; <string>28D7ACF70DDB3853001CB0EB</string>
3F3CE40F125B9B450083FDCB /* BG@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40B125B9B450083FDCB /* BG@2x.png */; }; <string>2538E80F123419CA00ACB5D7</string>
3F3CE410125B9B450083FDCB /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40C125B9B450083FDCB /* Default.png */; }; <string>2538E810123419CA00ACB5D7</string>
3F3CE411125B9B450083FDCB /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40D125B9B450083FDCB /* Default@2x.png */; }; <string>2538E812123419EC00ACB5D7</string>
420AA0D3093343A59375A4A7 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57FFE12DE575489F8CC48721 /* libPods.a */; }; <string>2538E813123419EC00ACB5D7</string>
/* End PBXBuildFile section */ </array>
<key>isa</key>
/* Begin PBXFileReference section */ <string>PBXGroup</string>
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; <key>path</key>
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterAppDelegate.h; sourceTree = "<group>"; }; <string>Classes</string>
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterAppDelegate.m; sourceTree = "<group>"; }; <key>sourceTree</key>
1D6058910D05DD3D006BFB54 /* RKTwitter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKTwitter.app; sourceTree = BUILT_PRODUCTS_DIR; }; <string>&lt;group&gt;</string>
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; </dict>
2538E80F123419CA00ACB5D7 /* RKTUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTUser.h; sourceTree = "<group>"; }; <key>0DBACE52495B418A8C446FFE</key>
2538E810123419CA00ACB5D7 /* RKTUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTUser.m; sourceTree = "<group>"; }; <dict>
2538E812123419EC00ACB5D7 /* RKTStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTStatus.h; sourceTree = "<group>"; }; <key>explicitFileType</key>
2538E813123419EC00ACB5D7 /* RKTStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTStatus.m; sourceTree = "<group>"; }; <string>archive.ar</string>
288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; <key>includeInIndex</key>
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterViewController.h; sourceTree = "<group>"; }; <string>0</string>
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterViewController.m; sourceTree = "<group>"; }; <key>isa</key>
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; <string>PBXFileReference</string>
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitter_Prefix.pch; sourceTree = "<group>"; }; <key>name</key>
3F3CE3FA125B9A6E0083FDCB /* listbg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = listbg.png; sourceTree = "<group>"; }; <string>libPods.a</string>
3F3CE3FB125B9A6E0083FDCB /* listbg@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "listbg@2x.png"; sourceTree = "<group>"; }; <key>path</key>
3F3CE40A125B9B450083FDCB /* BG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = BG.png; sourceTree = "<group>"; }; <string>libPods.a</string>
3F3CE40B125B9B450083FDCB /* BG@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "BG@2x.png"; sourceTree = "<group>"; }; <key>sourceTree</key>
3F3CE40C125B9B450083FDCB /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; }; <string>BUILT_PRODUCTS_DIR</string>
3F3CE40D125B9B450083FDCB /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; }; </dict>
57FFE12DE575489F8CC48721 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; <key>19C28FACFE9D520D11CA2CBB</key>
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RKTwitter-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; }; <dict>
8E386D7130E847E884FA57B1 /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; <key>children</key>
/* End PBXFileReference section */ <array>
<string>1D6058910D05DD3D006BFB54</string>
/* Begin PBXFrameworksBuildPhase section */ </array>
1D60588F0D05DD3D006BFB54 /* Frameworks */ = { <key>isa</key>
isa = PBXFrameworksBuildPhase; <string>PBXGroup</string>
buildActionMask = 2147483647; <key>name</key>
files = ( <string>Products</string>
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, <key>sourceTree</key>
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, <string>&lt;group&gt;</string>
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, </dict>
420AA0D3093343A59375A4A7 /* libPods.a in Frameworks */, <key>1D30AB110D05D00D00671497</key>
); <dict>
runOnlyForDeploymentPostprocessing = 0; <key>includeInIndex</key>
}; <string>1</string>
/* End PBXFrameworksBuildPhase section */ <key>isa</key>
<string>PBXFileReference</string>
/* Begin PBXGroup section */ <key>lastKnownFileType</key>
080E96DDFE201D6D7F000001 /* Classes */ = { <string>wrapper.framework</string>
isa = PBXGroup; <key>name</key>
children = ( <string>Foundation.framework</string>
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */, <key>path</key>
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */, <string>System/Library/Frameworks/Foundation.framework</string>
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */, <key>sourceTree</key>
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */, <string>SDKROOT</string>
2538E80F123419CA00ACB5D7 /* RKTUser.h */, </dict>
2538E810123419CA00ACB5D7 /* RKTUser.m */, <key>1D3623240D0F684500981E51</key>
2538E812123419EC00ACB5D7 /* RKTStatus.h */, <dict>
2538E813123419EC00ACB5D7 /* RKTStatus.m */, <key>fileEncoding</key>
); <string>4</string>
path = Classes; <key>isa</key>
sourceTree = "<group>"; <string>PBXFileReference</string>
}; <key>lastKnownFileType</key>
19C28FACFE9D520D11CA2CBB /* Products */ = { <string>sourcecode.c.h</string>
isa = PBXGroup; <key>path</key>
children = ( <string>RKTwitterAppDelegate.h</string>
1D6058910D05DD3D006BFB54 /* RKTwitter.app */, <key>sourceTree</key>
); <string>&lt;group&gt;</string>
name = Products; </dict>
sourceTree = "<group>"; <key>1D3623250D0F684500981E51</key>
}; <dict>
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { <key>fileEncoding</key>
isa = PBXGroup; <string>4</string>
children = ( <key>isa</key>
080E96DDFE201D6D7F000001 /* Classes */, <string>PBXFileReference</string>
29B97315FDCFA39411CA2CEA /* Other Sources */, <key>lastKnownFileType</key>
29B97317FDCFA39411CA2CEA /* Resources */, <string>sourcecode.c.objc</string>
29B97323FDCFA39411CA2CEA /* Frameworks */, <key>path</key>
19C28FACFE9D520D11CA2CBB /* Products */, <string>RKTwitterAppDelegate.m</string>
8E386D7130E847E884FA57B1 /* Pods.xcconfig */, <key>sourceTree</key>
); <string>&lt;group&gt;</string>
name = CustomTemplate; </dict>
sourceTree = "<group>"; <key>1D3623260D0F684500981E51</key>
}; <dict>
29B97315FDCFA39411CA2CEA /* Other Sources */ = { <key>fileRef</key>
isa = PBXGroup; <string>1D3623250D0F684500981E51</string>
children = ( <key>isa</key>
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */, <string>PBXBuildFile</string>
29B97316FDCFA39411CA2CEA /* main.m */, </dict>
); <key>1D60588D0D05DD3D006BFB54</key>
name = "Other Sources"; <dict>
sourceTree = "<group>"; <key>buildActionMask</key>
}; <string>2147483647</string>
29B97317FDCFA39411CA2CEA /* Resources */ = { <key>files</key>
isa = PBXGroup; <array>
children = ( <string>3F3CE3FC125B9A6E0083FDCB</string>
3F3CE40A125B9B450083FDCB /* BG.png */, <string>3F3CE3FD125B9A6E0083FDCB</string>
3F3CE40B125B9B450083FDCB /* BG@2x.png */, <string>3F3CE40E125B9B450083FDCB</string>
3F3CE40C125B9B450083FDCB /* Default.png */, <string>3F3CE40F125B9B450083FDCB</string>
3F3CE40D125B9B450083FDCB /* Default@2x.png */, <string>3F3CE410125B9B450083FDCB</string>
3F3CE3FA125B9A6E0083FDCB /* listbg.png */, <string>3F3CE411125B9B450083FDCB</string>
3F3CE3FB125B9A6E0083FDCB /* listbg@2x.png */, </array>
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */, <key>isa</key>
); <string>PBXResourcesBuildPhase</string>
path = Resources; <key>runOnlyForDeploymentPostprocessing</key>
sourceTree = "<group>"; <string>0</string>
}; </dict>
29B97323FDCFA39411CA2CEA /* Frameworks */ = { <key>1D60588E0D05DD3D006BFB54</key>
isa = PBXGroup; <dict>
children = ( <key>buildActionMask</key>
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, <string>2147483647</string>
1D30AB110D05D00D00671497 /* Foundation.framework */, <key>files</key>
288765A40DF7441C002DB57D /* CoreGraphics.framework */, <array>
57FFE12DE575489F8CC48721 /* libPods.a */, <string>1D60589B0D05DD56006BFB54</string>
); <string>1D3623260D0F684500981E51</string>
name = Frameworks; <string>28D7ACF80DDB3853001CB0EB</string>
sourceTree = "<group>"; <string>2538E811123419CA00ACB5D7</string>
}; <string>2538E814123419EC00ACB5D7</string>
/* End PBXGroup section */ </array>
<key>isa</key>
/* Begin PBXNativeTarget section */ <string>PBXSourcesBuildPhase</string>
1D6058900D05DD3D006BFB54 /* RKTwitter */ = { <key>runOnlyForDeploymentPostprocessing</key>
isa = PBXNativeTarget; <string>0</string>
buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitter" */; </dict>
buildPhases = ( <key>1D60588F0D05DD3D006BFB54</key>
1D60588D0D05DD3D006BFB54 /* Resources */, <dict>
1D60588E0D05DD3D006BFB54 /* Sources */, <key>buildActionMask</key>
1D60588F0D05DD3D006BFB54 /* Frameworks */, <string>2147483647</string>
539A97B3650143098666EC68 /* Copy Pods Resources */, <key>files</key>
); <array>
buildRules = ( <string>1D60589F0D05DD5A006BFB54</string>
); <string>1DF5F4E00D08C38300B7A737</string>
dependencies = ( <string>288765A50DF7441C002DB57D</string>
); <string>420AA0D3093343A59375A4A7</string>
name = RKTwitter; <string>5AEB547EF5A74330B7F617CF</string>
productName = RKTwitter; </array>
productReference = 1D6058910D05DD3D006BFB54 /* RKTwitter.app */; <key>isa</key>
productType = "com.apple.product-type.application"; <string>PBXFrameworksBuildPhase</string>
}; <key>runOnlyForDeploymentPostprocessing</key>
/* End PBXNativeTarget section */ <string>0</string>
</dict>
/* Begin PBXProject section */ <key>1D6058900D05DD3D006BFB54</key>
29B97313FDCFA39411CA2CEA /* Project object */ = { <dict>
isa = PBXProject; <key>buildConfigurationList</key>
attributes = { <string>1D6058960D05DD3E006BFB54</string>
LastUpgradeCheck = 0430; <key>buildPhases</key>
}; <array>
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitter" */; <string>1D60588D0D05DD3D006BFB54</string>
compatibilityVersion = "Xcode 3.2"; <string>1D60588E0D05DD3D006BFB54</string>
developmentRegion = English; <string>1D60588F0D05DD3D006BFB54</string>
hasScannedForEncodings = 1; <string>539A97B3650143098666EC68</string>
knownRegions = ( <string>4576998175B34B56A714043C</string>
English, </array>
Japanese, <key>buildRules</key>
French, <array/>
German, <key>dependencies</key>
); <array/>
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; <key>isa</key>
projectDirPath = ""; <string>PBXNativeTarget</string>
projectRoot = ""; <key>name</key>
targets = ( <string>RKTwitter</string>
1D6058900D05DD3D006BFB54 /* RKTwitter */, <key>productName</key>
); <string>RKTwitter</string>
}; <key>productReference</key>
/* End PBXProject section */ <string>1D6058910D05DD3D006BFB54</string>
<key>productType</key>
/* Begin PBXResourcesBuildPhase section */ <string>com.apple.product-type.application</string>
1D60588D0D05DD3D006BFB54 /* Resources */ = { </dict>
isa = PBXResourcesBuildPhase; <key>1D6058910D05DD3D006BFB54</key>
buildActionMask = 2147483647; <dict>
files = ( <key>explicitFileType</key>
3F3CE3FC125B9A6E0083FDCB /* listbg.png in Resources */, <string>wrapper.application</string>
3F3CE3FD125B9A6E0083FDCB /* listbg@2x.png in Resources */, <key>includeInIndex</key>
3F3CE40E125B9B450083FDCB /* BG.png in Resources */, <string>0</string>
3F3CE40F125B9B450083FDCB /* BG@2x.png in Resources */, <key>isa</key>
3F3CE410125B9B450083FDCB /* Default.png in Resources */, <string>PBXFileReference</string>
3F3CE411125B9B450083FDCB /* Default@2x.png in Resources */, <key>path</key>
); <string>RKTwitter.app</string>
runOnlyForDeploymentPostprocessing = 0; <key>sourceTree</key>
}; <string>BUILT_PRODUCTS_DIR</string>
/* End PBXResourcesBuildPhase section */ </dict>
<key>1D6058940D05DD3E006BFB54</key>
/* Begin PBXShellScriptBuildPhase section */ <dict>
539A97B3650143098666EC68 /* Copy Pods Resources */ = { <key>baseConfigurationReference</key>
isa = PBXShellScriptBuildPhase; <string>B66F935ABF8141B2BE13B1D2</string>
buildActionMask = 2147483647; <key>buildSettings</key>
files = ( <dict>
); <key>BUILD_STYLE</key>
inputPaths = ( <string>Debug</string>
); <key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
name = "Copy Pods Resources"; <string></string>
outputPaths = ( <key>COPY_PHASE_STRIP</key>
); <string>NO</string>
runOnlyForDeploymentPostprocessing = 0; <key>GCC_DYNAMIC_NO_PIC</key>
shellPath = /bin/sh; <string>NO</string>
shellScript = "\"${SRCROOT}/Pods/Pods-resources.sh\"\n"; <key>GCC_OPTIMIZATION_LEVEL</key>
}; <string>0</string>
/* End PBXShellScriptBuildPhase section */ <key>GCC_PRECOMPILE_PREFIX_HEADER</key>
<string>YES</string>
/* Begin PBXSourcesBuildPhase section */ <key>GCC_PREFIX_HEADER</key>
1D60588E0D05DD3D006BFB54 /* Sources */ = { <string>RKTwitter_Prefix.pch</string>
isa = PBXSourcesBuildPhase; <key>INFOPLIST_FILE</key>
buildActionMask = 2147483647; <string>Resources/RKTwitter-Info.plist</string>
files = ( <key>PRODUCT_NAME</key>
1D60589B0D05DD56006BFB54 /* main.m in Sources */, <string>RKTwitter</string>
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */, </dict>
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */, <key>isa</key>
2538E811123419CA00ACB5D7 /* RKTUser.m in Sources */, <string>XCBuildConfiguration</string>
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */, <key>name</key>
); <string>Debug</string>
runOnlyForDeploymentPostprocessing = 0; </dict>
}; <key>1D6058950D05DD3E006BFB54</key>
/* End PBXSourcesBuildPhase section */ <dict>
<key>baseConfigurationReference</key>
/* Begin XCBuildConfiguration section */ <string>B66F935ABF8141B2BE13B1D2</string>
1D6058940D05DD3E006BFB54 /* Debug */ = { <key>buildSettings</key>
isa = XCBuildConfiguration; <dict>
baseConfigurationReference = 8E386D7130E847E884FA57B1 /* Pods.xcconfig */; <key>BUILD_STYLE</key>
buildSettings = { <string>Release</string>
BUILD_STYLE = Debug; <key>COPY_PHASE_STRIP</key>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; <string>YES</string>
COPY_PHASE_STRIP = NO; <key>GCC_PRECOMPILE_PREFIX_HEADER</key>
GCC_DYNAMIC_NO_PIC = NO; <string>YES</string>
GCC_OPTIMIZATION_LEVEL = 0; <key>GCC_PREFIX_HEADER</key>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <string>RKTwitter_Prefix.pch</string>
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch; <key>INFOPLIST_FILE</key>
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist"; <string>Resources/RKTwitter-Info.plist</string>
PRODUCT_NAME = RKTwitter; <key>PRODUCT_NAME</key>
}; <string>RKTwitter</string>
name = Debug; <key>VALIDATE_PRODUCT</key>
}; <string>YES</string>
1D6058950D05DD3E006BFB54 /* Release */ = { </dict>
isa = XCBuildConfiguration; <key>isa</key>
baseConfigurationReference = 8E386D7130E847E884FA57B1 /* Pods.xcconfig */; <string>XCBuildConfiguration</string>
buildSettings = { <key>name</key>
BUILD_STYLE = Release; <string>Release</string>
COPY_PHASE_STRIP = YES; </dict>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>1D6058960D05DD3E006BFB54</key>
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch; <dict>
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist"; <key>buildConfigurations</key>
PRODUCT_NAME = RKTwitter; <array>
VALIDATE_PRODUCT = YES; <string>1D6058940D05DD3E006BFB54</string>
}; <string>1D6058950D05DD3E006BFB54</string>
name = Release; </array>
}; <key>defaultConfigurationIsVisible</key>
C01FCF4F08A954540054247B /* Debug */ = { <string>0</string>
isa = XCBuildConfiguration; <key>defaultConfigurationName</key>
buildSettings = { <string>Release</string>
ARCHS = "$(ARCHS_STANDARD_32_BIT)"; <key>isa</key>
BUILD_STYLE = Debug; <string>XCConfigurationList</string>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; </dict>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <key>1D60589B0D05DD56006BFB54</key>
GCC_WARN_UNUSED_VARIABLE = YES; <dict>
SDKROOT = iphoneos; <key>fileRef</key>
}; <string>29B97316FDCFA39411CA2CEA</string>
name = Debug; <key>isa</key>
}; <string>PBXBuildFile</string>
C01FCF5008A954540054247B /* Release */ = { </dict>
isa = XCBuildConfiguration; <key>1D60589F0D05DD5A006BFB54</key>
buildSettings = { <dict>
ARCHS = "$(ARCHS_STANDARD_32_BIT)"; <key>fileRef</key>
BUILD_STYLE = Release; <string>1D30AB110D05D00D00671497</string>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; <key>isa</key>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <string>PBXBuildFile</string>
GCC_WARN_UNUSED_VARIABLE = YES; </dict>
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; <key>1DF5F4DF0D08C38300B7A737</key>
SDKROOT = iphoneos; <dict>
}; <key>includeInIndex</key>
name = Release; <string>1</string>
}; <key>isa</key>
/* End XCBuildConfiguration section */ <string>PBXFileReference</string>
<key>lastKnownFileType</key>
/* Begin XCConfigurationList section */ <string>wrapper.framework</string>
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitter" */ = { <key>name</key>
isa = XCConfigurationList; <string>UIKit.framework</string>
buildConfigurations = ( <key>path</key>
1D6058940D05DD3E006BFB54 /* Debug */, <string>System/Library/Frameworks/UIKit.framework</string>
1D6058950D05DD3E006BFB54 /* Release */, <key>sourceTree</key>
); <string>SDKROOT</string>
defaultConfigurationIsVisible = 0; </dict>
defaultConfigurationName = Release; <key>1DF5F4E00D08C38300B7A737</key>
}; <dict>
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitter" */ = { <key>fileRef</key>
isa = XCConfigurationList; <string>1DF5F4DF0D08C38300B7A737</string>
buildConfigurations = ( <key>isa</key>
C01FCF4F08A954540054247B /* Debug */, <string>PBXBuildFile</string>
C01FCF5008A954540054247B /* Release */, </dict>
); <key>2538E80F123419CA00ACB5D7</key>
defaultConfigurationIsVisible = 0; <dict>
defaultConfigurationName = Release; <key>fileEncoding</key>
}; <string>4</string>
/* End XCConfigurationList section */ <key>isa</key>
}; <string>PBXFileReference</string>
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; <key>lastKnownFileType</key>
} <string>sourcecode.c.h</string>
<key>path</key>
<string>RKTUser.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>2538E810123419CA00ACB5D7</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>RKTUser.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>2538E811123419CA00ACB5D7</key>
<dict>
<key>fileRef</key>
<string>2538E810123419CA00ACB5D7</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>2538E812123419EC00ACB5D7</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>RKTStatus.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>2538E813123419EC00ACB5D7</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>RKTStatus.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>2538E814123419EC00ACB5D7</key>
<dict>
<key>fileRef</key>
<string>2538E813123419EC00ACB5D7</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>288765A40DF7441C002DB57D</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>CoreGraphics.framework</string>
<key>path</key>
<string>System/Library/Frameworks/CoreGraphics.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>288765A50DF7441C002DB57D</key>
<dict>
<key>fileRef</key>
<string>288765A40DF7441C002DB57D</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>28D7ACF60DDB3853001CB0EB</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>RKTwitterViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>28D7ACF70DDB3853001CB0EB</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>RKTwitterViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>28D7ACF80DDB3853001CB0EB</key>
<dict>
<key>fileRef</key>
<string>28D7ACF70DDB3853001CB0EB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>29B97313FDCFA39411CA2CEA</key>
<dict>
<key>attributes</key>
<dict>
<key>LastUpgradeCheck</key>
<string>0430</string>
</dict>
<key>buildConfigurationList</key>
<string>C01FCF4E08A954540054247B</string>
<key>compatibilityVersion</key>
<string>Xcode 3.2</string>
<key>developmentRegion</key>
<string>English</string>
<key>hasScannedForEncodings</key>
<string>1</string>
<key>isa</key>
<string>PBXProject</string>
<key>knownRegions</key>
<array>
<string>English</string>
<string>Japanese</string>
<string>French</string>
<string>German</string>
</array>
<key>mainGroup</key>
<string>29B97314FDCFA39411CA2CEA</string>
<key>projectDirPath</key>
<string></string>
<key>projectReferences</key>
<array/>
<key>projectRoot</key>
<string></string>
<key>targets</key>
<array>
<string>1D6058900D05DD3D006BFB54</string>
</array>
</dict>
<key>29B97314FDCFA39411CA2CEA</key>
<dict>
<key>children</key>
<array>
<string>080E96DDFE201D6D7F000001</string>
<string>29B97315FDCFA39411CA2CEA</string>
<string>29B97317FDCFA39411CA2CEA</string>
<string>29B97323FDCFA39411CA2CEA</string>
<string>19C28FACFE9D520D11CA2CBB</string>
<string>8E386D7130E847E884FA57B1</string>
<string>B66F935ABF8141B2BE13B1D2</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>CustomTemplate</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>29B97315FDCFA39411CA2CEA</key>
<dict>
<key>children</key>
<array>
<string>32CA4F630368D1EE00C91783</string>
<string>29B97316FDCFA39411CA2CEA</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Other Sources</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>29B97316FDCFA39411CA2CEA</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>main.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>29B97317FDCFA39411CA2CEA</key>
<dict>
<key>children</key>
<array>
<string>3F3CE40A125B9B450083FDCB</string>
<string>3F3CE40B125B9B450083FDCB</string>
<string>3F3CE40C125B9B450083FDCB</string>
<string>3F3CE40D125B9B450083FDCB</string>
<string>3F3CE3FA125B9A6E0083FDCB</string>
<string>3F3CE3FB125B9A6E0083FDCB</string>
<string>8D1107310486CEB800E47090</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>path</key>
<string>Resources</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>29B97323FDCFA39411CA2CEA</key>
<dict>
<key>children</key>
<array>
<string>1DF5F4DF0D08C38300B7A737</string>
<string>1D30AB110D05D00D00671497</string>
<string>288765A40DF7441C002DB57D</string>
<string>57FFE12DE575489F8CC48721</string>
<string>0DBACE52495B418A8C446FFE</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Frameworks</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>32CA4F630368D1EE00C91783</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>RKTwitter_Prefix.pch</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE3FA125B9A6E0083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>listbg.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE3FB125B9A6E0083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>listbg@2x.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE3FC125B9A6E0083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE3FA125B9A6E0083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>3F3CE3FD125B9A6E0083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE3FB125B9A6E0083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>3F3CE40A125B9B450083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>BG.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE40B125B9B450083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>BG@2x.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE40C125B9B450083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE40D125B9B450083FDCB</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default@2x.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>3F3CE40E125B9B450083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE40A125B9B450083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>3F3CE40F125B9B450083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE40B125B9B450083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>3F3CE410125B9B450083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE40C125B9B450083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>3F3CE411125B9B450083FDCB</key>
<dict>
<key>fileRef</key>
<string>3F3CE40D125B9B450083FDCB</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>420AA0D3093343A59375A4A7</key>
<dict>
<key>fileRef</key>
<string>57FFE12DE575489F8CC48721</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>4576998175B34B56A714043C</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array/>
<key>inputPaths</key>
<array/>
<key>isa</key>
<string>PBXShellScriptBuildPhase</string>
<key>name</key>
<string>Copy Pods Resources</string>
<key>outputPaths</key>
<array/>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
<key>shellPath</key>
<string>/bin/sh</string>
<key>shellScript</key>
<string>"${SRCROOT}/Pods/Pods-resources.sh"
</string>
</dict>
<key>539A97B3650143098666EC68</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array/>
<key>inputPaths</key>
<array/>
<key>isa</key>
<string>PBXShellScriptBuildPhase</string>
<key>name</key>
<string>Copy Pods Resources</string>
<key>outputPaths</key>
<array/>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
<key>shellPath</key>
<string>/bin/sh</string>
<key>shellScript</key>
<string>"${SRCROOT}/Pods/Pods-resources.sh"
</string>
</dict>
<key>57FFE12DE575489F8CC48721</key>
<dict>
<key>explicitFileType</key>
<string>archive.ar</string>
<key>includeInIndex</key>
<string>0</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>path</key>
<string>libPods.a</string>
<key>sourceTree</key>
<string>BUILT_PRODUCTS_DIR</string>
</dict>
<key>5AEB547EF5A74330B7F617CF</key>
<dict>
<key>fileRef</key>
<string>0DBACE52495B418A8C446FFE</string>
<key>isa</key>
<string>PBXBuildFile</string>
<key>settings</key>
<dict/>
</dict>
<key>8D1107310486CEB800E47090</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.plist.xml</string>
<key>path</key>
<string>RKTwitter-Info.plist</string>
<key>plistStructureDefinitionIdentifier</key>
<string>com.apple.xcode.plist.structure-definition.iphone.info-plist</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>8E386D7130E847E884FA57B1</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.xcconfig</string>
<key>name</key>
<string>Pods.xcconfig</string>
<key>path</key>
<string>Pods/Pods.xcconfig</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>B66F935ABF8141B2BE13B1D2</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.xcconfig</string>
<key>name</key>
<string>Pods.xcconfig</string>
<key>path</key>
<string>Pods/Pods.xcconfig</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>C01FCF4E08A954540054247B</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>C01FCF4F08A954540054247B</string>
<string>C01FCF5008A954540054247B</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>C01FCF4F08A954540054247B</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_32_BIT)</string>
<key>BUILD_STYLE</key>
<string>Debug</string>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>C01FCF5008A954540054247B</key>
<dict>
<key>buildSettings</key>
<dict>
<key>ARCHS</key>
<string>$(ARCHS_STANDARD_32_BIT)</string>
<key>BUILD_STYLE</key>
<string>Release</string>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>OTHER_CFLAGS</key>
<string>-DNS_BLOCK_ASSERTIONS=1</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
</dict>
<key>rootObject</key>
<string>29B97313FDCFA39411CA2CEA</string>
</dict>
</plist>
COCOAPODS: 0.15.1 PODS:
- AFNetworking (1.0RC1)
DEPENDENCIES: DEPENDENCIES:
- AFNetworking - AFNetworking
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb
PODS: COCOAPODS: 0.16.0.rc2
- AFNetworking (1.0RC1)
...@@ -11,4 +11,4 @@ SPEC CHECKSUMS: ...@@ -11,4 +11,4 @@ SPEC CHECKSUMS:
AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb AFNetworking: b21c1252d437fd322e7db1caa93b163d76a362cb
SSToolkit: 852044205c6a15586431e90f46b2ef01f693285a SSToolkit: 852044205c6a15586431e90f46b2ef01f693285a
COCOAPODS: 0.13.0 COCOAPODS: 0.16.0.rc2
// !$*UTF8*$! <?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">
archiveVersion = 1; <plist version="1.0">
classes = { <dict>
}; <key>archiveVersion</key>
objectVersion = 46; <string>1</string>
objects = { <key>classes</key>
<dict/>
/* Begin PBXBuildFile section */ <key>objectVersion</key>
5A94485369FE4D20AF69167F /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CCF41E5761E4409922431DB /* libPods.a */; }; <string>46</string>
B21B85BE1067D4F300E5C076 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B21B85BC1067D4F300E5C076 /* main.m */; }; <key>objects</key>
B22042911370FD1800604D62 /* SCImageCollectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = B22042901370FD1800604D62 /* SCImageCollectionViewItem.m */; }; <dict>
B24E9EAA121DC35B0085F81E /* SCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9E99121DC35B0085F81E /* SCAppDelegate.m */; }; <key>0385DB0FDA714929B58FB5B6</key>
B24E9EAB121DC35B0085F81E /* SCGradientViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9E9B121DC35B0085F81E /* SCGradientViewDemoViewController.m */; }; <dict>
B24E9EAC121DC35B0085F81E /* SCHUDViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9E9D121DC35B0085F81E /* SCHUDViewDemoViewController.m */; }; <key>includeInIndex</key>
B24E9EAD121DC35B0085F81E /* SCLineViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9E9F121DC35B0085F81E /* SCLineViewDemoViewController.m */; }; <string>1</string>
B24E9EAF121DC35B0085F81E /* SCPickerDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9EA3121DC35B0085F81E /* SCPickerDemoViewController.m */; }; <key>isa</key>
B24E9EB0121DC35B0085F81E /* SCPickerDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9EA5121DC35B0085F81E /* SCPickerDetailViewController.m */; }; <string>PBXFileReference</string>
B24E9EB1121DC35B0085F81E /* SCPieProgressViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9EA7121DC35B0085F81E /* SCPieProgressViewDemoViewController.m */; }; <key>lastKnownFileType</key>
B24E9EB2121DC35B0085F81E /* SCRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9EA9121DC35B0085F81E /* SCRootViewController.m */; }; <string>text.xcconfig</string>
B25541EE12FF22B500D6E187 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = B25541ED12FF22B500D6E187 /* Default-Landscape~ipad.png */; }; <key>name</key>
B25541F012FF22BA00D6E187 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = B25541EF12FF22BA00D6E187 /* Default-Portrait~ipad.png */; }; <string>Pods.xcconfig</string>
B257303D1292524F001FC061 /* SCLoadingViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B257303C1292524F001FC061 /* SCLoadingViewDemoViewController.m */; }; <key>path</key>
B27B1A581224228000111EA2 /* SCCollectionViewDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B27B1A571224228000111EA2 /* SCCollectionViewDemoViewController.m */; }; <string>Pods/Pods.xcconfig</string>
B28C6D0B12FBE96600667755 /* SSRatingDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B28C6D0A12FBE96600667755 /* SSRatingDemoViewController.m */; }; <key>sourceTree</key>
B2AED4B512FF2145006C956B /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = B2AED4B312FF2145006C956B /* Default.png */; }; <string>SOURCE_ROOT</string>
B2AED4B612FF2145006C956B /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2AED4B412FF2145006C956B /* Default@2x.png */; }; </dict>
B2AED4BA12FF21F8006C956B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2AED4B712FF21F8006C956B /* CoreGraphics.framework */; }; <key>080E96DDFE201D6D7F000001</key>
B2AED4BB12FF21F8006C956B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2AED4B812FF21F8006C956B /* Foundation.framework */; }; <dict>
B2AED4BC12FF21F8006C956B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2AED4B912FF21F8006C956B /* UIKit.framework */; }; <key>children</key>
B2DAC3C413304D5700091D5F /* Icon-48.png in Resources */ = {isa = PBXBuildFile; fileRef = B2DAC3C113304D5700091D5F /* Icon-48.png */; }; <array>
B2DAC3C513304D5700091D5F /* SamLogo.png in Resources */ = {isa = PBXBuildFile; fileRef = B2DAC3C213304D5700091D5F /* SamLogo.png */; }; <string>B27B1B0112246B4400111EA2</string>
B2DAC3C613304D5700091D5F /* SamLogo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B2DAC3C313304D5700091D5F /* SamLogo@2x.png */; }; <string>B27B1B0312246B4E00111EA2</string>
B2E241821301CE4900F7DC3B /* SCAddressBarDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B2E241811301CE4900F7DC3B /* SCAddressBarDemoViewController.m */; }; <string>B2B3CEFF1296F88B001BAC94</string>
B2E709AE12FF286E00DFF898 /* Icon-29.png in Resources */ = {isa = PBXBuildFile; fileRef = B2E709A812FF286E00DFF898 /* Icon-29.png */; }; <string>B27B1B0412246B6100111EA2</string>
B2E709B012FF286E00DFF898 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = B2E709AA12FF286E00DFF898 /* Icon-72.png */; }; </array>
B2E709B112FF286E00DFF898 /* Icon-114.png in Resources */ = {isa = PBXBuildFile; fileRef = B2E709AB12FF286E00DFF898 /* Icon-114.png */; }; <key>isa</key>
B2E709B312FF286E00DFF898 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B2E709AD12FF286E00DFF898 /* Icon.png */; }; <string>PBXGroup</string>
B2E709B512FF28CB00DFF898 /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = B2E709B412FF28CB00DFF898 /* iTunesArtwork */; }; <key>path</key>
E7FD242712F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FD242612F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.m */; }; <string>Classes</string>
/* End PBXBuildFile section */ <key>sourceTree</key>
<string>&lt;group&gt;</string>
/* Begin PBXFileReference section */ </dict>
1D6058910D05DD3D006BFB54 /* SSCatalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SSCatalog.app; sourceTree = BUILT_PRODUCTS_DIR; }; <key>19C28FACFE9D520D11CA2CBB</key>
4CCF41E5761E4409922431DB /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; <dict>
B21B85BC1067D4F300E5C076 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; <key>children</key>
B220428F1370FD1800604D62 /* SCImageCollectionViewItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCImageCollectionViewItem.h; sourceTree = "<group>"; }; <array>
B22042901370FD1800604D62 /* SCImageCollectionViewItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCImageCollectionViewItem.m; sourceTree = "<group>"; }; <string>1D6058910D05DD3D006BFB54</string>
B24E9E98121DC35B0085F81E /* SCAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCAppDelegate.h; sourceTree = "<group>"; }; </array>
B24E9E99121DC35B0085F81E /* SCAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCAppDelegate.m; sourceTree = "<group>"; }; <key>isa</key>
B24E9E9A121DC35B0085F81E /* SCGradientViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCGradientViewDemoViewController.h; sourceTree = "<group>"; }; <string>PBXGroup</string>
B24E9E9B121DC35B0085F81E /* SCGradientViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCGradientViewDemoViewController.m; sourceTree = "<group>"; }; <key>name</key>
B24E9E9C121DC35B0085F81E /* SCHUDViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCHUDViewDemoViewController.h; sourceTree = "<group>"; }; <string>Products</string>
B24E9E9D121DC35B0085F81E /* SCHUDViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCHUDViewDemoViewController.m; sourceTree = "<group>"; }; <key>sourceTree</key>
B24E9E9E121DC35B0085F81E /* SCLineViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCLineViewDemoViewController.h; sourceTree = "<group>"; }; <string>&lt;group&gt;</string>
B24E9E9F121DC35B0085F81E /* SCLineViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCLineViewDemoViewController.m; sourceTree = "<group>"; }; </dict>
B24E9EA2121DC35B0085F81E /* SCPickerDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPickerDemoViewController.h; sourceTree = "<group>"; }; <key>1D60588D0D05DD3D006BFB54</key>
B24E9EA3121DC35B0085F81E /* SCPickerDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPickerDemoViewController.m; sourceTree = "<group>"; }; <dict>
B24E9EA4121DC35B0085F81E /* SCPickerDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPickerDetailViewController.h; sourceTree = "<group>"; }; <key>buildActionMask</key>
B24E9EA5121DC35B0085F81E /* SCPickerDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPickerDetailViewController.m; sourceTree = "<group>"; }; <string>2147483647</string>
B24E9EA6121DC35B0085F81E /* SCPieProgressViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPieProgressViewDemoViewController.h; sourceTree = "<group>"; }; <key>files</key>
B24E9EA7121DC35B0085F81E /* SCPieProgressViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPieProgressViewDemoViewController.m; sourceTree = "<group>"; }; <array>
B24E9EA8121DC35B0085F81E /* SCRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCRootViewController.h; sourceTree = "<group>"; }; <string>B2AED4B512FF2145006C956B</string>
B24E9EA9121DC35B0085F81E /* SCRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCRootViewController.m; sourceTree = "<group>"; }; <string>B2AED4B612FF2145006C956B</string>
B24E9EB3121DC3610085F81E /* SSCatalog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSCatalog_Prefix.pch; sourceTree = "<group>"; }; <string>B25541EE12FF22B500D6E187</string>
B25541ED12FF22B500D6E187 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; }; <string>B25541F012FF22BA00D6E187</string>
B25541EF12FF22BA00D6E187 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; }; <string>B2E709AE12FF286E00DFF898</string>
B257303B1292524F001FC061 /* SCLoadingViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCLoadingViewDemoViewController.h; sourceTree = "<group>"; }; <string>B2E709B012FF286E00DFF898</string>
B257303C1292524F001FC061 /* SCLoadingViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCLoadingViewDemoViewController.m; sourceTree = "<group>"; }; <string>B2E709B112FF286E00DFF898</string>
B26043C069CC45748C596C90 /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; <string>B2E709B312FF286E00DFF898</string>
B27B1A561224228000111EA2 /* SCCollectionViewDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCollectionViewDemoViewController.h; sourceTree = "<group>"; }; <string>B2E709B512FF28CB00DFF898</string>
B27B1A571224228000111EA2 /* SCCollectionViewDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCollectionViewDemoViewController.m; sourceTree = "<group>"; }; <string>B2DAC3C413304D5700091D5F</string>
B27B1CCF12248F9D00111EA2 /* SSCatalog-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SSCatalog-Info.plist"; sourceTree = "<group>"; }; <string>B2DAC3C513304D5700091D5F</string>
B27BE8B2145369E900075F28 /* QuartzCore.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; <string>B2DAC3C613304D5700091D5F</string>
B28C6D0912FBE96600667755 /* SSRatingDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSRatingDemoViewController.h; sourceTree = "<group>"; }; </array>
B28C6D0A12FBE96600667755 /* SSRatingDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSRatingDemoViewController.m; sourceTree = "<group>"; }; <key>isa</key>
B2AED4B312FF2145006C956B /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; }; <string>PBXResourcesBuildPhase</string>
B2AED4B412FF2145006C956B /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; }; <key>runOnlyForDeploymentPostprocessing</key>
B2AED4B712FF21F8006C956B /* CoreGraphics.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; <string>0</string>
B2AED4B812FF21F8006C956B /* Foundation.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; </dict>
B2AED4B912FF21F8006C956B /* UIKit.framework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; <key>1D60588E0D05DD3D006BFB54</key>
B2B3CF551296FA76001BAC94 /* SSToolkit.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = SSToolkit.bundle; path = ../Resources/SSToolkit.bundle; sourceTree = SOURCE_ROOT; }; <dict>
B2DAC3C113304D5700091D5F /* Icon-48.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-48.png"; sourceTree = "<group>"; }; <key>buildActionMask</key>
B2DAC3C213304D5700091D5F /* SamLogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SamLogo.png; sourceTree = "<group>"; }; <string>2147483647</string>
B2DAC3C313304D5700091D5F /* SamLogo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SamLogo@2x.png"; sourceTree = "<group>"; }; <key>files</key>
B2E241801301CE4900F7DC3B /* SCAddressBarDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCAddressBarDemoViewController.h; sourceTree = "<group>"; }; <array>
B2E241811301CE4900F7DC3B /* SCAddressBarDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCAddressBarDemoViewController.m; sourceTree = "<group>"; }; <string>B21B85BE1067D4F300E5C076</string>
B2E709A812FF286E00DFF898 /* Icon-29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-29.png"; sourceTree = "<group>"; }; <string>B24E9EAA121DC35B0085F81E</string>
B2E709AA12FF286E00DFF898 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-72.png"; sourceTree = "<group>"; }; <string>B24E9EAB121DC35B0085F81E</string>
B2E709AB12FF286E00DFF898 /* Icon-114.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon-114.png"; sourceTree = "<group>"; }; <string>B24E9EAC121DC35B0085F81E</string>
B2E709AD12FF286E00DFF898 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; }; <string>B24E9EAD121DC35B0085F81E</string>
B2E709B412FF28CB00DFF898 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = "<group>"; }; <string>B24E9EAF121DC35B0085F81E</string>
B2E7B3501423774E00CAD739 /* libz.dylib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; <string>B24E9EB0121DC35B0085F81E</string>
E7FD242512F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCBadgeTableViewCellDemoViewController.h; sourceTree = "<group>"; }; <string>B24E9EB1121DC35B0085F81E</string>
E7FD242612F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCBadgeTableViewCellDemoViewController.m; sourceTree = "<group>"; }; <string>B24E9EB2121DC35B0085F81E</string>
/* End PBXFileReference section */ <string>B27B1A581224228000111EA2</string>
<string>B257303D1292524F001FC061</string>
/* Begin PBXFrameworksBuildPhase section */ <string>E7FD242712F4FFC5006A6691</string>
1D60588F0D05DD3D006BFB54 /* Frameworks */ = { <string>B28C6D0B12FBE96600667755</string>
isa = PBXFrameworksBuildPhase; <string>B2E241821301CE4900F7DC3B</string>
buildActionMask = 2147483647; <string>B22042911370FD1800604D62</string>
files = ( </array>
B2AED4BA12FF21F8006C956B /* CoreGraphics.framework in Frameworks */, <key>isa</key>
B2AED4BB12FF21F8006C956B /* Foundation.framework in Frameworks */, <string>PBXSourcesBuildPhase</string>
B2AED4BC12FF21F8006C956B /* UIKit.framework in Frameworks */, <key>runOnlyForDeploymentPostprocessing</key>
5A94485369FE4D20AF69167F /* libPods.a in Frameworks */, <string>0</string>
); </dict>
runOnlyForDeploymentPostprocessing = 0; <key>1D60588F0D05DD3D006BFB54</key>
}; <dict>
/* End PBXFrameworksBuildPhase section */ <key>buildActionMask</key>
<string>2147483647</string>
/* Begin PBXGroup section */ <key>files</key>
080E96DDFE201D6D7F000001 /* Classes */ = { <array>
isa = PBXGroup; <string>B2AED4BA12FF21F8006C956B</string>
children = ( <string>B2AED4BB12FF21F8006C956B</string>
B27B1B0112246B4400111EA2 /* Demo App */, <string>B2AED4BC12FF21F8006C956B</string>
B27B1B0312246B4E00111EA2 /* View Demos */, <string>5A94485369FE4D20AF69167F</string>
B2B3CEFF1296F88B001BAC94 /* Control Demos */, <string>7C9861F97F0544DB83D6D027</string>
B27B1B0412246B6100111EA2 /* View Controller Demos */, </array>
); <key>isa</key>
path = Classes; <string>PBXFrameworksBuildPhase</string>
sourceTree = "<group>"; <key>runOnlyForDeploymentPostprocessing</key>
}; <string>0</string>
19C28FACFE9D520D11CA2CBB /* Products */ = { </dict>
isa = PBXGroup; <key>1D6058900D05DD3D006BFB54</key>
children = ( <dict>
1D6058910D05DD3D006BFB54 /* SSCatalog.app */, <key>buildConfigurationList</key>
); <string>1D6058960D05DD3E006BFB54</string>
name = Products; <key>buildPhases</key>
sourceTree = "<group>"; <array>
}; <string>1D60588D0D05DD3D006BFB54</string>
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { <string>1D60588E0D05DD3D006BFB54</string>
isa = PBXGroup; <string>1D60588F0D05DD3D006BFB54</string>
children = ( <string>F63F716117F84407A7610108</string>
080E96DDFE201D6D7F000001 /* Classes */, <string>D0C4303A9A2347A79A120A19</string>
B21B85BB1067D4F300E5C076 /* Other Sources */, </array>
B21B85BF1067D4FD00E5C076 /* Resources */, <key>buildRules</key>
29B97323FDCFA39411CA2CEA /* Frameworks */, <array/>
19C28FACFE9D520D11CA2CBB /* Products */, <key>dependencies</key>
B26043C069CC45748C596C90 /* Pods.xcconfig */, <array/>
); <key>isa</key>
name = CustomTemplate; <string>PBXNativeTarget</string>
sourceTree = "<group>"; <key>name</key>
}; <string>SSCatalog</string>
29B97323FDCFA39411CA2CEA /* Frameworks */ = { <key>productName</key>
isa = PBXGroup; <string>TWCatalog</string>
children = ( <key>productReference</key>
B2AED4B712FF21F8006C956B /* CoreGraphics.framework */, <string>1D6058910D05DD3D006BFB54</string>
B2AED4B812FF21F8006C956B /* Foundation.framework */, <key>productType</key>
B2AED4B912FF21F8006C956B /* UIKit.framework */, <string>com.apple.product-type.application</string>
B27BE8B2145369E900075F28 /* QuartzCore.framework */, </dict>
B2E7B3501423774E00CAD739 /* libz.dylib */, <key>1D6058910D05DD3D006BFB54</key>
4CCF41E5761E4409922431DB /* libPods.a */, <dict>
); <key>explicitFileType</key>
name = Frameworks; <string>wrapper.application</string>
sourceTree = "<group>"; <key>includeInIndex</key>
}; <string>0</string>
B21B85BB1067D4F300E5C076 /* Other Sources */ = { <key>isa</key>
isa = PBXGroup; <string>PBXFileReference</string>
children = ( <key>path</key>
B21B85BC1067D4F300E5C076 /* main.m */, <string>SSCatalog.app</string>
B24E9EB3121DC3610085F81E /* SSCatalog_Prefix.pch */, <key>sourceTree</key>
); <string>BUILT_PRODUCTS_DIR</string>
path = "Other Sources"; </dict>
sourceTree = "<group>"; <key>1D6058940D05DD3E006BFB54</key>
}; <dict>
B21B85BF1067D4FD00E5C076 /* Resources */ = { <key>baseConfigurationReference</key>
isa = PBXGroup; <string>0385DB0FDA714929B58FB5B6</string>
children = ( <key>buildSettings</key>
B2DAC3C113304D5700091D5F /* Icon-48.png */, <dict>
B2DAC3C213304D5700091D5F /* SamLogo.png */, <key>ALWAYS_SEARCH_USER_PATHS</key>
B2DAC3C313304D5700091D5F /* SamLogo@2x.png */, <string>NO</string>
B2E709AD12FF286E00DFF898 /* Icon.png */, <key>CLANG_ENABLE_OBJC_ARC</key>
B2E709A812FF286E00DFF898 /* Icon-29.png */, <string>YES</string>
B2E709AA12FF286E00DFF898 /* Icon-72.png */, <key>COPY_PHASE_STRIP</key>
B2E709AB12FF286E00DFF898 /* Icon-114.png */, <string>NO</string>
B2AED4B312FF2145006C956B /* Default.png */, <key>GCC_DYNAMIC_NO_PIC</key>
B2AED4B412FF2145006C956B /* Default@2x.png */, <string>NO</string>
B25541EF12FF22BA00D6E187 /* Default-Portrait~ipad.png */, <key>GCC_OPTIMIZATION_LEVEL</key>
B25541ED12FF22B500D6E187 /* Default-Landscape~ipad.png */, <string>0</string>
B2E709B412FF28CB00DFF898 /* iTunesArtwork */, <key>GCC_PRECOMPILE_PREFIX_HEADER</key>
B2B3CF551296FA76001BAC94 /* SSToolkit.bundle */, <string>YES</string>
B27B1CCF12248F9D00111EA2 /* SSCatalog-Info.plist */, <key>GCC_PREFIX_HEADER</key>
); <string>Other Sources/SSCatalog_Prefix.pch</string>
path = Resources; <key>INFOPLIST_FILE</key>
sourceTree = "<group>"; <string>Resources/SSCatalog-Info.plist</string>
}; <key>IPHONEOS_DEPLOYMENT_TARGET</key>
B27B1B0112246B4400111EA2 /* Demo App */ = { <string>3.1.3</string>
isa = PBXGroup; <key>PRODUCT_NAME</key>
children = ( <string>SSCatalog</string>
B24E9E98121DC35B0085F81E /* SCAppDelegate.h */, <key>SDKROOT</key>
B24E9E99121DC35B0085F81E /* SCAppDelegate.m */, <string>iphoneos</string>
B24E9EA8121DC35B0085F81E /* SCRootViewController.h */, <key>TARGETED_DEVICE_FAMILY</key>
B24E9EA9121DC35B0085F81E /* SCRootViewController.m */, <string>1,2</string>
); </dict>
name = "Demo App"; <key>isa</key>
sourceTree = "<group>"; <string>XCBuildConfiguration</string>
}; <key>name</key>
B27B1B0312246B4E00111EA2 /* View Demos */ = { <string>Debug</string>
isa = PBXGroup; </dict>
children = ( <key>1D6058950D05DD3E006BFB54</key>
E7FD242512F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.h */, <dict>
E7FD242612F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.m */, <key>baseConfigurationReference</key>
B27B1A561224228000111EA2 /* SCCollectionViewDemoViewController.h */, <string>0385DB0FDA714929B58FB5B6</string>
B27B1A571224228000111EA2 /* SCCollectionViewDemoViewController.m */, <key>buildSettings</key>
B220428F1370FD1800604D62 /* SCImageCollectionViewItem.h */, <dict>
B22042901370FD1800604D62 /* SCImageCollectionViewItem.m */, <key>ALWAYS_SEARCH_USER_PATHS</key>
B24E9E9A121DC35B0085F81E /* SCGradientViewDemoViewController.h */, <string>NO</string>
B24E9E9B121DC35B0085F81E /* SCGradientViewDemoViewController.m */, <key>CLANG_ENABLE_OBJC_ARC</key>
B24E9E9C121DC35B0085F81E /* SCHUDViewDemoViewController.h */, <string>YES</string>
B24E9E9D121DC35B0085F81E /* SCHUDViewDemoViewController.m */, <key>COPY_PHASE_STRIP</key>
B24E9E9E121DC35B0085F81E /* SCLineViewDemoViewController.h */, <string>YES</string>
B24E9E9F121DC35B0085F81E /* SCLineViewDemoViewController.m */, <key>GCC_PRECOMPILE_PREFIX_HEADER</key>
B257303B1292524F001FC061 /* SCLoadingViewDemoViewController.h */, <string>YES</string>
B257303C1292524F001FC061 /* SCLoadingViewDemoViewController.m */, <key>GCC_PREFIX_HEADER</key>
B24E9EA6121DC35B0085F81E /* SCPieProgressViewDemoViewController.h */, <string>Other Sources/SSCatalog_Prefix.pch</string>
B24E9EA7121DC35B0085F81E /* SCPieProgressViewDemoViewController.m */, <key>INFOPLIST_FILE</key>
); <string>Resources/SSCatalog-Info.plist</string>
name = "View Demos"; <key>IPHONEOS_DEPLOYMENT_TARGET</key>
sourceTree = "<group>"; <string>3.1.3</string>
}; <key>PRODUCT_NAME</key>
B27B1B0412246B6100111EA2 /* View Controller Demos */ = { <string>SSCatalog</string>
isa = PBXGroup; <key>SDKROOT</key>
children = ( <string>iphoneos</string>
B24E9EA2121DC35B0085F81E /* SCPickerDemoViewController.h */, <key>TARGETED_DEVICE_FAMILY</key>
B24E9EA3121DC35B0085F81E /* SCPickerDemoViewController.m */, <string>1,2</string>
B24E9EA4121DC35B0085F81E /* SCPickerDetailViewController.h */, </dict>
B24E9EA5121DC35B0085F81E /* SCPickerDetailViewController.m */, <key>isa</key>
B28C6D0912FBE96600667755 /* SSRatingDemoViewController.h */, <string>XCBuildConfiguration</string>
B28C6D0A12FBE96600667755 /* SSRatingDemoViewController.m */, <key>name</key>
); <string>Release</string>
name = "View Controller Demos"; </dict>
sourceTree = "<group>"; <key>1D6058960D05DD3E006BFB54</key>
}; <dict>
B2B3CEFF1296F88B001BAC94 /* Control Demos */ = { <key>buildConfigurations</key>
isa = PBXGroup; <array>
children = ( <string>1D6058940D05DD3E006BFB54</string>
B2E241801301CE4900F7DC3B /* SCAddressBarDemoViewController.h */, <string>1D6058950D05DD3E006BFB54</string>
B2E241811301CE4900F7DC3B /* SCAddressBarDemoViewController.m */, </array>
); <key>defaultConfigurationIsVisible</key>
name = "Control Demos"; <string>0</string>
sourceTree = "<group>"; <key>defaultConfigurationName</key>
}; <string>Release</string>
/* End PBXGroup section */ <key>isa</key>
<string>XCConfigurationList</string>
/* Begin PBXNativeTarget section */ </dict>
1D6058900D05DD3D006BFB54 /* SSCatalog */ = { <key>29B97313FDCFA39411CA2CEA</key>
isa = PBXNativeTarget; <dict>
buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SSCatalog" */; <key>attributes</key>
buildPhases = ( <dict>
1D60588D0D05DD3D006BFB54 /* Resources */, <key>LastUpgradeCheck</key>
1D60588E0D05DD3D006BFB54 /* Sources */, <string>0420</string>
1D60588F0D05DD3D006BFB54 /* Frameworks */, <key>ORGANIZATIONNAME</key>
F63F716117F84407A7610108 /* Copy Pods Resources */, <string>Sam Soffes</string>
); </dict>
buildRules = ( <key>buildConfigurationList</key>
); <string>C01FCF4E08A954540054247B</string>
dependencies = ( <key>compatibilityVersion</key>
); <string>Xcode 3.2</string>
name = SSCatalog; <key>developmentRegion</key>
productName = TWCatalog; <string>English</string>
productReference = 1D6058910D05DD3D006BFB54 /* SSCatalog.app */; <key>hasScannedForEncodings</key>
productType = "com.apple.product-type.application"; <string>1</string>
}; <key>isa</key>
/* End PBXNativeTarget section */ <string>PBXProject</string>
<key>knownRegions</key>
/* Begin PBXProject section */ <array>
29B97313FDCFA39411CA2CEA /* Project object */ = { <string>English</string>
isa = PBXProject; <string>Japanese</string>
attributes = { <string>French</string>
LastUpgradeCheck = 0420; <string>German</string>
ORGANIZATIONNAME = "Sam Soffes"; <string>en</string>
}; </array>
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SSCatalog" */; <key>mainGroup</key>
compatibilityVersion = "Xcode 3.2"; <string>29B97314FDCFA39411CA2CEA</string>
developmentRegion = English; <key>projectDirPath</key>
hasScannedForEncodings = 1; <string></string>
knownRegions = ( <key>projectReferences</key>
English, <array/>
Japanese, <key>projectRoot</key>
French, <string></string>
German, <key>targets</key>
en, <array>
); <string>1D6058900D05DD3D006BFB54</string>
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; </array>
projectDirPath = ""; </dict>
projectRoot = ""; <key>29B97314FDCFA39411CA2CEA</key>
targets = ( <dict>
1D6058900D05DD3D006BFB54 /* SSCatalog */, <key>children</key>
); <array>
}; <string>080E96DDFE201D6D7F000001</string>
/* End PBXProject section */ <string>B21B85BB1067D4F300E5C076</string>
<string>B21B85BF1067D4FD00E5C076</string>
/* Begin PBXResourcesBuildPhase section */ <string>29B97323FDCFA39411CA2CEA</string>
1D60588D0D05DD3D006BFB54 /* Resources */ = { <string>19C28FACFE9D520D11CA2CBB</string>
isa = PBXResourcesBuildPhase; <string>B26043C069CC45748C596C90</string>
buildActionMask = 2147483647; <string>0385DB0FDA714929B58FB5B6</string>
files = ( </array>
B2AED4B512FF2145006C956B /* Default.png in Resources */, <key>isa</key>
B2AED4B612FF2145006C956B /* Default@2x.png in Resources */, <string>PBXGroup</string>
B25541EE12FF22B500D6E187 /* Default-Landscape~ipad.png in Resources */, <key>name</key>
B25541F012FF22BA00D6E187 /* Default-Portrait~ipad.png in Resources */, <string>CustomTemplate</string>
B2E709AE12FF286E00DFF898 /* Icon-29.png in Resources */, <key>sourceTree</key>
B2E709B012FF286E00DFF898 /* Icon-72.png in Resources */, <string>&lt;group&gt;</string>
B2E709B112FF286E00DFF898 /* Icon-114.png in Resources */, </dict>
B2E709B312FF286E00DFF898 /* Icon.png in Resources */, <key>29B97323FDCFA39411CA2CEA</key>
B2E709B512FF28CB00DFF898 /* iTunesArtwork in Resources */, <dict>
B2DAC3C413304D5700091D5F /* Icon-48.png in Resources */, <key>children</key>
B2DAC3C513304D5700091D5F /* SamLogo.png in Resources */, <array>
B2DAC3C613304D5700091D5F /* SamLogo@2x.png in Resources */, <string>B2AED4B712FF21F8006C956B</string>
); <string>B2AED4B812FF21F8006C956B</string>
runOnlyForDeploymentPostprocessing = 0; <string>B2AED4B912FF21F8006C956B</string>
}; <string>B27BE8B2145369E900075F28</string>
/* End PBXResourcesBuildPhase section */ <string>B2E7B3501423774E00CAD739</string>
<string>4CCF41E5761E4409922431DB</string>
/* Begin PBXShellScriptBuildPhase section */ <string>BFA84192647D4087A2545DD7</string>
F63F716117F84407A7610108 /* Copy Pods Resources */ = { </array>
isa = PBXShellScriptBuildPhase; <key>isa</key>
buildActionMask = 2147483647; <string>PBXGroup</string>
files = ( <key>name</key>
); <string>Frameworks</string>
inputPaths = ( <key>sourceTree</key>
); <string>&lt;group&gt;</string>
name = "Copy Pods Resources"; </dict>
outputPaths = ( <key>4CCF41E5761E4409922431DB</key>
); <dict>
runOnlyForDeploymentPostprocessing = 0; <key>explicitFileType</key>
shellPath = /bin/sh; <string>archive.ar</string>
shellScript = "\"${SRCROOT}/Pods/Pods-resources.sh\"\n"; <key>includeInIndex</key>
}; <string>0</string>
/* End PBXShellScriptBuildPhase section */ <key>isa</key>
<string>PBXFileReference</string>
/* Begin PBXSourcesBuildPhase section */ <key>path</key>
1D60588E0D05DD3D006BFB54 /* Sources */ = { <string>libPods.a</string>
isa = PBXSourcesBuildPhase; <key>sourceTree</key>
buildActionMask = 2147483647; <string>BUILT_PRODUCTS_DIR</string>
files = ( </dict>
B21B85BE1067D4F300E5C076 /* main.m in Sources */, <key>5A94485369FE4D20AF69167F</key>
B24E9EAA121DC35B0085F81E /* SCAppDelegate.m in Sources */, <dict>
B24E9EAB121DC35B0085F81E /* SCGradientViewDemoViewController.m in Sources */, <key>fileRef</key>
B24E9EAC121DC35B0085F81E /* SCHUDViewDemoViewController.m in Sources */, <string>4CCF41E5761E4409922431DB</string>
B24E9EAD121DC35B0085F81E /* SCLineViewDemoViewController.m in Sources */, <key>isa</key>
B24E9EAF121DC35B0085F81E /* SCPickerDemoViewController.m in Sources */, <string>PBXBuildFile</string>
B24E9EB0121DC35B0085F81E /* SCPickerDetailViewController.m in Sources */, </dict>
B24E9EB1121DC35B0085F81E /* SCPieProgressViewDemoViewController.m in Sources */, <key>7C9861F97F0544DB83D6D027</key>
B24E9EB2121DC35B0085F81E /* SCRootViewController.m in Sources */, <dict>
B27B1A581224228000111EA2 /* SCCollectionViewDemoViewController.m in Sources */, <key>fileRef</key>
B257303D1292524F001FC061 /* SCLoadingViewDemoViewController.m in Sources */, <string>BFA84192647D4087A2545DD7</string>
E7FD242712F4FFC5006A6691 /* SCBadgeTableViewCellDemoViewController.m in Sources */, <key>isa</key>
B28C6D0B12FBE96600667755 /* SSRatingDemoViewController.m in Sources */, <string>PBXBuildFile</string>
B2E241821301CE4900F7DC3B /* SCAddressBarDemoViewController.m in Sources */, <key>settings</key>
B22042911370FD1800604D62 /* SCImageCollectionViewItem.m in Sources */, <dict/>
); </dict>
runOnlyForDeploymentPostprocessing = 0; <key>B21B85BB1067D4F300E5C076</key>
}; <dict>
/* End PBXSourcesBuildPhase section */ <key>children</key>
<array>
/* Begin XCBuildConfiguration section */ <string>B21B85BC1067D4F300E5C076</string>
1D6058940D05DD3E006BFB54 /* Debug */ = { <string>B24E9EB3121DC3610085F81E</string>
isa = XCBuildConfiguration; </array>
baseConfigurationReference = B26043C069CC45748C596C90 /* Pods.xcconfig */; <key>isa</key>
buildSettings = { <string>PBXGroup</string>
ALWAYS_SEARCH_USER_PATHS = NO; <key>path</key>
CLANG_ENABLE_OBJC_ARC = YES; <string>Other Sources</string>
COPY_PHASE_STRIP = NO; <key>sourceTree</key>
GCC_DYNAMIC_NO_PIC = NO; <string>&lt;group&gt;</string>
GCC_OPTIMIZATION_LEVEL = 0; </dict>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>B21B85BC1067D4F300E5C076</key>
GCC_PREFIX_HEADER = "Other Sources/SSCatalog_Prefix.pch"; <dict>
INFOPLIST_FILE = "Resources/SSCatalog-Info.plist"; <key>fileEncoding</key>
IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; <string>4</string>
PRODUCT_NAME = SSCatalog; <key>isa</key>
SDKROOT = iphoneos; <string>PBXFileReference</string>
TARGETED_DEVICE_FAMILY = "1,2"; <key>lastKnownFileType</key>
}; <string>sourcecode.c.objc</string>
name = Debug; <key>path</key>
}; <string>main.m</string>
1D6058950D05DD3E006BFB54 /* Release */ = { <key>sourceTree</key>
isa = XCBuildConfiguration; <string>&lt;group&gt;</string>
baseConfigurationReference = B26043C069CC45748C596C90 /* Pods.xcconfig */; </dict>
buildSettings = { <key>B21B85BE1067D4F300E5C076</key>
ALWAYS_SEARCH_USER_PATHS = NO; <dict>
CLANG_ENABLE_OBJC_ARC = YES; <key>fileRef</key>
COPY_PHASE_STRIP = YES; <string>B21B85BC1067D4F300E5C076</string>
GCC_PRECOMPILE_PREFIX_HEADER = YES; <key>isa</key>
GCC_PREFIX_HEADER = "Other Sources/SSCatalog_Prefix.pch"; <string>PBXBuildFile</string>
INFOPLIST_FILE = "Resources/SSCatalog-Info.plist"; </dict>
IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; <key>B21B85BF1067D4FD00E5C076</key>
PRODUCT_NAME = SSCatalog; <dict>
SDKROOT = iphoneos; <key>children</key>
TARGETED_DEVICE_FAMILY = "1,2"; <array>
}; <string>B2DAC3C113304D5700091D5F</string>
name = Release; <string>B2DAC3C213304D5700091D5F</string>
}; <string>B2DAC3C313304D5700091D5F</string>
C01FCF4F08A954540054247B /* Debug */ = { <string>B2E709AD12FF286E00DFF898</string>
isa = XCBuildConfiguration; <string>B2E709A812FF286E00DFF898</string>
buildSettings = { <string>B2E709AA12FF286E00DFF898</string>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; <string>B2E709AB12FF286E00DFF898</string>
GCC_C_LANGUAGE_STANDARD = "compiler-default"; <string>B2AED4B312FF2145006C956B</string>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <string>B2AED4B412FF2145006C956B</string>
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; <string>B25541EF12FF22BA00D6E187</string>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <string>B25541ED12FF22B500D6E187</string>
GCC_WARN_UNUSED_VARIABLE = YES; <string>B2E709B412FF28CB00DFF898</string>
IPHONEOS_DEPLOYMENT_TARGET = 4.0; <string>B2B3CF551296FA76001BAC94</string>
SDKROOT = iphoneos; <string>B27B1CCF12248F9D00111EA2</string>
}; </array>
name = Debug; <key>isa</key>
}; <string>PBXGroup</string>
C01FCF5008A954540054247B /* Release */ = { <key>path</key>
isa = XCBuildConfiguration; <string>Resources</string>
buildSettings = { <key>sourceTree</key>
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; <string>&lt;group&gt;</string>
GCC_C_LANGUAGE_STANDARD = "compiler-default"; </dict>
GCC_VERSION = com.apple.compilers.llvm.clang.1_0; <key>B220428F1370FD1800604D62</key>
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; <dict>
GCC_WARN_ABOUT_RETURN_TYPE = YES; <key>fileEncoding</key>
GCC_WARN_UNUSED_VARIABLE = YES; <string>4</string>
IPHONEOS_DEPLOYMENT_TARGET = 4.0; <key>isa</key>
SDKROOT = iphoneos; <string>PBXFileReference</string>
}; <key>lastKnownFileType</key>
name = Release; <string>sourcecode.c.h</string>
}; <key>path</key>
/* End XCBuildConfiguration section */ <string>SCImageCollectionViewItem.h</string>
<key>sourceTree</key>
/* Begin XCConfigurationList section */ <string>&lt;group&gt;</string>
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SSCatalog" */ = { </dict>
isa = XCConfigurationList; <key>B22042901370FD1800604D62</key>
buildConfigurations = ( <dict>
1D6058940D05DD3E006BFB54 /* Debug */, <key>fileEncoding</key>
1D6058950D05DD3E006BFB54 /* Release */, <string>4</string>
); <key>isa</key>
defaultConfigurationIsVisible = 0; <string>PBXFileReference</string>
defaultConfigurationName = Release; <key>lastKnownFileType</key>
}; <string>sourcecode.c.objc</string>
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SSCatalog" */ = { <key>path</key>
isa = XCConfigurationList; <string>SCImageCollectionViewItem.m</string>
buildConfigurations = ( <key>sourceTree</key>
C01FCF4F08A954540054247B /* Debug */, <string>&lt;group&gt;</string>
C01FCF5008A954540054247B /* Release */, </dict>
); <key>B22042911370FD1800604D62</key>
defaultConfigurationIsVisible = 0; <dict>
defaultConfigurationName = Release; <key>fileRef</key>
}; <string>B22042901370FD1800604D62</string>
/* End XCConfigurationList section */ <key>isa</key>
}; <string>PBXBuildFile</string>
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; </dict>
} <key>B24E9E98121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCAppDelegate.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E99121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCAppDelegate.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9A121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCGradientViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9B121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCGradientViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9C121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCHUDViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9D121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCHUDViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9E121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCLineViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9E9F121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCLineViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA2121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCPickerDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA3121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCPickerDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA4121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCPickerDetailViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA5121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCPickerDetailViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA6121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCPieProgressViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA7121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCPieProgressViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA8121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCRootViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EA9121DC35B0085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCRootViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B24E9EAA121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9E99121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EAB121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9E9B121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EAC121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9E9D121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EAD121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9E9F121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EAF121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9EA3121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EB0121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9EA5121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EB1121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9EA7121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EB2121DC35B0085F81E</key>
<dict>
<key>fileRef</key>
<string>B24E9EA9121DC35B0085F81E</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B24E9EB3121DC3610085F81E</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SSCatalog_Prefix.pch</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B25541ED12FF22B500D6E187</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default-Landscape~ipad.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B25541EE12FF22B500D6E187</key>
<dict>
<key>fileRef</key>
<string>B25541ED12FF22B500D6E187</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B25541EF12FF22BA00D6E187</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default-Portrait~ipad.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B25541F012FF22BA00D6E187</key>
<dict>
<key>fileRef</key>
<string>B25541EF12FF22BA00D6E187</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B257303B1292524F001FC061</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCLoadingViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B257303C1292524F001FC061</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCLoadingViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B257303D1292524F001FC061</key>
<dict>
<key>fileRef</key>
<string>B257303C1292524F001FC061</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B26043C069CC45748C596C90</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.xcconfig</string>
<key>name</key>
<string>Pods.xcconfig</string>
<key>path</key>
<string>Pods/Pods.xcconfig</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>B27B1A561224228000111EA2</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCCollectionViewDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27B1A571224228000111EA2</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCCollectionViewDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27B1A581224228000111EA2</key>
<dict>
<key>fileRef</key>
<string>B27B1A571224228000111EA2</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B27B1B0112246B4400111EA2</key>
<dict>
<key>children</key>
<array>
<string>B24E9E98121DC35B0085F81E</string>
<string>B24E9E99121DC35B0085F81E</string>
<string>B24E9EA8121DC35B0085F81E</string>
<string>B24E9EA9121DC35B0085F81E</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Demo App</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27B1B0312246B4E00111EA2</key>
<dict>
<key>children</key>
<array>
<string>E7FD242512F4FFC5006A6691</string>
<string>E7FD242612F4FFC5006A6691</string>
<string>B27B1A561224228000111EA2</string>
<string>B27B1A571224228000111EA2</string>
<string>B220428F1370FD1800604D62</string>
<string>B22042901370FD1800604D62</string>
<string>B24E9E9A121DC35B0085F81E</string>
<string>B24E9E9B121DC35B0085F81E</string>
<string>B24E9E9C121DC35B0085F81E</string>
<string>B24E9E9D121DC35B0085F81E</string>
<string>B24E9E9E121DC35B0085F81E</string>
<string>B24E9E9F121DC35B0085F81E</string>
<string>B257303B1292524F001FC061</string>
<string>B257303C1292524F001FC061</string>
<string>B24E9EA6121DC35B0085F81E</string>
<string>B24E9EA7121DC35B0085F81E</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>View Demos</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27B1B0412246B6100111EA2</key>
<dict>
<key>children</key>
<array>
<string>B24E9EA2121DC35B0085F81E</string>
<string>B24E9EA3121DC35B0085F81E</string>
<string>B24E9EA4121DC35B0085F81E</string>
<string>B24E9EA5121DC35B0085F81E</string>
<string>B28C6D0912FBE96600667755</string>
<string>B28C6D0A12FBE96600667755</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>View Controller Demos</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27B1CCF12248F9D00111EA2</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>text.plist.xml</string>
<key>path</key>
<string>SSCatalog-Info.plist</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B27BE8B2145369E900075F28</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>QuartzCore.framework</string>
<key>path</key>
<string>System/Library/Frameworks/QuartzCore.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>B28C6D0912FBE96600667755</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SSRatingDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B28C6D0A12FBE96600667755</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SSRatingDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B28C6D0B12FBE96600667755</key>
<dict>
<key>fileRef</key>
<string>B28C6D0A12FBE96600667755</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2AED4B312FF2145006C956B</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2AED4B412FF2145006C956B</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Default@2x.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2AED4B512FF2145006C956B</key>
<dict>
<key>fileRef</key>
<string>B2AED4B312FF2145006C956B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2AED4B612FF2145006C956B</key>
<dict>
<key>fileRef</key>
<string>B2AED4B412FF2145006C956B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2AED4B712FF21F8006C956B</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>CoreGraphics.framework</string>
<key>path</key>
<string>System/Library/Frameworks/CoreGraphics.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>B2AED4B812FF21F8006C956B</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>Foundation.framework</string>
<key>path</key>
<string>System/Library/Frameworks/Foundation.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>B2AED4B912FF21F8006C956B</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.framework</string>
<key>name</key>
<string>UIKit.framework</string>
<key>path</key>
<string>System/Library/Frameworks/UIKit.framework</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>B2AED4BA12FF21F8006C956B</key>
<dict>
<key>fileRef</key>
<string>B2AED4B712FF21F8006C956B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2AED4BB12FF21F8006C956B</key>
<dict>
<key>fileRef</key>
<string>B2AED4B812FF21F8006C956B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2AED4BC12FF21F8006C956B</key>
<dict>
<key>fileRef</key>
<string>B2AED4B912FF21F8006C956B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2B3CEFF1296F88B001BAC94</key>
<dict>
<key>children</key>
<array>
<string>B2E241801301CE4900F7DC3B</string>
<string>B2E241811301CE4900F7DC3B</string>
</array>
<key>isa</key>
<string>PBXGroup</string>
<key>name</key>
<string>Control Demos</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2B3CF551296FA76001BAC94</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>wrapper.plug-in</string>
<key>name</key>
<string>SSToolkit.bundle</string>
<key>path</key>
<string>../Resources/SSToolkit.bundle</string>
<key>sourceTree</key>
<string>SOURCE_ROOT</string>
</dict>
<key>B2DAC3C113304D5700091D5F</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Icon-48.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2DAC3C213304D5700091D5F</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>SamLogo.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2DAC3C313304D5700091D5F</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>SamLogo@2x.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2DAC3C413304D5700091D5F</key>
<dict>
<key>fileRef</key>
<string>B2DAC3C113304D5700091D5F</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2DAC3C513304D5700091D5F</key>
<dict>
<key>fileRef</key>
<string>B2DAC3C213304D5700091D5F</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2DAC3C613304D5700091D5F</key>
<dict>
<key>fileRef</key>
<string>B2DAC3C313304D5700091D5F</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E241801301CE4900F7DC3B</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCAddressBarDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E241811301CE4900F7DC3B</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCAddressBarDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E241821301CE4900F7DC3B</key>
<dict>
<key>fileRef</key>
<string>B2E241811301CE4900F7DC3B</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E709A812FF286E00DFF898</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Icon-29.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E709AA12FF286E00DFF898</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Icon-72.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E709AB12FF286E00DFF898</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Icon-114.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E709AD12FF286E00DFF898</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>image.png</string>
<key>path</key>
<string>Icon.png</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E709AE12FF286E00DFF898</key>
<dict>
<key>fileRef</key>
<string>B2E709A812FF286E00DFF898</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E709B012FF286E00DFF898</key>
<dict>
<key>fileRef</key>
<string>B2E709AA12FF286E00DFF898</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E709B112FF286E00DFF898</key>
<dict>
<key>fileRef</key>
<string>B2E709AB12FF286E00DFF898</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E709B312FF286E00DFF898</key>
<dict>
<key>fileRef</key>
<string>B2E709AD12FF286E00DFF898</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E709B412FF28CB00DFF898</key>
<dict>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>file</string>
<key>path</key>
<string>iTunesArtwork</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>B2E709B512FF28CB00DFF898</key>
<dict>
<key>fileRef</key>
<string>B2E709B412FF28CB00DFF898</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>B2E7B3501423774E00CAD739</key>
<dict>
<key>includeInIndex</key>
<string>1</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>compiled.mach-o.dylib</string>
<key>name</key>
<string>libz.dylib</string>
<key>path</key>
<string>usr/lib/libz.dylib</string>
<key>sourceTree</key>
<string>SDKROOT</string>
</dict>
<key>BFA84192647D4087A2545DD7</key>
<dict>
<key>explicitFileType</key>
<string>archive.ar</string>
<key>includeInIndex</key>
<string>0</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>name</key>
<string>libPods.a</string>
<key>path</key>
<string>libPods.a</string>
<key>sourceTree</key>
<string>BUILT_PRODUCTS_DIR</string>
</dict>
<key>C01FCF4E08A954540054247B</key>
<dict>
<key>buildConfigurations</key>
<array>
<string>C01FCF4F08A954540054247B</string>
<string>C01FCF5008A954540054247B</string>
</array>
<key>defaultConfigurationIsVisible</key>
<string>0</string>
<key>defaultConfigurationName</key>
<string>Release</string>
<key>isa</key>
<string>XCConfigurationList</string>
</dict>
<key>C01FCF4F08A954540054247B</key>
<dict>
<key>buildSettings</key>
<dict>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>compiler-default</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_ABOUT_MISSING_PROTOTYPES</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>IPHONEOS_DEPLOYMENT_TARGET</key>
<string>4.0</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Debug</string>
</dict>
<key>C01FCF5008A954540054247B</key>
<dict>
<key>buildSettings</key>
<dict>
<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
<string>iPhone Developer</string>
<key>GCC_C_LANGUAGE_STANDARD</key>
<string>compiler-default</string>
<key>GCC_VERSION</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>GCC_WARN_ABOUT_MISSING_PROTOTYPES</key>
<string>YES</string>
<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
<string>YES</string>
<key>GCC_WARN_UNUSED_VARIABLE</key>
<string>YES</string>
<key>IPHONEOS_DEPLOYMENT_TARGET</key>
<string>4.0</string>
<key>SDKROOT</key>
<string>iphoneos</string>
</dict>
<key>isa</key>
<string>XCBuildConfiguration</string>
<key>name</key>
<string>Release</string>
</dict>
<key>D0C4303A9A2347A79A120A19</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array/>
<key>inputPaths</key>
<array/>
<key>isa</key>
<string>PBXShellScriptBuildPhase</string>
<key>name</key>
<string>Copy Pods Resources</string>
<key>outputPaths</key>
<array/>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
<key>shellPath</key>
<string>/bin/sh</string>
<key>shellScript</key>
<string>"${SRCROOT}/Pods/Pods-resources.sh"
</string>
</dict>
<key>E7FD242512F4FFC5006A6691</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>SCBadgeTableViewCellDemoViewController.h</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>E7FD242612F4FFC5006A6691</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.objc</string>
<key>path</key>
<string>SCBadgeTableViewCellDemoViewController.m</string>
<key>sourceTree</key>
<string>&lt;group&gt;</string>
</dict>
<key>E7FD242712F4FFC5006A6691</key>
<dict>
<key>fileRef</key>
<string>E7FD242612F4FFC5006A6691</string>
<key>isa</key>
<string>PBXBuildFile</string>
</dict>
<key>F63F716117F84407A7610108</key>
<dict>
<key>buildActionMask</key>
<string>2147483647</string>
<key>files</key>
<array/>
<key>inputPaths</key>
<array/>
<key>isa</key>
<string>PBXShellScriptBuildPhase</string>
<key>name</key>
<string>Copy Pods Resources</string>
<key>outputPaths</key>
<array/>
<key>runOnlyForDeploymentPostprocessing</key>
<string>0</string>
<key>shellPath</key>
<string>/bin/sh</string>
<key>shellScript</key>
<string>"${SRCROOT}/Pods/Pods-resources.sh"
</string>
</dict>
</dict>
<key>rootObject</key>
<string>29B97313FDCFA39411CA2CEA</string>
</dict>
</plist>
...@@ -6,6 +6,6 @@ DEPENDENCIES: ...@@ -6,6 +6,6 @@ DEPENDENCIES:
- JSONKit - JSONKit
SPEC CHECKSUMS: SPEC CHECKSUMS:
JSONKit: 3d4708953ea7ae399a49777372d8b060a43ddd27 JSONKit: a01a22c75f27eae76b4badd55a91c20fe6e86477
COCOAPODS: 0.13.0 COCOAPODS: 0.16.0.rc2
...@@ -11,40 +11,31 @@ unless Gem::Version::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new( ...@@ -11,40 +11,31 @@ unless Gem::Version::Requirement.new('>= 1.4.0').satisfied_by?(Gem::Version.new(
exit 1 exit 1
end end
module Pod require 'cocoapods/version'
VERSION = '0.15.2'
module Pod
class PlainInformative < StandardError class PlainInformative < StandardError
end end
class Informative < PlainInformative class Informative < PlainInformative
def message def message
# TODO: remove formatting from raise calls and remove conditional # TODO: remove formatting from raise calls and remove conditional
super !~ /\[!\]/ ? "[!] #{super}\n".red : super super !~ /\[!\]/ ? "[!] #{super}".red : super
end end
end end
autoload :Command, 'cocoapods/command' autoload :Command, 'cocoapods/command'
autoload :Config, 'cocoapods/config'
autoload :Dependency, 'cocoapods/dependency'
autoload :Downloader, 'cocoapods/downloader' autoload :Downloader, 'cocoapods/downloader'
autoload :Executable, 'cocoapods/executable' autoload :Executable, 'cocoapods/executable'
autoload :ExternalSources, 'cocoapods/external_sources'
autoload :Installer, 'cocoapods/installer' autoload :Installer, 'cocoapods/installer'
autoload :LocalPod, 'cocoapods/local_pod' autoload :LocalPod, 'cocoapods/local_pod'
autoload :Lockfile, 'cocoapods/lockfile'
autoload :Platform, 'cocoapods/platform'
autoload :Podfile, 'cocoapods/podfile'
autoload :Project, 'cocoapods/project' autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver' autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox' autoload :Sandbox, 'cocoapods/sandbox'
autoload :Source, 'cocoapods/source'
autoload :Spec, 'cocoapods/specification'
autoload :Specification, 'cocoapods/specification'
autoload :UI, 'cocoapods/user_interface' autoload :UI, 'cocoapods/user_interface'
autoload :Version, 'cocoapods/version'
autoload :Pathname, 'pathname' autoload :Pathname, 'pathname'
autoload :FileList, 'cocoapods/file_list'
module Generator module Generator
autoload :BridgeSupport, 'cocoapods/generator/bridge_support' autoload :BridgeSupport, 'cocoapods/generator/bridge_support'
...@@ -54,9 +45,17 @@ module Pod ...@@ -54,9 +45,17 @@ module Pod
autoload :Plist, 'cocoapods/generator/acknowledgements/plist' autoload :Plist, 'cocoapods/generator/acknowledgements/plist'
autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown' autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown'
autoload :DummySource, 'cocoapods/generator/dummy_source' autoload :DummySource, 'cocoapods/generator/dummy_source'
autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
autoload :XCConfig, 'cocoapods/generator/xcconfig'
end end
require 'cocoapods/file_list'
require 'cocoapods-core'
require 'cocoapods/config'
require 'cocoapods/source'
end end
if ENV['COCOA_PODS_ENV'] == 'development' if ENV['COCOA_PODS_ENV'] == 'development'
require 'awesome_print' require 'awesome_print'
require 'pry'
end end
require 'colored' require 'colored'
require 'claide'
module Pod module Pod
class Command class PlainInformative
autoload :ErrorReport, 'cocoapods/command/error_report' include CLAide::InformativeError
autoload :Install, 'cocoapods/command/install' end
autoload :List, 'cocoapods/command/list'
autoload :Linter, 'cocoapods/command/linter'
autoload :Outdated, 'cocoapods/command/outdated'
autoload :Push, 'cocoapods/command/push'
autoload :Repo, 'cocoapods/command/repo'
autoload :Search, 'cocoapods/command/search'
autoload :Setup, 'cocoapods/command/setup'
autoload :Spec, 'cocoapods/command/spec'
autoload :Update, 'cocoapods/command/update'
class Help < Informative
def initialize(command_class, argv, unrecognized_command = nil)
@command_class, @argv, @unrecognized_command = command_class, argv, unrecognized_command
end
def message
message = [
'',
@command_class.banner.gsub(/\$ pod (.*)/, '$ pod \1'.green),
'',
'Options:',
'',
options,
"\n",
].join("\n")
message << "[!] Unrecognized command: `#{@unrecognized_command}'\n".red if @unrecognized_command
message << "[!] Unrecognized argument#{@argv.count > 1 ? 's' : ''}: `#{@argv.join(' - ')}'\n".red unless @argv.empty?
message
end
private
def options
options = @command_class.options
keys = options.map(&:first)
key_size = keys.inject(0) { |size, key| key.size > size ? key.size : size }
options.map { |key, desc| " #{key.ljust(key_size)} #{desc}" }.join("\n")
end
end
class ARGV < Array class Command < CLAide::Command
def options; select { |x| x.to_s[0,1] == '-' }; end autoload :ErrorReport, 'cocoapods/command/error_report'
def arguments; self - options; end autoload :DeepLinter, 'cocoapods/command/deep_linter'
def option(name); !!delete(name); end
def shift_argument; (arg = arguments[0]) && delete(arg); end
end
def self.banner self.abstract_command = true
commands = ['install', 'update', 'outdated', 'list', 'push', 'repo', 'search', 'setup', 'spec'].sort self.command = 'pod'
banner = "To see help for the available commands run:\n\n" self.description = 'CocoaPods, the Objective-C library package manager.'
banner + commands.map { |cmd| " * $ pod #{cmd.green} --help" }.join("\n")
end
def self.options def self.options
[ [
['--help', 'Show help information'], ['--silent', 'Show nothing'],
['--silent', 'Print nothing'], ['--version', 'Show the version of CocoaPods'],
['--no-color', 'Print output without color'], ].concat(super)
['--verbose', 'Print more information while working'],
['--version', 'Prints the version of CocoaPods'],
]
end end
def self.run(*argv) def self.parse(argv)
sub_command = parse(*argv) command = super
unless sub_command.is_a?(Setup) || ENV['SKIP_SETUP'] unless command.is_a?(Setup) || ENV['SKIP_SETUP']
Setup.new(ARGV.new).run_if_needed Setup.new(CLAide::ARGV.new([])).run_if_needed
end end
sub_command.run command
UI.puts
rescue Interrupt
puts "[!] Cancelled".red
Config.instance.verbose? ? raise : exit(1)
rescue Exception => e
if e.is_a?(PlainInformative) || ENV['COCOA_PODS_ENV'] == 'development' # also catches Informative
puts e.message
puts *e.backtrace if Config.instance.verbose? || ENV['COCOA_PODS_ENV'] == 'development'
else
puts ErrorReport.report(e)
end
exit 1
end end
def self.parse(*argv) def self.run(argv)
argv = ARGV.new(argv) argv = CLAide::ARGV.new(argv)
if argv.option('--version') if argv.flag?('version')
puts VERSION puts VERSION
exit!(0) exit!(0)
end end
super(argv)
end
show_help = argv.option('--help') def self.report_error(error)
Config.instance.silent = argv.option('--silent') if error.is_a?(Interrupt)
Config.instance.verbose = argv.option('--verbose') puts "[!] Cancelled".red
Config.instance.verbose? ? raise : exit(1)
String.send(:define_method, :colorize) { |string , _| string } if argv.option( '--no-color' )
command_class = case command_argument = argv.shift_argument
when 'install' then Install
when 'list' then List
when 'outdated' then Outdated
when 'push' then Push
when 'repo' then Repo
when 'search' then Search
when 'setup' then Setup
when 'spec' then Spec
when 'update' then Update
end
if command_class.nil?
raise Help.new(self, argv, command_argument)
elsif show_help
raise Help.new(command_class, argv)
else else
command_class.new(argv) puts ErrorReport.report(error)
exit 1
end end
end end
include Config::Mixin
def initialize(argv) def initialize(argv)
raise Help.new(self.class, argv) config.silent = argv.flag?('silent')
super
config.verbose = self.verbose?
# TODO we should probably not even load colored unless needed
String.send(:define_method, :colorize) { |string , _| string } unless self.colorize_output?
end end
include Config::Mixin
private private
def verify_podfile_exists! def verify_podfile_exists!
...@@ -145,3 +74,11 @@ module Pod ...@@ -145,3 +74,11 @@ module Pod
end end
end end
require 'cocoapods/command/list'
require 'cocoapods/command/outdated'
require 'cocoapods/command/project'
require 'cocoapods/command/push'
require 'cocoapods/command/repo'
require 'cocoapods/command/search'
require 'cocoapods/command/setup'
require 'cocoapods/command/spec'
module Pod
class Command
class DeepLinter < Specification::Linter
include Config::Mixin
# Lints the specification adding a {Result} for any failed check to the
# {#results} list.
#
# @return [Bool] whether the specification passed validation.
#
def lint
super
unless quick
check_repo_path
spec.available_platforms.each do |platform|
UI.section "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed do
current_platform = platform
set_up_lint_environment
install_pod
build_pod
check_file_patterns
tear_down_lint_environment
end
end
end
errors.empty? && warnings.empty? && deprecations.empty?
end
# @return [Bool] whether the lint should skip the checks that requires
# the download or the build of the library.
#
attr_accessor :quick
# @return [Bool] whether the linter should not clean up temporary files
# for inspection.
#
attr_accessor :no_clean
# @return [Pathname] whether the lint should be performed
#
attr_accessor :repo_path
# @return [Bool] whether the lint should be performed against the root of
# the podspec instead to its original source. Uses the `:local` option
# of the Podfile.
#
attr_writer :local
def local?; @local; end
#-----------------------------------------------------------------------#
# !@group Lint results
public
# @return [Array<Result>] all the notes generated by the Linter.
#
def notes
@errors ||= results.select { |r| r.type == :note }
end
#-----------------------------------------------------------------------#
private
# !@group Lint steps
def check_repo_path
return unless repo_path
expected_path = "#{spec.name}/#{spec.version}/#{spec.name}.podspec"
path = file.relative_path_from(repo_path).to_s
unless path.end_with?(expected_path)
error "Incorrect path, the path is `#{file}` and should be `#{expected_path}`"
end
end
def set_up_lint_environment
tmp_dir.rmtree if tmp_dir.exist?
tmp_dir.mkpath
@original_config = Config.instance.clone
config.project_root = tmp_dir
config.project_pods_root = tmp_dir + 'Pods'
config.silent = !config.verbose
config.integrate_targets = false
config.generate_docs = false
end
def tear_down_lint_environment
tmp_dir.rmtree unless no_clean
Config.instance = @original_config
end
# It creates a podfile in memory and builds a library containing
# the pod for all available platforms with xcodebuild.
#
def install_pod
spec.activate_platform(current_platform)
podfile = podfile_from_spec
config.verbose
config.skip_repo_update = true
sandbox = Sandbox.new(config.project_pods_root)
resolver = Resolver.new(podfile, nil, sandbox)
installer = Installer.new(resolver)
installer.install!
@pod = installer.pods.find { |pod| pod.top_specification == spec }
config.silent
end
# Performs platform specific analysis.
# It requires to download the source at each iteration
#
# @note Treat xcodebuild warnings as notes because the spec maintainer
# might not be the author of the library
#
def build_pod
if `which xcodebuild`.strip.empty?
UI.warn "Skipping compilation with `xcodebuild' because it can't be found.\n".yellow
else
UI.message "\nBuilding with xcodebuild.\n".yellow if config.verbose? do
messages = []
output = Dir.chdir(config.project_pods_root) { `xcodebuild clean build 2>&1` }
clean_output = parse_xcodebuild_output(output)
messages += clean_output
puts(output) if config.verbose?
messages.each { |msg| ( msg.include?('error: ') ? @platform_errors[@platform] : @platform_notes[@platform] ) << msg }
end
end
end
# It checks that every file pattern specified in a spec yields
# at least one file. It requires the pods to be already present
# in the current working directory under Pods/spec.name.
#
# @return [Array<String>]
#
def check_file_patterns
error "The sources did not match any file" if !spec.source_files.empty? && @pod.source_files.empty?
error "The resources did not match any file" if !spec.resources.empty? && @pod.resource_files.empty?
error "The preserve_paths did not match any file" if !spec.preserve_paths.empty? && @pod.preserve_files.empty?
error "The exclude_header_search_paths did not match any file" if !spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty?
unless @pod.license_file || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
warning "Unable to find a license file"
end
end
# @errors += (@platform_errors[platform] - @errors).map {|m| "[#{platform}] #{m}"}
#-----------------------------------------------------------------------#
private
# !@group Helpers
# @return [Podfile] a podfile that requires the specification on the
# current platform.
#
# @note The generated podfile takes into account whether the linter is
# in local mode.
#
def podfile_from_spec
name = spec.name
podspec = file.realpath
platform = current_platform
local = local?
podfile = Pod::Podfile.new do
platform(platform.to_sym, platform.deployment_target)
if (local)
pod name, :local => podspec.dirname.to_s
else
pod name, :podspec => podspec.to_s
end
end
podfile
end
# @return [Pathname] the temporary directory used by the linter.
#
def tmp_dir
Pathname.new('/tmp/CocoaPods/Lint')
end
# @return [Pathname] the root of the installed pod.
#
def pod_dir
tmp_dir + 'Pods' + spec.name
end
# Parse the xcode build output to identify the lines which are relevant
# to the linter. It also removes the indentation and the temporary path.
#
# @param [String] output
# the output generated by the xcodebuild tool.
#
# @return [Array<String>] the lines that are relevant to the linter.
#
def parse_xcodebuild_output(output)
lines = output.split("\n")
selected_lines = lines.select do |l|
l.include?('error: ') &&
(l !~ /errors? generated\./) && (l !~ /error: \(null\)/) ||
l.include?('warning: ') && (l !~ /warnings? generated\./) ||
l.include?('note: ') && (l !~ /expanded from macro/)
end
selected_lines.map do |l|
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'') # Remove the unnecessary tmp path
new.gsub!(/^ */,' ') # Remove indentation
"XCODEBUILD > " << new # Mark
end
end
end
end
end
module Pod
class Command
class Linter
include Config::Mixin
# TODO: Add check to ensure that attributes inherited by subspecs are not duplicated ?
attr_accessor :quick, :no_clean, :repo_path
# @return [Bool] Wether the lint should be performed against the root of
# the podspec instead to its original source. Uses the `:local` option
# of the Podfile.
#
attr_accessor :local
alias :local? :local
attr_reader :spec, :file
attr_reader :errors, :warnings, :notes
def initialize(podspec)
@file = podspec
end
def spec_name
name = file.basename('.*').to_s
if @spec
name << " (#{spec.version})"
elsif @repo_path
name << " (#{file.dirname.basename})"
end
name
end
# Takes an array of podspec files and lints them all
#
# It returns true if the spec passed validation
#
def lint
@errors, @warnings, @notes = [], [], []
@platform_errors, @platform_warnings, @platform_notes = {}, {}, {}
if !deprecation_errors.empty?
@errors = deprecation_errors
@errors << "#{spec_name} [!] Fatal errors found skipping the rest of the validation"
else
@spec = Specification.from_file(file)
platforms = spec.available_platforms
if @repo_path
expected_path = "#{@spec.name}/#{@spec.version}/#{@spec.name}.podspec"
path = file.relative_path_from(@repo_path).to_s
@errors << "Incorrect path, the path is `#{file}` and should be `#{expected_path}`" unless path.end_with?(expected_path)
end
platforms.each do |platform|
@platform_errors[platform], @platform_warnings[platform], @platform_notes[platform] = [], [], []
spec.activate_platform(platform)
@platform = platform
puts "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed if config.verbose? && !@quick
# Skip validation if there are errors in the podspec as it would result in a crash
if !podspec_errors.empty?
@platform_errors[platform] += podspec_errors
@platform_notes[platform] << "#{platform.name} [!] Fatal errors found skipping the rest of the validation"
else
@platform_warnings[platform] += podspec_warnings
peform_extensive_analysis unless quick
end
end
# Get common messages
@errors += @platform_errors.values.reduce(:&)
@warnings += @platform_warnings.values.reduce(:&)
@notes += @platform_notes.values.reduce(:&)
platforms.each do |platform|
# Mark platform specific messages
@errors += (@platform_errors[platform] - @errors).map {|m| "[#{platform}] #{m}"}
@warnings += (@platform_warnings[platform] - @warnings).map {|m| "[#{platform}] #{m}"}
@notes += (@platform_notes[platform] - @notes).map {|m| "[#{platform}] #{m}"}
end
end
end
def result_type
return :error unless errors.empty?
return :warning unless warnings.empty?
return :note unless notes.empty?
:success
end
# Performs platform specific analysis.
# It requires to download the source at each iteration
#
def peform_extensive_analysis
set_up_lint_environment
install_pod
if `which xcodebuild`.strip.empty?
puts "Skipping compilation with `xcodebuild' because it can't be found.\n".yellow if config.verbose?
else
puts "\nBuilding with xcodebuild.\n".yellow if config.verbose?
# treat xcodebuild warnings as notes because the spec maintainer might not be the author of the library
xcodebuild_output.each { |msg| ( msg.include?('error: ') ? @platform_errors[@platform] : @platform_notes[@platform] ) << msg }
end
@platform_errors[@platform] += file_patterns_errors
@platform_warnings[@platform] += file_patterns_warnings
tear_down_lint_environment
end
def install_pod
podfile = podfile_from_spec
config.verbose
config.skip_repo_update = true
sandbox = Sandbox.new(config.project_pods_root)
installer = Installer.new(sandbox, podfile)
installer.install!
@pod = installer.local_pods.find { |pod| pod.top_specification == spec }
config.silent
end
def podfile_from_spec
name = spec.name
podspec = file.realpath
platform = @platform
local = local?
podfile = Pod::Podfile.new do
platform(platform.to_sym, platform.deployment_target)
if (local)
pod name, :local => podspec.dirname.to_s
else
pod name, :podspec => podspec.to_s
end
end
podfile
end
def set_up_lint_environment
tmp_dir.rmtree if tmp_dir.exist?
tmp_dir.mkpath
@original_config = Config.instance.clone
config.project_root = tmp_dir
config.project_pods_root = tmp_dir + 'Pods'
config.silent = !config.verbose
config.integrate_targets = false
config.generate_docs = false
end
def tear_down_lint_environment
tmp_dir.rmtree unless no_clean
Config.instance = @original_config
end
def tmp_dir
Pathname.new('/tmp/CocoaPods/Lint')
end
def pod_dir
tmp_dir + 'Pods' + spec.name
end
# It reads a podspec file and checks for strings corresponding
# to features that are or will be deprecated
#
# @return [Array<String>]
#
def deprecation_errors
text = @file.read
deprecations = []
deprecations << "`config.ios?' and `config.osx?' are deprecated" if text. =~ /config\..?os.?/
deprecations << "clean_paths are deprecated and ignored (use preserve_paths)" if text. =~ /clean_paths/
deprecations
end
# @return [Array<String>] List of the fatal defects detected in a podspec
def podspec_errors
messages = []
messages << "The name of the spec should match the name of the file" unless names_match?
messages << "Unrecognized platfrom" unless platform_valid?
messages << "Missing name" unless spec.name
messages << "Missing version" unless spec.version
messages << "Missing summary" if !spec.summary || spec.summary.empty?
messages << "Missing homepage" unless spec.homepage
messages << "Missing author(s)" unless spec.authors
messages << "Missing or invalid source: #{spec.source}" unless source_valid?
messages << "The summary should be short use `description` (max 140 characters)." if spec.summary && spec.summary.length > 140
# attributes with multiplatform values
return messages unless platform_valid?
messages << "The spec appears to be empty (no source files, resources, or preserve paths)" if spec.source_files.empty? && spec.subspecs.empty? && spec.resources.empty? && spec.preserve_paths.empty?
messages += paths_starting_with_a_slash_errors
messages += deprecation_errors
messages
end
def names_match?
return true unless spec.name
root_name = spec.name.match(/[^\/]*/)[0]
file.basename.to_s == root_name + '.podspec'
end
def platform_valid?
!spec.platform || [:ios, :osx].include?(spec.platform.name)
end
def source_valid?
spec.source && !(spec.source =~ /http:\/\/EXAMPLE/)
end
def paths_starting_with_a_slash_errors
messages = []
%w[source_files public_header_files resources clean_paths].each do |accessor|
patterns = spec.send(accessor.to_sym)
# Some values are multiplaform
patterns = patterns.is_a?(Hash) ? patterns.values.flatten(1) : patterns
patterns = patterns.compact # some patterns may be nil (public_header_files, for instance)
patterns.each do |pattern|
# Skip FileList that would otherwise be resolved from the working directory resulting
# in a potentially very expensi operation
next if pattern.is_a?(FileList)
invalid = pattern.is_a?(Array) ? pattern.any? { |path| path.start_with?('/') } : pattern.start_with?('/')
if invalid
messages << "Paths cannot start with a slash (#{accessor})"
break
end
end
end
messages
end
# @return [Array<String>] List of the **non** fatal defects detected in a podspec
def podspec_warnings
license = spec.license || {}
source = spec.source || {}
text = @file.read
messages = []
messages << "Missing license type" unless license[:type]
messages << "Sample license type" if license[:type] && license[:type] =~ /\(example\)/
messages << "Invalid license type" if license[:type] && license[:type] =~ /\n/
messages << "The summary is not meaningful" if spec.summary =~ /A short description of/
messages << "The description is not meaningful" if spec.description && spec.description =~ /An optional longer description of/
messages << "The summary should end with a dot" if spec.summary !~ /.*\./
messages << "The description should end with a dot" if spec.description !~ /.*\./ && spec.description != spec.summary
messages << "The summary should end with a dot" if spec.summary !~ /.*\./
messages << "Comments must be deleted" if text.scan(/^\s*#/).length > 24
messages << "Warnings must not be disabled (`-Wno' compiler flags)" if spec.compiler_flags.split(' ').any? {|flag| flag.start_with?('-Wno') }
if (git_source = source[:git])
messages << "Git sources should specify either a tag or a commit" unless source[:commit] || source[:tag]
if spec.version.to_s != '0.0.1'
messages << "The version of the spec should be part of the git tag (not always applicable)" if source[:tag] && !source[:tag].include?(spec.version.to_s)
messages << "Git sources without tag should be marked as 0.0.1 (not always applicable)" if !source[:tag]
end
if git_source.include?('github.com')
messages << "Github repositories should end in `.git'" unless git_source.end_with?('.git')
messages << "Github repositories should use `https' link" unless git_source.start_with?('https://github.com') || git_source.start_with?('git://gist.github.com')
end
end
messages
end
# It creates a podfile in memory and builds a library containing
# the pod for all available platfroms with xcodebuild.
#
# @return [Array<String>]
#
def xcodebuild_output
return [] if `which xcodebuild`.strip.empty?
messages = []
output = Dir.chdir(config.project_pods_root) { `xcodebuild clean build 2>&1` }
clean_output = process_xcode_build_output(output)
messages += clean_output
puts(output) if config.verbose?
messages
end
def process_xcode_build_output(output)
output_by_line = output.split("\n")
selected_lines = output_by_line.select do |l|
l.include?('error: ') && (l !~ /errors? generated\./) && (l !~ /error: \(null\)/)\
|| l.include?('warning: ') && (l !~ /warnings? generated\./)\
|| l.include?('note: ') && (l !~ /expanded from macro/)
end
selected_lines.map do |l|
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'') # Remove the unnecessary tmp path
new.gsub!(/^ */,' ') # Remove indentation
"XCODEBUILD > " << new # Mark
end
end
# It checks that every file pattern specified in a spec yields
# at least one file. It requires the pods to be alredy present
# in the current working directory under Pods/spec.name.
#
# @return [Array<String>]
#
def file_patterns_errors
messages = []
messages << "The sources did not match any file" if !spec.source_files.empty? && @pod.source_files.empty?
messages << "The resources did not match any file" if !spec.resources.empty? && @pod.resource_files.empty?
messages << "The preserve_paths did not match any file" if !spec.preserve_paths.empty? && @pod.preserve_files.empty?
messages << "The exclude_header_search_paths did not match any file" if !spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty?
messages
end
def file_patterns_warnings
messages = []
unless @pod.license_file || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
messages << "Unable to find a license file"
end
messages
end
end
end
end
module Pod module Pod
class Command class Command
class List < Command class List < Command
def self.banner self.summary = 'List pods'
%{List all pods: self.description = 'Lists all available pods.'
$ pod list
Lists all available pods.
$ pod list new
Lists the pods introduced in the master repository since the last check.}
end
def self.options def self.options
[[ [[
...@@ -24,51 +15,59 @@ module Pod ...@@ -24,51 +15,59 @@ module Pod
executable :git executable :git
def initialize(argv) def initialize(argv)
@update = argv.option('--update') @update = argv.flag?('update')
@stats = argv.option('--stats') @stats = argv.flag?('stats')
@new = argv.option('new') super
super unless argv.empty?
end end
def list_all def run
update_if_necessary!
sets = Source.all_sets sets = Source.all_sets
sets.each { |set| UI.pod(set, :name) } sets.each { |set| UI.pod(set, :name) }
UI.puts "\n#{sets.count} pods were found" UI.puts "\n#{sets.count} pods were found"
end end
def list_new def update_if_necessary!
days = [1,2,3,5,8] if @update && config.verbose?
dates, groups = {}, {} UI.section("\nUpdating Spec Repositories\n".yellow) do
days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d} Repo.new(ARGV.new(["update"])).run
sets = Source.all_sets end
creation_dates = Pod::Specification::Statistics.instance.creation_dates(sets) end
end
class New < List
self.summary = 'Lists pods introduced in the master spec-repo since the last check'
def run
update_if_necessary!
sets.each do |set| days = [1,2,3,5,8]
set_date = creation_dates[set.name] dates, groups = {}, {}
days.each do |d| days.each {|d| dates[d] = Time.now - 60 * 60 * 24 * d}
if set_date >= dates[d] sets = Source.all_sets
groups[d] = [] unless groups[d] creation_dates = Pod::Specification::Set::Statistics.instance.creation_dates(sets)
groups[d] << set
break sets.each do |set|
set_date = creation_dates[set.name]
days.each do |d|
if set_date >= dates[d]
groups[d] = [] unless groups[d]
groups[d] << set
break
end
end end
end end
end days.reverse.each do |d|
days.reverse.each do |d| sets = groups[d]
sets = groups[d] next unless sets
next unless sets UI.section("\nPods added in the last #{"day".pluralize(d)}".yellow) do
UI.section("\nPods added in the last #{"day".pluralize(d)}".yellow) do sorted = sets.sort_by {|s| creation_dates[s.name]}
sorted = sets.sort_by {|s| creation_dates[s.name]} sorted.each { |set| UI.pod(set, (@stats ? :stats : :name)) }
sorted.each { |set| UI.pod(set, (@stats ? :stats : :name)) } end
end end
end end
end end
def run
UI.section("\nUpdating Spec Repositories\n".yellow) do
Repo.new(ARGV.new(["update"])).run
end if @update && config.verbose?
@new ? list_new : list_all
end
end end
end end
end end
module Pod module Pod
class Command class Command
class Outdated < Command class Outdated < Command
def self.banner self.summary = 'Show outdated project dependencies'
%{Show outdated pods:
$ pod outdated self.description = <<-DESC
Shows the outdated pods in the current Podfile.lock, but only those from
Shows the outdated pods in the current Podfile.lock, but only those from spec repos, not those from local/external sources or `:head' versions.
spec repos, not those from local/external sources or `:head' versions.} DESC
end
def self.options def self.options
[["--no-update", "Skip running `pod repo update` before install"]].concat(super) [["--no-update", "Skip running `pod repo update` before install"]].concat(super)
end end
def initialize(argv) def initialize(argv)
config.skip_repo_update = argv.option('--no-update') config.skip_repo_update = argv.flag?('update', true)
super unless argv.empty? super
end end
def run def run
......
module Pod module Pod
class Command class Command
class Install < Command module Project
def self.banner
%{Installing dependencies of a project:
$ pod install
Downloads all dependencies defined in `Podfile' and creates an Xcode
Pods library project in `./Pods'.
The Xcode project file should be specified in your `Podfile` like this:
xcodeproj 'path/to/XcodeProject'
If no xcodeproj is specified, then a search for an Xcode project will
be made. If more than one Xcode project is found, the command will
raise an error.
This will configure the project to reference the Pods static library,
add a build configuration file, and add a post build script to copy
Pod resources.}
end
def self.options def self.options
[ [
["--no-clean", "Leave SCM dirs like `.git' and `.svn' intact after downloading"], ["--no-clean", "Leave SCM dirs like `.git' and `.svn' intact after downloading"],
...@@ -32,23 +11,61 @@ module Pod ...@@ -32,23 +11,61 @@ module Pod
end end
def initialize(argv) def initialize(argv)
config.clean = !argv.option('--no-clean') config.clean = argv.flag?('clean', true)
config.generate_docs = !argv.option('--no-doc') config.generate_docs = argv.flag?('doc', true)
config.integrate_targets = !argv.option('--no-integrate') config.integrate_targets = argv.flag?('integrate', true)
config.skip_repo_update = argv.option('--no-update') config.skip_repo_update = !argv.flag?('update', true)
super unless argv.empty? super
end end
def run_install_with_update(update) def run_install_with_update(update)
sandbox = Sandbox.new(config.project_pods_root) sandbox = Sandbox.new(config.project_pods_root)
installer = Installer.new(sandbox, config.podfile, config.lockfile) resolver = Resolver.new(config.podfile, config.lockfile, sandbox)
installer.install! resolver.update_mode = update
Installer.new(resolver).install!
end end
end
class Install < Command
include Project
self.summary = 'Install project dependencies'
self.description = <<-DESC
Downloads all dependencies defined in `Podfile' and creates an Xcode
Pods library project in `./Pods'.
The Xcode project file should be specified in your `Podfile` like this:
xcodeproj 'path/to/XcodeProject'
If no xcodeproj is specified, then a search for an Xcode project will
be made. If more than one Xcode project is found, the command will
raise an error.
This will configure the project to reference the Pods static library,
add a build configuration file, and add a post build script to copy
Pod resources.
DESC
def run def run
verify_podfile_exists! verify_podfile_exists!
run_install_with_update(false) run_install_with_update(false)
end end
end end
class Update < Command
include Project
self.summary = 'Update outdated project dependencies'
def run
verify_podfile_exists!
verify_lockfile_exists!
run_install_with_update(true)
end
end
end end
end end
...@@ -4,16 +4,16 @@ require 'active_support/core_ext/string/inflections' ...@@ -4,16 +4,16 @@ require 'active_support/core_ext/string/inflections'
module Pod module Pod
class Command class Command
class Push < Command class Push < Command
def self.banner self.summary = 'Push new specifications to a spec-repo'
%{Pushing new specifications to a spec-repo:
$ pod push REPO [NAME.podspec] self.description = <<-DESC
Validates NAME.podspec or `*.podspec' in the current working dir, creates
a directory and version folder for the pod in the local copy of
REPO (~/.cocoapods/[REPO]), copies the podspec file into the version directory,
and finally it pushes REPO to its remote.
DESC
Validates NAME.podspec or `*.podspec' in the current working dir, creates self.arguments = 'REPO [NAME.podspec]'
a directory and version folder for the pod in the local copy of
REPO (~/.cocoapods/[REPO]), copies the podspec file into the version directory,
and finally it pushes REPO to its remote.}
end
def self.options def self.options
[ ["--allow-warnings", "Allows to push if warnings are not evitable"], [ ["--allow-warnings", "Allows to push if warnings are not evitable"],
...@@ -24,11 +24,16 @@ module Pod ...@@ -24,11 +24,16 @@ module Pod
executable :git executable :git
def initialize(argv) def initialize(argv)
@allow_warnings = argv.option('--allow-warnings') @allow_warnings = argv.flag?('allow-warnings')
@local_only = argv.option('--local-only') @local_only = argv.flag?('local-only')
@repo = argv.shift_argument @repo = argv.shift_argument
@podspec = argv.shift_argument @podspec = argv.shift_argument
super unless argv.empty? && @repo super
end
def validate!
super
help! "A spec-repo name is required." unless @repo
end end
def run def run
...@@ -84,7 +89,7 @@ module Pod ...@@ -84,7 +89,7 @@ module Pod
lint_argv << "--silent" if config.silent lint_argv << "--silent" if config.silent
all_valid = true all_valid = true
podspec_files.each do |podspec| podspec_files.each do |podspec|
Spec.new(ARGV.new(lint_argv + [podspec.to_s])).run Spec.parse(lint_argv + [podspec.to_s]).run
end end
end end
......
...@@ -3,136 +3,154 @@ require 'fileutils' ...@@ -3,136 +3,154 @@ require 'fileutils'
module Pod module Pod
class Command class Command
class Repo < Command class Repo < Command
def self.banner self.abstract_command = true
%{Managing spec-repos:
$ pod repo add NAME URL [BRANCH] # TODO should not show a usage banner!
self.summary = 'Manage spec-repositories'
Clones `URL' in the local spec-repos directory at `~/.cocoapods'. The class Add < Repo
remote can later be referred to by `NAME'. self.summary = 'Add a spec repo.'
$ pod repo update [NAME] self.description = <<-DESC
Clones `URL' in the local spec-repos directory at `~/.cocoapods'. The
remote can later be referred to by `NAME'.
DESC
Updates the local clone of the spec-repo `NAME'. If `NAME' is omitted self.arguments = 'NAME URL [BRANCH]'
this will update all spec-repos in `~/.cocoapods'.
$ pod repo lint [NAME | DIRECTORY] def initialize(argv)
@name, @url, @branch = argv.shift_argument, argv.shift_argument, argv.shift_argument
Lints the spec-repo `NAME'. If a directory is provided it is assumed super
to be the root of a repo. Finally, if NAME is not provided this will end
lint all the spec-repos known to CocoaPods.}
end
def self.options
[["--only-errors", "Lint presents only the errors"]].concat(super)
end
extend Executable def validate!
executable :git super
unless @name && @url
help! "Adding a repo needs a `NAME' and a `URL."
end
end
def initialize(argv) def run
case @action = argv.arguments[0] UI.section("Cloning spec repo `#{@name}' from `#{@url}'#{" (branch `#{@branch}')" if @branch}") do
when 'add' config.repos_dir.mkpath
unless (@name = argv.arguments[1]) && (@url = argv.arguments[2]) Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") }
raise Informative, "#{@action == 'add' ? 'Adding' : 'Updating the remote of'} a repo needs a `name' and a `url'." Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
check_versions(dir)
end end
@branch = argv.arguments[3]
when 'update'
@name = argv.arguments[1]
when 'lint'
@name = argv.arguments[1]
@only_errors = argv.option('--only-errors')
else
super
end end
end end
def dir class Update < Repo
config.repos_dir + @name self.summary = 'Update a spec repo.'
end
def run self.description = <<-DESC
send @action.gsub('-', '_') Updates the local clone of the spec-repo `NAME'. If `NAME' is omitted
end this will update all spec-repos in `~/.cocoapods'.
DESC
self.arguments = '[NAME]'
def add def initialize(argv)
UI.section("Cloning spec repo `#{@name}' from `#{@url}'#{" (branch `#{@branch}')" if @branch}") do @name = argv.shift_argument
config.repos_dir.mkpath super
Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") }
Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
check_versions(dir)
end end
end
def update def run
dirs = @name ? [dir] : config.repos_dir.children.select {|c| c.directory?} dirs = @name ? [dir] : config.repos_dir.children.select {|c| c.directory?}
dirs.each do |dir| dirs.each do |dir|
UI.section "Updating spec repo `#{dir.basename}'" do UI.section "Updating spec repo `#{dir.basename}'" do
Dir.chdir(dir) do Dir.chdir(dir) do
`git rev-parse >/dev/null 2>&1` `git rev-parse >/dev/null 2>&1`
if $?.exitstatus.zero? if $?.exitstatus.zero?
git!("pull") git!("pull")
else else
UI.message "Not a git repository" UI.message "Not a git repository"
end
end end
end end
check_versions(dir)
end end
check_versions(dir)
end end
end end
def lint class Lint < Repo
if @name self.summary = 'Validates all specs in a repo.'
dirs = File.exists?(@name) ? [ Pathname.new(@name) ] : [ dir ]
else self.description = <<-DESC
dirs = config.repos_dir.children.select {|c| c.directory?} Lints the spec-repo `NAME'. If a directory is provided it is assumed
to be the root of a repo. Finally, if `NAME' is not provided this
will lint all the spec-repos known to CocoaPods.
DESC
self.arguments = '[ NAME | DIRECTORY ]'
def self.options
[["--only-errors", "Lint presents only the errors"]].concat(super)
end end
dirs.each do |dir|
check_versions(dir)
UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
podspecs = Pathname.glob( dir + '**/*.podspec')
invalid_count = 0
podspecs.each do |podspec|
linter = Linter.new(podspec)
linter.quick = true
linter.repo_path = dir
linter.lint
case linter.result_type
when :error
invalid_count += 1
color = :red
should_display = true
when :warning
color = :yellow
should_display = !@only_errors
end
if should_display def initialize(argv)
UI.puts " -> ".send(color) << linter.spec_name @name = argv.shift_argument
print_messages('ERROR', linter.errors) @only_errors = argv.flag?('only-errors')
unless @only_errors super
print_messages('WARN', linter.warnings) end
print_messages('NOTE', linter.notes)
def run
if @name
dirs = File.exists?(@name) ? [ Pathname.new(@name) ] : [ dir ]
else
dirs = config.repos_dir.children.select {|c| c.directory?}
end
dirs.each do |dir|
check_versions(dir)
UI.puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
podspecs = Pathname.glob( dir + '**/*.podspec')
invalid_count = 0
podspecs.each do |podspec|
linter = Linter.new(podspec)
linter.quick = true
linter.repo_path = dir
linter.lint
case linter.result_type
when :error
invalid_count += 1
color = :red
should_display = true
when :warning
color = :yellow
should_display = !@only_errors
end
if should_display
UI.puts " -> ".send(color) << linter.spec_name
print_messages('ERROR', linter.errors)
unless @only_errors
print_messages('WARN', linter.warnings)
print_messages('NOTE', linter.notes)
end
UI.puts unless config.silent?
end end
UI.puts unless config.silent?
end end
end UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
if invalid_count == 0 if invalid_count == 0
UI.puts "All the specs passed validation.".green << "\n\n" unless config.silent? UI.puts "All the specs passed validation.".green << "\n\n" unless config.silent?
else else
raise Informative, "#{invalid_count} podspecs failed validation." raise Informative, "#{invalid_count} podspecs failed validation."
end
end end
end end
end end
def print_messages(type, messages) extend Executable
return if config.silent? executable :git
messages.each {|msg| UI.puts " - #{type.ljust(5)} | #{msg}"}
# TODO some of the following methods can probably move to one of the subclasses.
def dir
config.repos_dir + @name
end end
def check_versions(dir) def check_versions(dir)
...@@ -147,6 +165,13 @@ module Pod ...@@ -147,6 +165,13 @@ module Pod
UI.puts "\nCocoapods #{versions['last']} is available.\n".green if has_update(versions) && config.new_version_message? UI.puts "\nCocoapods #{versions['last']} is available.\n".green if has_update(versions) && config.new_version_message?
end end
protected
def print_messages(type, messages)
return if config.silent?
messages.each {|msg| UI.puts " - #{type.ljust(5)} | #{msg}"}
end
def self.compatible?(name) def self.compatible?(name)
dir = Config.instance.repos_dir + name dir = Config.instance.repos_dir + name
versions = versions(dir) versions = versions(dir)
......
module Pod module Pod
class Command class Command
class Search < Command class Search < Command
def self.banner self.summary = 'Search pods'
%{Search pods:
$ pod search [QUERY] self.description = <<-DESC
Searches for pods, ignoring case, whose name matches `QUERY'. If the
`--full' option is specified, this will also search in the summary and
description of the pods.
DESC
Searches for pods, ignoring case, whose name matches `QUERY'. If the self.arguments = '[QUERY]'
`--full' option is specified, this will also search in the summary and
description of the pods.}
end
def self.options def self.options
[[ [[
...@@ -19,15 +19,26 @@ module Pod ...@@ -19,15 +19,26 @@ module Pod
end end
def initialize(argv) def initialize(argv)
@full_text_search = argv.option('--full') @full_text_search = argv.flag?('full')
@stats = argv.option('--stats') @stats = argv.flag?('stats')
@query = argv.shift_argument @query = argv.shift_argument
super unless argv.empty? && @query super
end
def validate!
super
help! "A search query is required." unless @query
end end
def run def run
sets = Source.search_by_name(@query.strip, @full_text_search) sets = Source.search_by_name(@query.strip, @full_text_search)
sets.each { |set| UI.pod(set, (@stats ? :stats : :normal)) } sets.each do |set|
begin
UI.pod(set, (@stats ? :stats : :normal))
rescue DSLError => e
UI.warn "Skipping `#{set.name}` because the podspec contains errors."
end
end
end end
end end
end end
......
module Pod module Pod
class Command class Command
class Setup < Command class Setup < Command
def self.banner self.summary = 'Setup the CocoaPods environment'
%{Setup CocoaPods environment:
$ pod setup self.description = <<-DESC
Creates a directory at `~/.cocoapods' which will hold your spec-repos.
This is where it will create a clone of the public `master' spec-repo from:
Creates a directory at `~/.cocoapods' which will hold your spec-repos. https://github.com/CocoaPods/Specs
This is where it will create a clone of the public `master' spec-repo from:
https://github.com/CocoaPods/Specs If the clone already exists, it will ensure that it is up-to-date.
DESC
If the clone already exists, it will ensure that it is up-to-date.}
end
def self.options def self.options
[["--push", "Use this option to enable push access once granted"]].concat(super) [["--push", "Use this option to enable push access once granted"]].concat(super)
...@@ -22,8 +20,8 @@ module Pod ...@@ -22,8 +20,8 @@ module Pod
executable :git executable :git
def initialize(argv) def initialize(argv)
@push_option = argv.option('--push') @push_option = argv.flag?('push')
super unless argv.empty? super
end end
def dir def dir
...@@ -71,11 +69,11 @@ module Pod ...@@ -71,11 +69,11 @@ module Pod
end end
def add_master_repo def add_master_repo
@command ||= Repo.new(ARGV.new(['add', 'master', url, 'master'])).run @command ||= Repo::Add.parse(['master', url, 'master']).run
end end
def update_master_repo def update_master_repo
Repo.new(ARGV.new(['update', 'master'])).run Repo::Update.run(['master'])
end end
def set_master_repo_branch def set_master_repo_branch
......
...@@ -5,118 +5,128 @@ require 'active_support/core_ext/string/inflections' ...@@ -5,118 +5,128 @@ require 'active_support/core_ext/string/inflections'
module Pod module Pod
class Command class Command
class Spec < Command class Spec < Command
def self.banner self.abstract_command = true
%{Managing PodSpec files:
$ pod spec create [ NAME | https://github.com/USER/REPO ] self.summary = 'Manage pod specs'
Creates a PodSpec, in the current working dir, called `NAME.podspec'. class Create < Spec
If a GitHub url is passed the spec is prepopulated. self.summary = 'Create spec file stub.'
$ pod spec lint [ NAME.podspec | DIRECTORY | http://PATH/NAME.podspec, ... ] self.description = <<-DESC
Creates a PodSpec, in the current working dir, called `NAME.podspec'.
If a GitHub url is passed the spec is prepopulated.
DESC
Validates `NAME.podspec'. If a directory is provided it validates self.arguments = '[ NAME | https://github.com/USER/REPO ]'
the podspec files found, including subfolders. In case
the argument is omitted, it defaults to the current working dir.}
end
def self.options def initialize(argv)
[ ["--quick", "Lint skips checks that would require to download and build the spec"], @name_or_url, @url = argv.shift_argument, argv.shift_argument
["--local", "Lint a podspec against the local files contained in its directory"], super
["--only-errors", "Lint validates even if warnings are present"], end
["--no-clean", "Lint leaves the build directory intact for inspection"] ].concat(super)
end
def initialize(argv) def validate!
@action = argv.shift_argument
if @action == 'create'
@name_or_url = argv.shift_argument
@url = argv.shift_argument
super if @name_or_url.nil?
super unless argv.empty?
elsif @action == 'lint'
@quick = argv.option('--quick')
@local = argv.option('--local')
@only_errors = argv.option('--only-errors')
@no_clean = argv.option('--no-clean')
@podspecs_paths = argv
else
super super
help! "A pod name or repo URL is required." unless @name_or_url
end end
end
def run def run
send @action if repo_id_match = (@url || @name_or_url).match(/github.com\/([^\/\.]*\/[^\/\.]*)\.*/)
end # This is to make sure Faraday doesn't warn the user about the `system_timer` gem missing.
old_warn, $-w = $-w, nil
begin
require 'faraday'
ensure
$-w = old_warn
end
require 'octokit'
def create repo_id = repo_id_match[1]
if repo_id_match = (@url || @name_or_url).match(/github.com\/([^\/\.]*\/[^\/\.]*)\.*/) data = github_data_for_template(repo_id)
# This is to make sure Faraday doesn't warn the user about the `system_timer` gem missing. data[:name] = @name_or_url if @url
old_warn, $-w = $-w, nil UI.puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
begin else
require 'faraday' data = default_data_for_template(@name_or_url)
ensure
$-w = old_warn
end end
require 'octokit' spec = spec_template(data)
(Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
repo_id = repo_id_match[1] UI.puts "\nSpecification created at #{data[:name]}.podspec".green
data = github_data_for_template(repo_id)
data[:name] = @name_or_url if @url
UI.puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
else
data = default_data_for_template(@name_or_url)
end end
spec = spec_template(data)
(Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
UI.puts "\nSpecification created at #{data[:name]}.podspec".green
end end
def lint class Lint < Spec
UI.puts self.summary = 'Validates a spec file.'
invalid_count = 0
podspecs_to_lint.each do |podspec|
linter = Linter.new(podspec)
linter.quick = @quick
linter.local = @local
linter.no_clean = @no_clean
# Show immediatly which pod is being processed.
print " -> #{linter.spec_name}\r" unless config.silent?
$stdout.flush
linter.lint
case linter.result_type
when :error
invalid_count += 1
color = :red
when :warning
invalid_count += 1 unless @only_errors
color = :yellow
else
color = :green
end
# This overwrites the previously printed text self.description = <<-DESC
UI.puts " -> ".send(color) << linter.spec_name unless config.silent? Validates `NAME.podspec'. If a directory is provided it validates
print_messages('ERROR', linter.errors) the podspec files found, including subfolders. In case
print_messages('WARN', linter.warnings) the argument is omitted, it defaults to the current working dir.
print_messages('NOTE', linter.notes) DESC
UI.puts unless config.silent? self.arguments = '[ NAME.podspec | DIRECTORY | http://PATH/NAME.podspec, ... ]'
def self.options
[ ["--quick", "Lint skips checks that would require to download and build the spec"],
["--local", "Lint a podspec against the local files contained in its directory"],
["--only-errors", "Lint validates even if warnings are present"],
["--no-clean", "Lint leaves the build directory intact for inspection"] ].concat(super)
end end
count = podspecs_to_lint.count def initialize(argv)
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n" unless config.silent? @quick = argv.flag?('quick')
if invalid_count == 0 @local = argv.flag?('local')
lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation." @only_errors = argv.flag?('only-errors')
UI.puts lint_passed_message.green << "\n\n" unless config.silent? @no_clean = argv.flag?('clean', false)
else @podspecs_paths = argv.arguments!
raise Informative, count == 1 ? "The spec did not pass validation." : "#{invalid_count} out of #{count} specs failed validation." super
end
def run
UI.puts
invalid_count = 0
podspecs_to_lint.each do |podspec|
linter = Linter.new(podspec)
linter.quick = @quick
linter.local = @local
linter.no_clean = @no_clean
# Show immediatly which pod is being processed.
print " -> #{linter.spec_name}\r" unless config.silent?
$stdout.flush
linter.lint
case linter.result_type
when :error
invalid_count += 1
color = :red
when :warning
invalid_count += 1 unless @only_errors
color = :yellow
else
color = :green
end
# This overwrites the previously printed text
UI.puts " -> ".send(color) << linter.spec_name unless config.silent?
print_messages('ERROR', linter.errors)
print_messages('WARN', linter.warnings)
print_messages('NOTE', linter.notes)
UI.puts unless config.silent?
end
count = podspecs_to_lint.count
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n" unless config.silent?
if invalid_count == 0
lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation."
UI.puts lint_passed_message.green << "\n\n" unless config.silent?
else
raise Informative, count == 1 ? "The spec did not pass validation." : "#{invalid_count} out of #{count} specs failed validation."
end
podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
end end
podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
end end
# TODO some of the following methods can probably move to one of the subclasses.
private private
def print_messages(type, messages) def print_messages(type, messages)
...@@ -224,7 +234,7 @@ Pod::Spec.new do |s| ...@@ -224,7 +234,7 @@ Pod::Spec.new do |s|
# s.description = <<-DESC # s.description = <<-DESC
# An optional longer description of #{data[:name]} # An optional longer description of #{data[:name]}
# #
# * Markdonw format. # * Markdown format.
# * Don't worry about the indent, we strip it! # * Don't worry about the indent, we strip it!
# DESC # DESC
s.homepage = "#{data[:homepage]}" s.homepage = "#{data[:homepage]}"
...@@ -258,7 +268,7 @@ Pod::Spec.new do |s| ...@@ -258,7 +268,7 @@ Pod::Spec.new do |s|
# #
# s.author = '#{data[:author_name]}', 'other author' # s.author = '#{data[:author_name]}', 'other author'
# Specify the location from where the source should be retreived. # Specify the location from where the source should be retrieved.
# #
s.source = { :git => "#{data[:source_url]}", #{data[:ref_type]} => "#{data[:ref]}" } s.source = { :git => "#{data[:source_url]}", #{data[:ref_type]} => "#{data[:ref]}" }
# s.source = { :svn => 'http://EXAMPLE/#{data[:name]}/tags/1.0.0' } # s.source = { :svn => 'http://EXAMPLE/#{data[:name]}/tags/1.0.0' }
...@@ -292,9 +302,9 @@ Pod::Spec.new do |s| ...@@ -292,9 +302,9 @@ Pod::Spec.new do |s|
# made available to the application. If the pattern is a directory then the # made available to the application. If the pattern is a directory then the
# path will automatically have '*.h' appended. # path will automatically have '*.h' appended.
# #
# Also allows the use of the FileList class like `source_files does. # Also allows the use of the FileList class like `source_files' does.
# #
# If you do not explicitely set the list of public header files, # If you do not explicitly set the list of public header files,
# all headers of source_files will be made public. # all headers of source_files will be made public.
# #
# s.public_header_files = 'Classes/**/*.h' # s.public_header_files = 'Classes/**/*.h'
...@@ -302,7 +312,7 @@ Pod::Spec.new do |s| ...@@ -302,7 +312,7 @@ Pod::Spec.new do |s|
# A list of resources included with the Pod. These are copied into the # A list of resources included with the Pod. These are copied into the
# target bundle with a build phase script. # target bundle with a build phase script.
# #
# Also allows the use of the FileList class like `source_files does. # Also allows the use of the FileList class like `source_files' does.
# #
# s.resource = "icon.png" # s.resource = "icon.png"
# s.resources = "Resources/*.png" # s.resources = "Resources/*.png"
...@@ -310,7 +320,7 @@ Pod::Spec.new do |s| ...@@ -310,7 +320,7 @@ Pod::Spec.new do |s|
# A list of paths to preserve after installing the Pod. # A list of paths to preserve after installing the Pod.
# CocoaPods cleans by default any file that is not used. # CocoaPods cleans by default any file that is not used.
# Please don't include documentation, example, and test files. # Please don't include documentation, example, and test files.
# Also allows the use of the FileList class like `source_files does. # Also allows the use of the FileList class like `source_files' does.
# #
# s.preserve_paths = "FilesToSave", "MoreFilesToSave" # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
......
module Pod
class Command
class Update < Install
def self.banner
%{Updating dependencies of a project:
$ pod update
Updates all dependencies.}
end
def self.options
[["--no-update", "Skip running `pod repo update` before install"]].concat(super)
end
def initialize(argv)
config.skip_repo_update = argv.option('--no-update')
super unless argv.empty?
end
def run
verify_podfile_exists!
verify_lockfile_exists!
run_install_with_update(true)
end
end
end
end
...@@ -74,6 +74,12 @@ module Pod ...@@ -74,6 +74,12 @@ module Pod
end end
end end
# @return [Sandbox]
#
def sandbox
@sandbox ||= Sandbox.new(project_pods_root)
end
module Mixin module Mixin
def config def config
Config.instance Config.instance
......
require 'cocoapods/open_uri'
module Pod
class Dependency < Gem::Dependency
attr_reader :head
alias :head? :head
attr_accessor :specification, :external_source
def initialize(*name_and_version_requirements, &block)
if name_and_version_requirements.empty? && block
@inline_podspec = true
@specification = Specification.new(&block)
super(@specification.name, @specification.version)
elsif !name_and_version_requirements.empty? && block.nil?
version = name_and_version_requirements.last
if name_and_version_requirements.last.is_a?(Hash)
@external_source = ExternalSources.from_params(name_and_version_requirements[0].split('/').first, name_and_version_requirements.pop)
elsif version.is_a?(Symbol) && version == :head || version.is_a?(Version) && version.head?
name_and_version_requirements.pop
@head = true
end
super(*name_and_version_requirements)
if head? && !latest_version?
raise Informative, "A `:head' dependency may not specify version requirements."
end
else
raise Informative, "A dependency needs either a name and version requirements, " \
"a source hash, or a block which defines a podspec."
end
end
def latest_version?
versions = @version_requirements.requirements.map(&:last)
versions == [Gem::Version.new('0')]
end
def ==(other)
super && (head? == other.head?) && (@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
# In case this is a dependency for a subspec, e.g. 'RestKit/Networking',
# this returns 'RestKit', which is what the Pod::Source needs to know to
# retrieve the correct Set from disk.
def top_level_spec_name
subspec_dependency? ? @name.split('/').first : @name
end
# Returns a copy of the dependency, but with the name of the top level
# spec. This is used by Pod::Specification::Set to merge dependencies on
# the complete set, irrespective of what spec in the set wil be used.
def to_top_level_spec_dependency
dep = dup
dep.name = top_level_spec_name
dep
end
def to_s
version = ''
if external?
version << @external_source.description
elsif inline?
version << 'defined in Podfile'
elsif head?
version << 'HEAD'
elsif @version_requirements != Gem::Requirement.default
version << @version_requirements.to_s
end
result = @name.dup
result << " (#{version})" unless version.empty?
result
end
def specification_from_sandbox(sandbox, platform)
@external_source.specification_from_sandbox(sandbox, platform)
end
def match_version?(version)
match?(name, version) && (version.head? == head?)
end
# Taken from RubyGems 1.3.7
unless public_method_defined?(:match?)
def match?(spec_name, spec_version)
pattern = name
if Regexp === pattern
return false unless pattern =~ spec_name
else
return false unless pattern == spec_name
end
return true if requirement.to_s == ">= 0"
requirement.satisfied_by? Gem::Version.new(spec_version)
end
end
# Taken from a newer version of RubyGems
unless public_method_defined?(:merge)
def merge other
unless name == other.name then
raise ArgumentError,
"#{self} and #{other} have different names"
end
default = Gem::Requirement.default
self_req = self.requirement
other_req = other.requirement
return self.class.new name, self_req if other_req == default
return self.class.new name, other_req if self_req == default
self.class.new name, self_req.as_list.concat(other_req.as_list)
end
end
module ExternalSources
def self.from_params(name, params)
return unless name && params
if params.key?(:git)
GitSource.new(name, params)
elsif params.key?(:podspec)
PodspecSource.new(name, params)
elsif params.key?(:local)
LocalSource.new(name, params)
else
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)
specification_from_local(sandbox, platform) || specification_from_external(sandbox, platform)
end
def specification_from_local(sandbox, platform)
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.top_specification
end
end
def specification_from_external(sandbox, platform)
podspec = copy_external_source_into_sandbox(sandbox, platform)
spec = specification_from_local(sandbox, platform)
raise Informative, "No podspec found for `#{name}' in #{description}" unless spec
spec
end
# Can store from a pathname or a string
#
def store_podspec(sandbox, podspec)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath
if podspec.is_a?(String)
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.include?('Spec.new')
output_path.open('w') { |f| f.puts(podspec) }
else
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.exist?
FileUtils.copy(podspec, output_path)
end
end
def ==(other)
return if other.nil?
name == other.name && params == other.params
end
end
class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, platform)
UI.info("->".green + " Pre-downloading: '#{name}'") do
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.downloaded = true
end
end
end
def description
"from `#{@params[:git]}'".tap do |description|
description << ", commit `#{@params[:commit]}'" if @params[:commit]
description << ", branch `#{@params[:branch]}'" if @params[:branch]
description << ", tag `#{@params[:tag]}'" if @params[:tag]
end
end
end
# can be http, file, etc
class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, _)
UI.info("->".green + " Fetching podspec for `#{name}' from: #{@params[:podspec]}") do
path = @params[:podspec]
path = Pathname.new(path).expand_path if path.start_with?("~")
open(path) { |io| store_podspec(sandbox, io.read) }
end
end
def description
"from `#{@params[:podspec]}'"
end
end
class LocalSource < AbstractExternalSource
def pod_spec_path
path = Pathname.new(@params[:local]).expand_path
path += "#{name}.podspec"# unless path.to_s.include?("#{name}.podspec")
raise Informative, "No podspec found for `#{name}' in `#{@params[:local]}'" unless path.exist?
path
end
def copy_external_source_into_sandbox(sandbox, _)
store_podspec(sandbox, pod_spec_path)
end
def specification_from_local(sandbox, platform)
specification_from_external(sandbox, platform)
end
def specification_from_external(sandbox, platform)
copy_external_source_into_sandbox(sandbox, platform)
spec = Specification.from_file(pod_spec_path)
spec.source = @params
spec
end
def description
"from `#{@params[:local]}'"
end
end
end
end
end
module Pod
module ExternalSources
def self.from_dependency(dependency)
name = dependency.root_name
params = dependency.external_source
if params.key?(:git)
GitSource.new(name, params)
elsif params.key?(:podspec)
PodspecSource.new(name, params)
elsif params.key?(:local)
LocalSource.new(name, params)
else
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)
specification_from_local(sandbox, platform) || specification_from_external(sandbox, platform)
end
def specification_from_local(sandbox, platform)
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.top_specification
end
end
def specification_from_external(sandbox, platform)
podspec = copy_external_source_into_sandbox(sandbox, platform)
spec = specification_from_local(sandbox, platform)
raise Informative, "No podspec found for `#{name}' in #{description}" unless spec
spec
end
# Can store from a pathname or a string
#
def store_podspec(sandbox, podspec)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath
if podspec.is_a?(String)
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.include?('Spec.new')
output_path.open('w') { |f| f.puts(podspec) }
else
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.exist?
FileUtils.copy(podspec, output_path)
end
end
def ==(other)
return if other.nil?
name == other.name && params == other.params
end
end
class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, platform)
UI.info("->".green + " Pre-downloading: '#{name}'") do
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.downloaded = true
end
end
end
def description
"from `#{@params[:git]}'".tap do |description|
description << ", commit `#{@params[:commit]}'" if @params[:commit]
description << ", branch `#{@params[:branch]}'" if @params[:branch]
description << ", tag `#{@params[:tag]}'" if @params[:tag]
end
end
end
# can be http, file, etc
class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, _)
UI.info("->".green + " Fetching podspec for `#{name}' from: #{@params[:podspec]}") do
path = @params[:podspec]
path = Pathname.new(path).expand_path if path.start_with?("~")
open(path) { |io| store_podspec(sandbox, io.read) }
end
end
def description
"from `#{@params[:podspec]}'"
end
end
class LocalSource < AbstractExternalSource
def pod_spec_path
path = Pathname.new(@params[:local]).expand_path
path += "#{name}.podspec"# unless path.to_s.include?("#{name}.podspec")
raise Informative, "No podspec found for `#{name}' in `#{@params[:local]}'" unless path.exist?
path
end
def copy_external_source_into_sandbox(sandbox, _)
store_podspec(sandbox, pod_spec_path)
end
def specification_from_local(sandbox, platform)
specification_from_external(sandbox, platform)
end
def specification_from_external(sandbox, platform)
copy_external_source_into_sandbox(sandbox, platform)
spec = Specification.from_file(pod_spec_path)
spec.source = @params
spec
end
def description
"from `#{@params[:local]}'"
end
end
end
end
...@@ -15,6 +15,10 @@ install_resource() ...@@ -15,6 +15,10 @@ install_resource()
echo "ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" echo "ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
ibtool --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" ibtool --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
;; ;;
*.framework)
echo "rsync -rp ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -rp "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*) *)
echo "cp -R ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" echo "cp -R ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
cp -R "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" cp -R "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
...@@ -26,7 +30,7 @@ EOS ...@@ -26,7 +30,7 @@ EOS
attr_reader :resources attr_reader :resources
# A list of files relative to the project pods root. # A list of files relative to the project pods root.
def initialize(resources) def initialize(resources = [])
@resources = resources @resources = resources
end end
......
module Pod
module Generator
# Generates a prefix header file for a Pods library. The prefix header is
# generated according to the platform of the target and the pods.
#
# According to the platform the prefix header imports `UIKit/UIKit.h` or
# `Cocoa/Cocoa.h`.
#
class PrefixHeader
# @return [Platform] the platform for which the prefix header will be
# generated.
#
attr_reader :platform
# @return [Array<LocalPod>] the LocalPod for the target for which the
# prefix header needs to be generated.
#
attr_reader :pods
# @param [Platform] platform @see platform
#
# @param [Array<LocalPod>] @see pods
#
def initialize(platform, pods)
@platform = platform
@pods = pods
end
#--------------------------------------#
# Generates the contents of the prefix header according to the platform
# and the pods.
#
# @note If the platform is iOS an import call to `UIKit/UIKit.h` is
# added to the top of the prefix header. For OS X `Cocoa/Cocoa.h`
# is imported.
#
# @return [String]
#
# TODO: Subspecs can specify prefix header information too.
#
def generate
result = "#ifdef __OBJC__\n"
result << "#import #{platform == :ios ? '<UIKit/UIKit.h>' : '<Cocoa/Cocoa.h>'}\n"
result << "#endif\n"
pods.each do |pod|
result << "\n"
if prefix_header_contents = pod.top_specification.prefix_header_contents
result << prefix_header_contents
result << "\n"
elsif prefix_header = pod.prefix_header_file
result << prefix_header.read
end
end
result
end
# Generates and saves the prefix header to the given path.
#
# @param [Pathname] path
# the path where the prefix header should be stored.
#
# @return [void]
#
def save_as(path)
path.open('w') { |header| header.write(generate) }
end
end
end
end
module Pod
module Generator
# Generates an xcconfig file for each target of the Pods project. The
# configuration file should be used by the user target as well.
#
class XCConfig
# @return [Sandbox] the sandbox where the Pods project is installed.
#
attr_reader :sandbox
# @return [Array<LocalPod>] the list of LocalPods for the library.
#
attr_reader :pods
# @return [String] the relative path of the Pods root respect the user
# project that should be integrated by this library.
#
attr_reader :relative_pods_root
# @param [Platform] platform @see platform
#
# @param [Array<LocalPod>] @see pods
#
def initialize(sandbox, pods, relative_pods_root)
@sandbox = sandbox
@pods = pods
@relative_pods_root = relative_pods_root
end
# @return [Bool] whether the Podfile specifies to add the `-fobjc-arc`
# flag for compatibility.
#
attr_accessor :set_arc_compatibility_flag
#-----------------------------------------------------------------------#
# Generates the xcconfig for the library.
#
# @return [Xcodeproj::Config]
#
def generate
ld_flags = '-ObjC'
if set_arc_compatibility_flag && pods.any? { |pod| pod.requires_arc? }
ld_flags << ' -fobjc-arc'
end
@xcconfig = Xcodeproj::Config.new({
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}',
'PODS_ROOT' => relative_pods_root,
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(sandbox.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}'
})
pods.each { |pod| @xcconfig.merge!(pod.xcconfig) }
@xcconfig
end
# @return [Xcodeproj::Config] The generated xcconfig.
#
attr_reader :xcconfig
# @return [Hash] The settings of the xcconfig that the Pods project
# needs to override.
#
def self.pods_project_settings
{ 'PODS_ROOT' => '${SRCROOT}',
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_BUILD_HEADERS_SEARCH_PATHS}' }
end
# Generates and saves the xcconfig to the given path.
#
# @param [Pathname] path
# the path where the prefix header should be stored.
#
# @return [void]
#
def save_as(path)
path.open('w') { |file| file.write(generate) }
end
#-----------------------------------------------------------------------#
# @!group Private helpers.
private
# @return [String] the default linker flags. `-ObjC` is always included
# while `-fobjc-arc` is included only if requested in the
# Podfile.
#
def default_ld_flags
flags = %w[ -ObjC ]
requires_arc = pods.any? { |pod| pod.requires_arc? }
if requires_arc && set_arc_compatibility_flag
flags << '-fobjc-arc'
end
flags.join(" ")
end
# Converts an array of strings to a single string where the each string
# is surrounded by double quotes and separated by a space. Used to
# represent strings in a xcconfig file.
#
# @param [Array<String>] strings
# a list of strings.
#
# @return [String] the resulting string.
#
def quote(strings)
strings.map { |s| %W|"#{s}"| }.join(" ")
end
end
end
end
...@@ -120,6 +120,7 @@ module Pod ...@@ -120,6 +120,7 @@ module Pod
integrate_user_project integrate_user_project
end end
# <<<<<<< HEAD
# Performs only the computation parts of an installation. # Performs only the computation parts of an installation.
# #
# It is used by the `outdated` subcommand. # It is used by the `outdated` subcommand.
...@@ -384,6 +385,24 @@ module Pod ...@@ -384,6 +385,24 @@ module Pod
end end
@local_pods = local_pods_by_target.values.flatten.uniq.sort_by { |pod| pod.name.downcase } @local_pods = local_pods_by_target.values.flatten.uniq.sort_by { |pod| pod.name.downcase }
# =======
# def project
# return @project if @project
# @project = Pod::Project.new(sandbox)
# # TODO
# # @project.user_build_configurations = @podfile.user_build_configurations
# pods.each { |p| p.add_file_references_to_project(@project) }
# pods.each { |p| p.link_headers }
# @project.add_podfile(config.project_podfile)
# @project
# end
#
# def target_installers
# @target_installers ||= @podfile.target_definitions.values.map do |definition|
# pods_for_target = pods_by_target[definition]
# TargetInstaller.new(project, definition, pods_for_target) unless definition.empty?
# end.compact
# >>>>>>> core-extraction
end end
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
...@@ -575,6 +594,11 @@ module Pod ...@@ -575,6 +594,11 @@ module Pod
local_pods.each { |p| p.add_file_references_to_project(pods_project) } local_pods.each { |p| p.add_file_references_to_project(pods_project) }
local_pods.each { |p| p.link_headers } local_pods.each { |p| p.link_headers }
end end
# <<<<<<< HEAD
# =======
#
# UserProjectIntegrator.new(@podfile).integrate! if config.integrate_targets?
# >>>>>>> core-extraction
end end
def run_pre_install_hooks def run_pre_install_hooks
......
module Pod module Pod
class Installer class Installer
# This class is reponsible of creating and configuring the static library # This class is responsible of creating and configuring the static library
# target in Pods project. Every target is generated from a target # target in Pods project. Every target is generated from a target
# definition of the Podfile. # definition of the Podfile.
# #
class TargetInstaller class TargetInstaller
include Config::Mixin
# @return [Podfile]
#
# TODO: is really needed to pass the podfile?
#
attr_reader :podfile
# @return [Project] The Pods project. # @return [Project] The Pods project.
# #
attr_reader :project attr_reader :project
# @return [TargetDefinition] The target definition whoose target needs to # @return [TargetDefinition] The target definition whose target needs to
# be generated. # be generated.
# #
attr_reader :target_definition attr_reader :target_definition
def initialize(podfile, project, target_definition) # @param [Array<LocalPod>] pods the pods are required by the target
@podfile = podfile # definition of this installer.
@project = project #
attr_reader :pods
# @param [Project] project @see project
# @param [TargetDefinition] target_definition @see target_definition
# @param [Array<LocalPod>] pods @see pods
#
def initialize(project, target_definition, pods)
@project = project
@target_definition = target_definition @target_definition = target_definition
@pods = pods
end end
# @return [void] Creates the target in the Pods project and its support # Creates the target in the Pods project and its support files.
# files.
# #
# @param [Array<LocalPod>] pods The pods are required by the target # @return [void]
# definition of this installer.
# #
# @param [Sandbox] sandbox The sanbox where the support files def install!
# should be generated. add_target
add_build_files_to_target
add_file_reference_for_support_files
configure_target
create_xcconfig_file
create_prefix_header
create_bridge_support_file
create_copy_resources_script
end
# TODO: This has to be removed, but this means the specs have to be
# updated if they need a reference to the prefix header.
# #
def install!(pods, sandbox) def prefix_header_filename
self.requires_arc = pods.any? { |pod| pod.requires_arc? } library.prefix_header_name
end
@target = @project.add_pod_target(@target_definition.label, @target_definition.platform) #-----------------------------------------------------------------------#
source_file_descriptions = [] # @!group Installation steps
pods.each { |p| p.add_build_files_to_target(@target) }
support_files_group = @project.support_files_group.new_group(@target_definition.label) private
target_support_files.each { |path| support_files_group.new_file(path) }
xcconfig_file = support_files_group.files.find { |f| f.path == @target_definition.xcconfig_name } # Adds the library for the {#target_definition} to the Pods
configure_build_configurations(xcconfig_file, sandbox) # project.
create_files(pods, sandbox) #
# @return [void]
#
def add_target
@library = @project.add_pod_library(target_definition)
@target = @library.target
end end
# @return [PBXNativeTarget] The target generated by the installation # Adds the build files of the pods to the target.
# process.
# #
attr_reader :target # @return [void]
#
def add_build_files_to_target
pods.each { |p| p.add_build_files_to_target(target) }
end
# Adds the file references for the support files that are generated by
# the installation process to the Pods project.
#
# @return [void]
#
def add_file_reference_for_support_files
g = project.support_files_group.new_group(target_definition.label)
g.new_file(library.copy_resources_script_name)
g.new_file(library.prefix_header_name)
g.new_file(library.xcconfig_name).tap { |f| @xcconfig_file_ref = f }
end
# @return [Boold] Wether the any of the pods requires arc. # Configures the build settings of the target.
#
# @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
# #
# TODO: This should not be an attribute reader. # @return [void]
# #
attr_accessor :requires_arc def configure_target
set = {
'GCC_PREFIX_HEADER' => library.prefix_header_name
}
if @target_definition.inhibit_all_warnings?
set['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end
attr_reader :xcconfig Generator::XCConfig.pods_project_settings.each do |key, value|
set[key] = value
end
# In a workspace this is where the static library headers should be found. @target.build_configurations.each do |c|
# c.base_configuration_reference = xcconfig_file_ref
def generate_xcconfig(pods, sandbox) c.build_settings.merge!(set)
xcconfig = Xcodeproj::Config.new({ end
'ALWAYS_SEARCH_USER_PATHS' => 'YES', # needed to make EmbedReader build
'OTHER_LDFLAGS' => default_ld_flags,
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}',
# CocoaPods global keys
'PODS_ROOT' => @target_definition.relative_pods_root,
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quoted(sandbox.build_headers.search_paths).join(" "),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quoted(sandbox.public_headers.search_paths).join(" "),
# Pods project specific keys
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}'
})
pods.each { |pod| xcconfig.merge!(pod.xcconfig) }
@xcconfig = xcconfig
end end
# Generates the contents of the xcconfig file and saves it to disk.
# #
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
# libraries like `EmbedReader`.
# #
def copy_resources_script_for(pods) # @return [void]
@copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map { |p| p.relative_resource_files }.flatten) #
end def create_xcconfig_file
UI.message "- Generating xcconfig file at #{UI.path(library.xcconfig_path)}" do
def bridge_support_generator_for(pods, sandbox) gen = Generator::XCConfig.new(sandbox, pods, library.relative_pods_root)
Generator::BridgeSupport.new(pods.map do |pod| gen.set_arc_compatibility_flag = target_definition.podfile.set_arc_compatibility_flag?
pod.relative_header_files.map { |header| sandbox.root + header } gen.save_as(library.xcconfig_path)
end.flatten) library.xcconfig = gen.xcconfig
end
end end
# TODO This has to be removed, but this means the specs have to be updated if they need a reference to the prefix header. # Creates a prefix header file which imports `UIKit` or `Cocoa`. This
def prefix_header_filename # file also include any prefix header content reported by the
@target_definition.prefix_header_name # specification of the pods.
#
# @return [void]
#
def create_prefix_header
UI.message "- Generating prefix header at #{UI.path(library.prefix_header_path)}" do
gen = Generator::PrefixHeader.new(target_definition.platform, pods)
gen.save_as(library.prefix_header_path)
end
end end
# TODO move out to Generator::PrefixHeader # Generates the bridge support metadata if requested by the {Podfile}.
def save_prefix_header_as(pathname, pods) #
pathname.open('w') do |header| # @note the bridge support metadata is added to the resources of the
header.puts "#ifdef __OBJC__" # library because it is needed for environments interpreted at
header.puts "#import #{@target_definition.platform == :ios ? '<UIKit/UIKit.h>' : '<Cocoa/Cocoa.h>'}" # runtime.
header.puts "#endif" #
pods.each do |pod| # @return [void]
if prefix_header_contents = pod.top_specification.prefix_header_contents #
header.puts def create_bridge_support_file
header.puts prefix_header_contents if target_definition.podfile.generate_bridge_support?
elsif prefix_header = pod.prefix_header_file UI.message "- Generating BridgeSupport metadata at #{UI.path library.bridge_support_path}" do
header.puts generator = Generator::BridgeSupport.new(pods.map do |pod|
header.puts prefix_header.read pod.relative_header_files.map { |header| sandbox.root + header }
end end.flatten)
generator.save_as(library.bridge_support_path)
copy_resources_script.resources << library.bridge_support_name
end end
end end
end end
def target_support_files # Creates a script that copies the resources to the bundle of the client
[:copy_resources_script_name, :prefix_header_name, :xcconfig_name].map { |file| @target_definition.send(file) } # target.
end #
# TODO: This should be replaced by an Xcode copy resources build phase.
def configure_build_configurations(xcconfig_file, sandbox) #
@target.build_configurations.each do |config| # @return [void]
config.base_configuration_reference = xcconfig_file #
config.build_settings['OTHER_LDFLAGS'] = '' def create_copy_resources_script
config.build_settings['GCC_PREFIX_HEADER'] = @target_definition.prefix_header_name UI.message "- Generating copy resources script at #{UI.path(library.copy_resources_script_path)}" do
config.build_settings['PODS_ROOT'] = '${SRCROOT}' copy_resources_script.resources << pods.map { |p| p.relative_resource_files }.flatten
config.build_settings['PODS_HEADERS_SEARCH_PATHS'] = '${PODS_BUILD_HEADERS_SEARCH_PATHS}' copy_resources_script.save_as(library.copy_resources_script_path)
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = @target_definition.inhibit_all_warnings? ? 'YES' : 'NO'
end end
end end
#-----------------------------------------------------------------------#
# @!group Installation products.
public
# @return [Library] the library for the target definition.
# #
# @note Generated by the {#add_target} step.
# #
def create_files(pods, sandbox) attr_reader :library
bridge_support_metadata_path = sandbox.root + @target_definition.bridge_support_name
UI.message "- Generating BridgeSupport metadata file at #{UI.path bridge_support_metadata_path}" do
bridge_support_generator_for(pods, sandbox).save_as(bridge_support_metadata_path)
copy_resources_script_for(pods).resources << @target_definition.bridge_support_name
end if @podfile.generate_bridge_support?
UI.message "- Generating xcconfig file at #{UI.path(sandbox.root + @target_definition.xcconfig_name)}" do # @return [PBXNativeTarget] the target generated by the installation
generate_xcconfig(pods, sandbox) # process.
xcconfig.save_as(sandbox.root + @target_definition.xcconfig_name) #
@target_definition.xcconfig = xcconfig # @note Generated by the {#add_target} step.
end #
attr_reader :target
UI.message "- Generating prefix header at #{UI.path(sandbox.root + @target_definition.prefix_header_name)}" do # @return [PBXFileReference] the file reference to the xcconfig file of
save_prefix_header_as(sandbox.root + @target_definition.prefix_header_name, pods) # the target.
end #
# @note Generated by the {#add_file_reference_for_support_files} step.
#
attr_reader :xcconfig_file_ref
UI.message "- Generating copy resources script at #{UI.path(sandbox.root + @target_definition.copy_resources_script_name)}" do #-----------------------------------------------------------------------#
copy_resources_script_for(pods).save_as(sandbox.root + @target_definition.copy_resources_script_name)
end # @!group Private helpers.
end
private private
def quoted(strings) # @return [Sandbox] sandbox the sandbox where the support files should
strings.map { |s| "\"#{s}\"" } # be generated.
#
def sandbox
project.sandbox
end end
def default_ld_flags # Creates and caches the copy resource script.
flags = %w{-ObjC} #
flags << '-fobjc-arc' if @podfile.set_arc_compatibility_flag? && self.requires_arc # @return [CopyResourcesScript]
flags.join(" ") #
def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new
end end
end end
end end
......
...@@ -6,67 +6,156 @@ require 'active_support/core_ext/array/conversions' ...@@ -6,67 +6,156 @@ require 'active_support/core_ext/array/conversions'
module Pod module Pod
class Installer class Installer
# The {UserProjectIntegrator} integrates the libraries generated by
# TargetDefinitions of the {Podfile} with their correspondent user
# projects.
#
class UserProjectIntegrator class UserProjectIntegrator
include Pod::Config::Mixin
def initialize(podfile) # @return [Podfile] the podfile that should be integrated with the user
@podfile = podfile # projects.
end #
attr_reader :podfile
def integrate! # @return [Project] the pods project which contains the libraries to
create_workspace! # integrate.
#
attr_reader :pods_project
# Only need to write out the user's project if any of the target # @return [Pathname] the path of the installation.
# integrators actually did some work. #
target_integrators.map(&:integrate!) # TODO: This is only used to compute the workspace path in case that it
end # should be inferred by the project. If the workspace should be in
# the same dir of the project, this could be removed.
#
attr_reader :project_root
def workspace_path # @param [Podfile] podfile @see #podfile.
@podfile.workspace || raise(Informative, "Could not automatically select an Xcode workspace. " \ #
"Specify one in your Podfile.") def initialize(podfile, pods_project, project_root)
@podfile = podfile
@pods_project = pods_project
@project_root = project_root
end end
def pods_project_path # Integrates the user projects associated with the {TargetDefinitions}
config.project_root + "Pods/Pods.xcodeproj" # with the Pods project and its products.
#
# @return [void]
#
def integrate!
create_workspace
integrate_user_targets
warn_about_empty_podfile
end end
def target_integrators #--------------------------------------#
@target_integrators ||= @podfile.target_definitions.values.map do |definition|
TargetIntegrator.new(definition) unless definition.empty?
end.compact
end
def user_project_paths # @!group Integration steps
@podfile.target_definitions.values.map do |td|
next if td.empty?
td.user_project.path #|| raise(Informative, "Could not resolve the Xcode project in which the " \
# "`#{td.name}' target should be integrated.")
end.compact
end
def create_workspace! private
# Creates and saved the workspace containing the Pods project and the
# user projects.
#
# @return [void]
#
def create_workspace
workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path) workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
[pods_project_path, *user_project_paths].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 path = project_path.relative_path_from(workspace_path.dirname).to_s
workspace << project_path unless workspace.include?(project_path) workspace << path unless workspace.include?(path)
end end
unless workspace_path.exist? || config.silent? unless workspace_path.exist?
UI.notice "From now on use `#{workspace_path.basename}'." UI.notice "From now on use `#{workspace_path.basename}'."
end end
workspace.save_as(workspace_path) workspace.save_as(workspace_path)
end end
class TargetIntegrator # Integrates the targets of the user projects with the libraries
include Pod::Config::Mixin # generated from the {Podfile}.
#
# @note {TargetDefinition} without dependencies are skipped prevent
# creating empty libraries for targets definitions which are only
# wrappers for others.
#
# @return [void]
#
def integrate_user_targets
pods_project.libraries.each do |lib|
next if lib.target_definition.empty?
TargetIntegrator.new(lib).integrate!
end
end
# Warns the user if the podfile is empty.
#
# @note The workspace is created in any case and all the user projects
# are added to it, however the projects are not integrated as
# there is no way to discern between target definitions which are
# empty and target definitions which just serve the purpose to
# wrap other ones. This is not an issue because empty target
# definitions generate empty libraries.
#
# @return [void]
#
def warn_about_empty_podfile
unless podfile.target_definitions.values.any?{ |td| !td.empty? }
UI.warn "[!] The Podfile does not contain any dependency."
end
end
attr_reader :target_definition #--------------------------------------#
def initialize(target_definition) # @!group Helpers.
@target_definition = target_definition
public
# @return [Pathname] the path where the workspace containing the Pods
# project and the user projects should be saved.
#
def workspace_path
if podfile.workspace_path
podfile.workspace_path
elsif user_project_paths.count == 1
project = user_project_paths.first.basename('.xcodeproj')
project_root + "#{project}.xcworkspace"
else
raise Informative, "Could not automatically select an Xcode " \
"workspace. Specify one in your Podfile like so:\n\n" \
" workspace 'path/to/Workspace.xcworkspace'\n"
end end
end
def inspect # @return [Array<Pathname>] the paths of all the user projects referenced
"#<#{self.class} for target `#{@target_definition.label}'>" # by the target definitions.
#
# @note Empty target definitions are ignored.
#
def user_project_paths
pods_project.libraries.map do |lib|
# TODO: remove
next if lib.target_definition.empty?
lib.user_project_path
end.compact.uniq
end
#-----------------------------------------------------------------------#
# This class is responsible for integrating the library generated by a
# {TargetDefinition} with its destination project.
#
class TargetIntegrator
# @return [Library] the library that should be integrated.
#
attr_reader :library
# @param [Library] library @see #target_definition
#
def initialize(library)
@library = library
end end
# Integrates the user project targets. Only the targets that do **not** # Integrates the user project targets. Only the targets that do **not**
...@@ -77,113 +166,153 @@ module Pod ...@@ -77,113 +166,153 @@ module Pod
# #
def integrate! def integrate!
return if targets.empty? return if targets.empty?
UI.section(integration_message) do
UI.section("Integrating `#{@target_definition.lib_name}' into #{'target'.pluralize(targets.size)} " \
"`#{targets.map(&:name).to_sentence}' of Xcode project #{UI.path user_project_path}.") do
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.user_project.path) save_user_project
end end
end end
# @return [Pathname] the path of the user project. # @return [Array<PBXNativeTarget>] the list of targets that the Pods
# lib that need to be integrated.
# #
# @raises If the path doesn't exits. # @note A target is considered integrated if it already references
# #
# @raises If the project is implicit and there are multiple projects. def targets
# @targets ||= library.user_targets.reject do |t|
def user_project_path t.frameworks_build_phase.files.any? do |bf|
if path = @target_definition.user_project.path bf.file_ref.name == library.name
unless path.exist? end
raise Informative, "The Xcode project `#{path}' does not exist." end.reject do |target|
# TODO: check merge for commit 6311a9b5e044a9d403838f1c65894c15d806f3f0
target.frameworks_build_phase.files.any? do |build_file|
file_ref = build_file.file_ref
!file_ref.proxy? && file_ref.display_name == @target_definition.lib_name
end end
path
else
raise Informative, "Could not automatically select an Xcode project.\n" \
"Specify one in your Podfile like so:\n\n" \
" xcodeproj 'path/to/XcodeProject'"
end end
end end
# @return [Xcodeproj::Project] Returns the project of the user.
#
def user_project def user_project
@user_project ||= Xcodeproj::Project.new(user_project_path) library.user_project
end end
# This returns a list of the targets from the user’s project to which # @return [String] a string representation suitable for debugging.
# this Pods static library should be linked. If no explicit target was
# specified, then the first encountered target is assumed.
# #
# In addition this will only return targets that do **not** already def inspect
# have the Pods library in their frameworks build phase. "#<#{self.class} for target `#{target_definition.label}'>"
#
# @return [Array<PBXNativeTarget>] Returns the list of targets that
# the Pods lib should be linked with.
def targets
@targets ||= begin
if link_with = @target_definition.link_with
# Find explicitly linked targets.
user_project.targets.select do |target|
link_with.include? target.name
end
elsif @target_definition.name != :default
# Find the target with the matching name.
target = user_project.targets.find { |target| target.name == @target_definition.name.to_s }
raise Informative, "Unable to find a target named `#{@target_definition.name.to_s}'" unless target
[target]
else
# Default to the first, which in a simple project is probably an app target.
[user_project.targets.first]
end.reject do |target|
# Reject any target that already has this Pods library in one of its frameworks build phases
target.frameworks_build_phase.files.any? { |build_file| build_file.file_ref.name == @target_definition.lib_name }
end
end
end end
#--------------------------------------#
# @!group Integration steps
private
# Adds the `xcconfig` configurations files generated for the current
# {TargetDefinition} to the build configurations of the targets that
# should be integrated.
#
# @note It also checks if any build setting of the build
# configurations overrides the `xcconfig` file and warns the
# user.
#
# TODO: If the xcconfig is already set don't override it and inform
# the user.
#
# @return [void]
#
def add_xcconfig_base_configuration def add_xcconfig_base_configuration
xcconfig = user_project.new_file(@target_definition.xcconfig_relative_path) xcconfig = user_project.new_file(library.xcconfig_relative_path)
targets.each do |target| targets.each do |target|
config_build_names_by_overriden_key = {} check_overridden_build_settings(library.xcconfig, target)
target.build_configurations.each do |config| target.build_configurations.each do |config|
config_name = config.name
if @target_definition.xcconfig
@target_definition.xcconfig.attributes.each do |key, value|
target_value = config.build_settings[key]
if target_value && !target_value.include?('$(inherited)')
config_build_names_by_overriden_key[key] ||= []
config_build_names_by_overriden_key[key] << config_name
end
end
end
config.base_configuration_reference = xcconfig config.base_configuration_reference = xcconfig
end end
config_build_names_by_overriden_key.each do |key, config_build_names|
name = "#{target.name} [#{config_build_names.join(' - ')}]"
actions = [ "Use the `$(inherited)' flag, or", "Remove the build settings from the target." ]
UI.warn("The target `#{name}' overrides the `#{key}' build setting defined in `#{@target_definition.xcconfig_relative_path}'.", actions)
end
end end
end end
# Adds a file reference to the library of the {TargetDefinition} and
# adds it to the frameworks build phase of the targets.
#
# @return [void]
#
def add_pods_library def add_pods_library
frameworks = user_project.frameworks_group frameworks = user_project.frameworks_group
pods_library = frameworks.new_static_library(@target_definition.label) pods_library = frameworks.new_static_library(library.label)
targets.each do |target| targets.each do |target|
target.frameworks_build_phase.add_file_reference(pods_library) target.frameworks_build_phase.add_file_reference(pods_library)
end end
end end
# Adds a shell script build phase responsible to copy the resources
# generated by the TargetDefinition to the bundle of the product of the
# targets.
#
# @return [void]
#
def add_copy_resources_script_phase def add_copy_resources_script_phase
targets.each do |target| targets.each do |target|
phase = target.new_shell_script_build_phase('Copy Pods Resources') phase = target.new_shell_script_build_phase('Copy Pods Resources')
phase.shell_script = %{"#{@target_definition.copy_resources_script_relative_path}"\n} path = library.copy_resources_script_relative_path
phase.shell_script = %{"#{path}"\n}
end end
end end
# Saves the changes to the user project to the disk.
#
# @return [void]
#
def save_user_project
user_project.save_as(library.user_project_path)
end
#--------------------------------------#
# @!group Private helpers.
private
# Informs the user about any build setting of the target which might
# override the given xcconfig file.
#
# @return [void]
#
def check_overridden_build_settings(xcconfig, target)
return unless xcconfig
configs_by_overridden_key = {}
target.build_configurations.each do |config|
xcconfig.attributes.keys.each do |key|
configs_by_overridden_key[key] ||= []
target_value = config.build_settings[key]
if target_value && !target_value.include?('$(inherited)')
configs_by_overridden_key[key] << config.name
end
end
configs_by_overridden_key.each do |key, config_names|
name = "#{target.name} [#{config_names.join(' - ')}]"
actions = [
"Use the `$(inherited)' flag, or",
"Remove the build settings from the target."
]
UI.warn("The target `#{name}' overrides the `#{key}' build " \
"setting defined in `#{xcconfig_relative_path}'.",
actions)
end
end
end
# @return [String] the message that should be displayed for the target
# integration.
#
def integration_message
"Integrating `#{library.name}' into " \
"#{'target'.pluralize(targets.size)} " \
"`#{targets.map(&:name).to_sentence}` " \
"of project #{UI.path library.user_project_path}."
end
end end
end end
end end
......
...@@ -21,6 +21,7 @@ module Pod ...@@ -21,6 +21,7 @@ module Pod
# returns absolute paths. # returns absolute paths.
# #
class LocalPod class LocalPod
autoload :PathList, 'cocoapods/local_pod/path_list'
# @return [Specification] The specification that describes the pod. # @return [Specification] The specification that describes the pod.
# #
...@@ -59,7 +60,7 @@ module Pod ...@@ -59,7 +60,7 @@ module Pod
# computed values. In other words, it should be immutable. # computed values. In other words, it should be immutable.
# #
def initialize(specification, sandbox, platform) def initialize(specification, sandbox, platform)
@top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform @top_specification, @sandbox, @platform = specification.root, sandbox, platform
@top_specification.activate_platform(platform) @top_specification.activate_platform(platform)
@specifications = [] << specification @specifications = [] << specification
end end
...@@ -80,7 +81,7 @@ module Pod ...@@ -80,7 +81,7 @@ module Pod
# @raise {Informative} If the specification is not part of the same pod. # @raise {Informative} If the specification is not part of the same pod.
# #
def add_specification(spec) def add_specification(spec)
unless spec.top_level_parent == top_specification unless spec.root == top_specification
raise Informative, raise Informative,
"[Local Pod] Attempt to add a specification from another pod" "[Local Pod] Attempt to add a specification from another pod"
end end
...@@ -94,13 +95,17 @@ module Pod ...@@ -94,13 +95,17 @@ module Pod
@sandbox.root + top_specification.name @sandbox.root + top_specification.name
end end
def path_list
@path_list ||= PathList.new(root)
end
# @return [String] A string representation of the pod which indicates if # @return [String] A string representation of the pod which indicates if
# the pods comes from a local source or has a preferred # the pods comes from a local source or has a preferred
# dependency. # dependency.
# #
def to_s def to_s
s = top_specification.to_s s = top_specification.to_s
s << " defaulting to #{top_specification.preferred_dependency} subspec" if top_specification.preferred_dependency s << " defaulting to #{top_specification.default_subspec} subspec" if top_specification.default_subspec
s s
end end
...@@ -156,6 +161,7 @@ module Pod ...@@ -156,6 +161,7 @@ module Pod
def clean! def clean!
clean_paths.each { |path| FileUtils.rm_rf(path) } clean_paths.each { |path| FileUtils.rm_rf(path) }
@cleaned = true @cleaned = true
path_list.read_file_system
end end
# Finds the absolute paths, including hidden ones, of the files # Finds the absolute paths, including hidden ones, of the files
...@@ -242,7 +248,7 @@ module Pod ...@@ -242,7 +248,7 @@ module Pod
# #
def source_files_by_spec def source_files_by_spec
options = {:glob => '*.{h,hpp,hh,m,mm,c,cpp}'} options = {:glob => '*.{h,hpp,hh,m,mm,c,cpp}'}
paths_by_spec(:source_files, options) @source_files_by_spec ||= paths_by_spec(:source_files, '*.{h,hpp,hh,m,mm,c,cpp}')
end end
# @return [Array<Pathname>] The paths of the header files. # @return [Array<Pathname>] The paths of the header files.
...@@ -277,7 +283,7 @@ module Pod ...@@ -277,7 +283,7 @@ module Pod
# header files (i.e. the build ones) are intended to be public. # header files (i.e. the build ones) are intended to be public.
# #
def public_header_files_by_spec def public_header_files_by_spec
public_headers = paths_by_spec(:public_header_files, :glob => '*.{h,hpp,hh}') public_headers = paths_by_spec(:public_header_files, '*.{h,hpp,hh}')
build_headers = header_files_by_spec build_headers = header_files_by_spec
result = {} result = {}
...@@ -294,7 +300,20 @@ module Pod ...@@ -294,7 +300,20 @@ module Pod
# @return [Array<Pathname>] The paths of the resources. # @return [Array<Pathname>] The paths of the resources.
# #
def resource_files def resource_files
paths_by_spec(:resources).values.flatten specs ||= specifications
paths_by_spec = {}
processed_paths = []
specs = specs.sort_by { |s| s.name.length }
specs.each do |spec|
spec_paths = spec.resources[:resources]
paths = expanded_paths(spec_paths, '**/*', spec.exclude_files)
unless paths.empty?
paths_by_spec[spec] = paths - processed_paths
processed_paths += paths
end
end
paths_by_spec.values.flatten
end end
# @return [Array<Pathname>] The *relative* paths of the resources. # @return [Array<Pathname>] The *relative* paths of the resources.
...@@ -331,11 +350,14 @@ module Pod ...@@ -331,11 +350,14 @@ module Pod
# specification or automatically detected. # specification or automatically detected.
# #
def license_file def license_file
if top_specification.license && top_specification.license[:file] unless @license_file
root + top_specification.license[:file] if top_specification.license && top_specification.license[:file]
else @license_file = root + top_specification.license[:file]
expanded_paths(%w[ licen{c,s}e{*,.*} ]).first else
@license_file = expanded_paths(%w[ licen{c,s}e{*,.*} ]).first
end
end end
@license_file
end end
# @return [String] The text of the license of the pod from the # @return [String] The text of the license of the pod from the
...@@ -352,7 +374,14 @@ module Pod ...@@ -352,7 +374,14 @@ module Pod
end end
def xcconfig def xcconfig
specifications.map { |s| s.xcconfig }.reduce(:merge) config = Xcodeproj::Config.new
specifications.each do |s|
config.merge(s.xcconfig)
config.libraries.merge(s.libraries)
config.frameworks.merge(s.frameworks)
config.weak_frameworks.merge(s.weak_frameworks)
end
config
end end
# Computes the paths of all the public headers of the pod including every # Computes the paths of all the public headers of the pod including every
...@@ -372,8 +401,8 @@ module Pod ...@@ -372,8 +401,8 @@ module Pod
end end
specs = [top_specification] + top_specification.recursive_subspecs specs = [top_specification] + top_specification.recursive_subspecs
source_files = paths_by_spec(:source_files, { :glob => '*.{h}'}, specs) source_files = paths_by_spec(:source_files, '*.{h}', specs)
public_headers = paths_by_spec(:public_header_files,{ :glob => '*.{h}'}, specs) public_headers = paths_by_spec(:public_header_files, '*.{h}', specs)
result = [] result = []
specs.each do |spec| specs.each do |spec|
...@@ -431,7 +460,7 @@ module Pod ...@@ -431,7 +460,7 @@ module Pod
"project before adding the build files to the target." "project before adding the build files to the target."
end end
file_references_by_spec.each do |spec, file_reference| file_references_by_spec.each do |spec, file_reference|
target.add_file_references(file_reference, spec.compiler_flags.strip) target.add_file_references(file_reference, (spec.compiler_flags * " ").strip)
end end
end end
...@@ -474,7 +503,7 @@ module Pod ...@@ -474,7 +503,7 @@ module Pod
end end
# @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers # @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers
# folders as the keys and the the absolute paths of the header files # folders as the keys and the absolute paths of the header files
# as the values. # as the values.
# #
# @todo this is being overridden in the RestKit 0.9.4 spec, need to do # @todo this is being overridden in the RestKit 0.9.4 spec, need to do
...@@ -489,7 +518,7 @@ module Pod ...@@ -489,7 +518,7 @@ module Pod
dir = spec.header_dir ? (headers_sandbox + spec.header_dir) : headers_sandbox dir = spec.header_dir ? (headers_sandbox + spec.header_dir) : headers_sandbox
paths.each do |from| paths.each do |from|
from_relative = from.relative_path_from(root) from_relative = from.relative_path_from(root)
to = dir + spec.copy_header_mapping(from_relative) to = dir + (spec.header_mappings_dir ? from.relative_path_from(spec.header_mappings_dir) : from.basename)
(mappings[to.dirname] ||= []) << from (mappings[to.dirname] ||= []) << from
end end
end end
...@@ -507,27 +536,29 @@ module Pod ...@@ -507,27 +536,29 @@ module Pod
# included in the linker search paths. # included in the linker search paths.
# #
def headers_excluded_from_search_paths def headers_excluded_from_search_paths
options = { :glob => '*.{h,hpp,hh}' } #TODO
paths = paths_by_spec(:exclude_header_search_paths, options) # paths = paths_by_spec(:exclude_header_search_paths, '*.{h,hpp,hh}')
paths.values.compact.uniq # paths.values.compact.uniq
[]
end end
# @!group Paths Patterns # @!group Paths Patterns
# The paths obtained by resolving the patterns of an attribute # The paths obtained by resolving the patterns of an attribute
# groupped by spec. # grouped by spec.
# #
# @param [Symbol] accessor The accessor to use to obtain the paths patterns. # @param [Symbol] accessor The accessor to use to obtain the paths patterns.
#
# @param [Hash] options (see #expanded_paths) # @param [Hash] options (see #expanded_paths)
# #
def paths_by_spec(accessor, options = {}, specs = nil) def paths_by_spec(accessor, dir_pattern = nil, specs = nil)
specs ||= specifications specs ||= specifications
paths_by_spec = {} paths_by_spec = {}
processed_paths = [] processed_paths = []
specs = specs.sort_by { |s| s.name.length } specs = specs.sort_by { |s| s.name.length }
specs.each do |spec| specs.each do |spec|
paths = expanded_paths(spec.send(accessor), options) paths = expanded_paths(spec.send(accessor), dir_pattern, spec.exclude_files)
unless paths.empty? unless paths.empty?
paths_by_spec[spec] = paths - processed_paths paths_by_spec[spec] = paths - processed_paths
processed_paths += paths processed_paths += paths
...@@ -552,34 +583,29 @@ module Pod ...@@ -552,34 +583,29 @@ module Pod
# #
# @return [Array<Pathname>] A list of the paths. # @return [Array<Pathname>] A list of the paths.
# #
def expanded_paths(patterns, options = {}) def expanded_paths(patterns, dir_pattern = nil, exclude_patterns = nil)
unless exists? unless exists?
raise Informative, "[Local Pod] Attempt to resolve paths for nonexistent pod.\n" \ raise Informative, "[Local Pod] Attempt to resolve paths for nonexistent pod.\n" \
"\tSpecifications: #{@specifications.inspect}\n" \ "\tSpecifications: #{@specifications.inspect}\n" \
"\t Patterns: #{patterns.inspect}\n" \ "\t Patterns: #{patterns.inspect}"
"\t Options: #{options.inspect}"
end end
# Noticeable impact on performance
return [] if patterns.empty? return [] if patterns.empty?
patterns = [ patterns ] if patterns.is_a?(String) patterns = [ patterns ] if patterns.is_a?(String)
file_lists = patterns.select { |p| p.is_a?(FileList) } file_lists = patterns.select { |p| p.is_a?(FileList) }
glob_patterns = patterns - file_lists glob_patterns = patterns - file_lists
result = [] result = []
result << path_list.glob(glob_patterns, dir_pattern, exclude_patterns)
result << file_lists.map do |file_list| result << file_lists.map do |file_list|
file_list.prepend_patterns(root) file_list.prepend_patterns(root)
file_list.glob file_list.glob
end end
result << glob_patterns.map do |pattern|
pattern = root + pattern
if pattern.directory? && options[:glob]
pattern += options[:glob]
end
Pathname.glob(pattern, File::FNM_CASEFOLD)
end.flatten
result.flatten.compact.uniq result.flatten.compact.uniq
end end
...@@ -616,5 +642,5 @@ module Pod ...@@ -616,5 +642,5 @@ module Pod
true true
end end
end end
end end # LocalPod
end end # Pod
module Pod
class LocalPod
# The {PathList} class is designed to perform multiple glob matches against
# a given directory. Basically, it generates a list of all the children
# paths and matches the globs patterns against them, resulting in just
# one access to the file system.
#
# @note A {PathList} once it has generated the list of the paths this is
# updated only if explicitly requested by calling
# {PathList#read_file_system}
#
class PathList
# @return [Pathname] The root of the list whose files and directories
# are used to perform the matching operations.
#
attr_accessor :root
# @param [Pathname] root The root of the PathList.
#
def initialize(root)
@root = root
end
# @return [Array<String>] The list of absolute the path of all the files
# contained in {root}.
#
def files
read_file_system unless @files
@files
end
# @return [Array<String>] The list of absolute the path of all the
# directories contained in {root}.
#
def dirs
read_file_system unless @dirs
@dirs
end
# @return [void] Reads the file system and populates the files and paths
# lists.
#
def read_file_system
root_length = root.to_s.length+1
paths = Dir.glob(root + "**/*", File::FNM_DOTMATCH)
paths = paths.map { |p| p[root_length..-1] }
paths = paths.reject { |p| p == '.' || p == '..' }
dirs_entries = paths.select { |path| path.end_with?('/.', '/..') }
@files = paths - dirs_entries
@dirs = dirs_entries.map { |d| d.gsub(/\/\.\.?$/,'') }.uniq
end
# @return [Array<Pathname>] Similar to {glob} but returns the absolute
# paths.
#
def glob(patterns, dir_pattern = nil, exclude_patterns = nil)
relative_glob(patterns, dir_pattern, exclude_patterns).map {|p| root + p }
end
# @return [Array<Pathname>] The list of relative paths that are case
# insensitively matched by a given pattern. This method emulates
# {Dir#glob} with the {File::FNM_CASEFOLD} option.
#
# @param [String,Array<String>] patterns A signle {Dir#glob} like
# pattern, or a list of patterns.
#
# @param [String] dir_pattern An optional pattern to append to a
# pattern, if it is the path to a
# directory.
#
def relative_glob(patterns, dir_pattern = nil, exclude_patterns = nil)
return [] if patterns.empty?
patterns = [ patterns ] if patterns.is_a? String
list = patterns.map do |pattern|
if pattern.is_a?(String)
pattern += '/' + dir_pattern if directory?(pattern) && dir_pattern
expanded_patterns = dir_glob_equivalent_patterns(pattern)
files.select do |path|
expanded_patterns.any? do |p|
File.fnmatch(p, path, File::FNM_CASEFOLD | File::FNM_PATHNAME)
end
end
else
files.select { |path| path.match(pattern) }
end
end.flatten
list -= relative_glob(exclude_patterns) if exclude_patterns
list.map { |path| Pathname.new(path) }
end
# @return [Bool] Wether a path is a directory. The result of this method
# computed without accessing the file system and is case insensitive.
#
# @param [String, Pathname] sub_path The path that could be a directory.
#
def directory?(sub_path)
sub_path = sub_path.to_s.downcase.sub(/\/$/, '')
dirs.any? { |dir| dir.downcase == sub_path }
end
# @return [Array<String>] An array of patterns converted from a
# {Dir.glob} pattern to patterns that {File.fnmatch} can handle. This
# is used by the {#relative_glob} method to emulate {Dir.glob}.
#
# The expansion provides support for:
#
# - Literals
#
# dir_glob_equivalent_patterns('{file1,file2}.{h,m}')
# => ["file1.h", "file1.m", "file2.h", "file2.m"]
#
# - Matching the direct children of a directory with `**`
#
# dir_glob_equivalent_patterns('Classes/**/file.m')
# => ["Classes/**/file.m", "Classes/file.m"]
#
# @param [String] pattern A {Dir#glob} like pattern.
#
def dir_glob_equivalent_patterns(pattern)
pattern.gsub!('/**/', '{/**/,/}')
values_by_set = {}
pattern.scan(/\{[^}]*\}/) do |set|
values = set.gsub(/[{}]/, '').split(',')
values_by_set[set] = values
end
if values_by_set.empty?
[ pattern ]
else
patterns = [ pattern ]
values_by_set.each do |set, values|
patterns = patterns.map do |pattern|
values.map do |value|
pattern.gsub(set, value)
end
end.flatten
end
patterns
end
end
end # PathList
end # LocalPod
end # Pod
require 'digest'
module Pod
class Lockfile
# @return [Lockfile] Returns the Lockfile saved in path.
# Returns {nil} If the file can't be loaded.
#
def self.from_file(path)
return nil unless path.exist?
begin
hash = YAML.load(File.open(path))
rescue Exception => e
raise Informative, "Podfile.lock syntax error: #{e.inspect}"
end
lockfile = Lockfile.new(hash)
lockfile.defined_in_file = path
lockfile
end
# @return [Lockfile] Generates a lockfile from a {Podfile} and the
# list of {Specifications} that were installed.
#
def self.generate(podfile, specs)
Lockfile.new(generate_hash_from_podfile(podfile, specs))
end
# @return [String] The file where this Lockfile is defined.
#
attr_accessor :defined_in_file
# @return [String] The hash used to initialize the Lockfile.
#
attr_reader :to_hash
# @param [Hash] hash A Hash representation of a Lockfile.
#
def initialize(hash)
@to_hash = hash
end
# @return [Array<String, Hash{String => Array[String]}>] The pods installed
# and their dependencies.
#
def pods
@pods ||= to_hash['PODS'] || []
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
#
def dependencies
@dependencies ||= to_hash['DEPENDENCIES'].map { |dep| dependency_from_string(dep) } || []
end
# @return [Hash{String => Hash}] A hash where the name of the pods are
# the keys and the values are the parameters of an
# {AbstractExternalSource} of the dependency that required the pod.
#
def external_sources
@external_sources ||= to_hash["EXTERNAL SOURCES"] || {}
end
# @return [Array<String>] The names of the installed Pods.
#
def pods_names
@pods_names ||= pods.map do |pod|
pod = pod.keys.first unless pod.is_a?(String)
name_and_version_for_pod(pod)[0]
end
end
# @return [Hash{String => Version}] A Hash containing the name
# of the installed Pods (top spec name) as the keys and their
# corresponding {Version} as the values.
#
def pods_versions
unless @pods_versions
@pods_versions = {}
pods.each do |pod|
pod = pod.keys.first unless pod.is_a?(String)
name, version = name_and_version_for_pod(pod)
@pods_versions[name] = version
@pods_versions[name.split('/').first] = version
end
end
@pods_versions
end
# @return [Dependency] A dependency that describes the exact installed version
# of a Pod.
#
def dependency_for_installed_pod_named(name)
version = pods_versions[name]
raise Informative, "Attempt to lock a Pod without an known version." unless version
dependency = Dependency.new(name, version)
if external_source = external_sources[name]
dependency.external_source = Dependency::ExternalSources.from_params(dependency.name, external_source)
end
dependency
end
# @param [String] The string that describes a {Specification} generated
# from {Specification#to_s}.
#
# @example Strings examples
# "libPusher"
# "libPusher (1.0)"
# "libPusher (HEAD based on 1.0)"
# "RestKit/JSON"
#
# @return [String, Version] The name and the version of a
# pod.
#
def name_and_version_for_pod(string)
match_data = string.match(/(\S*) \((.*)\)/)
name = match_data[1]
vers = Version.from_string(match_data[2])
[name, vers]
end
# @param [String] The string that describes a {Dependency} generated
# from {Dependency#to_s}.
#
# @example Strings examples
# "libPusher"
# "libPusher (= 1.0)"
# "libPusher (~> 1.0.1)"
# "libPusher (> 1.0, < 2.0)"
# "libPusher (HEAD)"
# "libPusher (from `www.example.com')"
# "libPusher (defined in Podfile)"
# "RestKit/JSON"
#
# @return [Dependency] The dependency described by the string.
#
def dependency_from_string(string)
match_data = string.match(/(\S*)( (.*))?/)
name = match_data[1]
version = match_data[2]
version = version.gsub(/[()]/,'') if version
case version
when nil
Dependency.new(name)
when /defined in Podfile/
# @TODO: store the whole spec?, the version?
Dependency.new(name)
when /from `(.*)'/
external_source_info = external_sources[name]
Dependency.new(name, external_source_info)
when /HEAD/
# @TODO: find a way to serialize from the Downloader the information
# necessary to restore a head version.
Dependency.new(name, :head)
else
Dependency.new(name, version)
end
end
# Analyzes the {Lockfile} and detects any changes applied to the {Podfile}
# since the last installation.
#
# For each Pod, it detects one state among the following:
#
# - added: Pods that weren't present in the Podfile.
# - changed: Pods that were present in the Podfile but changed:
# - Pods whose version is not compatible anymore with Podfile,
# - Pods that changed their head or external options.
# - removed: Pods that were removed form the Podfile.
# - unchanged: Pods that are still compatible with Podfile.
#
# @TODO: detect changes for inline dependencies?
#
# @return [Hash{Symbol=>Array[Strings]}] A hash where pods are grouped
# by the state in which they are.
#
def detect_changes_with_podfile(podfile)
previous_podfile_deps = dependencies.map(&:name)
user_installed_pods = pods_names.reject { |name| !previous_podfile_deps.include?(name) }
deps_to_install = podfile.dependencies.dup
result = {}
result[:added] = []
result[:changed] = []
result[:removed] = []
result[:unchanged] = []
user_installed_pods.each do |pod_name|
dependency = deps_to_install.find { |d| d.name == pod_name }
deps_to_install.delete(dependency)
version = pods_versions[pod_name]
external_source = Dependency::ExternalSources.from_params(pod_name, external_sources[pod_name])
if dependency.nil?
result[:removed] << pod_name
elsif !dependency.match_version?(version) || dependency.external_source != external_source
result[:changed] << pod_name
else
result[:unchanged] << pod_name
end
end
deps_to_install.each do |dependency|
result[:added] << dependency.name
end
result
end
# @return [void] Writes the Lockfile to {#path}.
#
def write_to_disk(path)
path.dirname.mkpath unless path.dirname.exist?
File.open(path, 'w') {|f| f.write(to_yaml) }
defined_in_file = path
end
# @return [String] A string useful to represent the Lockfile in a message
# presented to the user.
#
def to_s
"Podfile.lock"
end
# @return [String] The YAML representation of the Lockfile, used for
# serialization.
#
def to_yaml
to_hash.to_yaml.gsub(/^--- ?\n/,"").gsub(/^([A-Z])/,"\n\\1")
end
# @return [Hash] The Hash representation of the Lockfile generated from
# a given Podfile and the list of resolved Specifications.
#
def self.generate_hash_from_podfile(podfile, specs)
hash = {}
# Get list of [name, dependencies] pairs.
pod_and_deps = specs.map do |spec|
[spec.to_s, spec.dependencies.map(&:to_s).sort]
end.uniq
# Merge dependencies of iOS and OS X version of the same pod.
tmp = {}
pod_and_deps.each do |name, deps|
if tmp[name]
tmp[name].concat(deps).uniq!
else
tmp[name] = deps
end
end
pod_and_deps = tmp.sort_by(&:first).map do |name, deps|
deps.empty? ? name : { name => deps }
end
hash["PODS"] = pod_and_deps
hash["DEPENDENCIES"] = podfile.dependencies.map{ |d| d.to_s }.sort
external_sources = {}
deps = podfile.dependencies.select(&:external?).sort{ |d, other| d.name <=> other.name}
deps.each{ |d| external_sources[d.name] = d.external_source.params }
hash["EXTERNAL SOURCES"] = external_sources unless external_sources.empty?
checksums = {}
specs.select { |spec| !spec.defined_in_file.nil? }.each do |spec|
checksum = Digest::SHA1.hexdigest(File.read(spec.defined_in_file))
checksum = checksum.encode('UTF-8') if checksum.respond_to?(:encode)
checksums[spec.name] = checksum
end
hash["SPEC CHECKSUMS"] = checksums unless checksums.empty?
hash["COCOAPODS"] = VERSION
hash
end
end
end
module Pod
# A platform describes an SDK name and deployment target.
#
class Platform
# @return [Platform] Convenience method to initialize an iOS platform.
#
def self.ios
new :ios
end
# @return [Platform] Convenience method to initialize an OS X platform.
#
def self.osx
new :osx
end
# Constructs a platform from either another platform or by
# specifying the symbolic name and optionally the deployment target.
#
# @overload initialize(name, deployment_target)
# @param [Symbol] name The name of platform.
# @param [String, Version] deployment_target The optional deployment.
# If not provided a default value according to the platform name will
# be assigned.
#
# @note that if the name is not specified a default deployment
# target will not be assigned.
#
# @example
#
# Platform.new(:ios)
# Platform.new(:ios, '4.3')
#
# @overload initialize(platform)
# @param [Platform] platform Another {Platform}.
#
# @example
#
# platform = Platform.new(:ios)
# Platform.new(platform)
#
def initialize(input, target = nil)
if input.is_a? Platform
@symbolic_name = input.name
@deployment_target = input.deployment_target
else
@symbolic_name = input
target = target[:deployment_target] if target.is_a?(Hash)
@deployment_target = Version.create(target)
end
end
# @return [Symbol] The name of the SDK represented by the platform.
#
def name
@symbolic_name
end
# @return [Version] The deployment target of the platform.
#
attr_reader :deployment_target
# @param [Platform, Symbol] other The other platform to check.
#
# @note If a symbol is passed the comparison does not take into account
# the deployment target.
#
# @return [Boolean] Whether two platforms are the equivalent.
#
def ==(other)
if other.is_a?(Symbol)
@symbolic_name == other
else
(name == other.name) && (deployment_target == other.deployment_target)
end
end
# In the context of operating system SDKs, a platform supports another
# one if they have the same name and the other platform has a minor or
# equal deployment target.
#
# @return Whether the platform supports another platform.
#
def supports?(other)
other = Platform.new(other)
if other.deployment_target && deployment_target
(other.name == name) && (other.deployment_target <= deployment_target)
else
other.name == name
end
end
# @return [String] A string representation including the deployment target.
#
def to_s
case @symbolic_name
when :ios
s = 'iOS'
when :osx
s = 'OS X'
end
s << " #{deployment_target}" if deployment_target
s
end
# @return [Symbol] A Symbol representation of the name.
#
def to_sym
name
end
# @return Whether the platform requires legacy architectures for iOS.
#
def requires_legacy_ios_archs?
(name == :ios) && deployment_target && (deployment_target < Version.new("4.3"))
end
end
end
module Pod
class Podfile
class Informative < ::Pod::Informative
def podfile_line
@podfile_line ||= self.backtrace.find {|t| t =~ /Podfile/}
end
def message
if podfile_line
super + " (#{podfile_line})\n".red
else
super
end
end
end
class UserProject
include Config::Mixin
DEFAULT_BUILD_CONFIGURATIONS = { 'Debug' => :debug, 'Release' => :release }.freeze
def initialize(path = nil, build_configurations = {})
self.path = path if path
@build_configurations = build_configurations.merge(DEFAULT_BUILD_CONFIGURATIONS)
end
def path=(path)
path = path.to_s
@path = Pathname.new(File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj")
@path = config.project_root + @path unless @path.absolute?
@path
end
def path
if @path
@path
else
xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
if xcodeprojs.size == 1
@path = xcodeprojs.first
end
end
end
def project
Xcodeproj::Project.new(path) if path && path.exist?
end
def build_configurations
if project
project.build_configurations.map(&:name).inject({}) do |hash, name|
hash[name] = :release; hash
end.merge(@build_configurations)
else
@build_configurations
end
end
end
class TargetDefinition
include Config::Mixin
attr_reader :name, :target_dependencies
attr_accessor :user_project, :link_with, :platform, :parent, :exclusive, :inhibit_all_warnings
def initialize(name, options = {})
@name, @target_dependencies = name, []
@parent, @exclusive = options.values_at(:parent, :exclusive)
end
# A target is automatically `exclusive` if the `platform` does not match
# the parent's `platform`.
def exclusive
if @exclusive.nil?
if @platform.nil?
false
else
@parent.platform != @platform
end
else
@exclusive
end
end
alias_method :exclusive?, :exclusive
def user_project
@user_project || @parent.user_project
end
def link_with=(targets)
@link_with = targets.is_a?(Array) ? targets : [targets]
end
def platform
@platform || (@parent.platform if @parent)
end
def inhibit_all_warnings
@inhibit_all_warnings.nil? ? (@parent.inhibit_all_warnings? if @parent) : @inhibit_all_warnings
end
alias_method :inhibit_all_warnings?, :inhibit_all_warnings
def label
if name == :default
"Pods"
elsif exclusive?
"Pods-#{name}"
else
"#{@parent.label}-#{name}"
end
end
def acknowledgements_path
config.project_pods_root + "#{label}-Acknowledgements"
end
# Returns a path, which is relative to the project_root, relative to the
# `$(SRCROOT)` of the user's project.
def relative_to_srcroot(path)
if user_project.path.nil?
# 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
def relative_pods_root
"${SRCROOT}/#{relative_to_srcroot "Pods"}"
end
def lib_name
"lib#{label}.a"
end
def xcconfig_name
"#{label}.xcconfig"
end
def xcconfig_relative_path
relative_to_srcroot("Pods/#{xcconfig_name}").to_s
end
attr_accessor :xcconfig
def copy_resources_script_name
"#{label}-resources.sh"
end
def copy_resources_script_relative_path
"${SRCROOT}/#{relative_to_srcroot("Pods/#{copy_resources_script_name}")}"
end
def prefix_header_name
"#{label}-prefix.pch"
end
def bridge_support_name
"#{label}.bridgesupport"
end
# Returns *all* dependencies of this target, not only the target specific
# ones in `target_dependencies`.
def dependencies
@target_dependencies + (exclusive? ? [] : @parent.dependencies)
end
def empty?
target_dependencies.empty?
end
end
def self.from_file(path)
podfile = Podfile.new do
string = File.open(path, 'r:utf-8') { |f| f.read }
# TODO: work around for Rubinius incomplete encoding in 1.9 mode
string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
begin
eval(string, nil, path.to_s)
rescue Exception => e
raise Informative, "Podfile syntax error: #{e.inspect}"
end
end
podfile.defined_in_file = path
podfile.validate!
podfile
end
include Config::Mixin
def initialize(&block)
@target_definition = TargetDefinition.new(:default, :exclusive => true)
@target_definition.user_project = UserProject.new
@target_definitions = { :default => @target_definition }
instance_eval(&block)
end
# Specifies the platform for which a static library should be build.
# This can be either `:osx` for Mac OS X applications, or `:ios` for iOS
# applications.
#
# @param [Symbol] name The name of platform.
# @param [String, Version] target The optional deployment.
# If not provided a default value according to the platform name will
# be assigned.
#
# @example
#
# platform :ios, "4.0"
# platform :ios
#
# @note If the deployment target requires it (< 4.3), armv6 will be added
# to ARCHS.
#
def platform(name, target = nil)
# Support for deprecated options parameter
target = target[:deployment_target] if target.is_a?(Hash)
unless target
case name
when :ios
target = '4.3'
when :osx
target = '10.6'
else
raise ::Pod::Podfile::Informative, "Unsupported platform: platform must be one of [:ios, :osx]"
end
end
@target_definition.platform = Platform.new(name, target)
end
# Specifies the Xcode workspace that should contain all the projects.
#
# If no explicit Xcode workspace is specified and only **one** project exists
# in the same directory as the Podfile, then the name of that project is used
# as the workspace’s name.
#
# @example
#
# workspace 'MyWorkspace'
#
def workspace(path = nil)
if path
@workspace = config.project_root + (File.extname(path) == '.xcworkspace' ? path : "#{path}.xcworkspace")
elsif @workspace
@workspace
else
projects = @target_definitions.map { |_, td| td.user_project.path }.uniq
if projects.size == 1 && (xcodeproj = @target_definitions[:default].user_project.path)
config.project_root + "#{xcodeproj.basename('.xcodeproj')}.xcworkspace"
end
end
end
# Specifies the Xcode project that contains the target that the Pods library
# should be linked with.
#
# If no explicit project is specified, it will use the Xcode project of the
# parent target. If none of the target definitions specify an explicit project
# and there is only **one** project in the same directory as the Podfile then
# that project will be used.
#
# @example
#
# # Look for target to link with in an Xcode project called ‘MyProject.xcodeproj’.
# xcodeproj 'MyProject'
#
# target :test do
# # This Pods library links with a target in another project.
# xcodeproj 'TestProject'
# end
#
def xcodeproj(path, build_configurations = {})
@target_definition.user_project = UserProject.new(path, build_configurations)
end
# Specifies the target(s) in the user’s project that this Pods library
# should be linked in.
#
# If no explicit target is specified, then the Pods target will be linked
# with the first target in your project. So if you only have one target you
# do not need to specify the target to link with.
#
# @example
#
# # Link with a target called ‘MyApp’ (in the user's project).
# link_with 'MyApp'
#
# # Link with the targets in the user’s project called ‘MyApp’ and ‘MyOtherApp’.
# link_with ['MyApp', 'MyOtherApp']
#
def link_with(targets)
@target_definition.link_with = targets
end
# Inhibits **all** warnings from the Pods library.
#
# When used, this is applied to all targets inheriting from the current one.
def inhibit_all_warnings!
@target_definition.inhibit_all_warnings = true
end
# Specifies a dependency of the project.
#
# A dependency requirement is defined by the name of the Pod and _optionally_
# a list of version requirements.
#
#
# When starting out with a project it is likely that you will want to use the
# latest version of a Pod. If this is the case, simply omit the version
# requirements.
#
# pod 'SSZipArchive'
#
#
# Later on in the project you may want to freeze to a specific version of a
# Pod, in which case you can specify that version number.
#
# pod 'Objection', '0.9'
#
#
# Besides no version, or a specific one, it is also possible to use operators:
#
# * `> 0.1` Any version higher than 0.1
# * `>= 0.1` Version 0.1 and any higher version
# * `< 0.1` Any version lower than 0.1
# * `<= 0.1` Version 0.1 and any lower version
# * `~> 0.1.2` Version 0.1.2 and the versions upto 0.2, not including 0.2
#
# A list of version requirements can be specified for even more fine
# grained control.
#
#
# For more information, regarding versioning policy, see:
#
# * http://semver.org
# * http://docs.rubygems.org/read/chapter/7
#
#
# Finally, instead of a version, you can specify the `:head` flag. This will
# use the pod’s latest version spec version, but force the download of the
# ‘bleeding edge’ version. Use this with caution, as the spec might not be
# compatible anymore.
#
#
# ## Dependency on a library, outside those available in a spec repo.
#
# ### From a podspec in the root of a library repo.
#
# Sometimes you may want to use the bleeding edge version of a Pod. Or a
# specific revision. If this is the case, you can specify that with your
# pod declaration.
#
#
# To use the `master` branch of the repo:
#
# pod 'TTTFormatterKit', :git => 'https://github.com/gowalla/AFNetworking.git'
#
#
# Or specify a commit:
#
# pod 'TTTFormatterKit', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
#
#
# It is important to note, though, that this means that the version will
# have to satisfy any other dependencies on the Pod by other Pods.
#
#
# The `podspec` file is expected to be in the root of the repo, if this
# library does not have a `podspec` file in its repo yet, you will have to
# use one of the approaches outlined in the sections below.
#
#
# ### From a podspec outside a spec repo, for a library without podspec.
#
# If a podspec is available from another source outside of the library’s
# repo. Consider, for instance, a podpsec available via HTTP:
#
# pod 'JSONKit', :podspec => 'https://raw.github.com/gist/1346394/1d26570f68ca27377a27430c65841a0880395d72/JSONKit.podspec'
#
#
# ### For a library without any available podspec
#
# Finally, if no living soul has created a podspec, for the library you want
# to use, yet, you will have to specify the library yourself.
#
#
# When you omit arguments and pass a block to `pod`, an instance of
# Pod::Specification is yielded to the block. This is the same class which
# is normally used to specify a Pod.
#
# ```
# pod do |spec|
# spec.name = 'JSONKit'
# spec.version = '1.4'
# spec.source = { :git => 'https://github.com/johnezang/JSONKit.git', :tag => 'v1.4' }
# spec.source_files = 'JSONKit.*'
# end
# ```
#
#
# For more info on the definition of a Pod::Specification see:
# https://github.com/CocoaPods/CocoaPods/wiki/A-pod-specification
def pod(*name_and_version_requirements, &block)
@target_definition.target_dependencies << Dependency.new(*name_and_version_requirements, &block)
end
# Use the dependencies of a podspec file.
#
def podspec(options = nil)
if options && path = options[:path]
path = File.extname(path) == '.podspec' ? path : "#{path}.podspec"
file = Pathname.new(File.expand_path(path))
elsif options && name = options[:name]
name = File.extname(name) == '.podspec' ? name : "#{name}.podspec"
file = config.project_root + name
else
file = config.project_root.glob('*.podspec').first
end
spec = Specification.from_file(file)
spec.activate_platform(@target_definition.platform)
deps = spec.recursive_subspecs.push(spec).map {|specification| specification.external_dependencies }
deps = deps.flatten.uniq
@target_definition.target_dependencies.concat(deps)
end
def dependency(*name_and_version_requirements, &block)
warn "[DEPRECATED] `dependency' is deprecated (use `pod')"
pod(*name_and_version_requirements, &block)
end
# Specifies that a BridgeSupport metadata document should be generated from
# the headers of all installed Pods.
#
# This is for scripting languages such as MacRuby, Nu, and JSCocoa, which use
# it to bridge types, functions, etc better.
def generate_bridge_support!
@generate_bridge_support = true
end
# Defines a new static library target and scopes dependencies defined from
# the given block. The target will by default include the dependencies
# defined outside of the block, unless the `:exclusive => true` option is
# given.
#
# Consider the following Podfile:
#
# pod 'ASIHTTPRequest'
#
# target :debug do
# pod 'SSZipArchive'
# end
#
# target :test, :exclusive => true do
# pod 'JSONKit'
# end
#
# This Podfile defines three targets. The first one is the `:default` target,
# which produces the `libPods.a` file. The second and third are the `:debug`
# and `:test` ones, which produce the `libPods-debug.a` and `libPods-test.a`
# files.
#
# The `:default` target has only one dependency (ASIHTTPRequest), whereas the
# `:debug` target has two (ASIHTTPRequest, SSZipArchive). The `:test` target,
# however, is an exclusive target which means it will only have one
# dependency (JSONKit).
def target(name, options = {})
parent = @target_definition
options[:parent] = parent
@target_definitions[name] = @target_definition = TargetDefinition.new(name, options)
yield
ensure
@target_definition = parent
end
# This hook allows you to make any changes to the downloaded Pods and to
# their targets before they are installed.
#
# pre_install do |installer|
# # Do something fancy!
# end
#
def pre_install(&block)
@pre_install_callback = block
end
# This hook allows you to make any last changes to the generated Xcode project
# before it is written to disk, or any other tasks you might want to perform.
#
# For instance, say you'd want to customize the `OTHER_LDFLAGS` of all targets:
#
# post_install do |installer|
# installer.project.targets.each do |target|
# target.build_configurations.each do |config|
# config.build_settings['GCC_ENABLE_OBJC_GC'] = 'supported'
# end
# end
# end
def post_install(&block)
@post_install_callback = block
end
# Specifies that the -fobjc-arc flag should be added to the OTHER_LD_FLAGS.
#
# This is used as a workaround for a compiler bug with non-ARC projects.
# (see https://github.com/CocoaPods/CocoaPods/issues/142)
#
# This was originally done automatically but libtool as of Xcode 4.3.2 no
# longer seems to support the -fobjc-arc flag. Therefore it now has to be
# enabled explicitly using this method.
#
# This may be removed in a future release.
def set_arc_compatibility_flag!
@set_arc_compatibility_flag = true
end
# Not attributes
def podfile?
true
end
attr_accessor :defined_in_file
attr_reader :target_definitions
def dependencies
@target_definitions.values.map(&:target_dependencies).flatten.uniq
end
def dependency_by_top_level_spec_name(name)
dependencies.find { |d| d.top_level_spec_name == name }
end
def generate_bridge_support?
@generate_bridge_support
end
def set_arc_compatibility_flag?
@set_arc_compatibility_flag
end
def user_build_configurations
configs_array = @target_definitions.values.map { |td| td.user_project.build_configurations }
configs_array.inject({}) { |hash, config| hash.merge(config) }
end
def pre_install!(installer)
@pre_install_callback.call(installer) if @pre_install_callback
end
def post_install!(installer)
@post_install_callback.call(installer) if @post_install_callback
end
def validate!
end
def to_s
"Podfile"
end
end
end
require 'xcodeproj/project' require 'xcodeproj'
# Xcodeproj::Project::Object::PBXCopyFilesBuildPhase.instance_eval do
# def self.new_pod_dir(project, pod_name, path)
# new(project, nil, {
# "dstPath" => "Pods/#{path}",
# "name" => "Copy #{pod_name} Public Headers",
# })
# end
# end
module Pod module Pod
# Provides support for generating the Pods project
#
class Project < Xcodeproj::Project class Project < Xcodeproj::Project
attr_reader :support_files_group include Config::Mixin
# @return [Sandbox] the sandbox that contains the project.
#
attr_reader :sandbox
def initialize(*) # @param [Sandbox] sandbox @see #sandbox
super #
new_group('Pods') def initialize(sandbox)
super(nil)
@sandbox = sandbox
@support_files_group = new_group('Targets Support Files') @support_files_group = new_group('Targets Support Files')
@user_build_configurations = [] @user_build_configurations = []
@libraries = []
end end
def user_build_configurations=(user_build_configurations) # @return [Pathname] the path of the Pods project.
@user_build_configurations = user_build_configurations #
# The configurations at the top level only need to exist, they don't hold def path
# any build settings themselves, that's left to `add_pod_target`. sandbox.project_path
user_build_configurations.each do |name, _|
unless build_configurations.map(&:name).include?(name)
bc = new(XCBuildConfiguration)
bc.name = name
build_configurations << bc
end
end
end end
# Shortcut access to the `Pods' PBXGroup. # @return [String] a string representation suited for debugging.
#
def inspect
"#<#{self.class}>"
end
#--------------------------------------#
#@!group Working with groups
# @return [PBXGroup] the group where the support files for the Pod
# libraries should be added.
#
attr_reader :support_files_group
# Returns the `Pods` group, creating it if needed.
#
# @return [PBXGroup] the group.
#
def pods def pods
@pods ||= self['Pods'] || new_group('Pods') @pods ||= new_group('Pods')
end end
# Shortcut access to the `Local Pods' PBXGroup. # Returns the `Local Pods` group, creating it if needed. This group is used
# to contain locally sourced pods.
#
# @return [PBXGroup] the group.
#
def local_pods def local_pods
@local_pods ||= self['Local Pods'] || new_group('Local Pods') @local_pods ||= new_group('Local Pods')
end end
# Adds a group as child to the `Pods' group namespacing subspecs. # Adds a group as child to the `Pods` group namespacing subspecs.
#
# TODO: Pass the specification directly and don't expose the pods groups.
#
def add_spec_group(name, parent_group) def add_spec_group(name, parent_group)
current_group = parent_group current_group = parent_group
group = nil group = nil
...@@ -55,19 +74,69 @@ module Pod ...@@ -55,19 +74,69 @@ module Pod
group group
end end
def add_pod_target(name, platform) #--------------------------------------#
target = new_target(:static_library, name, platform.name)
settings = {} #@!group Manipulating the project
if platform.requires_legacy_ios_archs?
settings['ARCHS'] = "armv6 armv7" # @return [Array<Library>] the libraries generated from the target
# definitions of the Podfile.
#
attr_reader :libraries
# Adds a file reference to the podfile.
#
# @param [#to_s] path
# the path of the podfile
#
# @return [PBXFileReference]
#
def add_podfile(podfile_path)
podfile_path = Pathname.new(podfile_path)
podfile_ref = new_file(podfile_path.relative_path_from(path.dirname))
podfile_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
podfile_ref
end
# Creates the user build configurations for the Pods project.
#
# @note The configurations at the top level only need to exist, they
# don't hold any build settings themselves, that's left to
# `add_pod_library`.
#
# @return [void]
#
# TODO: why is this needed?
#
def user_build_configurations=(user_build_configurations)
@user_build_configurations = user_build_configurations
user_build_configurations.each do |name, _|
unless build_configurations.map(&:name).include?(name)
bc = new(XCBuildConfiguration)
bc.name = name
build_configurations << bc
end
end end
end
if platform == :ios && platform.deployment_target # Creates a static library target for the given target_definition.
# TODO: add for osx as well #
settings['IPHONEOS_DEPLOYMENT_TARGET'] = platform.deployment_target.to_s # @param [TargetDefinition] target_definition
# the target definition of the library.
#
# @raise If the target definition doesn't specifies a platform.
#
# @return [Library] the library for the created target.
#
def add_pod_library(target_definition)
name = target_definition.label
platform = target_definition.platform
unless platform
raise Informative, "Missing platform for #{target_definition}"
end end
settings = settings_for_platform(platform)
target = new_target(:static_library, name, platform.name)
target.build_settings('Debug').merge!(settings) target.build_settings('Debug').merge!(settings)
target.build_settings('Release').merge!(settings) target.build_settings('Release').merge!(settings)
...@@ -81,7 +150,265 @@ module Pod ...@@ -81,7 +150,265 @@ module Pod
end end
end end
target lib = Library.new(target_definition, target)
libraries << lib
lib
end
#--------------------------------------#
#@!group Helpers
private
# Returns the Xcode build settings for a target with the given platform.
#
# @param [Platform] platform
# the platform for which the build settings are needed.
#
# @return [Hash] the build settings.
#
def settings_for_platform(platform)
settings = {}
settings['ARCHS'] = "armv6 armv7" if platform.requires_legacy_ios_archs?
if dt = platform.deployment_target
if platform == :ios
settings['IPHONEOS_DEPLOYMENT_TARGET'] = dt.to_s
else
# TODO: add MACOSX_DEPLOYMENT_TARGET
end
end
settings
end
#-------------------------------------------------------------------------#
# Describes a library generated for the Pods project.
#
class Library
include Config::Mixin
# @return [PBXNativeTarget] the target definition of the Podfile that
# generated this library.
#
attr_reader :target_definition
# @return [PBXNativeTarget] the target generated in the Pods project for
# this library.
#
attr_reader :target
# @param [TargetDefinition] target_definition @see target_definition
# @param [PBXNativeTarget] target @see target
# @param [Project] project @see project
#
def initialize(target_definition, target)
@target_definition = target_definition
@target = target
end
def label
target_definition.label
end
#-----------------------------------------------------------------------#
# @!group User project
# @return [Xcodeproj::Project]
# the project that will be integrated.
#
def user_project
@user_project ||= Xcodeproj::Project.new(user_project_path)
end
# Returns the path of the user project that the {TargetDefinition}
# should integrate.
#
# @raises If the project is implicit and there are multiple projects.
#
# @raises If the path doesn't exits.
#
# @return [Pathname] the path of the user project.
#
def user_project_path
unless @user_project_path
if target_definition.user_project_path
@user_project_path = Pathname.new(config.project_root + target_definition.user_project_path)
unless @user_project_path.exist?
raise Informative, "Unable to find the Xcode project `#{@user_project_path}` for the target `#{label}`."
end
else
xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
if xcodeprojs.size == 1
@user_project_path = xcodeprojs.first
else
raise Informative, "Could not automatically select an Xcode project. " \
"Specify one in your Podfile like so:\n\n" \
" xcodeproj 'path/to/Project.xcodeproj'\n"
end
end
end
@user_project_path
end
# Returns a list of the targets from the project of {TargetDefinition}
# that needs to be integrated.
#
# @note The method first looks if there is a target specified with
# the `link_with` option of the {TargetDefinition}. Otherwise
# it looks for the target that has the same name of the target
# definition. Finally if no target was found the first
# encountered target is returned (it is assumed to be the one
# to integrate in simple projects).
#
# @note This will only return targets that do **not** already have
# the Pods library in their frameworks build phase.
#
# @return [Array<PBXNativeTarget>] the list of targets that the Pods
# lib should be linked with.
#
def user_targets
unless @targets
if link_with = target_definition.link_with
@targets = user_project.targets.select { |t| link_with.include? t.name }
raise Informative, "Unable to find a target named `#{link_with.to_sentence}` to link with target definition `#{target_definition.name}`" if @targets.empty?
elsif target_definition.name != :default
target = user_project.targets.find { |t| t.name == target_definition.name.to_s }
@targets = [ target ].compact
raise Informative, "Unable to find a target named `#{target_definition.name.to_s}`" if @targets.empty?
else
@targets = [ user_project.targets.first ].compact
raise Informative, "Unable to find a target" if @targets.empty?
end
end
@targets
end
#-----------------------------------------------------------------------#
# @!group TargetInstaller & UserProjectIntegrator helpers
# @return [String] the name of the library.
#
def name
"lib#{target_definition.label}.a"
end
# @return [Project] the Pods project.
#
def project
target.project
end
# Computes the relative path of a sandboxed file from the `$(SRCROOT)` of
# the user's project.
#
# @param [Pathname] path
#
# @return [String] the computed path.
#
def relative_to_srcroot(path = nil)
base_path = path ? config.project_pods_root + path : config.project_pods_root
(base_path).relative_path_from(user_project_path.dirname).to_s
end
def relative_pods_root
"${SRCROOT}/#{relative_to_srcroot}"
end
# @return [Pathname] the folder where to store the support files of this
# library.
#
# TODO: each library should have a folder for its support files
#
def support_files_root
project.sandbox.root
end
#---------------------------------------#
# @return [Xcodeproj::Config] the configuration file of the library
#
# @note The configuration is generated by the {TargetInstaller} and
# used by {UserProjectIntegrator} to check for any overridden
# values.
#
attr_accessor :xcconfig
# @return [String] the name of the xcconfig file relative to this target.
#
def xcconfig_name
"#{label}.xcconfig"
end
# @return [Pathname] the absolute path of the xcconfig file.
#
def xcconfig_path
support_files_root + xcconfig_name
end
# @return [String] the path of the xcconfig file relative to the root of
# the user project.
#
def xcconfig_relative_path
relative_to_srcroot("#{xcconfig_name}").to_s
end
#---------------------------------------#
# @return [String] the name of the copy resources script relative to this
# target.
#
def copy_resources_script_name
"#{label}-resources.sh"
end
# @return [Pathname] the absolute path of the copy resources script.
#
def copy_resources_script_path
support_files_root + copy_resources_script_name
end
# @return [String] the path of the copy resources script relative to the
# root of the user project.
#
def copy_resources_script_relative_path
"${SRCROOT}/#{relative_to_srcroot("#{copy_resources_script_name}")}"
end
#---------------------------------------#
# @return [String] the name of the prefix header file relative to this
# target.
#
def prefix_header_name
"#{label}-prefix.pch"
end
# @return [Pathname] the absolute path of the prefix header file.
#
def prefix_header_path
support_files_root + prefix_header_name
end
#---------------------------------------#
# @return [String] the name of the bridge support file relative to this
# target.
#
def bridge_support_name
"#{label}.bridgesupport"
end
# @return [Pathname] the absolute path of the bridge support file.
#
def bridge_support_path
support_files_root + bridge_support_name
end
end end
end end
end end
...@@ -38,7 +38,7 @@ module Pod ...@@ -38,7 +38,7 @@ module Pod
# #
attr_accessor :update_external_specs attr_accessor :update_external_specs
def initialize(sandbox, podfile, locked_dependencies) def initialize(sandbox, podfile, locked_dependencies = [])
@sandbox = sandbox @sandbox = sandbox
@podfile = podfile @podfile = podfile
@locked_dependencies = locked_dependencies @locked_dependencies = locked_dependencies
...@@ -68,7 +68,7 @@ module Pod ...@@ -68,7 +68,7 @@ module Pod
# whether the resolver is in update mode or not. # whether the resolver is in update mode or not.
# #
def resolve def resolve
@cached_sources = Source::Aggregate.new @cached_sources = Source::Aggregate.new(config.repos_dir)
@cached_sets = {} @cached_sets = {}
@cached_specs = {} @cached_specs = {}
@specs_by_target = {} @specs_by_target = {}
...@@ -86,12 +86,15 @@ module Pod ...@@ -86,12 +86,15 @@ module Pod
@specs_by_target @specs_by_target
end end
#-----------------------------------------------------------------------#
private private
# @return [Array<Set>] A cache of the sets used to resolve the dependencies. # @return [Array<Set>] A cache of the sets used to resolve the dependencies.
# #
attr_reader :cached_sets attr_reader :cached_sets
# @return [Source::Aggregate] A cache of the sources needed to find the # @return [Source::Aggregate] A cache of the sources needed to find the
# podspecs. # podspecs.
# #
...@@ -125,7 +128,7 @@ module Pod ...@@ -125,7 +128,7 @@ module Pod
if @loaded_specs.include?(dependency.name) if @loaded_specs.include?(dependency.name)
validate_platform(@cached_specs[dependency.name], target_definition) validate_platform(@cached_specs[dependency.name], target_definition)
else else
spec = set.specification_by_name(dependency.name) spec = set.specification.subspec_by_name(dependency.name)
@pods_from_external_sources << spec.pod_name if dependency.external? @pods_from_external_sources << spec.pod_name if dependency.external?
@loaded_specs << spec.name @loaded_specs << spec.name
@cached_specs[spec.name] = spec @cached_specs[spec.name] = spec
...@@ -145,7 +148,7 @@ module Pod ...@@ -145,7 +148,7 @@ module Pod
# #
# If the update_external_specs flag is activated the dependencies with # If the update_external_specs flag is activated the dependencies with
# external sources are always resolved against the remote. Otherwise the # external sources are always resolved against the remote. Otherwise the
# specification is retrieved from the sanbox that fetches the external # specification is retrieved from the sandbox that fetches the external
# source only if needed. # source only if needed.
# #
def find_cached_set(dependency, platform) def find_cached_set(dependency, platform)
...@@ -155,13 +158,15 @@ module Pod ...@@ -155,13 +158,15 @@ module Pod
Specification::Set::External.new(dependency.specification) Specification::Set::External.new(dependency.specification)
elsif external_source = dependency.external_source elsif external_source = dependency.external_source
if update_external_specs if update_external_specs
spec = external_source.specification_from_external(sandbox, platform) external_source = ExternalSources.from_dependency(dependency)
spec = external_source.specification_from_external(@sandbox, platform)
else else
spec = external_source.specification_from_sandbox(sandbox, platform) external_source = ExternalSources.from_dependency(dependency)
spec = external_source.specification_from_sandbox(@sandbox, platform)
end end
set = Specification::Set::External.new(spec) set = Specification::Set::External.new(spec)
if dependency.subspec_dependency? if dependency.subspec_dependency?
@cached_sets[dependency.top_level_spec_name] ||= set @cached_sets[dependency.root_name] ||= set
end end
set set
else else
......
...@@ -26,14 +26,18 @@ module Pod ...@@ -26,14 +26,18 @@ module Pod
root + "Pods.xcodeproj" root + "Pods.xcodeproj"
end end
def inspect
"#<#{self.class}> with root #{root}"
end
def prepare_for_install def prepare_for_install
build_headers.prepare_for_install build_headers.prepare_for_install
public_headers.prepare_for_install public_headers.prepare_for_install
end end
def local_pod_for_spec(spec, platform) def local_pod_for_spec(spec, platform)
key = [spec.top_level_parent.name, platform.to_sym] key = [spec.root.name, platform.to_sym]
(@cached_local_pods[key] ||= LocalPod.new(spec.top_level_parent, self, platform)).tap do |pod| (@cached_local_pods[key] ||= LocalPod.new(spec.root, self, platform)).tap do |pod|
pod.add_specification(spec) pod.add_specification(spec)
end end
end end
...@@ -41,8 +45,8 @@ module Pod ...@@ -41,8 +45,8 @@ module Pod
# TODO: refactor the pods from a local source should not be chached by the sandbox # TODO: refactor the pods from a local source should not be chached by the sandbox
# #
def locally_sourced_pod_for_spec(spec, platform) def locally_sourced_pod_for_spec(spec, platform)
key = [spec.top_level_parent.name, platform.to_sym] key = [spec.root.name, platform.to_sym]
(@cached_locally_sourced_pods[key] ||= LocalPod::LocalSourcedPod.new(spec.top_level_parent, self, platform)).tap do |pod| (@cached_locally_sourced_pods[key] ||= LocalPod::LocalSourcedPod.new(spec.root, self, platform)).tap do |pod|
pod.add_specification(spec) pod.add_specification(spec)
end end
end end
......
module Pod module Pod
# The {Source} class is responsible to manage a collection of podspecs.
#
# @note The backing store of the podspecs collection is an implementation detail
# abstraced from the rest of CocoaPods.
#
# @note The default implementation uses a git repo as a backing store, where the
# podspecs are namespaces as:
#
# #{POD_NAME}/#{VERSION}/#{POD_NAME}.podspec
#
# @todo For better abstranction the sources should be responsible to update themselves.
#
class Source class Source
class << self
# @return [Pathname] The location of the repo. include Config::Mixin
#
attr_reader :repo
# @param [Pathname] repo @see repo.
#
def initialize(repo)
@repo = repo
end
# @return [String] the name of the repo.
#
def name
@repo.basename.to_s
end
# @!group Quering the source
# @return [Array<String>] The name of all the Pods.
#
def pods
@repo.children.map do |child|
child.basename.to_s if child.directory? && child.basename.to_s != '.git'
end.compact
end
# @return [Array<Sets>] The sets of all the Pods.
#
def pod_sets
pods.map { |pod| Specification::Set.new(pod, self) }
end
# @return [Array<Version>] All the available versions for the Pod, sorted
# from highest to lowest.
#
# @param [String] name The name of the Pod.
#
def versions(name)
pod_dir = repo + name
pod_dir.children.map do |v|
basename = v.basename.to_s
Version.new(basename) if v.directory? && basename[0,1] != '.'
end.compact.sort.reverse
end
# @return [Specification] The specification for a given version of Pod.
#
# @param [String] name The name of the Pod.
#
# @param [Version,String] version
# The version for the specification.
#
def specification(name, version)
specification_path = repo + name + version.to_s + "#{name}.podspec"
Specification.from_file(specification_path)
end
# @!group Searching the source
# @return [Set] A set for a given dependency. The set is identified by the
# name of the dependency and takes into account subspecs.
#
def search(dependency)
pod_sets.find do |set|
# First match the (top level) name, which does not yet load the spec from disk
set.name == dependency.top_level_spec_name &&
# Now either check if it's a dependency on the top level spec, or if it's not
# check if the requested subspec exists in the top level spec.
set.specification.subspec_by_name(dependency.name)
end
end
# @return [Array<Set>] The sets that contain the search term.
#
# @param [String] query The search term.
#
# @param [Bool] full_text_search Whether the search should be limited to
# the name of the Pod or should include
# also the author, the summary, and the
# description.
#
# @note Full text search requires to load the specification for each pod,
# hence is considerably slower.
#
def search_by_name(query, full_text_search = false)
pod_sets.map do |set|
text = if full_text_search
s = set.specification
"#{s.name} #{s.authors} #{s.summary} #{s.description}"
else
set.name
end
set if text.downcase.include?(query.downcase)
end.compact
end
# The {Source::Aggregate} manages all the sources available to CocoaPods. # TODO: Move exceptions to clients?
#
class Aggregate
# @return [Array<Source>] All the sources. # @return [Array<Source>] the list of all the sources known to this
# installation of CocoaPods.
# #
def all def all
@sources ||= dirs.map { |repo| Source.new(repo) }.sort_by(&:name) Aggregate.new(config.repos_dir).all
end
# @return [Array<String>] The names of all the pods available.
#
def all_pods
all.map(&:pods).flatten.uniq
end end
# @return [Array<Set>] The sets for all the pods available. # @return [Array<Specification::Set>] the list of all the specification
# # sets know to this installation of CocoaPods.
# @note Implementation detail: The sources don't cache their values
# because they might change in response to an update. Therefore
# this method to prevent slowness caches the values before
# processing them.
# #
def all_sets def all_sets
pods_by_source = {} Aggregate.new(config.repos_dir).all_sets
all.each do |source|
pods_by_source[source] = source.pods
end
sources = pods_by_source.keys
pods = pods_by_source.values.flatten.uniq
pods.map do |pod|
pod_sources = sources.select{ |s| pods_by_source[s].include?(pod) }.compact
Specification::Set.new(pod, pod_sources)
end
end end
# @return [Set] A set for a given dependency including all the Sources # Search all the sources to match the set for the given dependency.
# that countain the Pod.
# #
# @raises If no source including the set can be foud. # @return [Set, nil] a set for a given dependency including all the
# {Source} that contain the Pod. If no sources containing the
# Pod where found it returns nil.
# #
# @see Source#search # @raise If no source including the set can be found.
# #
def search(dependency) def search(dependency)
sources = all.select { |s| !s.search(dependency).nil? } set = Aggregate.new(config.repos_dir).search(dependency)
raise(Informative, "[!] Unable to find a pod named `#{dependency.name}'".red) if sources.empty? raise Informative, "Unable to find a pod named `#{dependency.name}`" unless set
Specification::Set.new(dependency.top_level_spec_name, sources) set
end end
# @return [Array<Set>] The sets that contain the search term. # Search all the sources with the given search term.
# #
# @raises If no source including the set can be foud. # @param [String] query
# The search term.
# #
# @see Source#search_by_name # @param [Bool] full_text_search
# Whether the search should be limited to the name of the Pod or
# should include also the author, the summary, and the
# description.
# #
def search_by_name(query, full_text_search = false) # @raises If no source including the set can be found.
pods_by_source = {} #
result = [] # @note Full text search requires to load the specification for each pod,
all.each { |s| pods_by_source[s] = s.search_by_name(query, full_text_search).map(&:name) } # hence is considerably slower.
pod_names = pods_by_source.values.flatten.uniq #
pod_names.each do |pod| # @return [Array<Set>] The sets that contain the search term.
sources = [] #
pods_by_source.each{ |source, pods| sources << source if pods.include?(pod) } def search_by_name(name, full_text_search = false)
result << Specification::Set.new(pod, sources) result = Aggregate.new(config.repos_dir).search_by_name(name, full_text_search)
end
if result.empty? if result.empty?
extra = ", author, summary, or description" if full_text_search extra = ", author, summary, or description" if full_text_search
raise(Informative, "Unable to find a pod with name" \ raise Informative "Unable to find a pod with name#{extra} matching `#{query}'"
"#{extra} matching `#{query}'")
end end
result result
end end
# @return [Array<Pathname>] The directories where the sources are stored.
#
# @raises If the repos dir doesn't exits.
#
def dirs
if ENV['CP_MASTER_REPO_DIR']
[Pathname.new(ENV['CP_MASTER_REPO_DIR'])]
else
repos_dir = Config.instance.repos_dir
unless repos_dir.exist?
raise Informative, "No spec repos found in `#{repos_dir}'. " \
"To fetch the `master' repo run: $ pod setup"
end
repos_dir.children.select(&:directory?)
end
end
end
# @!group Shortcuts
def self.all
Aggregate.new.all
end
def self.all_sets
Aggregate.new.all_sets
end
def self.search(dependency)
Aggregate.new.search(dependency)
end
def self.search_by_name(name, full_text_search = false)
Aggregate.new.search_by_name(name, full_text_search)
end end
end end
end end
require 'xcodeproj/config'
require 'active_support/core_ext/string/strip.rb'
module Pod
extend Config::Mixin
def self._eval_podspec(path)
string = File.open(path, 'r:utf-8') { |f| f.read }
# TODO: work around for Rubinius incomplete encoding in 1.9 mode
string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
eval(string, nil, path.to_s)
end
class Specification
autoload :Set, 'cocoapods/specification/set'
autoload :Statistics, 'cocoapods/specification/statistics'
### Initalization
# The file is expected to define and return a Pods::Specification.
# If name is equals to nil it returns the top level Specification,
# otherwise it returned the specification with the name that matches
def self.from_file(path, subspec_name = nil)
unless path.exist?
raise Informative, "No podspec exists at path `#{path}'."
end
spec = ::Pod._eval_podspec(path)
spec.defined_in_file = path
spec.subspec_by_name(subspec_name)
end
def initialize(parent = nil, name = nil)
@parent, @name = parent, name
@define_for_platforms = [:osx, :ios]
@clean_paths, @subspecs = [], []
@deployment_target = {}
unless parent
@source = {:git => ''}
end
# multi-platform attributes
%w[ source_files
public_header_files
resources
preserve_paths
exclude_header_search_paths
frameworks
weak_frameworks
libraries
dependencies
compiler_flags ].each do |attr|
instance_variable_set( "@#{attr}", { :ios => [], :osx => [] } )
end
@xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new }
@header_dir = { :ios => nil, :osx => nil }
@requires_arc = { :ios => nil, :osx => nil }
@header_mappings_dir = { :ios => nil, :osx => nil }
yield self if block_given?
end
### Meta programming
# Creates a top level attribute reader. A lambda can
# be passed to process the ivar before returning it
def self.top_attr_reader(attr, read_lambda = nil)
define_method(attr) do
ivar = instance_variable_get("@#{attr}")
@parent ? top_level_parent.send(attr) : ( read_lambda ? read_lambda.call(self, ivar) : ivar )
end
end
# Creates a top level attribute writer. A lambda can
# be passed to initalize the value
def self.top_attr_writer(attr, init_lambda = nil)
define_method("#{attr}=") do |value|
raise Informative, "#{self.inspect} Can't set `#{attr}' for subspecs." if @parent
instance_variable_set("@#{attr}", init_lambda ? init_lambda.call(value) : value);
end
end
# Creates a top level attribute accessor. A lambda can
# be passed to initialize the value in the attribute writer.
def self.top_attr_accessor(attr, writer_labmda = nil)
top_attr_reader attr
top_attr_writer attr, writer_labmda
end
# Returns the value of the attribute for the active platform
# chained with the upstream specifications. The ivar must store
# the platform specific values as an array.
#
def self.pltf_chained_attr_reader(attr)
define_method(attr) do
active_plaform_check
ivar_value = instance_variable_get("@#{attr}")[active_platform]
@parent ? @parent.send(attr) + ivar_value : ( ivar_value )
end
end
# Returns the first value defined of the attribute traversing the chain
# upwards.
#
def self.pltf_first_defined_attr_reader(attr)
define_method(attr) do
active_plaform_check
ivar_value = instance_variable_get("@#{attr}")[active_platform]
ivar_value.nil? ? (@parent.send(attr) if @parent) : ivar_value
end
end
def active_plaform_check
raise Informative, "#{self.inspect} not activated for a platform before consumption." unless active_platform
end
# Attribute writer that works in conjuction with the PlatformProxy.
def self.platform_attr_writer(attr, block = nil)
define_method("#{attr}=") do |value|
current = instance_variable_get("@#{attr}")
@define_for_platforms.each do |platform|
block ? current[platform] = block.call(value, current[platform]) : current[platform] = value
end
end
end
def self.pltf_chained_attr_accessor(attr, block = nil)
pltf_chained_attr_reader(attr)
platform_attr_writer(attr, block)
end
# The PlatformProxy works in conjuction with Specification#_on_platform.
# It allows a syntax like `spec.ios.source_files = file`
class PlatformProxy
def initialize(specification, platform)
@specification, @platform = specification, platform
end
%w{ source_files=
public_header_files=
resource=
resources=
preserve_paths=
preserve_path=
xcconfig=
framework=
frameworks=
weak_framework=
weak_frameworks=
library=
libraries=
compiler_flags=
deployment_target=
header_dir=
requires_arc
dependency }.each do |method|
define_method(method) do |args|
@specification._on_platform(@platform) do
@specification.send(method, args)
end
end
end
end
def ios
PlatformProxy.new(self, :ios)
end
def osx
PlatformProxy.new(self, :osx)
end
### Deprecated attributes - TODO: remove once master repo and fixtures have been updated
attr_writer :part_of_dependency
attr_writer :part_of
top_attr_accessor :clean_paths, lambda { |patterns| pattern_list(patterns) }
alias_method :clean_path=, :clean_paths=
### Regular attributes
attr_accessor :parent
attr_accessor :preferred_dependency
def name
@parent ? "#{@parent.name}/#{@name}" : @name
end
attr_writer :name
# @return [String] The name of the pod.
#
def pod_name
top_level_parent.name
end
### Attributes that return the first value defined in the chain
def platform
@platform || ( @parent ? @parent.platform : nil )
end
def platform=(platform)
@platform = Platform.new(*platform)
end
# If not platform is specified all the platforms are returned.
def available_platforms
platform.nil? ? @define_for_platforms.map { |platform| Platform.new(platform, deployment_target(platform)) } : [ platform ]
end
### Top level attributes. These attributes represent the unique features of pod and can't be specified by subspecs.
top_attr_accessor :defined_in_file
top_attr_accessor :source
top_attr_accessor :homepage
top_attr_accessor :summary
top_attr_accessor :documentation
top_attr_accessor :version, lambda { |v| Version.new(v) }
top_attr_reader :description, lambda { |instance, ivar| ivar || instance.summary }
top_attr_writer :description, lambda { |d| d.strip_heredoc }
# @!method license
#
# @abstract
# The license of the pod.
#
# @example
# s.license = 'MIT'
# s.license = { :type => 'MIT', :file => 'license.txt', :text => 'Permission is granted to...' }
#
top_attr_accessor :license, lambda { |license|
license = ( license.kind_of? String ) ? { :type => license } : license
license[:text] = license[:text].strip_heredoc if license[:text]
license
}
# @!method authors
#
# @abstract
# The list of the authors (with email) of the pod.
#
top_attr_accessor :authors, lambda { |*names_and_email_addresses|
list = names_and_email_addresses.flatten
unless list.first.is_a?(Hash)
authors = list.last.is_a?(Hash) ? list.pop : {}
list.each { |name| authors[name] = nil }
end
authors || list.first
}
alias_method :author=, :authors=
### Attributes **with** multiple platform support
# @todo allow for subspecs?
#
top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
top_attr_accessor :prefix_header_contents
pltf_chained_attr_accessor :source_files, lambda {|value, current| pattern_list(value) }
pltf_chained_attr_accessor :public_header_files, lambda {|value, current| pattern_list(value) }
pltf_chained_attr_accessor :resources, lambda {|value, current| pattern_list(value) }
pltf_chained_attr_accessor :preserve_paths, lambda {|value, current| pattern_list(value) } # Paths that should not be cleaned
pltf_chained_attr_accessor :exclude_header_search_paths, lambda {|value, current| pattern_list(value) } # Headers to be excluded from being added to search paths (RestKit)
pltf_chained_attr_accessor :frameworks, lambda {|value, current| (current << value).flatten }
pltf_chained_attr_accessor :weak_frameworks, lambda {|value, current| (current << value).flatten }
pltf_chained_attr_accessor :libraries, lambda {|value, current| (current << value).flatten }
alias_method :resource=, :resources=
alias_method :preserve_path=, :preserve_paths=
alias_method :framework=, :frameworks=
alias_method :weak_framework=, :weak_frameworks=
alias_method :library=, :libraries=
# @!method requires_arc=
#
# @abstract Wether the `-fobjc-arc' flag should be added to the compiler
# flags.
#
# @param [Bool] Wether the source files require ARC.
#
platform_attr_writer :requires_arc
pltf_first_defined_attr_reader :requires_arc
# @!method header_dir=
#
# @abstract The directory where to name space the headers files of
# the specification.
#
# @param [String] The headers directory.
#
platform_attr_writer :header_dir, lambda { |dir, _| Pathname.new(dir) }
pltf_first_defined_attr_reader :header_dir
# If not provided the headers files are flattened
#
platform_attr_writer :header_mappings_dir, lambda { |file, _| Pathname.new(file) }
pltf_first_defined_attr_reader :header_mappings_dir
# @!method xcconfig=
#
platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } }
def xcconfig
result = raw_xconfig.dup
result.libraries.merge(libraries)
result.frameworks.merge(frameworks)
result.weak_frameworks.merge(weak_frameworks)
result
end
def raw_xconfig
@parent ? @parent.raw_xconfig.merge(@xcconfig[active_platform]) : @xcconfig[active_platform]
end
def recursive_compiler_flags
@parent ? @parent.recursive_compiler_flags | @compiler_flags[active_platform] : @compiler_flags[active_platform]
end
def compiler_flags
flags = recursive_compiler_flags.dup
flags << '-fobjc-arc' if requires_arc
flags.join(' ')
end
platform_attr_writer :compiler_flags, lambda {|value, current| current << value }
def dependency(*name_and_version_requirements)
name, *version_requirements = name_and_version_requirements.flatten
raise Informative, "A specification can't require self as a subspec" if name == self.name
raise Informative, "A subspec can't require one of its parents specifications" if @parent && @parent.name.include?(name)
dep = Dependency.new(name, *version_requirements)
@define_for_platforms.each do |platform|
@dependencies[platform] << dep
end
dep
end
# External dependencies are inherited by subspecs
def external_dependencies(all_platforms = false)
active_plaform_check unless all_platforms
result = all_platforms ? @dependencies.values.flatten : @dependencies[active_platform]
result += parent.external_dependencies if parent
result
end
# A specification inherits the preferred_dependency or
# all the compatible subspecs as dependencies
def subspec_dependencies
active_plaform_check
specs = preferred_dependency ? [subspec_by_name("#{name}/#{preferred_dependency}")] : subspecs
specs.compact \
.select { |s| s.supports_platform?(active_platform) } \
.map { |s| Dependency.new(s.name, version) }
end
def dependencies
external_dependencies + subspec_dependencies
end
include Config::Mixin
def top_level_parent
@parent ? @parent.top_level_parent : self
end
def subspec?
!@parent.nil?
end
def subspec(name, &block)
subspec = Specification.new(self, name, &block)
@subspecs << subspec
subspec
end
attr_reader :subspecs
def recursive_subspecs
@recursive_subspecs ||= begin
mapper = lambda do |spec|
spec.subspecs.map do |subspec|
[subspec, *mapper.call(subspec)]
end.flatten
end
mapper.call(self)
end
end
def subspec_by_name(name)
return self if name.nil? || name == self.name
# Remove this spec's name from the beginning of the name we’re looking for
# and take the first component from the remainder, which is the spec we need
# to find now.
remainder = name[self.name.size+1..-1]
raise Informative, "Unable to find a specification named `#{name}' in `#{pod_name}'." unless remainder
subspec_name = remainder.split('/').shift
subspec = subspecs.find { |s| s.name == "#{self.name}/#{subspec_name}" }
raise Informative, "Unable to find a specification named `#{name}' in `#{pod_name}'." unless subspec
# If this was the last component in the name, then return the subspec,
# otherwise we recursively keep calling subspec_by_name until we reach the
# last one and return that
remainder.empty? ? subspec : subspec.subspec_by_name(name)
end
def local?
!source.nil? && !source[:local].nil?
end
def pod_destroot
config.project_pods_root + top_level_parent.name
end
def self.pattern_list(patterns)
if patterns.is_a?(Array) && (!defined?(Rake) || !patterns.is_a?(Rake::FileList))
patterns
else
[patterns]
end
end
# This method takes a header path and returns the location it should have
# in the pod's header dir.
#
# By default all headers are copied to the pod's header dir without any
# namespacing. However if the top level attribute accessor header_mappings_dir
# is specified the namespacing will be preserved from that directory.
def copy_header_mapping(from)
header_mappings_dir ? from.relative_path_from(header_mappings_dir) : from.basename
end
# This is a convenience method which gets called after all pods have been
# downloaded but before they have been installed, and the Xcode project and
# related files have been generated. (It receives the Pod::LocalPod
# instance generated form the specification and the #
# Pod::Podfile::TargetDefinition instance for the current target.) Override
# this to, for instance, to run any build script:
#
# Pod::Spec.new do |s|
# def s.pre_install(pod, target_definition)
# Dir.chdir(pod.root){ `sh make.sh` }
# end
# end
def pre_install(pod, target_definition)
FALSE
end
# This is a convenience method which gets called after all pods have been
# downloaded, installed, and the Xcode project and related files have been
# generated. (It receives the Pod::Installer::TargetInstaller instance for
# the current target.) Override this to, for instance, add to the prefix
# header:
#
# Pod::Spec.new do |s|
# def s.post_install(target_installer)
# prefix_header = config.project_pods_root + target_installer.prefix_header_filename
# prefix_header.open('a') do |file|
# file.puts(%{#ifdef __OBJC__\n#import "SSToolkitDefines.h"\n#endif})
# end
# end
# end
def post_install(target_installer)
FALSE
end
def podfile?
false
end
# This is used by the specification set
def dependency_by_top_level_spec_name(name)
external_dependencies(true).each do |dep|
return dep if dep.top_level_spec_name == name
end
end
def to_s
"#{name} (#{version})"
end
def inspect
"#<#{self.class.name} for #{to_s}>"
end
def ==(other)
object_id == other.object_id ||
(self.class === other &&
name && name == other.name &&
version && version == other.version)
end
# Returns whether the specification is supported in a given platform
def supports_platform?(*platform)
platform = platform[0].is_a?(Platform) ? platform[0] : Platform.new(*platform)
available_platforms.any? { |p| platform.supports?(p) }
end
# Defines the active platform for comsumption of the specification and
# returns self for method chainability.
# The active platform must the the same accross the chain so attributes
# that are inherited can be correctly resolved.
def activate_platform(*platform)
platform = platform[0].is_a?(Platform) ? platform[0] : Platform.new(*platform)
raise Informative, "#{to_s} is not compatible with #{platform}." unless supports_platform?(platform)
top_level_parent.active_platform = platform.to_sym
self
end
top_attr_accessor :active_platform
### Not attributes
# @visibility private
#
# This is used by PlatformProxy to assign attributes for the scoped platform.
def _on_platform(platform)
before, @define_for_platforms = @define_for_platforms, [platform]
yield
ensure
@define_for_platforms = before
end
# @visibility private
#
# This is multi-platform and to support
# subspecs with different platforms is is resolved as the
# first non nil value accross the chain.
def deployment_target=(version)
raise Informative, "The deployment target must be defined per platform like `s.ios.deployment_target = '5.0'`." unless @define_for_platforms.count == 1
@deployment_target[@define_for_platforms.first] = version
end
def deployment_target(platform)
@deployment_target[platform] || ( @parent ? @parent.deployment_target(platform) : nil )
end
end
Spec = Specification
end
require 'active_support/core_ext/array/conversions'
module Pod
class Specification
# A Specification::Set is resposible of handling all the specifications of
# a Pod. This class stores the information of the dependencies that reuired
# a Pod in the resolution process.
#
# @note The alpahbetical order of the sets is used to select a specification
# if multiple are available for a given version.
#
# @note The set class is not and should be not aware of the backing store
# of a Source.
#
class Set
# @return [String] The name of the Pod.
#
attr_reader :name
# @return [Array<Source>] The sources that contain the specifications for
# the available versions of a Pod.
#
attr_reader :sources
# @param [String] name The name of the Pod.
#
# @param [Array<Source>,Source] sources
# The sources that contain a Pod.
#
def initialize(name, sources)
@name = name
sources = sources.is_a?(Array) ? sources : [sources]
@sources = sources.sort_by(&:name)
@required_by = []
@dependencies = []
end
# @return [void] Stores a dependency on the Pod.
#
# @param [Dependency] dependency A dependency that requires the Pod.
#
# @param [String] dependent_name The name of the owner of the
# dependency. It is used only to display
# the Pod::Informative.
#
# @raises If the versions requirement of the dependency are not
# compatible with the previously stored dependencies.
#
def required_by(dependency, dependent_name)
unless @required_by.empty? || dependency.requirement.satisfied_by?(Gem::Version.new(required_version.to_s))
raise Informative, "#{dependent_name} tries to activate `#{dependency}', but already activated version `#{required_version}' by #{@required_by.to_sentence}."
end
@specification = nil
@required_by << dependent_name
@dependencies << dependency
end
# @return [Dependency] A dependency including all the versions
# requirements of the stored dependencies.
#
def dependency
@dependencies.inject(Dependency.new(name)) do |previous, dependency|
previous.merge(dependency.to_top_level_spec_dependency)
end
end
# @return [Specification] The specification for the given subspec name,
# from {specification}.
#
# @param [String] name The name of the specification. It can be the
# name of the top level parent or the name of a
# subspec.
#
# @see specification
#
def specification_by_name(name)
specification.top_level_parent.subspec_by_name(name)
end
# @return [Specification] The top level specification of the Pod for the
# {required_version}.
#
# @note If multiple sources have a specification for the
# {required_version} The alpahbetical order of their names is used
# to disambiguate.
#
def specification
unless @specification
sources = []
versions_by_source.each{ |source, versions| sources << source if versions.include?(required_version) }
source = sources.sort_by(&:name).first
@specification = source.specification(name, required_version)
end
@specification
end
# @return [Version] The highest version that satisfies {dependency}.
#
def required_version
versions.find { |v| dependency.match?(name, v) } ||
raise(Informative, "Required version (#{dependency}) not found for `#{name}'.\nAvailable versions: #{versions.join(', ')}")
end
# @return [Array<Version>] All the available versions for the Pod, sorted
# from highest to lowest.
#
def versions
versions_by_source.values.flatten.uniq.sort.reverse
end
# @return [Hash{Source => Version}] All the available versions for the
# Pod groupped by source.
#
def versions_by_source
result = {}
sources.each do |source|
result[source] = source.versions(name)
end
result
end
def ==(other)
self.class === other && @name == other.name && @sources.map(&:name) == other.sources.map(&:name)
end
def to_s
"#<#{self.class.name} for `#{name}' with required version `#{required_version}' available at `#{sources.map(&:name) * ', '}'>"
end
alias_method :inspect, :to_s
# The Set::External class handles Pods from external sources. Pods from
# external sources don't use the {Pod::Sources} and are intialized by a
# given specification.
#
# @note External sources *don't* support subspecs.
#
class External < Set
def initialize(specification)
@specification = specification
@required_by = []
@dependencies = []
end
def name
@specification.top_level_parent.name
end
def ==(other)
self.class === other && @specification == other.specification
end
def required_by(dependency, dependent_name)
before = @specification
super(dependency, dependent_name)
ensure
@specification = before
end
def specification_path
raise "specification_path"
end
def specification
@specification
end
def versions
[@specification.version]
end
end
end
end
end
require 'yaml'
# This is to make sure Faraday doesn't warn the user about the `system_timer` gem missing.
old_warn, $-w = $-w, nil
begin
require 'faraday'
ensure
$-w = old_warn
end
require 'octokit'
module Pod
class Specification
class Statistics
def self.instance
@instance ||= new
end
def self.instance=(instance)
@instance = instance
end
attr_accessor :cache_file, :cache_expiration
def initialize
@cache_file = Config.instance.repos_dir + 'statistics.yml'
@cache_expiration = 60 * 60 * 24 * 3
end
def creation_date(set)
compute_creation_date(set)
end
def creation_dates(sets)
dates = {}
sets.each { |set| dates[set.name] = compute_creation_date(set, false) }
save_cache
dates
end
def github_watchers(set)
github_stats_if_needed(set)
get_value(set, :gh_watchers)
end
def github_forks(set)
github_stats_if_needed(set)
get_value(set, :gh_forks)
end
def github_pushed_at(set)
github_stats_if_needed(set)
get_value(set, :pushed_at)
end
private
def cache
@cache ||= cache_file && cache_file.exist? ? YAML::load(cache_file.read) : {}
end
def get_value(set, key)
if cache[set.name] && cache[set.name][key]
cache[set.name][key]
end
end
def set_value(set, key, value)
cache[set.name] ||= {}
cache[set.name][key] = value
end
def save_cache
File.open(cache_file, 'w') { |f| f.write(YAML::dump(cache)) } if cache_file
end
def compute_creation_date(set, save = true)
date = get_value(set, :creation_date)
unless date
Dir.chdir(set.sources.first.repo) do
date = Time.at(`git log --first-parent --format=%ct #{set.name}`.split("\n").last.to_i)
end
set_value(set, :creation_date, date)
end
save_cache if save
date
end
def github_stats_if_needed(set)
return if get_value(set, :gh_date) && get_value(set, :gh_date) > Time.now - cache_expiration
spec = set.specification
url = spec.source[:git] || ''
repo_id = url[/github.com\/([^\/\.]*\/[^\/\.]*)\.*/, 1]
return unless repo_id
begin
repo = Octokit.repo(repo_id)
rescue
return
end
cache[set.name] ||= {}
set_value(set, :gh_watchers, repo['watchers'])
set_value(set, :gh_forks, repo['forks'])
set_value(set, :pushed_at, repo['pushed_at'])
set_value(set, :gh_date, Time.now)
save_cache
end
end
end
end
module Pod module Pod
require 'colored'
# Provides support for UI output. It provides support for nexted sections of
# information and for a verbose mode.
#
module UserInterface module UserInterface
autoload :UIPod, 'cocoapods/user_interface/ui_pod' require 'colored'
@title_colors = %w|yellow green| @title_colors = %w|yellow green|
@title_level = 0 @title_level = 0
...@@ -10,6 +13,7 @@ module Pod ...@@ -10,6 +13,7 @@ module Pod
@treat_titles_as_messages = false @treat_titles_as_messages = false
class << self class << self
include Config::Mixin include Config::Mixin
attr_accessor :indentation_level, :title_level attr_accessor :indentation_level, :title_level
...@@ -22,8 +26,8 @@ module Pod ...@@ -22,8 +26,8 @@ module Pod
# to their level. In normal mode titles are printed only if # to their level. In normal mode titles are printed only if
# they have nesting level smaller than 2. # they have nesting level smaller than 2.
# #
# TODO: refactor to title (for always visible titles like search) # TODO: Refactor to title (for always visible titles like search)
# and sections (titles that reppresent collapsible sections). # and sections (titles that represent collapsible sections).
# #
def section(title, verbose_prefix = '', relative_indentation = 0) def section(title, verbose_prefix = '', relative_indentation = 0)
if config.verbose? if config.verbose?
...@@ -110,11 +114,11 @@ module Pod ...@@ -110,11 +114,11 @@ module Pod
# that the user should take. # that the user should take.
# #
# @param [String] message The message to print. # @param [String] message The message to print.
# @param [Actions] actions The actions that the user should take. # @param [Array] actions The actions that the user should take.
# #
# return [void] # return [void]
# #
def warn(message, actions) def warn(message, actions = [])
puts("\n[!] #{message}".yellow) puts("\n[!] #{message}".yellow)
actions.each do |action| actions.each do |action|
indented = wrap_string(action, " - ") indented = wrap_string(action, " - ")
...@@ -140,7 +144,7 @@ module Pod ...@@ -140,7 +144,7 @@ module Pod
if mode == :name if mode == :name
puts_indented set.name puts_indented set.name
else else
pod = UIPod.new(set) pod = Specification::Set::Presenter.new(set)
title("\n-> #{pod.name} (#{pod.version})".green, '', 1) do title("\n-> #{pod.name} (#{pod.version})".green, '', 1) do
puts_indented pod.summary puts_indented pod.summary
labeled('Homepage', pod.homepage) labeled('Homepage', pod.homepage)
......
module Pod module Pod
class Version < Gem::Version VERSION = '0.17.0.alpha'
# @returns A Version described by its #to_s method.
#
# @TODO The `from' part of the regexp should be remove before 1.0.0.
#
def self.from_string(string)
if string =~ /HEAD (based on|from) (.*)/
v = Version.new($2)
v.head = true
v
else
Version.new(string)
end
end
attr_accessor :head
alias_method :head?, :head
def to_s
head? ? "HEAD based on #{super}" : super
end
end
end end
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
51E94E13164472080035348C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51E94E12164472080035348C /* Foundation.framework */; };
51E94E18164472090035348C /* Sample_Lib.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 51E94E17164472090035348C /* Sample_Lib.h */; };
51E94E1A164472090035348C /* Sample_Lib.m in Sources */ = {isa = PBXBuildFile; fileRef = 51E94E19164472090035348C /* Sample_Lib.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
51E94E0D164472080035348C /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/${PRODUCT_NAME}";
dstSubfolderSpec = 16;
files = (
51E94E18164472090035348C /* Sample_Lib.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
51E94E0F164472080035348C /* libSample Lib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSample Lib.a"; sourceTree = BUILT_PRODUCTS_DIR; };
51E94E12164472080035348C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
51E94E16164472090035348C /* Sample Lib-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Sample Lib-Prefix.pch"; sourceTree = "<group>"; };
51E94E17164472090035348C /* Sample_Lib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sample_Lib.h; sourceTree = "<group>"; };
51E94E19164472090035348C /* Sample_Lib.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Sample_Lib.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
51E94E0C164472080035348C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
51E94E13164472080035348C /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
51E94E04164472080035348C = {
isa = PBXGroup;
children = (
51E94E14164472090035348C /* Sample Lib */,
51E94E11164472080035348C /* Frameworks */,
51E94E10164472080035348C /* Products */,
);
sourceTree = "<group>";
};
51E94E10164472080035348C /* Products */ = {
isa = PBXGroup;
children = (
51E94E0F164472080035348C /* libSample Lib.a */,
);
name = Products;
sourceTree = "<group>";
};
51E94E11164472080035348C /* Frameworks */ = {
isa = PBXGroup;
children = (
51E94E12164472080035348C /* Foundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
51E94E14164472090035348C /* Sample Lib */ = {
isa = PBXGroup;
children = (
51E94E17164472090035348C /* Sample_Lib.h */,
51E94E19164472090035348C /* Sample_Lib.m */,
51E94E15164472090035348C /* Supporting Files */,
);
path = "Sample Lib";
sourceTree = "<group>";
};
51E94E15164472090035348C /* Supporting Files */ = {
isa = PBXGroup;
children = (
51E94E16164472090035348C /* Sample Lib-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
51E94E0E164472080035348C /* Sample Lib */ = {
isa = PBXNativeTarget;
buildConfigurationList = 51E94E1D164472090035348C /* Build configuration list for PBXNativeTarget "Sample Lib" */;
buildPhases = (
51E94E0B164472080035348C /* Sources */,
51E94E0C164472080035348C /* Frameworks */,
51E94E0D164472080035348C /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "Sample Lib";
productName = "Sample Lib";
productReference = 51E94E0F164472080035348C /* libSample Lib.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
51E94E06164472080035348C /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0450;
ORGANIZATIONNAME = CocoaPods;
};
buildConfigurationList = 51E94E09164472080035348C /* Build configuration list for PBXProject "Sample Lib" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 51E94E04164472080035348C;
productRefGroup = 51E94E10164472080035348C /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
51E94E0E164472080035348C /* Sample Lib */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
51E94E0B164472080035348C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
51E94E1A164472090035348C /* Sample_Lib.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
51E94E1B164472090035348C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
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_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
SDKROOT = iphoneos;
};
name = Debug;
};
51E94E1C164472090035348C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
51E94E1E164472090035348C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/Sample_Lib.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Sample Lib/Sample Lib-Prefix.pch";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
51E94E1F164472090035348C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DSTROOT = /tmp/Sample_Lib.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Sample Lib/Sample Lib-Prefix.pch";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
51E94E09164472080035348C /* Build configuration list for PBXProject "Sample Lib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
51E94E1B164472090035348C /* Debug */,
51E94E1C164472090035348C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
51E94E1D164472090035348C /* Build configuration list for PBXNativeTarget "Sample Lib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
51E94E1E164472090035348C /* Debug */,
51E94E1F164472090035348C /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 51E94E06164472080035348C /* Project object */;
}
//
// Prefix header for all source files of the 'Sample Lib' target in the 'Sample Lib' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif
//
// Sample_Lib.h
// Sample Lib
//
// Created by Eloy Durán on 11/2/12.
// Copyright (c) 2012 CocoaPods. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Sample_Lib : NSObject
@end
//
// Sample_Lib.m
// Sample Lib
//
// Created by Eloy Durán on 11/2/12.
// Copyright (c) 2012 CocoaPods. All rights reserved.
//
#import "Sample_Lib.h"
@implementation Sample_Lib
@end
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
51075D541521D0C100E39B41 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 51075D521521D0C100E39B41 /* InfoPlist.strings */; }; 51075D541521D0C100E39B41 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 51075D521521D0C100E39B41 /* InfoPlist.strings */; };
51075D561521D0C100E39B41 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 51075D551521D0C100E39B41 /* main.m */; }; 51075D561521D0C100E39B41 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 51075D551521D0C100E39B41 /* main.m */; };
51075D5A1521D0C100E39B41 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 51075D591521D0C100E39B41 /* AppDelegate.m */; }; 51075D5A1521D0C100E39B41 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 51075D591521D0C100E39B41 /* AppDelegate.m */; };
51E94E2A1644722C0035348C /* libSample Lib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51E94E28164472200035348C /* libSample Lib.a */; };
A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497114F9BE9A0080D870 /* UIKit.framework */; }; A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497114F9BE9A0080D870 /* UIKit.framework */; };
A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497314F9BE9A0080D870 /* Foundation.framework */; }; A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497314F9BE9A0080D870 /* Foundation.framework */; };
A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497514F9BE9A0080D870 /* CoreGraphics.framework */; }; A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A346497514F9BE9A0080D870 /* CoreGraphics.framework */; };
...@@ -21,6 +22,16 @@ ...@@ -21,6 +22,16 @@
A346498214F9BE9A0080D870 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A346498114F9BE9A0080D870 /* AppDelegate.m */; }; A346498214F9BE9A0080D870 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A346498114F9BE9A0080D870 /* AppDelegate.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
51E94E27164472200035348C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 51E94E201644721F0035348C /* Sample Lib.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 51E94E0F164472080035348C;
remoteInfo = "Sample Lib";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
51075D4A1521D0C100E39B41 /* TestRunner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestRunner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51075D4A1521D0C100E39B41 /* TestRunner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestRunner.app; sourceTree = BUILT_PRODUCTS_DIR; };
51075D511521D0C100E39B41 /* TestRunner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestRunner-Info.plist"; sourceTree = "<group>"; }; 51075D511521D0C100E39B41 /* TestRunner-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestRunner-Info.plist"; sourceTree = "<group>"; };
...@@ -29,6 +40,7 @@ ...@@ -29,6 +40,7 @@
51075D571521D0C100E39B41 /* TestRunner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestRunner-Prefix.pch"; sourceTree = "<group>"; }; 51075D571521D0C100E39B41 /* TestRunner-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestRunner-Prefix.pch"; sourceTree = "<group>"; };
51075D581521D0C100E39B41 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 51075D581521D0C100E39B41 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
51075D591521D0C100E39B41 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 51075D591521D0C100E39B41 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
51E94E201644721F0035348C /* Sample Lib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Sample Lib.xcodeproj"; path = "Sample Lib/Sample Lib.xcodeproj"; sourceTree = "<group>"; };
A346496D14F9BE9A0080D870 /* SampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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; }; 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; }; A346497314F9BE9A0080D870 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
...@@ -56,6 +68,7 @@ ...@@ -56,6 +68,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
51E94E2A1644722C0035348C /* libSample Lib.a in Frameworks */,
A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */, A346497214F9BE9A0080D870 /* UIKit.framework in Frameworks */,
A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */, A346497414F9BE9A0080D870 /* Foundation.framework in Frameworks */,
A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */, A346497614F9BE9A0080D870 /* CoreGraphics.framework in Frameworks */,
...@@ -86,9 +99,18 @@ ...@@ -86,9 +99,18 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
51E94E211644721F0035348C /* Products */ = {
isa = PBXGroup;
children = (
51E94E28164472200035348C /* libSample Lib.a */,
);
name = Products;
sourceTree = "<group>";
};
A346496214F9BE990080D870 = { A346496214F9BE990080D870 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
51E94E201644721F0035348C /* Sample Lib.xcodeproj */,
A346497714F9BE9A0080D870 /* SampleProject */, A346497714F9BE9A0080D870 /* SampleProject */,
51075D4F1521D0C100E39B41 /* TestRunner */, 51075D4F1521D0C100E39B41 /* TestRunner */,
A346497014F9BE9A0080D870 /* Frameworks */, A346497014F9BE9A0080D870 /* Frameworks */,
...@@ -192,6 +214,12 @@ ...@@ -192,6 +214,12 @@
mainGroup = A346496214F9BE990080D870; mainGroup = A346496214F9BE990080D870;
productRefGroup = A346496E14F9BE9A0080D870 /* Products */; productRefGroup = A346496E14F9BE9A0080D870 /* Products */;
projectDirPath = ""; projectDirPath = "";
projectReferences = (
{
ProductGroup = 51E94E211644721F0035348C /* Products */;
ProjectRef = 51E94E201644721F0035348C /* Sample Lib.xcodeproj */;
},
);
projectRoot = ""; projectRoot = "";
targets = ( targets = (
A346496C14F9BE9A0080D870 /* SampleProject */, A346496C14F9BE9A0080D870 /* SampleProject */,
...@@ -200,6 +228,16 @@ ...@@ -200,6 +228,16 @@
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */
51E94E28164472200035348C /* libSample Lib.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libSample Lib.a";
remoteRef = 51E94E27164472200035348C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
51075D481521D0C100E39B41 /* Resources */ = { 51075D481521D0C100E39B41 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
......
Subproject commit ddda7566d193fe0e5fa1c419f5b5239ef964f263 Subproject commit 84ea24c2f3a5d463da1e7945c60fd3f33f73dee2
...@@ -8,7 +8,6 @@ Pod::Spec.new do |s| ...@@ -8,7 +8,6 @@ Pod::Spec.new do |s|
s.source = { :git => 'http://banana-corp.local/banana-lib.git', :tag => 'v1.0' } s.source = { :git => 'http://banana-corp.local/banana-lib.git', :tag => 'v1.0' }
s.source_files = 'Classes/*.{h,m}', 'Vendor' s.source_files = 'Classes/*.{h,m}', 'Vendor'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' } s.xcconfig = { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' }
s.clean_paths = "sub-dir"
s.prefix_header_file = 'Classes/BananaLib.pch' s.prefix_header_file = 'Classes/BananaLib.pch'
s.resources = "Resources/*.png" s.resources = "Resources/*.png"
s.dependency 'monkey', '~> 1.0.1', '< 1.0.9' s.dependency 'monkey', '~> 1.0.1', '< 1.0.9'
......
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Install" do module Pod
extend SpecHelper::Command describe Command::Install do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
it "should include instructions on how to reference the xcode project" do it "tells the user that no Podfile or podspec was found in the current working dir" do
Pod::Command::Install.banner.should.match %r{xcodeproj 'path/to/XcodeProject'} exception = lambda { run_command('install', '--no-update') }.should.raise Informative
end exception.message.should.include "No `Podfile' found in the current working directory."
end
it "tells the user that no Podfile or podspec was found in the current working dir" do
exception = lambda { run_command('install','--no-update') }.should.raise Pod::Informative
exception.message.should.include "No `Podfile' found in the current working directory."
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::List" do module Pod
extend SpecHelper::TemporaryRepos describe Command::List do
extend SpecHelper::TemporaryRepos
def command(arguments = argv) it "lists the known pods" do
command = Pod::Command::List.new(arguments) out = run_command('list')
end [ /ZBarSDK/,
/TouchJSON/,
it "complains for wrong parameters" do /SDURLCache/,
lambda { command(argv('wrong')).run }.should.raise Pod::Command::Help /MagicalRecord/,
lambda { command(argv('--wrong')).run }.should.raise Pod::Command::Help /A2DynamicDelegate/,
end /\d+ pods were found/
].each { |regex| out.should =~ regex }
end
it "presents the known pods" do it "lists the new pods" do
list = command() Time.stubs(:now).returns(Time.mktime(2012,2,3))
list.run out = run_command('list', 'new')
[ /ZBarSDK/, [ 'iCarousel',
/TouchJSON/, 'libPusher',
/SDURLCache/, 'SSCheckBoxView',
/MagicalRecord/, 'KKPasscodeLock',
/A2DynamicDelegate/, 'SOCKit',
/\d+ pods were found/ 'FileMD5Hash',
].each { |regex| Pod::UI.output.should =~ regex } 'cocoa-oauth',
end 'iRate'
].each {|s| out.should.include s }
it "returns the new pods" do end
Time.stubs(:now).returns(Time.mktime(2012,2,3))
list = command(argv('new'))
list.run
[ 'iCarousel',
'libPusher',
'SSCheckBoxView',
'KKPasscodeLock',
'SOCKit',
'FileMD5Hash',
'cocoa-oauth',
'iRate'
].each {|s| Pod::UI.output.should.include s }
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Outdated do module Pod
extend SpecHelper::Command describe Command::Outdated do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
it "tells the user that no Podfile was found in the current working dir" do it "tells the user that no Podfile was found in the current working dir" do
exception = lambda { run_command('outdated','--no-update') }.should.raise Pod::Informative exception = lambda { run_command('outdated', '--no-update') }.should.raise Informative
exception.message.should.include "No `Podfile' found in the current working directory." exception.message.should.include "No `Podfile' found in the current working directory."
end end
it "tells the user that no Lockfile was found in the current working dir" do it "tells the user that no Lockfile was found in the current working dir" do
file = temporary_directory + 'Podfile' file = temporary_directory + 'Podfile'
File.open(file, 'w') {|f| f.write('platform :ios') } File.open(file, 'w') {|f| f.write('platform :ios') }
Dir.chdir(temporary_directory) do Dir.chdir(temporary_directory) do
exception = lambda { run_command('outdated','--no-update') }.should.raise Pod::Informative exception = lambda { run_command('outdated', '--no-update') }.should.raise Informative
exception.message.should.include "No `Podfile.lock' found in the current working directory" exception.message.should.include "No `Podfile.lock' found in the current working directory"
end
end end
end end
end end
......
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Push do module Pod
extend SpecHelper::Command describe Command::Push do
extend SpecHelper::TemporaryDirectory extend SpecHelper::Command
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
before do before do
config.repos_dir = SpecHelper.tmp_repos_path config.repos_dir = SpecHelper.tmp_repos_path
end end
def master_repo def master_repo
fixture('spec-repos/master') fixture('spec-repos/master')
end end
it "complains for wrong parameters" do it "requires a spec-repo name" do
lambda { run_command('push') }.should.raise Pod::Command::Help lambda { command('push').validate! }.should.raise CLAide::Help
lambda { run_command('push', '--allow-warnings') }.should.raise Pod::Command::Help end
lambda { run_command('push', '--wrong-option') }.should.raise Pod::Command::Help
end
it "complains if it can't find the repo" do it "complains if it can't find the repo" do
repo1 = add_repo('repo1', master_repo) repo1 = add_repo('repo1', master_repo)
Dir.chdir(fixture('banana-lib')) do Dir.chdir(fixture('banana-lib')) do
lambda { run_command('push', 'repo2') }.should.raise Pod::Informative lambda { run_command('push', 'repo2') }.should.raise Informative
end
end end
end
it "complains if it can't find a spec" do it "complains if it can't find a spec" do
repo1 = add_repo('repo1', master_repo) repo1 = add_repo('repo1', master_repo)
lambda { run_command('push', 'repo1') }.should.raise Pod::Informative lambda { run_command('push', 'repo1') }.should.raise Informative
end end
it "it raises if the pod is not validated" do it "it raises if the pod is not validated" do
repo1 = add_repo('repo1', master_repo) repo1 = add_repo('repo1', master_repo)
repo2 = add_repo('repo2', repo1.dir) repo2 = add_repo('repo2', repo1.dir)
git_config('repo2', 'remote.origin.url').should == (tmp_repos_path + 'repo1').to_s git_config('repo2', 'remote.origin.url').should == (tmp_repos_path + 'repo1').to_s
Dir.chdir(fixture('banana-lib')) do Dir.chdir(fixture('banana-lib')) do
lambda { command('push', 'repo2', '--silent').run }.should.raise Pod::Informative lambda { run_command('push', 'repo2', '--silent') }.should.raise Informative
end
# (repo1.dir + 'BananaLib/1.0/BananaLib.podspec').read.should.include 'Added!'
end end
# (repo1.dir + 'BananaLib/1.0/BananaLib.podspec').read.should.include 'Added!'
end
before do before do
# prepare the repos # prepare the repos
@upstream = add_repo('upstream', master_repo) @upstream = add_repo('upstream', master_repo)
@local_repo = add_repo('local_repo', @upstream.dir) @local_repo = add_repo('local_repo', @upstream.dir)
git_config('local_repo', 'remote.origin.url').should == (tmp_repos_path + 'upstream').to_s git_config('local_repo', 'remote.origin.url').should == (tmp_repos_path + 'upstream').to_s
# prepare the spec # prepare the spec
spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
spec_fix = spec.gsub(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s) spec_fix = spec.gsub(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s)
spec_add = spec.gsub(/'JSONKit'/, "'PushTest'") spec_add = spec.gsub(/'JSONKit'/, "'PushTest'")
File.open(temporary_directory + 'JSONKit.podspec', 'w') {|f| f.write(spec_fix) } File.open(temporary_directory + 'JSONKit.podspec', 'w') {|f| f.write(spec_fix) }
File.open(temporary_directory + 'PushTest.podspec', 'w') {|f| f.write(spec_add) } File.open(temporary_directory + 'PushTest.podspec', 'w') {|f| f.write(spec_add) }
end end
it "refuses to push if the repo is not clean" do it "refuses to push if the repo is not clean" do
File.open(@local_repo.dir + 'README', 'w') {|f| f.write('Added!') } File.open(@local_repo.dir + 'README', 'w') {|f| f.write('Added!') }
(@local_repo.dir + 'README').read.should.include 'Added!' (@local_repo.dir + 'README').read.should.include 'Added!'
cmd = command('push', 'local_repo') cmd = command('push', 'local_repo')
cmd.expects(:validate_podspec_files).returns(true) cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { lambda { cmd.run }.should.raise Pod::Informative } Dir.chdir(temporary_directory) { lambda { cmd.run }.should.raise Informative }
(@upstream.dir + 'PushTest/1.4/PushTest.podspec').should.not.exist? (@upstream.dir + 'PushTest/1.4/PushTest.podspec').should.not.exist?
end end
it "sucessfully pushes a spec" do it "sucessfully pushes a spec" do
git('upstream', 'checkout master') # checkout master, to allow push in a non-bare repository git('upstream', 'checkout master') # checkout master, to allow push in a non-bare repository
cmd = command('push', 'local_repo') cmd = command('push', 'local_repo')
cmd.expects(:validate_podspec_files).returns(true) cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { cmd.run } Dir.chdir(temporary_directory) { cmd.run }
Pod::UI.output.should.include('[Add] PushTest (1.4)') UI.output.should.include('[Add] PushTest (1.4)')
Pod::UI.output.should.include('[Fix] JSONKit (1.4)') UI.output.should.include('[Fix] JSONKit (1.4)')
git('upstream', 'checkout test') # checkout because test because is it the branch used in the specs. git('upstream', 'checkout test') # checkout because test because is it the branch used in the specs.
(@upstream.dir + 'PushTest/1.4/PushTest.podspec').read.should.include('PushTest') (@upstream.dir + 'PushTest/1.4/PushTest.podspec').read.should.include('PushTest')
end
end end
end end
...@@ -7,20 +7,9 @@ describe "Pod::Command::Repo" do ...@@ -7,20 +7,9 @@ describe "Pod::Command::Repo" do
end end
describe "In general" do describe "In general" do
extend SpecHelper::Command
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
it "runs with correct parameters" do
lambda { run_command('repo', 'update') }.should.not.raise
lambda { run_command('repo', 'lint', temporary_directory.to_s) }.should.not.raise
end
it "complains for wrong parameters" do
lambda { run_command('repo', 'add') }.should.raise Pod::Informative
lambda { run_command('repo', 'add', 'NAME') }.should.raise Pod::Informative
end
it "adds a spec-repo" do it "adds a spec-repo" do
run_command('repo', 'add', 'private', fixture('spec-repos/master')) run_command('repo', 'add', 'private', fixture('spec-repos/master'))
git_config('private', 'remote.origin.url').should == fixture('spec-repos/master').to_s git_config('private', 'remote.origin.url').should == fixture('spec-repos/master').to_s
...@@ -67,7 +56,6 @@ describe "Pod::Command::Repo" do ...@@ -67,7 +56,6 @@ describe "Pod::Command::Repo" do
end end
describe "Concerning a repo support" do describe "Concerning a repo support" do
extend SpecHelper::Command
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
......
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Search" do module Pod
extend SpecHelper::Command describe Command::Search do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
before do before do
config.repos_dir = fixture('spec-repos') config.repos_dir = fixture('spec-repos')
end end
it "runs with correct parameters" do it "runs with correct parameters" do
lambda { run_command('search', 'table') }.should.not.raise lambda { run_command('search', 'table') }.should.not.raise
lambda { run_command('search', 'table', '--full') }.should.not.raise lambda { run_command('search', 'table', '--full') }.should.not.raise
end end
it "complains for wrong parameters" do it "complains for wrong parameters" do
lambda { run_command('search') }.should.raise Pod::Command::Help lambda { run_command('search') }.should.raise CLAide::Help
lambda { run_command('search', 'too', 'many') }.should.raise Pod::Command::Help lambda { run_command('search', 'too', 'many') }.should.raise CLAide::Help
lambda { run_command('search', 'too', '--wrong') }.should.raise Pod::Command::Help lambda { run_command('search', 'too', '--wrong') }.should.raise CLAide::Help
lambda { run_command('search', '--wrong') }.should.raise Pod::Command::Help lambda { run_command('search', '--wrong') }.should.raise CLAide::Help
end end
it "presents the search results" do it "presents the search results" do
output = run_command('search', 'table') output = run_command('search', 'table')
output.should.include 'EGOTableViewPullRefresh' output.should.include 'EGOTableViewPullRefresh'
end end
it "searches for a pod with name matching the given query ignoring case" do it "searches for a pod with name matching the given query ignoring case" do
[ [
[' s ', %w{ ASIHTTPRequest ASIWebPageRequest JSONKit SSZipArchive }], [' s ', %w{ ASIHTTPRequest ASIWebPageRequest JSONKit SSZipArchive }],
['json', %w{ JSONKit SBJson }], ['json', %w{ JSONKit SBJson }],
].each do |query, results| ].each do |query, results|
output = run_command('search', query) output = run_command('search', query)
results.each { |pod| output.should.include? pod } results.each { |pod| output.should.include? pod }
end
end end
end
it "searches for a pod with name, summary, or description matching the given query ignoring case" do it "searches for a pod with name, summary, or description matching the given query ignoring case" do
[ [
['dROP', %w{ Reachability }], ['dROP', %w{ Reachability }],
['is', %w{ ASIHTTPRequest SSZipArchive }], ['is', %w{ ASIHTTPRequest SSZipArchive }],
['luke redpath', %w{ Kiwi libPusher LRMocky LRResty LRTableModel}], ['luke redpath', %w{ Kiwi libPusher LRMocky LRResty LRTableModel}],
].each do |query, results| ].each do |query, results|
output = run_command('search', '--full', query) output = run_command('search', query, '--full')
results.each { |pod| output.should.include? pod } results.each { |pod| output.should.include? pod }
end
end end
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe "Pod::Command::Setup" do describe Command::Setup do
extend SpecHelper::Command extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryRepos
extend SpecHelper::TemporaryRepos
before do
before do config.repos_dir = SpecHelper.tmp_repos_path
config.repos_dir = SpecHelper.tmp_repos_path end
end
it "runs with correct parameters" do
it "runs with correct parameters" do lambda { run_command('setup') }.should.not.raise
lambda { run_command('setup') }.should.not.raise end
end
it "complains for wrong parameters" do
it "complains for wrong parameters" do lambda { run_command('setup', 'wrong') }.should.raise CLAide::Help
lambda { run_command('setup', 'wrong') }.should.raise Pod::Command::Help lambda { run_command('setup', '--wrong') }.should.raise CLAide::Help
lambda { run_command('setup', '--wrong') }.should.raise Pod::Command::Help end
end
it "returns the read only URL of the `master' spec-repo" do
it "returns the read only URL of the `master' spec-repo" do cmd = Command::Setup.new(argv)
cmd = Pod::Command::Setup.new(argv) cmd.url.should == 'https://github.com/CocoaPods/Specs.git'
cmd.url.should == 'https://github.com/CocoaPods/Specs.git' end
end
it "returns the push URL of the `master' spec-repo" do
it "returns the push URL of the `master' spec-repo" do config.silent = true
config.silent = true cmd = Command::Setup.new(argv('--push'))
cmd = Pod::Command::Setup.new(argv('--push')) cmd.url.should == 'git@github.com:CocoaPods/Specs.git'
cmd.url.should == 'git@github.com:CocoaPods/Specs.git' end
end
class Command::Setup
class Pod::Command::Setup def read_only_url; SpecHelper.fixture('spec-repos/master'); end
def read_only_url; SpecHelper.fixture('spec-repos/master'); end end
end
it "creates the local spec-repos directory and creates a clone of the `master' repo" do
it "creates the local spec-repos directory and creates a clone of the `master' repo" do output = run_command('setup')
output = run_command('setup') output.should.include "Setup completed"
output.should.include "Setup completed" output.should.not.include "push"
output.should.not.include "push" git_config('master', 'remote.origin.url').should == fixture('spec-repos/master').to_s
git_config('master', 'remote.origin.url').should == fixture('spec-repos/master').to_s end
end
it "preserves push access for the `master' repo" do
it "preserves push access for the `master' repo" do output = run_command('setup')
output = run_command('setup') output.should.not.include "push"
output.should.not.include "push" git('master', 'remote set-url origin git@github.com:CocoaPods/Specs.git')
git('master', 'remote set-url origin git@github.com:CocoaPods/Specs.git') command('setup').url.should == 'git@github.com:CocoaPods/Specs.git'
command('setup').url.should == 'git@github.com:CocoaPods/Specs.git' end
end
it "can run if needed" do
it "can run if needed" do output = run_command('setup')
output = run_command('setup') output.should.include "Setup completed"
output.should.include "Setup completed" UI.output = ''
Pod::UI.output = '' command('setup').run_if_needed
command('setup').run_if_needed UI.output.should == ''
Pod::UI.output.should == '' end
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Spec do module Pod
extend SpecHelper::Command describe Command::Spec do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
it "complains for wrong parameters" do it "complains for wrong parameters" do
lambda { run_command('spec') }.should.raise Pod::Command::Help lambda { run_command('spec') }.should.raise CLAide::Help
lambda { run_command('spec', 'create') }.should.raise Pod::Command::Help lambda { run_command('spec', 'create') }.should.raise CLAide::Help
lambda { run_command('spec', '--create') }.should.raise Pod::Command::Help lambda { run_command('spec', '--create') }.should.raise CLAide::Help
lambda { run_command('spec', 'NAME') }.should.raise Pod::Command::Help lambda { run_command('spec', 'NAME') }.should.raise CLAide::Help
lambda { run_command('spec', 'createa') }.should.raise Pod::Command::Help lambda { run_command('spec', 'createa') }.should.raise CLAide::Help
lambda { run_command('lint', 'agument1', '2') }.should.raise Pod::Command::Help lambda { run_command('lint', 'agument1', '2') }.should.raise CLAide::Help
end
end end
end
describe "Pod::Command::Spec#create" do describe "Command::Spec#create" do
extend SpecHelper::Command extend SpecHelper::Github
extend SpecHelper::Github extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryRepos
extend SpecHelper::TemporaryRepos
it "creates a new podspec stub file" do
it "creates a new podspec stub file" do run_command('spec', 'create', 'Bananas')
run_command('spec', 'create', 'Bananas') path = temporary_directory + 'Bananas.podspec'
path = temporary_directory + 'Bananas.podspec' spec = Specification.from_file(path).activate_platform(:ios)
spec = Pod::Specification.from_file(path).activate_platform(:ios)
spec.name.should == 'Bananas'
spec.name.should == 'Bananas' spec.license.should == { :type => "MIT (example)" }
spec.license.should == { :type => "MIT (example)" } spec.version.should == Version.new('0.0.1')
spec.version.should == Pod::Version.new('0.0.1') spec.summary.should == 'A short description of Bananas.'
spec.summary.should == 'A short description of Bananas.' spec.homepage.should == 'http://EXAMPLE/Bananas'
spec.homepage.should == 'http://EXAMPLE/Bananas' spec.authors.should == { `git config --get user.name`.strip => `git config --get user.email`.strip}
spec.authors.should == { `git config --get user.name`.strip => `git config --get user.email`.strip} spec.source.should == { :git => 'http://EXAMPLE/Bananas.git', :tag => '0.0.1' }
spec.source.should == { :git => 'http://EXAMPLE/Bananas.git', :tag => '0.0.1' } spec.description.should == 'A short description of Bananas.'
spec.description.should == 'A short description of Bananas.' spec.source_files.should == ['Classes', 'Classes/**/*.{h,m}']
spec.source_files.should == ['Classes', 'Classes/**/*.{h,m}'] spec.public_header_files.should == []
spec.public_header_files.should == [] end
end
it "correctly creates a podspec from github" do it "correctly creates a podspec from github" do
expect_github_repo_request expect_github_repo_request
expect_github_user_request expect_github_user_request
expect_github_tags_request expect_github_tags_request
run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git') run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git')
path = temporary_directory + 'libPusher.podspec' path = temporary_directory + 'libPusher.podspec'
spec = Pod::Specification.from_file(path) spec = Specification.from_file(path)
spec.name.should == 'libPusher' spec.name.should == 'libPusher'
spec.license.should == { :type => "MIT (example)" } spec.license.should == { :type => "MIT (example)" }
spec.version.should == Pod::Version.new('1.3') spec.version.should == Version.new('1.3')
spec.summary.should == 'An Objective-C interface to Pusher (pusherapp.com)' spec.summary.should == 'An Objective-C interface to Pusher (pusherapp.com)'
spec.homepage.should == 'https://github.com/lukeredpath/libPusher' spec.homepage.should == 'https://github.com/lukeredpath/libPusher'
spec.authors.should == {"Luke Redpath"=>"luke@lukeredpath.co.uk"} spec.authors.should == {"Luke Redpath"=>"luke@lukeredpath.co.uk"}
spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' } spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' }
end end
it "accepts a name when creating a podspec form github" do it "accepts a name when creating a podspec form github" do
expect_github_repo_request expect_github_repo_request
expect_github_user_request expect_github_user_request
expect_github_tags_request expect_github_tags_request
run_command('spec', 'create', 'other_name', 'https://github.com/lukeredpath/libPusher.git') run_command('spec', 'create', 'other_name', 'https://github.com/lukeredpath/libPusher.git')
path = temporary_directory + 'other_name.podspec' path = temporary_directory + 'other_name.podspec'
spec = Pod::Specification.from_file(path) spec = Specification.from_file(path)
spec.name.should == 'other_name' spec.name.should == 'other_name'
spec.license.should == { :type => "MIT (example)" } spec.license.should == { :type => "MIT (example)" }
spec.version.should == Pod::Version.new('1.3') spec.version.should == Version.new('1.3')
spec.summary.should == 'An Objective-C interface to Pusher (pusherapp.com)' spec.summary.should == 'An Objective-C interface to Pusher (pusherapp.com)'
spec.homepage.should == 'https://github.com/lukeredpath/libPusher' spec.homepage.should == 'https://github.com/lukeredpath/libPusher'
spec.authors.should == {"Luke Redpath"=>"luke@lukeredpath.co.uk"} spec.authors.should == {"Luke Redpath"=>"luke@lukeredpath.co.uk"}
spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' } spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' }
end end
it "correctly suggests the head commit if a suitable tag is not available on github" do it "correctly suggests the head commit if a suitable tag is not available on github" do
expect_github_repo_request expect_github_repo_request
expect_github_user_request expect_github_user_request
expect_github_tags_request([{"name" => "experiment"}]) expect_github_tags_request([{"name" => "experiment"}])
expect_github_branches_request expect_github_branches_request
run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git') run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git')
path = temporary_directory + 'libPusher.podspec' path = temporary_directory + 'libPusher.podspec'
spec = Pod::Specification.from_file(path) spec = Specification.from_file(path)
spec.version.should == Pod::Version.new('0.0.1') spec.version.should == Version.new('0.0.1')
spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :commit => '5f482b0693ac2ac1ad85d1aabc27ec7547cc0bc7' } spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :commit => '5f482b0693ac2ac1ad85d1aabc27ec7547cc0bc7' }
end end
it "provides a markdown template if a github repo doesn't have semantic version tags" do it "provides a markdown template if a github repo doesn't have semantic version tags" do
expect_github_repo_request expect_github_repo_request
expect_github_user_request expect_github_user_request
expect_github_tags_request([{"name" => "experiment"}]) expect_github_tags_request([{"name" => "experiment"}])
expect_github_branches_request expect_github_branches_request
output = run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git') output = run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git')
output.should.include 'MARKDOWN TEMPLATE' output.should.include 'MARKDOWN TEMPLATE'
output.should.include 'Please add semantic version tags' output.should.include 'Please add semantic version tags'
end
end end
end
describe "Pod::Command::Spec#lint" do describe "Command::Spec#lint" do
extend SpecHelper::Command extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryRepos
extend SpecHelper::TemporaryRepos
it "complains if it can't find any spec to lint" do it "complains if it can't find any spec to lint" do
Dir.chdir(temporary_directory) do Dir.chdir(temporary_directory) do
lambda { command('spec', 'lint').run }.should.raise Pod::Informative lambda { command('spec', 'lint').run }.should.raise Informative
end
end end
end
it "lints the current working directory" do it "lints the current working directory" do
Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do
cmd = command('spec', 'lint', '--quick', '--only-errors') cmd = command('spec', 'lint', '--quick', '--only-errors')
cmd.run cmd.run
Pod::UI.output.should.include "passed validation" UI.output.should.include "passed validation"
end
end end
end
it "lints a remote podspec" do it "lints a remote podspec" do
Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do
cmd = command('spec', 'lint', '--quick', '--only-errors', '--silent', 'https://github.com/CocoaPods/Specs/raw/master/A2DynamicDelegate/2.0.1/A2DynamicDelegate.podspec') cmd = command('spec', 'lint', '--quick', '--only-errors', '--silent', 'https://github.com/CocoaPods/Specs/raw/master/A2DynamicDelegate/2.0.1/A2DynamicDelegate.podspec')
VCR.use_cassette('linter', :record => :new_episodes) { lambda { cmd.run }.should.not.raise } VCR.use_cassette('linter', :record => :new_episodes) { lambda { cmd.run }.should.not.raise }
end
end end
end
before do before do
text = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read text = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
text.gsub!(/.*license.*/, "") text.gsub!(/.*license.*/, "")
file = temporary_directory + 'JSONKit.podspec' file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) } File.open(file, 'w') {|f| f.write(text) }
@spec_path = file.to_s @spec_path = file.to_s
end end
it "lints a givent podspec" do it "lints a given podspec" do
cmd = command('spec', 'lint', '--quick', @spec_path) cmd = command('spec', 'lint', '--quick', @spec_path)
lambda { cmd.run }.should.raise Pod::Informative lambda { cmd.run }.should.raise Informative
Pod::UI.output.should.include "Missing license type" UI.output.should.include "Missing license type"
end end
it "respects the -only--errors option" do it "respects the -only--errors option" do
cmd = command('spec', 'lint', '--quick', '--only-errors', @spec_path) cmd = command('spec', 'lint', '--quick', '--only-errors', @spec_path)
lambda { cmd.run }.should.not.raise lambda { cmd.run }.should.not.raise
Pod::UI.output.should.include "Missing license type" UI.output.should.include "Missing license type"
end
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Update do module Pod
extend SpecHelper::Command describe Command::Update do
extend SpecHelper::TemporaryDirectory extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos extend SpecHelper::TemporaryRepos
it "tells the user that no Podfile was found in the current working dir" do it "tells the user that no Podfile was found in the current working dir" do
exception = lambda { run_command('update','--no-update') }.should.raise Pod::Informative exception = lambda { run_command('update','--no-update') }.should.raise Informative
exception.message.should.include "No `Podfile' found in the current working directory." exception.message.should.include "No `Podfile' found in the current working directory."
end end
it "tells the user that no Lockfile was found in the current working dir" do it "tells the user that no Lockfile was found in the current working dir" do
file = temporary_directory + 'Podfile' file = temporary_directory + 'Podfile'
File.open(file, 'w') {|f| f.write('platform :ios') } File.open(file, 'w') {|f| f.write('platform :ios') }
Dir.chdir(temporary_directory) do Dir.chdir(temporary_directory) do
exception = lambda { run_command('update','--no-update') }.should.raise Pod::Informative exception = lambda { run_command('update','--no-update') }.should.raise Informative
exception.message.should.include "No `Podfile.lock' found in the current working directory" exception.message.should.include "No `Podfile.lock' found in the current working directory"
end
end end
end end
end end
......
require File.expand_path('../../spec_helper', __FILE__)
# describe "Pod::Command" do
# extend SpecHelper::Command
# extend SpecHelper::TemporaryDirectory
# extend SpecHelper::TemporaryRepos
#
# TODO:
# it "raises help informative if an unknown parameter is passed"
# it "performs setup if needed"
# end
...@@ -6,7 +6,7 @@ describe Pod::UI do ...@@ -6,7 +6,7 @@ describe Pod::UI do
before do before do
@set = Pod::Source.search(Pod::Dependency.new('CocoaLumberjack')) @set = Pod::Source.search(Pod::Dependency.new('CocoaLumberjack'))
Pod::Specification::Statistics.instance.cache_file = nil Pod::Specification::Set::Statistics.instance.cache_file = nil
end end
it "presents the name, version, description, homepage and source of a specification set" do it "presents the name, version, description, homepage and source of a specification set" do
...@@ -20,12 +20,6 @@ describe Pod::UI do ...@@ -20,12 +20,6 @@ describe Pod::UI do
output.should.include? 'https://github.com/robbiehanson/CocoaLumberjack.git' output.should.include? 'https://github.com/robbiehanson/CocoaLumberjack.git'
end end
it "presents the name, version, description, homepage and source of a specification set" do
Pod::UI.pod(@set)
output = Pod::UI.output
output.should.include? 'Versions: 1.6, 1.3.3, 1.3.2, 1.3.1, 1.3, 1.2.3, 1.2.2, 1.2.1, 1.2, 1.1, 1.0 [master repo]'
end
it "presents the stats of a specification set" do it "presents the stats of a specification set" do
repo = { "forks"=>42, "watchers"=>318, "pushed_at"=>"2011-01-26T19:06:43Z" } repo = { "forks"=>42, "watchers"=>318, "pushed_at"=>"2011-01-26T19:06:43Z" }
Octokit.expects(:repo).with("robbiehanson/CocoaLumberjack").returns(repo) Octokit.expects(:repo).with("robbiehanson/CocoaLumberjack").returns(repo)
......
require File.expand_path('../../spec_helper', __FILE__)
describe Pod::Installer::UserProjectIntegrator do
extend SpecHelper::TemporaryDirectory
def integrate!
@integrator = Pod::Installer::UserProjectIntegrator.new(@podfile)
@integrator.integrate!
@sample_project = Xcodeproj::Project.new(@sample_project_path)
end
before do
config.silent = true
@sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
config.project_root = @sample_project_path.dirname
sample_project_path = @sample_project_path
@podfile = Pod::Podfile.new do
platform :ios
xcodeproj sample_project_path, 'Test' => :debug
link_with 'SampleProject' # this is an app target!
pod 'JSONKit'
target :test_runner, :exclusive => true do
link_with 'TestRunner'
pod 'Kiwi'
end
end
@sample_project = Xcodeproj::Project.new(@sample_project_path)
end
before do
integrate!
end
it 'adds references to the Pods static libraries to the Frameworks group' do
@sample_project["Frameworks/libPods.a"].should.not == nil
@sample_project["Frameworks/libPods-test_runner.a"].should.not == nil
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.projpaths.sort.should == %w{ Pods/Pods.xcodeproj 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 'sets the Pods xcconfig as the base config for each build configuration' do
@podfile.target_definitions.each do |_, definition|
target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
xcconfig_file = @sample_project.files.find { |f| f.path == "Pods/#{definition.xcconfig_name}" }
target.build_configurations.each do |config|
config.base_configuration_reference.should == xcconfig_file
end
end
end
it 'adds the libPods static library to the "Link binary with libraries" build phase of each target' do
@podfile.target_definitions.each do |_, definition|
target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
target.frameworks_build_phase.files.find { |f| f.file_ref.name == definition.lib_name}.should.not == nil
end
end
it 'adds a Copy Pods Resources build phase to each target' do
@podfile.target_definitions.each do |_, definition|
target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
phase = target.shell_script_build_phases.find { |bp| bp.name == "Copy Pods Resources" }
phase.shell_script.strip.should == "\"${SRCROOT}/Pods/#{definition.copy_resources_script_name}\""
end
end
before do
# Reset the cached TargetIntegrator#targets lists.
@integrator.instance_variable_set(:@target_integrators, nil)
end
it "only tries to integrate Pods libraries into user targets that haven't been integrated yet" do
app_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :default }
test_runner_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :test_runner }
# Remove libPods.a from the app target. But don't do it through TargetIntegrator#targets,
# as it will return only those that still need integration.
app_target = app_integrator.user_project.targets.find { |t| t.name == 'SampleProject' }
app_target.frameworks_build_phase.files.last.remove_from_project
app_integrator.expects(:add_pods_library)
test_runner_integrator.expects(:add_pods_library).never
@integrator.integrate!
end
it "does not even try to save the project if none of the target integrators had any work to do" do
@integrator.target_integrators.first.user_project.expects(:save_as).never
@integrator.integrate!
end
end
...@@ -43,18 +43,16 @@ else ...@@ -43,18 +43,16 @@ else
$?.should.be.success $?.should.be.success
end end
puts " ! ".red << "Skipping xcodebuild based checks, because it can't be found." if `which xcodebuild`.strip.empty? puts " ! ".red << "Skipping xcodebuild based checks, because it can't be found." if skip_xcodebuild?
def should_xcodebuild(target_definition) def should_xcodebuild(target_definition)
return if `which xcodebuilda`.strip.empty? return if skip_xcodebuild?
target = target_definition target = target_definition
with_xcodebuild_available do Dir.chdir(config.project_pods_root) do
Dir.chdir(config.project_pods_root) do print "[!] Compiling #{target.label}...\r"
print "[!] Compiling #{target.label}...\r" should_successfully_perform "xcodebuild -target '#{target.label}'"
should_successfully_perform "xcodebuild -target '#{target.label}'" lib_path = config.project_pods_root + "build/Release#{'-iphoneos' if target.platform == :ios}" + target.lib_name
lib_path = config.project_pods_root + "build/Release#{'-iphoneos' if target.platform == :ios}" + target.lib_name `lipo -info '#{lib_path}'`.should.include "#{target.platform == :ios ? 'armv7' : 'x86_64'}"
`lipo -info '#{lib_path}'`.should.include "architecture: #{target.platform == :ios ? 'armv7' : 'x86_64'}"
end
end end
end end
......
...@@ -21,13 +21,21 @@ require 'spec_helper/temporary_repos' ...@@ -21,13 +21,21 @@ require 'spec_helper/temporary_repos'
require 'spec_helper/user_interface' require 'spec_helper/user_interface'
require 'spec_helper/pre_flight' require 'spec_helper/pre_flight'
ENV['SKIP_SETUP'] = 'true'
if ENV['SKIP_XCODEBUILD'].nil? && `which xcodebuild`.strip.empty?
ENV['SKIP_XCODEBUILD'] = 'true'
end
require 'claide'
module Bacon module Bacon
class Context class Context
include Pod::Config::Mixin include Pod::Config::Mixin
include SpecHelper::Fixture include SpecHelper::Fixture
include SpecHelper::Command
def argv(*argv) def skip_xcodebuild?
Pod::Command::ARGV.new(argv) ENV['SKIP_XCODEBUILD']
end end
end end
end end
...@@ -36,7 +44,7 @@ config = Pod::Config.instance ...@@ -36,7 +44,7 @@ config = Pod::Config.instance
config.silent = true config.silent = true
config.repos_dir = SpecHelper.tmp_repos_path config.repos_dir = SpecHelper.tmp_repos_path
config.project_root = SpecHelper.temporary_directory config.project_root = SpecHelper.temporary_directory
Pod::Specification::Statistics.instance.cache_file = nil Pod::Specification::Set::Statistics.instance.cache_file = nil
require 'tmpdir' require 'tmpdir'
...@@ -69,3 +77,4 @@ VCR.configure do |c| ...@@ -69,3 +77,4 @@ VCR.configure do |c|
c.allow_http_connections_when_no_cassette = true c.allow_http_connections_when_no_cassette = true
end end
require "active_support/core_ext/string/strip"
...@@ -3,10 +3,29 @@ module Bacon ...@@ -3,10 +3,29 @@ module Bacon
@needs_first_put = true @needs_first_put = true
module ColorOutput def self.color(color, string)
# Graciously yanked from https://github.com/zen-cms/Zen-Core and subsequently modified case color
# MIT License when :red
# Thanks, YorickPeterse! #:nodoc: "\e[31m#{string}\e[0m"
when :green
"\e[32m#{string}\e[0m"
when :yellow
"\e[33m#{string}\e[0m"
else
# Support for Conque
"\e[0m#{string}\e[0m"
end
end
#---------------------------------------------------------------------------#
# Overrides the SpecDoxzRtput to provide colored output by default
#
# Based on https://github.com/zen-cms/Zen-Core and subsequently modified
# which is available under the MIT License. Thanks YorickPeterse!
#
module SpecDoxOutput
def handle_specification(name) def handle_specification(name)
if @needs_first_put if @needs_first_put
@needs_first_put = false @needs_first_put = false
...@@ -27,18 +46,20 @@ module Bacon ...@@ -27,18 +46,20 @@ module Bacon
error = yield error = yield
if !error.empty? if !error.empty?
puts "#{spaces}\e[31m- #{description} [FAILED]\e[0m" puts Bacon.color(:red, "#{spaces}- #{description} [FAILED]")
elsif disabled elsif disabled
puts "#{spaces}\e[33m- #{description} [DISABLED]\e[0m" puts Bacon.color(:yellow, "#{spaces}- #{description} [DISABLED]")
else else
puts "#{spaces}\e[32m- #{description}\e[0m" puts Bacon.color(:green, "#{spaces}- #{description}")
end end
end end
#:nodoc: #:nodoc:
def handle_summary def handle_summary
print ErrorLog if Backtraces print ErrorLog if Backtraces
puts "\e[33m#{Counter[:disabled]} disabled specifications\n\e[0m" unless Counter[:disabled].zero? unless Counter[:disabled].zero?
puts Bacon.color(:yellow, "#{Counter[:disabled]} disabled specifications\n")
end
puts "%d specifications (%d requirements), %d failures, %d errors" % puts "%d specifications (%d requirements), %d failures, %d errors" %
Counter.values_at(:specifications, :requirements, :failed, :errors) Counter.values_at(:specifications, :requirements, :failed, :errors)
end end
...@@ -48,7 +69,53 @@ module Bacon ...@@ -48,7 +69,53 @@ module Bacon
return ' ' * @specs_depth return ' ' * @specs_depth
end end
end end
extend ColorOutput
#---------------------------------------------------------------------------#
# Overrides the TestUnitOutput to provide colored result output.
#
module TestUnitOutput
def handle_specification(name)
print Bacon.color(nil, ':')
yield
end
def handle_requirement(description, disabled = false)
error = yield
if !error.empty?
m = error[0..0]
c = (m == "E" ? :red : :yellow) unless @first_error
print Bacon.color(c, m)
@first_error = true
elsif disabled
print "D"
else
print Bacon.color(nil, '.')
end
end
def handle_summary
first_error = ''
error_count = 0
ErrorLog.lines.each do |s|
error_count += 1 if s.include?('Error:') || s.include?('Informative')
first_error << s if error_count <= 1
end
puts "\n#{first_error}" if Backtraces
unless Counter[:disabled].zero?
puts Bacon.color(:yellow, "#{Counter[:disabled]} disabled specifications")
end
result = "%d specifications (%d requirements), %d failures, %d errors" %
Counter.values_at(:specifications, :requirements, :failed, :errors)
if Counter[:failed].zero?
puts Bacon.color(:green, result)
else
puts Bacon.color(:red, result)
end
end
end
#---------------------------------------------------------------------------#
module FilterBacktraces module FilterBacktraces
def handle_summary def handle_summary
...@@ -58,6 +125,9 @@ module Bacon ...@@ -58,6 +125,9 @@ module Bacon
super super
end end
end end
#---------------------------------------------------------------------------#
extend FilterBacktraces extend FilterBacktraces
class Context class Context
...@@ -67,3 +137,6 @@ module Bacon ...@@ -67,3 +137,6 @@ module Bacon
end end
end end
end end
...@@ -2,9 +2,13 @@ require 'spec_helper/temporary_directory' ...@@ -2,9 +2,13 @@ require 'spec_helper/temporary_directory'
module SpecHelper module SpecHelper
module Command module Command
def argv(*argv)
CLAide::ARGV.new(argv)
end
def command(*argv) def command(*argv)
argv << '--no-color' argv << '--no-color'
Pod::Command.parse(*argv) Pod::Command.parse(argv)
end end
def run_command(*args) def run_command(*args)
...@@ -14,7 +18,9 @@ module SpecHelper ...@@ -14,7 +18,9 @@ module SpecHelper
# been converted to use the UI.puts # been converted to use the UI.puts
config_silent = config.silent? config_silent = config.silent?
config.silent = false config.silent = false
command(*args).run cmd = command(*args)
cmd.validate!
cmd.run
config.silent = config_silent config.silent = config_silent
Pod::UI.output Pod::UI.output
end end
......
...@@ -28,7 +28,7 @@ module SpecHelper ...@@ -28,7 +28,7 @@ module SpecHelper
end end
def add_repo(name, from) def add_repo(name, from)
command = command('repo', 'add', name, from) command = Pod::Command.parse(['repo', 'add', name, from])
command.run command.run
# The test branch is used by the push specs # The test branch is used by the push specs
Dir.chdir(command.dir) do Dir.chdir(command.dir) do
......
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Command::DeepLinter do
extend SpecHelper::TemporaryDirectory
def write_podspec(text, name = 'JSONKit.podspec')
file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) }
file
end
def stub_podspec(pattern = nil, replacement = nil)
spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
spec.gsub!(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s)
spec.gsub!(pattern, replacement) if pattern && replacement
spec
end
it "respects quick mode" do
file = write_podspec(stub_podspec)
linter = Command::DeepLinter.new(file)
linter.expects(:peform_multiplatform_analysis).never
linter.expects(:install_pod).never
linter.expects(:xcodebuild_output_for_platfrom).never
linter.expects(:file_patterns_errors_for_platfrom).never
linter.quick = true
linter.lint
end
unless skip_xcodebuild?
it "uses xcodebuild to generate notes and warnings" do
file = write_podspec(stub_podspec)
linter = Command::DeepLinter.new(file)
linter.lint
linter.result_type.should == :warning
linter.notes.join(' | ').should.include "JSONKit/JSONKit.m:1640:27: warning: equality comparison with extraneous parentheses"
end
end
it "checks for file patterns" do
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\ns.resources = 'WRONG_FOLDER'"))
linter = Command::DeepLinter.new(file)
linter.stubs(:xcodebuild_output).returns([])
linter.quick = false
linter.lint
linter.result_type.should == :error
linter.errors.join(' | ').should.include "The resources did not match any file"
end
it "uses the deployment target of the specification" do
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'; s.platform = :ios, '5.0'"))
linter = Command::DeepLinter.new(file)
linter.quick = true
linter.lint
podfile = linter.podfile_from_spec
deployment_target = podfile.target_definitions[:default].platform.deployment_target
deployment_target.to_s.should == "5.0"
end
end
end
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Linter" do
extend SpecHelper::TemporaryDirectory
def write_podspec(text, name = 'JSONKit.podspec')
file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) }
file
end
def stub_podspec(pattern = nil, replacement = nil)
spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
spec.gsub!(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s)
spec.gsub!(pattern, replacement) if pattern && replacement
spec
end
it "fails a specifications that does not contain the minimum required attributes" do
file = write_podspec('Pod::Spec.new do |s| end')
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :error
linter.errors.join(' | ') =~ /name.*version.*summary.*homepage.*authors.*(source.*part_of).*source_files/
end
it "fails specifications if the name does not match the name of the file" do
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKitAAA'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :error
linter.errors.count.should == 1
linter.errors[0].should =~ /The name of the spec should match the name of the file/
end
it "fails a specification if a path starts with a slash" do
file = write_podspec(stub_podspec(/s.source_files = 'JSONKit\.\*'/, "s.source_files = '/JSONKit.*'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :error
linter.errors.count.should == 1
linter.errors[0].should =~ /Paths cannot start with a slash/
end
it "fails a specification if the platform is unrecognized" do
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'\ns.platform = :iososx\n"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :error
linter.errors.count.should == 1
linter.errors[0].should =~ /Unrecognized platfrom/
end
it "fails validation if the specification contains warnings" do
file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :warning
linter.errors.should.be.empty
linter.warnings.should.not.be.empty
end
it "correctly report specification that only contain warnings" do
file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :warning
end
it "respects quick mode" do
file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(file)
linter.expects(:peform_multiplatform_analysis).never
linter.expects(:install_pod).never
linter.expects(:xcodebuild_output_for_platfrom).never
linter.expects(:file_patterns_errors_for_platfrom).never
linter.quick = true
linter.lint
end
it "produces deprecation notices" do
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\n if config.ios?\nend"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
linter.result_type.should == :error
linter.warnings.should.be.empty
linter.errors.join(' | ').should =~ /`config.ios\?' and `config.osx\?' are deprecated/
end
it "uses xcodebuild to generate notes and warnings" do
file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(file)
linter.lint
linter.result_type.should == :warning
linter.notes.join(' | ').should.include "JSONKit/JSONKit.m:1640:27: warning: equality comparison with extraneous parentheses" unless `which xcodebuild`.strip.empty?
end
it "checks for file patterns" do
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\ns.resources = 'WRONG_FOLDER'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.stubs(:xcodebuild_output).returns([])
linter.quick = false
linter.lint
linter.result_type.should == :error
linter.errors.join(' | ').should.include "The resources did not match any file"
end
it "uses the deployment target of the specification" do
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'; s.platform = :ios, '5.0'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
podfile = linter.podfile_from_spec
deployment_target = podfile.target_definitions[:default].platform.deployment_target
deployment_target.to_s.should == "5.0"
end
end
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Command" do module Pod
it "returns the proper command class" do describe Command do
Pod::Command.parse('setup').should.be.instance_of Pod::Command::Setup it "returns the proper command class" do
Pod::Command.parse('spec', 'create', 'name').should.be.instance_of Pod::Command::Spec Command.parse(%w{ install }).should.be.instance_of Command::Install
Pod::Command.parse('repo', 'update').should.be.instance_of Pod::Command::Repo Command.parse(%w{ list }).should.be.instance_of Command::List
Command.parse(%w{ outdated }).should.be.instance_of Command::Outdated
Command.parse(%w{ push }).should.be.instance_of Command::Push
Command.parse(%w{ repo }).should.be.instance_of Command::Repo
Command.parse(%w{ repo add }).should.be.instance_of Command::Repo::Add
Command.parse(%w{ repo lint }).should.be.instance_of Command::Repo::Lint
Command.parse(%w{ repo update }).should.be.instance_of Command::Repo::Update
Command.parse(%w{ search }).should.be.instance_of Command::Search
Command.parse(%w{ setup }).should.be.instance_of Command::Setup
Command.parse(%w{ spec create }).should.be.instance_of Command::Spec::Create
Command.parse(%w{ spec lint }).should.be.instance_of Command::Spec::Lint
Command.parse(%w{ repo update }).should.be.instance_of Command::Repo::Update
end
end end
end end
describe "Pod::Command::Repo" do
it "complains about unknown arguments" do
lambda { Pod::Command::Repo.new(argv('something')) }.should.raise Pod::Command::Help
end
end
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Dependency do
it "merges dependencies (taken from newer RubyGems version)" do
dep1 = Dependency.new('bananas', '>= 1.8')
dep2 = Dependency.new('bananas', '1.9')
dep1.merge(dep2).should == Dependency.new('bananas', '>= 1.8', '1.9')
end
it "returns the name of the dependency, or the name of the pod of which this is a subspec" do
dep = Dependency.new('RestKit')
dep.top_level_spec_name.should == 'RestKit'
dep = Dependency.new('RestKit/Networking')
dep.top_level_spec_name.should == 'RestKit'
end
it "returns a copy of the dependency but for the top level spec, if it's a subspec" do
dep = Dependency.new('RestKit', '>= 1.2.3')
dep.to_top_level_spec_dependency.should == Dependency.new('RestKit', '>= 1.2.3')
dep = Dependency.new('RestKit/Networking', '>= 1.2.3')
dep.to_top_level_spec_dependency.should == Dependency.new('RestKit', '>= 1.2.3')
end
it "is equal to another dependency if `external_source' is the same" do
dep1 = Dependency.new('bananas', :git => 'GIT-URL')
dep2 = Dependency.new('bananas')
dep1.should.not == dep2
dep3 = Dependency.new('bananas', :git => 'GIT-URL')
dep1.should == dep3
end
it "is equal to another dependency if `specification' is equal" do
dep1 = Dependency.new { |s| s.name = 'bananas'; s.version = '1' }
dep2 = Dependency.new('bananas')
dep1.should.not == dep2
dep2 = Dependency.new { |s| s.name = 'bananas'; s.version = '1' }
dep1.should == dep2
end
it 'raises if created without either valid name/version/external requirements or a block' do
lambda { Dependency.new }.should.raise Informative
end
describe "defined with a block" do
before do
@dependency = Dependency.new do |spec|
spec.name = "my-custom-spec"
spec.version = "1.0.3"
end
end
it 'it identifies itself as an inline dependency' do
@dependency.should.be.inline
end
it 'attaches a custom spec to the dependency, configured by the block' do
@dependency.specification.name.should == "my-custom-spec"
end
end
describe "with a hash of external source settings" do
before do
@dependency = Dependency.new("cocoapods", :git => "git://github.com/cocoapods/cocoapods")
end
it 'identifies itself as an external dependency' do
@dependency.should.be.external
end
end
describe "with flags" do
it "identifies itself as a `bleeding edge' dependency" do
dependency = Dependency.new("cocoapods", :head)
dependency.should.be.head
dependency.to_s.should == "cocoapods (HEAD)"
end
it "only supports the `:head' option on the last version of a pod" do
should.raise Informative do
Dependency.new("cocoapods", "1.2.3", :head)
end
end
it "raises if an invalid flag is given" do
should.raise ArgumentError do
Dependency.new("cocoapods", :foot)
end
end
end
describe Dependency::ExternalSources do
before do
@sandbox = temporary_sandbox
end
it "marks a LocalPod as downloaded if it's from GitSource" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
@sandbox.installed_pod_named('Reachability', Platform.ios).downloaded.should.be.true
end
it "creates a copy of the podspec (GitSource)" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (PodspecSource)" do
dependency = Dependency.new("Reachability", :podspec => fixture('integration/Reachability/Reachability.podspec').to_s)
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (LocalSource)" do
dependency = Dependency.new("Reachability", :local => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe ExternalSources do
before do
@sandbox = temporary_sandbox
end
it "marks a LocalPod as downloaded if it's from GitSource" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
external_source = ExternalSources.from_dependency(dependency)
external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
@sandbox.installed_pod_named('Reachability', Platform.ios).downloaded.should.be.true
end
it "creates a copy of the podspec (GitSource)" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
external_source = ExternalSources.from_dependency(dependency)
external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (PodspecSource)" do
dependency = Dependency.new("Reachability", :podspec => fixture('integration/Reachability/Reachability.podspec').to_s)
external_source = ExternalSources.from_dependency(dependency)
external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (LocalSource)" do
dependency = Dependency.new("Reachability", :local => fixture('integration/Reachability'))
external_source = ExternalSources.from_dependency(dependency)
external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
end
end
require File.expand_path('../../../spec_helper', __FILE__)
describe PrefixHeader = Pod::Generator::PrefixHeader do
before do
platform = Pod::Platform.ios
specification = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(specification, nil, platform)
pods = [ @pod ]
@gen = PrefixHeader.new(platform, pods)
@pod.stubs(:root).returns(Pathname.new(fixture('banana-lib')))
end
it "includes the contents of the specification's prefix header" do
spec = @pod.top_specification
spec.prefix_header_contents = '#import "BlocksKit.h"'
@gen.generate.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import "BlocksKit.h"
EOS
end
it "includes the contents of the specification's prefix header file" do
@gen.generate.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import <BananaTree/BananaTree.h>
EOS
end
it "prefers the inline specification of the prefix header contents" do
spec = @pod.top_specification
spec.prefix_header_contents = '#import "BlocksKit.h"'
@pod.prefix_header_file.should.be.not.nil
@gen.generate.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import "BlocksKit.h"
EOS
end
it "imports UIKit in iOS platforms" do
@gen.stubs(:platform).returns(Pod::Platform.ios)
@gen.generate.should.include?('#import <UIKit/UIKit.h>')
end
it "imports Cocoa for OS X platforms" do
@gen.stubs(:platform).returns(Pod::Platform.osx)
@gen.generate.should.include?('#import <Cocoa/Cocoa.h>')
end
extend SpecHelper::TemporaryDirectory
it "writes the prefix header file to the disk" do
path = temporary_directory + 'Test.pch'
@gen.save_as(path)
path.read.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import <BananaTree/BananaTree.h>
EOS
end
end
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Generator::XCConfig do
before do
specification = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(specification, config.sandbox, :ios)
@generator = Generator::XCConfig.new(config.sandbox, [@pod], './Pods')
end
it "returns the sandbox" do
@generator.sandbox.class.should == Sandbox
end
it "returns the pods" do
@generator.pods.should == [@pod]
end
it "returns the path of the pods root relative to the user project" do
@generator.relative_pods_root.should == './Pods'
end
#-----------------------------------------------------------------------#
before do
@xcconfig = @generator.generate
end
it "generates the xcconfig" do
@xcconfig.class.should == Xcodeproj::Config
end
it 'adds the sandbox header search paths to the xcconfig, with quotes' do
@xcconfig.to_hash['PODS_BUILD_HEADERS_SEARCH_PATHS'].should.include("\"#{config.sandbox.build_headers.search_paths.join('" "')}\"")
end
it 'does not add the -fobjc-arc to OTHER_LDFLAGS by default as Xcode 4.3.2 does not support it' do
@xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.not.include("-fobjc-arc")
end
it 'adds the -fobjc-arc to OTHER_LDFLAGS if any pods require arc (to support non-ARC projects on iOS 4.0)' do
@generator.set_arc_compatibility_flag = true
@pod.top_specification.stubs(:requires_arc).returns(true)
@xcconfig = @generator.generate
@xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.include("-fobjc-arc")
end
#-----------------------------------------------------------------------#
it 'returns the settings that the pods project needs to override' do
Generator::XCConfig.pods_project_settings.should.not.be.nil
end
it 'overrides the relative path of the pods root in the Pods project' do
Generator::XCConfig.pods_project_settings['PODS_ROOT'].should == '${SRCROOT}'
end
it 'overrides the headers search path of the pods project to the build headers folder' do
expected = '${PODS_BUILD_HEADERS_SEARCH_PATHS}'
Generator::XCConfig.pods_project_settings['PODS_HEADERS_SEARCH_PATHS'].should == expected
end
#-----------------------------------------------------------------------#
extend SpecHelper::TemporaryDirectory
it "saves the xcconfig" do
path = temporary_directory + 'sample.xcconfig'
@generator.save_as(path)
generated = Xcodeproj::Config.new(path)
generated.class.should == Xcodeproj::Config
end
end
end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
TMP_POD_ROOT = ROOT + "tmp" + "podroot" unless defined? TMP_POD_ROOT describe TargetInstaller = Pod::Installer::TargetInstaller do
describe "In general" do
before do
@podfile = Pod::Podfile.new do
platform :ios
end
@target_definition = @podfile.target_definitions[:default]
@project = Pod::Project.new(config.sandbox)
@specification = fixture_spec('banana-lib/BananaLib.podspec')
@pods = [Pod::LocalPod.new(@specification, config.sandbox, Pod::Platform.ios)]
@installer = TargetInstaller.new(@project, @target_definition, @pods,)
end
describe Pod::Installer::TargetInstaller do it "returns the project" do
extend SpecHelper::TemporaryDirectory @installer.project.should == @project
end
before do it "returns the target_definition" do
@podfile = Pod::Podfile.new do @installer.target_definition.should == @target_definition
platform :ios
xcodeproj 'dummy'
end end
@target_definition = @podfile.target_definitions[:default]
@project = Pod::Project.new it "returns the pods of the target definition" do
@project.new_group('Targets Support Files') @installer.pods.should == @pods
end
end
@installer = Pod::Installer::TargetInstaller.new(@podfile, @project, @target_definition) describe "Installation" do
extend SpecHelper::TemporaryDirectory
before do
@podfile = Pod::Podfile.new do
platform :ios
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions[:default]
@project = Pod::Project.new(config.sandbox)
specification = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(specification, config.sandbox, @target_definition.platform)
@installer = TargetInstaller.new(@project, @target_definition, [@pod])
specification.prefix_header_contents = '#import "BlocksKit.h"'
@pod.stubs(:root).returns(Pathname.new(fixture('banana-lib')))
end
@sandbox = Pod::Sandbox.new(TMP_POD_ROOT) def do_install!
FileUtils.cp_r(fixture('banana-lib'), TMP_POD_ROOT + 'BananaLib') # Prevent raise for missing dummy project.
@specification = fixture_spec('banana-lib/BananaLib.podspec') Pathname.any_instance.stubs(:exist?).returns(true)
@pods = [Pod::LocalPod.new(@specification, @sandbox, Pod::Platform.ios)] @pod.add_file_references_to_project(@project)
end @installer.install!
end
def do_install! it 'adds a new static library target to the project' do
@pods.each { |pod| pod.add_file_references_to_project(@project) } do_install!
@installer.install!(@pods, @sandbox) @project.targets.count.should == 1
end @project.targets.first.name.should == @target_definition.label
end
it 'adds a new static library target to the project' do it 'adds the source files of each pod to the target of the Pod library' do
do_install! do_install!
@project.targets.count.should == 1 names = @installer.target.source_build_phase.files.map { |bf| bf.file_ref.name }
@project.targets.first.name.should == @target_definition.label names.should == [ "Banana.m" ]
end end
it "adds the user's build configurations to the target" do it "adds file references for the support files of the target" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug } do_install!
do_install! group = @project.support_files_group['Pods']
@project.targets.first.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test } group.children.map(&:display_name).sort.should == [
end "Pods-prefix.pch", "Pods-resources.sh", "Pods.xcconfig"
]
end
it 'adds each pod to the static library target' do #--------------------------------------#
@pods[0].expects(:add_build_files_to_target)
do_install!
end
# TODO: move to project it "adds the settings of the xcconfig that need to be overridden to the target" do
# it 'tells each pod to link its headers' do do_install!
# @pods[0].expects(:link_headers) build_configuration = @project.targets.first.build_configurations
# do_install! build_settings = build_configuration.first.build_settings
# end Pod::Generator::XCConfig.pods_project_settings.each do |key, value|
build_settings[key].should == value
end
end
it 'adds the sandbox header search paths to the xcconfig, with quotes' do it "adds the user's build configurations to the target" do
do_install! @project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@installer.xcconfig.to_hash['PODS_BUILD_HEADERS_SEARCH_PATHS'].should.include("\"#{@sandbox.build_headers.search_paths.join('" "')}\"") do_install!
end @project.targets.first.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end
it 'does not add the -fobjc-arc to OTHER_LDFLAGS by default as Xcode 4.3.2 does not support it' do it "does not enable the GCC_WARN_INHIBIT_ALL_WARNINGS flag by default" do
do_install! do_install!
@installer.xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.not.include("-fobjc-arc") @installer.target.build_configurations.each do |config|
end config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should.be.nil
end
end
it 'adds the -fobjc-arc to OTHER_LDFLAGS if any pods require arc (to support non-ARC projects on iOS 4.0)' do it "enables the GCC_WARN_INHIBIT_ALL_WARNINGS flag" do
@podfile.stubs(:set_arc_compatibility_flag? => true) @podfile.inhibit_all_warnings!
@specification.stubs(:requires_arc).returns(true) do_install!
do_install! @installer.target.build_configurations.each do |config|
@installer.xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.include("-fobjc-arc") config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should == 'YES'
end end
end
it "does not enable the GCC_WARN_INHIBIT_ALL_WARNINGS flag by default" do it "creates and xcconfig file" do
do_install! do_install!
@installer.target.build_configurations.each do |config| xcconfig = config.sandbox.root + 'Pods.xcconfig'
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should == 'NO' xcconfig.read.should == <<-EOS.strip_heredoc.gsub(/\n$/, '')
ALWAYS_SEARCH_USER_PATHS = YES
OTHER_LDFLAGS = -ObjC
HEADER_SEARCH_PATHS = ${PODS_HEADERS_SEARCH_PATHS}
PODS_ROOT = ${SRCROOT}/Pods
PODS_BUILD_HEADERS_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders"
PODS_PUBLIC_HEADERS_SEARCH_PATHS = "${PODS_ROOT}/Headers"
PODS_HEADERS_SEARCH_PATHS = ${PODS_PUBLIC_HEADERS_SEARCH_PATHS}
EOS
end end
end
it "enables the GCC_WARN_INHIBIT_ALL_WARNINGS flag" do it "creates a prefix header, including the contents of the specification's prefix header" do
@podfile.inhibit_all_warnings! @pod.top_specification.prefix_header_contents = '#import "BlocksKit.h"'
do_install! do_install!
@installer.target.build_configurations.each do |config| prefix_header = config.sandbox.root + 'Pods-prefix.pch'
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should == 'YES' prefix_header.read.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import "BlocksKit.h"
EOS
end end
end
it "creates a prefix header, including the contents of the specification's prefix header file" do it "creates a bridge support file" do
do_install! Pod::Podfile.any_instance.stubs(:generate_bridge_support? => true)
prefix_header = @sandbox.root + 'Pods.pch' Pod::Generator::BridgeSupport.any_instance.expects(:save_as).once
@installer.save_prefix_header_as(prefix_header, @pods) do_install!
prefix_header.read.should == <<-EOS end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import <BananaTree/BananaTree.h>
EOS
end
it "creates a prefix header, including the contents of the specification's prefix header" do it "creates a create copy resources script" do
do_install! do_install!
prefix_header = @sandbox.root + 'Pods.pch' script = config.sandbox.root + 'Pods-resources.sh'
@specification.prefix_header_contents = '#import "BlocksKit.h"' script.read.should.include?('logo-sidebar.png')
@installer.save_prefix_header_as(prefix_header, @pods) end
prefix_header.read.should == <<-EOS
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#import "BlocksKit.h"
EOS
end end
end end
require File.expand_path('../../../spec_helper', __FILE__) require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Installer::UserProjectIntegrator do describe UserProjectIntegrator = Pod::Installer::UserProjectIntegrator do
extend SpecHelper::TemporaryDirectory
describe "In general" do
before do extend SpecHelper::TemporaryDirectory
@sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject') before do
config.project_root = @sample_project_path.dirname @sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
sample_project_path = @sample_project_path sample_project_path = @sample_project_path
@podfile = Pod::Podfile.new do @podfile = Pod::Podfile.new do
platform :ios platform :ios
xcodeproj sample_project_path xcodeproj sample_project_path
pod 'JSONKit' pod 'JSONKit'
target :test_runner, :exclusive => true do target :test_runner, :exclusive => true do
link_with 'TestRunner' link_with 'TestRunner'
pod 'Kiwi' pod 'Kiwi'
end
end end
@project_root = @sample_project_path.dirname
@pods_project = Pod::Project.new(config.sandbox)
@integrator = UserProjectIntegrator.new(@podfile, @pods_project, @project_root)
@podfile.target_definitions.values.each { |td| @pods_project.add_pod_library(td) }
end end
@integrator = Pod::Installer::UserProjectIntegrator.new(@podfile) it "returns the podfile" do
end @integrator.podfile.should == @podfile
end
it "returns the path to the workspace from the Podfile" do it "returns the pods project" do
@integrator.workspace_path.should == config.project_root + 'SampleProject.xcworkspace' @integrator.pods_project.should == @pods_project
end end
it "raises if no workspace could be selected" do it "returns the project root" do
@podfile.stubs(:workspace) @integrator.project_root.should == @project_root
lambda { @integrator.workspace_path }.should.raise Pod::Informative end
end
it "returns the path to the Pods.xcodeproj document" do it "uses the path of the workspace defined in the podfile" do
@integrator.pods_project_path.should == config.project_root + 'Pods/Pods.xcodeproj' path = "a_path"
end @podfile.workspace path
@integrator.workspace_path.should == path + ".xcworkspace"
end
it "returns a Pod::Installer::UserProjectIntegrator::Target for each target definition in the Podfile" do it "names the workspace after the user project if needed" do
@integrator.target_integrators.map(&:target_definition).should == @podfile.target_definitions.values @integrator.workspace_path.should == @sample_project_path.dirname + 'SampleProject.xcworkspace'
end end
before do it "raises if no workspace could be selected" do
@target_integrator = @integrator.target_integrators.first @integrator.expects(:user_project_paths).returns(%w[ project1 project2 ])
end lambda { @integrator.workspace_path }.should.raise Pod::Informative
end
it "returns the the user's project, that contains the target, from the Podfile" do it "returns the paths of the user projects" do
@target_integrator.user_project_path.should == @sample_project_path @integrator.user_project_paths.should == [ @sample_project_path ]
@target_integrator.user_project.should == Xcodeproj::Project.new(@sample_project_path) end
end end
it "raises if no project could be selected" do #--------------------------------------#
@target_integrator.target_definition.user_project.stubs(:path).returns(nil)
lambda { @target_integrator.user_project_path }.should.raise Pod::Informative
end
it "raises if the project path doesn't exist" do describe "Integration" do
@target_integrator.target_definition.user_project.path.stubs(:exist?).returns(false) extend SpecHelper::TemporaryDirectory
lambda { @target_integrator.user_project_path }.should.raise Pod::Informative
end
it "uses the target with the same name if the name is different from `:default'" do before do
target_integrator = @integrator.target_integrators[1] @sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
target_integrator.target_definition.stubs(:name).returns('TestRunner') sample_project_path = @sample_project_path
target_integrator.target_definition.stubs(:link_with).returns(nil) @podfile = Pod::Podfile.new do
target_integrator.targets.first.name.should == 'TestRunner' platform :ios
end xcodeproj sample_project_path
pod 'JSONKit'
end
@project_root = @sample_project_path.dirname
@pods_project = Pod::Project.new(config.sandbox)
@integrator = UserProjectIntegrator.new(@podfile, @pods_project, @project_root)
@podfile.target_definitions.values.each { |td| @pods_project.add_pod_library(td) }
@integrator.integrate!
end
it "adds the project being integrated to the workspace" do
workspace = Xcodeproj::Workspace.new_from_xcworkspace(@integrator.workspace_path)
workspace.projpaths.sort.should == %w{ ../Pods/Pods.xcodeproj SampleProject.xcodeproj }
end
it "it raises if it can't find a target with the same name" do it "adds the Pods project to the workspace" do
target_integrator = @integrator.target_integrators.find { |ti| ti.target_definition.name == :test_runner } workspace = Xcodeproj::Workspace.new_from_xcworkspace(@integrator.workspace_path)
target_integrator.target_definition.stubs(:link_with).returns(nil) workspace.projpaths.find { |path| path =~ /Pods.xcodeproj/ }.should.not.be.nil
lambda { target_integrator.targets }.should.raise Pod::Informative end
xit "warns if the podfile does not contain any dependency" do
Pod::UI.output.should.include?('The Podfile does not contain any dependency')
end
end end
end
#-----------------------------------------------------------------------------#
describe TargetIntegrator = Pod::Installer::UserProjectIntegrator::TargetIntegrator do
describe "In general" do
before do
@sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
sample_project_path = @sample_project_path
@podfile = Pod::Podfile.new do
platform :ios
xcodeproj sample_project_path
end
@pods_project = Pod::Project.new(config.sandbox)
@podfile.target_definitions.values.each { |td| @pods_project.add_pod_library(td) }
@library = @pods_project.libraries.first
@target_integrator = TargetIntegrator.new(@library)
end
it "returns the Pod library that should be integrated" do
@target_integrator.library.should == @library
end
it "returns the user's project, that contains the target, from the Podfile" do
@target_integrator.user_project.should == Xcodeproj::Project.new(@sample_project_path)
end
it "uses the first target in the user's project if no explicit target is specified" do
target_integrator = @integrator.target_integrators.find { |ti| ti.target_definition.name == :default }
target_integrator.target_definition.stubs(:link_with).returns(nil)
target_integrator.targets.should == [Xcodeproj::Project.new(@sample_project_path).targets.first]
end end
# before do
# sample_project_path = SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
# config.project_root = sample_project_path.dirname
# @podfile = Pod::Podfile.new do
# platform :ios
# xcodeproj sample_project_path, 'Test' => :debug
# link_with 'SampleProject' # this is an app target!
# pod 'JSONKit'
#
# target :test_runner, :exclusive => true do
# link_with 'TestRunner'
# pod 'Kiwi'
# end
# end
# @sample_project_path = sample_project_path
# pods_project = Pod::Project.new(config.sandbox)
# @integrator = Pod::Installer::UserProjectIntegrator.new(@podfile, pods_project)
# @integrator.integrate!
# @sample_project = Xcodeproj::Project.new(sample_project_path)
# end
#
# it 'adds references to the Pods static libraries to the Frameworks group' do
# @sample_project["Frameworks/libPods.a"].should.not == nil
# @sample_project["Frameworks/libPods-test_runner.a"].should.not == nil
# end
#
#
# it 'sets the Pods xcconfig as the base config for each build configuration' do
# @podfile.target_definitions.each do |_, definition|
# target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
# xcconfig_file = @sample_project.files.find { |f| f.path == "Pods/#{definition.xcconfig_name}" }
# target.build_configurations.each do |config|
# config.base_configuration_reference.should == xcconfig_file
# end
# end
# end
#
# it 'adds the libPods static library to the "Link binary with libraries" build phase of each target' do
# @podfile.target_definitions.each do |_, definition|
# target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
# target.frameworks_build_phase.files.find { |f| f.file_ref.name == definition.lib_name}.should.not == nil
# end
# end
#
# it 'adds a Copy Pods Resources build phase to each target' do
# @podfile.target_definitions.each do |_, definition|
# target = @sample_project.targets.find { |t| t.name == definition.link_with.first }
# phase = target.shell_script_build_phases.find { |bp| bp.name == "Copy Pods Resources" }
# phase.shell_script.strip.should == "\"${SRCROOT}/Pods/#{definition.copy_resources_script_name}\""
# end
# end
#
# before do
# # Reset the cached TargetIntegrator#targets lists.
# @integrator.instance_variable_set(:@target_integrators, nil)
# end
#
# it "only tries to integrate Pods libraries into user targets that haven't been integrated yet" do
# app_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :default }
# test_runner_integrator = @integrator.target_integrators.find { |t| t.target_definition.name == :test_runner }
#
# # Remove libPods.a from the app target. But don't do it through TargetIntegrator#targets,
# # as it will return only those that still need integration.
# app_target = app_integrator.user_project.targets.find { |t| t.name == 'SampleProject' }
# app_target.frameworks_build_phase.files.last.remove_from_project
#
# # Set the name of the libPods.a PBXFileReference to `nil` to ensure the file’s basename
# # is used instead. Not sure yet what makes it so that the name is nil in the first place.
# test_target = test_runner_integrator.user_project.targets.find { |t| t.name == 'TestRunner' }
# build_file = test_target.frameworks_build_phase.files.last
# build_file.file_ref.name = nil
#
# app_integrator.expects(:add_pods_library)
# test_runner_integrator.expects(:add_pods_library).never
#
# @integrator.integrate!
# end
#
# it "does not even try to save the project if none of the target integrators had any work to do" do
# @integrator.target_integrators.first.user_project.expects(:save_as).never
# @integrator.integrate!
# end
# end
#
end end
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
# it 'tells each pod to link its headers' do
# @pods[0].expects(:link_headers)
# do_install!
# end
module Pod module Pod
describe Installer do describe Installer do
...@@ -17,6 +23,28 @@ module Pod ...@@ -17,6 +23,28 @@ module Pod
xcodeproj 'MyProject' xcodeproj 'MyProject'
pods.each { |name| pod name } pods.each { |name| pod name }
end end
# @sandbox = temporary_sandbox
# config.project_pods_root = temporary_sandbox.root
# FileUtils.cp_r(fixture('integration/JSONKit'), @sandbox.root + 'JSONKit')
# resolver = Resolver.new(podfile, nil, @sandbox)
# @installer = Installer.new(resolver)
# target_installer = @installer.target_installers.first
# target_installer.install
# @xcconfig = target_installer.xcconfig.to_hash
end
it "sets the header search paths where installed Pod headers can be found" do
@xcconfig['ALWAYS_SEARCH_USER_PATHS'].should == 'YES'
end
it "configures the project to load all members that implement Objective-c classes or categories from the static library" do
@xcconfig['OTHER_LDFLAGS'].should == '-ObjC'
end
it "sets the PODS_ROOT build variable" do
@xcconfig['PODS_ROOT'].should.not == nil
end end
def generate_lockfile def generate_lockfile
...@@ -40,8 +68,15 @@ module Pod ...@@ -40,8 +68,15 @@ module Pod
# end # end
# end # end
# <<<<<<< HEAD
it "marks all pods as added if there is no lockfile" do it "marks all pods as added if there is no lockfile" do
@installer.pods_added_from_the_lockfile.should == ['JSONKit'] @installer.pods_added_from_the_lockfile.should == ['JSONKit']
# =======
# it "adds the files of the pod to the Pods project only once" do
# @installer.install!
# group = @installer.project.pods.groups.find { |g| g.name == 'Reachability' }
# group.files.map(&:name).sort.should == ["Reachability.h", "Reachability.m"]
# >>>>>>> core-extraction
end end
end end
......
require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::LocalPod::PathList do
before do
@path_list = Pod::LocalPod::PathList.new(fixture('banana-lib'))
end
it "creates the list of all the files" do
files = @path_list.files
files.reject! do |f|
f.include?('libPusher') || f.include?('.git') || f.include?('DS_Store')
end
files.sort.should == %w|
BananaLib.podspec
Classes Classes/Banana.h Classes/Banana.m Classes/BananaLib.pch
README
Resources Resources/logo-sidebar.png
sub-dir sub-dir/sub-dir-2 sub-dir/sub-dir-2/somefile.txt |
end
it "creates theh list of the directories" do
dirs = @path_list.dirs
dirs.reject! do |f|
f.include?('libPusher') || f.include?('.git')
end
dirs.sort.should == %w| Classes Resources sub-dir sub-dir/sub-dir-2 |
end
it "detects a directory" do
@path_list.directory?('classes').should == true
end
it "doesn't reports as a directory a file" do
@path_list.directory?('Classes/Banana.m').should == false
end
it "can glob the root for a given pattern" do
paths = @path_list.relative_glob('Classes/*.{h,m}').map(&:to_s)
paths.sort.should == %w| Classes/Banana.h Classes/Banana.m |
end
it "supports the `**` glob pattern" do
paths = @path_list.relative_glob('Classes/**/*.{h,m}').map(&:to_s)
paths.sort.should == %w| Classes/Banana.h Classes/Banana.m |
end
it "supports an optional pattern for globbing directories" do
paths = @path_list.relative_glob('Classes', '*.{h,m}').map(&:to_s)
paths.sort.should == %w| Classes/Banana.h Classes/Banana.m |
end
it "can return the absolute paths from glob" do
paths = @path_list.glob('Classes/*.{h,m}')
paths.all? { |p| p.absolute? }.should == true
end
it "can return the relative paths from glob" do
paths = @path_list.relative_glob('Classes/*.{h,m}')
paths.any? { |p| p.absolute? }.should == false
end
it "expands a pattern into all the combinations of Dir#glob literals" do
patterns = @path_list.dir_glob_equivalent_patterns('{file1,file2}.{h,m}')
patterns.sort.should == %w| file1.h file1.m file2.h file2.m |
end
it "returns the original pattern if there are no Dir#glob expansions" do
patterns = @path_list.dir_glob_equivalent_patterns('file*.*')
patterns.sort.should == %w| file*.* |
end
it "expands `**`" do
patterns = @path_list.dir_glob_equivalent_patterns('Classes/**/file.m')
patterns.sort.should == %w| Classes/**/file.m Classes/file.m |
end
it "supports a combination of `**` and literals" do
patterns = @path_list.dir_glob_equivalent_patterns('Classes/**/file.{h,m}')
patterns.sort.should == %w| Classes/**/file.h Classes/**/file.m Classes/file.h Classes/file.m |
end
end
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
describe Pod::LocalPod do describe Pod::LocalPod do
# a LocalPod represents a local copy of the dependency, inside the pod root, built from a spec
describe "in general" do describe "in general" do
before do before do
@sandbox = temporary_sandbox @sandbox = temporary_sandbox
...@@ -83,14 +81,14 @@ describe Pod::LocalPod do ...@@ -83,14 +81,14 @@ describe Pod::LocalPod do
end end
it "can add it's source files to an Xcode project target" do it "can add it's source files to an Xcode project target" do
project = Pod::Project.new project = Pod::Project.new(@sandbox)
@pod.add_file_references_to_project(project) @pod.add_file_references_to_project(project)
project['Pods/BananaLib/Banana.h'].path.should == "BananaLib/Classes/Banana.h" project['Pods/BananaLib/Banana.h'].path.should == "BananaLib/Classes/Banana.h"
project['Pods/BananaLib/Banana.m'].path.should == "BananaLib/Classes/Banana.m" project['Pods/BananaLib/Banana.m'].path.should == "BananaLib/Classes/Banana.m"
end end
it "can add it's source files to a target with any specially configured compiler flags" do it "can add it's source files to a target with any specially configured compiler flags" do
project = Pod::Project.new project = Pod::Project.new(@sandbox)
target = project.new_target(:static, 'Pods', :ios) target = project.new_target(:static, 'Pods', :ios)
@pod.top_specification.compiler_flags = '-d some_flag' @pod.top_specification.compiler_flags = '-d some_flag'
@pod.add_file_references_to_project(project) @pod.add_file_references_to_project(project)
...@@ -115,6 +113,8 @@ describe Pod::LocalPod do ...@@ -115,6 +113,8 @@ describe Pod::LocalPod do
end end
end end
#---------------------------------------------------------------------------#
describe "with installed source and multiple subspecs" do describe "with installed source and multiple subspecs" do
def assert_array_equals(expected, computed) def assert_array_equals(expected, computed)
......
require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Lockfile" do
describe "In general" do
extend SpecHelper::TemporaryDirectory
def sample
text = <<-LOCKFILE.strip_heredoc
PODS:
- BananaLib (1.0):
- monkey (< 1.0.9, ~> 1.0.1)
- monkey (1.0.8)
DEPENDENCIES:
- BananaLib (~> 1.0)
SPEC CHECKSUMS:
BananaLib: !binary |-
MjI2Y2RkMTJkMzBhMWU4ZWM4OGM1ZmRkZWU2MDcwZDg0YTI1MGZjMQ==
COCOAPODS: #{Pod::VERSION}
LOCKFILE
end
def podfile
Pod::Podfile.new do
platform :ios
pod 'BananaLib', '~>1.0'
end
end
def specs
specs = [
Pod::Specification.from_file(fixture('banana-lib/BananaLib.podspec')),
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
specs
end
def tmp_path
temporary_directory + 'Podfile.lock'
end
it "loads from a hash" do
lockfile = Pod::Lockfile.new(YAML.load(sample))
lockfile.to_hash.should == YAML.load(sample)
end
it "loads from a file" do
File.open(tmp_path, 'w') {|f| f.write(sample) }
lockfile = Pod::Lockfile.from_file(tmp_path)
lockfile.defined_in_file.should == tmp_path
lockfile.to_hash.should == YAML.load(sample)
end
it "can be generated from a Podfile and a list of Specifications" do
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash.should == YAML.load(sample)
end
before do
@lockfile = Pod::Lockfile.generate(podfile, specs)
end
it "generates a valid YAML representation" do
YAML.load(@lockfile.to_yaml).should == YAML.load(sample)
end
it "generates a valid Dictionary representation" do
@lockfile.to_hash.should == YAML.load(sample)
end
it "returns the list of the installed pods" do
@lockfile.pods_names.should == %w| BananaLib monkey |
end
it "returns the versions of the installed pods" do
@lockfile.pods_versions.should == {
"BananaLib" => Pod::Version.new("1.0"),
"monkey" => Pod::Version.new("1.0.8")
}
end
it "serializes correctly `:head' dependencies" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', :head
end
specs = [
Pod::Specification.new do |s|
s.name = "BananaLib"
s.version = "1.0"
end,
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (HEAD)"
end
it "serializes correctly external dependencies" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', { :git => "www.example.com", :tag => '1.0' }
end
specs = [
Pod::Specification.new do |s|
s.name = "BananaLib"
s.version = "1.0"
end,
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (from `www.example.com', tag `1.0')"
lockfile.to_hash["EXTERNAL SOURCES"]["BananaLib"].should == { :git => "www.example.com", :tag => '1.0' }
end
it "creates a dependency from a string" do
d = @lockfile.dependency_from_string("BananaLib (1.0)")
d.name.should == "BananaLib"
d.requirement.should =~ Pod::Version.new("1.0")
d.head.should.be.nil
d.external_source.should.be.nil
end
it "creates a head dependency from a string" do
d = @lockfile.dependency_from_string("BananaLib (HEAD)")
d.name.should == "BananaLib"
d.requirement.should.be.none?
d.head.should.be.true
d.external_source.should.be.nil
end
it "creates an external dependency from a string" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', { :git => "www.example.com", :tag => '1.0' }
end
lockfile = Pod::Lockfile.generate(podfile, [])
d = lockfile.dependency_from_string("BananaLib (from `www.example.com', tag `1.0')")
d.name.should == "BananaLib"
d.requirement.should.be.none?
d.external?.should.be.true
d.external_source.description.should == "from `www.example.com', tag `1.0'"
end
end
describe "Concerning initialization from a file" do
extend SpecHelper::TemporaryDirectory
it "returns nil if it can't find the initialization file" do
lockfile = Pod::Lockfile.from_file(temporary_directory + 'Podfile.lock_not_existing')
lockfile.should == nil
end
end
describe "Concerning the identification of changes in the Podfile" do
before do
@podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
end
@specs = [
Pod::Specification.new do |s|
s.name = "BlocksKit"
s.version = "1.0.0"
end,
Pod::Specification.new do |s|
s.name = "JSONKit"
s.version = "1.4"
end ]
@specs.each { |s| s.activate_platform(:ios) }
@lockfile = Pod::Lockfile.generate(@podfile, @specs)
end
it "detects an added Pod" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
pod 'TTTAttributedLabel'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>[],
:unchanged=>["BlocksKit", "JSONKit"],
:added=>["TTTAttributedLabel"]
}
end
it "detects an removed Pod" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>["JSONKit"],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "detects Pods whose version changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', "> 1.4"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "it doesn't mark a changed Pods whose version changed but is still compatible with the Podfile" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', "> 1.0"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>[],
:unchanged=>["BlocksKit", "JSONKit"],
:added=>[]
}
end
it "detects Pods whose external source changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :git => "example1.com"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
@lockfile = Pod::Lockfile.generate(podfile, @specs)
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :git => "example2.com"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "detects Pods whose head state changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :head
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
@specs = [
Pod::Specification.new do |s|
s.name = "BlocksKit"
s.version = "1.0.0"
end,
Pod::Specification.new do |s|
s.name = "JSONKit"
s.version = "1.4"
s.version.head = true
end ]
@specs.each { |s| s.activate_platform(:ios) }
@lockfile = Pod::Lockfile.generate(podfile, @specs)
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
describe Pod::Platform do
describe "by default" do
it "returns a new Platform instance" do
Pod::Platform.ios.should == Pod::Platform.new(:ios)
Pod::Platform.osx.should == Pod::Platform.new(:osx)
end
it "can be initialized from another platform" do
platform = Pod::Platform.new(:ios)
new = Pod::Platform.new(platform)
new.should == platform
end
before do
@platform = Pod::Platform.ios
end
it "exposes it's symbolic name" do
@platform.name.should == :ios
end
it "can be compared for equality with another platform with the same symbolic name" do
@platform.should == Pod::Platform.new(:ios)
end
it "can be compared for equality with another platform with the same symbolic name and the same deployment target" do
@platform.should.not == Pod::Platform.new(:ios, '4.0')
Pod::Platform.new(:ios, '4.0').should == Pod::Platform.new(:ios, '4.0')
end
it "can be compared for equality with a matching symbolic name (backwards compatibility reasons)" do
@platform.should == :ios
end
it "presents an accurate string representation" do
@platform.to_s.should == "iOS"
Pod::Platform.new(:osx).to_s.should == 'OS X'
Pod::Platform.new(:ios, '5.0.0').to_s.should == 'iOS 5.0.0'
Pod::Platform.new(:osx, '10.7').to_s.should == 'OS X 10.7'
end
it "uses it's name as it's symbold version" do
@platform.to_sym.should == :ios
end
it "allows to specify the deployment target on initialization" do
p = Pod::Platform.new(:ios, '4.0.0')
p.deployment_target.should == Pod::Version.new('4.0.0')
end
it "allows to specify the deployment target in a hash on initialization (backwards compatibility from 0.6)" do
p = Pod::Platform.new(:ios, { :deployment_target => '4.0.0' })
p.deployment_target.should == Pod::Version.new('4.0.0')
end
end
describe "regarding supporting platforms" do
it "supports platforms with the same operating system" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:ios)
p1.should.supports?(p2)
p1 = Pod::Platform.new(:osx)
p2 = Pod::Platform.new(:osx)
p1.should.supports?(p2)
end
it "supports a platform with a lower or equal deployment_target" do
p1 = Pod::Platform.new(:ios, '5.0')
p2 = Pod::Platform.new(:ios, '4.0')
p1.should.supports?(p1)
p1.should.supports?(p2)
p2.should.not.supports?(p1)
end
it "doesn't supports a platform with a different operating system" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:osx)
p1.should.not.supports?(p2)
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Podfile" do
it "loads from a file" do
podfile = Pod::Podfile.from_file(fixture('Podfile'))
podfile.defined_in_file.should == fixture('Podfile')
end
it "assigns the platform attribute to the current target" do
podfile = Pod::Podfile.new { platform :ios }
podfile.target_definitions[:default].platform.should == :ios
end
it "provides a default deployment target if not specified" do
podfile = Pod::Podfile.new { platform :ios }
podfile.target_definitions[:default].platform.deployment_target.should == Pod::Version.new('4.3')
end
it "raise error if unsupported platform is supplied" do
lambda {
Pod::Podfile.new { platform :iOS }
}.should.raise Pod::Podfile::Informative
begin
Pod::Podfile.new { platform :iOS }
rescue Pod::Podfile::Informative => e
e.stubs(:podfile_line).returns("./podfile_spec.rb:1")
e.message.should.be =~ /podfile_spec\.rb:1/
end
end
it "adds dependencies" do
podfile = Pod::Podfile.new { pod 'ASIHTTPRequest'; pod 'SSZipArchive', '>= 0.1' }
podfile.dependencies.size.should == 2
podfile.dependency_by_top_level_spec_name('ASIHTTPRequest').should == Pod::Dependency.new('ASIHTTPRequest')
podfile.dependency_by_top_level_spec_name('SSZipArchive').should == Pod::Dependency.new('SSZipArchive', '>= 0.1')
end
it "adds a dependency on a Pod repo outside of a spec repo (the repo is expected to contain a podspec)" do
podfile = Pod::Podfile.new do
pod 'SomeExternalPod', :git => 'GIT-URL', :commit => '1234'
end
dep = podfile.dependency_by_top_level_spec_name('SomeExternalPod')
dep.external_source.params.should == { :git => 'GIT-URL', :commit => '1234' }
end
it "adds a subspec dependency on a Pod repo outside of a spec repo (the repo is expected to contain a podspec)" do
podfile = Pod::Podfile.new do
pod 'MainSpec/FirstSubSpec', :git => 'GIT-URL', :commit => '1234'
end
dep = podfile.dependency_by_top_level_spec_name('MainSpec')
dep.external_source.name.should == 'MainSpec'
end
it "adds a dependency on a library outside of a spec repo (the repo does not need to contain a podspec)" do
podfile = Pod::Podfile.new do
pod 'SomeExternalPod', :podspec => 'http://gist/SomeExternalPod.podspec'
end
dep = podfile.dependency_by_top_level_spec_name('SomeExternalPod')
dep.external_source.params.should == { :podspec => 'http://gist/SomeExternalPod.podspec' }
end
it "adds a dependency on a library by specifying the podspec inline" do
podfile = Pod::Podfile.new do
pod do |s|
s.name = 'SomeExternalPod'
end
end
dep = podfile.dependency_by_top_level_spec_name('SomeExternalPod')
dep.specification.name.should == 'SomeExternalPod'
end
it "specifies that BridgeSupport metadata should be generated" do
Pod::Podfile.new {}.should.not.generate_bridge_support
Pod::Podfile.new { generate_bridge_support! }.should.generate_bridge_support
end
it 'specifies that ARC compatibility flag should be generated' do
Pod::Podfile.new { set_arc_compatibility_flag! }.should.set_arc_compatibility_flag
end
it "stores a block that will be called with the Installer before the target integration" do
yielded = nil
Pod::Podfile.new do
pre_install do |installer|
yielded = installer
end
end.pre_install!(:an_installer)
yielded.should == :an_installer
end
it "stores a block that will be called with the Installer instance once installation is finished (but the project is not written to disk yet)" do
yielded = nil
Pod::Podfile.new do
post_install do |installer|
yielded = installer
end
end.post_install!(:an_installer)
yielded.should == :an_installer
end
it "assumes the xcode project is the only existing project in the root" do
podfile = Pod::Podfile.new do
target(:another_target) {}
end
path = config.project_root + 'MyProject.xcodeproj'
Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([path])
podfile.target_definitions[:default].user_project.path.should == path
podfile.target_definitions[:another_target].user_project.path.should == path
end
it "assumes the basename of the workspace is the same as the default target's project basename" do
path = config.project_root + 'MyProject.xcodeproj'
Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([path])
Pod::Podfile.new {}.workspace.should == config.project_root + 'MyProject.xcworkspace'
Pod::Podfile.new do
xcodeproj 'AnotherProject.xcodeproj'
end.workspace.should == config.project_root + 'AnotherProject.xcworkspace'
end
it "does not base the workspace name on the default target's project if there are multiple projects specified" do
Pod::Podfile.new do
xcodeproj 'MyProject'
target :another_target do
xcodeproj 'AnotherProject'
end
end.workspace.should == nil
end
it "specifies the Xcode workspace to use" do
Pod::Podfile.new do
xcodeproj 'AnotherProject'
workspace 'MyWorkspace'
end.workspace.should == config.project_root + 'MyWorkspace.xcworkspace'
Pod::Podfile.new do
xcodeproj 'AnotherProject'
workspace 'MyWorkspace.xcworkspace'
end.workspace.should == config.project_root + 'MyWorkspace.xcworkspace'
end
describe "concerning targets (dependency groups)" do
it "returns wether or not a target has any dependencies" do
Pod::Podfile.new do
end.target_definitions[:default].should.be.empty
Pod::Podfile.new do
pod 'JSONKit'
end.target_definitions[:default].should.not.be.empty
end
before do
@podfile = Pod::Podfile.new do
platform :ios
xcodeproj 'iOS Project', 'iOS App Store' => :release, 'Test' => :debug
target :debug do
pod 'SSZipArchive'
end
target :test, :exclusive => true do
link_with 'TestRunner'
inhibit_all_warnings!
pod 'JSONKit'
target :subtarget do
pod 'Reachability'
end
end
target :osx_target do
platform :osx
xcodeproj 'OSX Project.xcodeproj', 'Mac App Store' => :release, 'Test' => :debug
link_with 'OSXTarget'
pod 'ASIHTTPRequest'
target :nested_osx_target do
end
end
pod 'ASIHTTPRequest'
end
end
it "returns all dependencies of all targets combined, which is used during resolving to ensure compatible dependencies" do
@podfile.dependencies.map(&:name).sort.should == %w{ ASIHTTPRequest JSONKit Reachability SSZipArchive }
end
it "adds dependencies outside of any explicit target block to the default target" do
target = @podfile.target_definitions[:default]
target.label.should == 'Pods'
target.dependencies.should == [Pod::Dependency.new('ASIHTTPRequest')]
end
it "adds dependencies of the outer target to non-exclusive targets" do
target = @podfile.target_definitions[:debug]
target.label.should == 'Pods-debug'
target.dependencies.sort_by(&:name).should == [
Pod::Dependency.new('ASIHTTPRequest'),
Pod::Dependency.new('SSZipArchive')
]
end
it "does not add dependencies of the outer target to exclusive targets" do
target = @podfile.target_definitions[:test]
target.label.should == 'Pods-test'
target.dependencies.should == [Pod::Dependency.new('JSONKit')]
end
it "adds dependencies of the outer target to nested targets" do
target = @podfile.target_definitions[:subtarget]
target.label.should == 'Pods-test-subtarget'
target.dependencies.should == [Pod::Dependency.new('Reachability'), Pod::Dependency.new('JSONKit')]
end
it "returns the Xcode project that contains the target to link with" do
[:default, :debug, :test, :subtarget].each do |target_name|
target = @podfile.target_definitions[target_name]
target.user_project.path.should == config.project_root + 'iOS Project.xcodeproj'
end
[:osx_target, :nested_osx_target].each do |target_name|
target = @podfile.target_definitions[target_name]
target.user_project.path.should == config.project_root + 'OSX Project.xcodeproj'
end
end
it "returns a Xcode project found in the working dir when no explicit project is specified" do
xcodeproj1 = config.project_root + '1.xcodeproj'
Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([xcodeproj1])
Pod::Podfile::UserProject.new.path.should == xcodeproj1
end
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'
Pathname.expects(:glob).with(config.project_root + '*.xcodeproj').returns([xcodeproj1, xcodeproj2])
Pod::Podfile::UserProject.new.path.should == nil
end
it "leaves the name of the target, to link with, to be automatically resolved" do
target = @podfile.target_definitions[:default]
target.link_with.should == nil
end
it "returns the names of the explicit targets to link with" do
target = @podfile.target_definitions[:test]
target.link_with.should == ['TestRunner']
end
it "returns the name of the Pods static library" do
@podfile.target_definitions[:default].lib_name.should == 'libPods.a'
@podfile.target_definitions[:test].lib_name.should == 'libPods-test.a'
end
it "returns the name of the xcconfig file for the target" do
@podfile.target_definitions[:default].xcconfig_name.should == 'Pods.xcconfig'
@podfile.target_definitions[:default].xcconfig_relative_path.should == 'Pods/Pods.xcconfig'
@podfile.target_definitions[:test].xcconfig_name.should == 'Pods-test.xcconfig'
@podfile.target_definitions[:test].xcconfig_relative_path.should == 'Pods/Pods-test.xcconfig'
end
it "returns the name of the 'copy resources script' file for the target" do
@podfile.target_definitions[:default].copy_resources_script_name.should == 'Pods-resources.sh'
@podfile.target_definitions[:default].copy_resources_script_relative_path.should == '${SRCROOT}/Pods/Pods-resources.sh'
@podfile.target_definitions[:test].copy_resources_script_name.should == 'Pods-test-resources.sh'
@podfile.target_definitions[:test].copy_resources_script_relative_path.should == '${SRCROOT}/Pods/Pods-test-resources.sh'
end
it "returns the name of the 'prefix header' file for the target" do
@podfile.target_definitions[:default].prefix_header_name.should == 'Pods-prefix.pch'
@podfile.target_definitions[:test].prefix_header_name.should == 'Pods-test-prefix.pch'
end
it "returns the name of the BridgeSupport file for the target" do
@podfile.target_definitions[:default].bridge_support_name.should == 'Pods.bridgesupport'
@podfile.target_definitions[:test].bridge_support_name.should == 'Pods-test.bridgesupport'
end
it "returns the platform of the target" do
@podfile.target_definitions[:default].platform.should == :ios
@podfile.target_definitions[:test].platform.should == :ios
@podfile.target_definitions[:osx_target].platform.should == :osx
end
it "assigs a deployment target to the platforms if not specified" do
@podfile.target_definitions[:default].platform.deployment_target.to_s.should == '4.3'
@podfile.target_definitions[:test].platform.deployment_target.to_s.should == '4.3'
@podfile.target_definitions[:osx_target].platform.deployment_target.to_s.should == '10.6'
end
it "autmatically marks a target as exclusive if the parent platform doesn't match" do
@podfile.target_definitions[:osx_target].should.be.exclusive
@podfile.target_definitions[:nested_osx_target].should.not.be.exclusive
end
it "returns the specified configurations and wether it should be based on a debug or a release build" do
Pod::Podfile::UserProject.any_instance.stubs(:project)
all = { 'Release' => :release, 'Debug' => :debug, 'Test' => :debug }
@podfile.target_definitions[:default].user_project.build_configurations.should == all.merge('iOS App Store' => :release)
@podfile.target_definitions[:test].user_project.build_configurations.should == all.merge('iOS App Store' => :release)
@podfile.target_definitions[:osx_target].user_project.build_configurations.should == all.merge('Mac App Store' => :release)
@podfile.target_definitions[:nested_osx_target].user_project.build_configurations.should == all.merge('Mac App Store' => :release)
@podfile.user_build_configurations.should == all.merge('iOS App Store' => :release, 'Mac App Store' => :release)
end
it "defaults, for unspecified configurations, to a release build" do
project = Pod::Podfile::UserProject.new(fixture('SampleProject/SampleProject.xcodeproj'), 'Test' => :debug)
project.build_configurations.should == { 'Release' => :release, 'Debug' => :debug, 'Test' => :debug, 'App Store' => :release }
end
it "specifies that the inhibit all warnings flag should be added to the target's build settings" do
@podfile.target_definitions[:default].should.not.inhibit_all_warnings
@podfile.target_definitions[:test].should.inhibit_all_warnings
@podfile.target_definitions[:subtarget].should.inhibit_all_warnings
end
describe "with an Xcode project that's not in the project_root" do
before do
@target_definition = @podfile.target_definitions[:default]
@target_definition.user_project.stubs(:path).returns(config.project_root + 'subdir/iOS Project.xcodeproj')
end
it "returns the $(PODS_ROOT) relative to the project's $(SRCROOT)" do
@target_definition.relative_pods_root.should == '${SRCROOT}/../Pods'
end
it "simply returns the $(PODS_ROOT) path if no xcodeproj file is available and doesn't needs to integrate" do
config.integrate_targets.should.equal true
config.integrate_targets = false
@target_definition.relative_pods_root.should == '${SRCROOT}/../Pods'
@target_definition.user_project.stubs(:path).returns(nil)
@target_definition.relative_pods_root.should == '${SRCROOT}/Pods'
config.integrate_targets = true
end
it "returns the xcconfig file path relative to the project's $(SRCROOT)" do
@target_definition.xcconfig_relative_path.should == '../Pods/Pods.xcconfig'
end
it "returns the 'copy resources script' path relative to the project's $(SRCROOT)" do
@target_definition.copy_resources_script_relative_path.should == '${SRCROOT}/../Pods/Pods-resources.sh'
end
end
end
describe "concerning the podspec method" do
xit "it can use use the dependencies of a podspec" do
end
xit "it allows to specify the name of a podspec" do
end
xit "it allows to specify the path of a podspec" do
end
end
describe "concerning validations" do
it "raises if it should integrate and can't find an xcodeproj" do
config.integrate_targets = true
target_definition = Pod::Podfile.new {}.target_definitions[:default]
target_definition.user_project.stubs(:path).returns(nil)
exception = lambda {
target_definition.relative_pods_root
}.should.raise Pod::Informative
exception.message.should.include "Xcode project"
end
end
end
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
describe 'Pod::Project' do describe Pod::Project do
before do describe "In general" do
@project = Pod::Project.new before do
end @project = Pod::Project.new(config.sandbox)
end
it "adds a group to the `Pods' group" do it "returns the sandbox used for the project" do
group = @project.add_spec_group('JSONKit', @project.pods) @project.sandbox.should == config.sandbox
@project.pods.children.should.include?(group) end
g = @project['Pods/JSONKit']
g.name.should == 'JSONKit'
g.children.should.be.empty?
end
it "namespaces subspecs in groups" do it "creates the support file group on initialization" do
group = @project.add_spec_group('JSONKit/Subspec', @project.pods) @project.support_files_group.name.should == 'Targets Support Files'
@project.pods.groups.find { |g| g.name == 'JSONKit' }.children.should.include?(group) end
g = @project['Pods/JSONKit/Subspec']
g.name.should == 'Subspec'
g.children.should.be.empty?
end
# it "creates a copy build header phase which will copy headers to a specified path" do it "returns its path" do
# @project.targets.new @project.path.should == config.sandbox.project_path
# phase = @project.targets.first.copy_files_build_phases.new_pod_dir("SomePod", "Path/To/Source") end
# find_object({
# 'isa' => 'PBXCopyFilesBuildPhase',
# 'dstPath' => 'Pods/Path/To/Source',
# 'name' => 'Copy SomePod Public Headers'
# }).should.not == nil
# @project.targets.first.build_phases.should.include phase
# end
it "adds build configurations named after every configuration across all of the user's projects" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release }
@project.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end
it "adds build configurations named after every configuration across all of the user's projects to a target" do it "returns the `Pods` group" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release } @project.pods.name.should == 'Pods'
target = @project.add_pod_target('SomeTarget', Pod::Platform.ios) end
target.build_settings('Test')["VALIDATE_PRODUCT"].should == nil
target.build_settings('AppStore')["VALIDATE_PRODUCT"].should == "YES" it "returns the `Local Pods` group" do
end @project.local_pods.name.should == 'Local Pods'
end
describe "concerning its :ios targets" do it "adds a group for a specification" do
it "sets VALIDATE_PRODUCT to YES for the Release configuration" do group = @project.add_spec_group('JSONKit', @project.pods)
target = Pod::Project.new.add_pod_target('Pods', Pod::Platform.ios) @project.pods.children.should.include?(group)
target.build_settings('Release')["VALIDATE_PRODUCT"].should == "YES" g = @project['Pods/JSONKit']
g.name.should == 'JSONKit'
g.children.should.be.empty?
end
it "namespaces subspecs in groups" do
group = @project.add_spec_group('JSONKit/Subspec', @project.pods)
@project.pods.groups.find { |g| g.name == 'JSONKit' }.children.should.include?(group)
g = @project['Pods/JSONKit/Subspec']
g.name.should == 'Subspec'
g.children.should.be.empty?
end
it "adds the Podfile configured as a Ruby file" do
@project.add_podfile(config.project_podfile)
f = @project['Podfile']
f.name.should == 'Podfile'
f.source_tree.should == 'SOURCE_ROOT'
f.xc_language_specification_identifier.should == 'xcode.lang.ruby'
f.path.should == '../Podfile'
end
it "adds build configurations named after every configuration across all of the user's projects" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release }
@project.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end end
end end
describe "concerning its :ios targets with a deployment target" do describe "Libraries" do
before do before do
@project = Pod::Project.new @project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios, '4.3'
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
end end
it "sets ARCHS to 'armv6 armv7' for both configurations if the deployment target is less than 4.3" do it "adds build configurations named after every configuration across all of the user's projects to a target" do
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.0")) @project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release }
target.build_settings('Debug')["ARCHS"].should == "armv6 armv7" library = @project.add_pod_library(@target_definition)
target.build_settings('Release')["ARCHS"].should == "armv6 armv7" target = library.target
target.build_settings('Test')["VALIDATE_PRODUCT"].should == nil
target.build_settings('AppStore')["VALIDATE_PRODUCT"].should == "YES"
end
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.1")) it "sets ARCHS to 'armv6 armv7' for both configurations if the deployment target is less than 4.3 for iOS targets" do
@target_definition.platform = Pod::Platform.new(:ios, '4.2')
library = @project.add_pod_library(@target_definition)
target = library.target
target.build_settings('Debug')["ARCHS"].should == "armv6 armv7" target.build_settings('Debug')["ARCHS"].should == "armv6 armv7"
target.build_settings('Release')["ARCHS"].should == "armv6 armv7" target.build_settings('Release')["ARCHS"].should == "armv6 armv7"
end
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.2")) before do
target.build_settings('Debug')["ARCHS"].should == "armv6 armv7" @lib = @project.add_pod_library(@target_definition)
target.build_settings('Release')["ARCHS"].should == "armv6 armv7" @target = @lib.target
end end
it "uses standard ARCHs if deployment target is 4.3 or above" do it "uses standard ARCHs if deployment target is 4.3 or above" do
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.3")) @target.build_settings('Debug')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
target.build_settings('Debug')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)" @target.build_settings('Release')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
target.build_settings('Release')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)" end
it "sets VALIDATE_PRODUCT to YES for the Release configuration for iOS targets" do
@lib.target.build_settings('Release')["VALIDATE_PRODUCT"].should == "YES"
end
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.4")) it "sets IPHONEOS_DEPLOYMENT_TARGET for iOS targets" do
target.build_settings('Debug')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)" @target.build_settings('Debug')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3"
target.build_settings('Release')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)" @target.build_settings('Release')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3"
end end
it "sets IPHONEOS_DEPLOYMENT_TARGET for both configurations" do it "returns the added libraries" do
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios)) @project.libraries.should == [ @lib ]
target.build_settings('Debug')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3" end
target.build_settings('Release')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3" end
end
#-----------------------------------------------------------------------------#
describe Pod::Project::Library do
describe "In general" do
before do
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
it "returns the target_definition that generated it" do
@lib.target_definition.should == @target_definition
end
target = @project.add_pod_target('Pods', Pod::Platform.new(:ios, :deployment_target => "4.0")) it "returns it target in the Pods project" do
target.build_settings('Debug')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.0" @lib.target.name.should == 'Pods'
target.build_settings('Release')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.0"
end end
it "returns the label of the target definition" do
@lib.label.should == 'Pods'
end
end
#---------------------------------------#
describe "User project" do
before do
user_project_path = fixture('SampleProject/SampleProject.xcodeproj')
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
xcodeproj user_project_path
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
it "returns the user project path" do
path = fixture('SampleProject/SampleProject.xcodeproj')
@lib.user_project_path.should == path
end
it "raises if no project could be selected" do
@target_definition.stubs(:user_project_path).returns(nil)
Pathname.any_instance.stubs(:exist?).returns(true)
lambda { @lib.user_project_path }.should.raise Pod::Informative
end
it "raises if the project path doesn't exist" do
Pathname.any_instance.stubs(:exist?).returns(false)
lambda { @lib.user_project_path }.should.raise Pod::Informative
end
it "returns the user project" do
@lib.user_project.class.should == Xcodeproj::Project
end
it "returns the user targets associated with the target definition" do
@lib.user_targets.all? { |t| t.isa == 'PBXNativeTarget' }.should.be.true
@lib.user_targets.map(&:name).should == [ 'SampleProject' ]
end
it "uses the targets specified to link with by the target definition" do
@target_definition.stubs(:link_with).returns(['TestRunner'])
@target_definition.stubs(:name).returns('NON-EXISTING')
@lib.user_targets.first.name.should == 'TestRunner'
end
it "it raises if it can't find any target specified to link with by the target definition" do
@target_definition.stubs(:link_with).returns(['NON-EXISTING'])
lambda { @lib.user_targets }.should.raise Pod::Informative
end
it "uses the target with the same name if the target definition name is different from `:default'" do
@target_definition.stubs(:name).returns('TestRunner')
@lib.user_targets.first.name.should == 'TestRunner'
end
it "it raises if it can't find a target with the same name of the target definition" do
@target_definition.stubs(:name).returns('NON-EXISTING')
lambda { @lib.user_targets }.should.raise Pod::Informative
end
it "uses the first target in the user's project if no explicit target is specified for the default target definition" do
project = Xcodeproj::Project.new(@lib.user_project_path)
@lib.user_targets.should == [ project.targets.first ]
end
end
#---------------------------------------#
describe "TargetInstaller & UserProjectIntegrator" do
before do
user_project_path = fixture('SampleProject/SampleProject.xcodeproj')
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
xcodeproj user_project_path
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
#---------------------------------------#
it "returns the name of its product" do
@lib.name.should == 'libPods.a'
end
it "returns it Pods project" do
@lib.project.path.should == config.sandbox.project_path
end
#---------------------------------------#
it "stores the xcconfig" do
@lib.xcconfig = Xcodeproj::Config.new({'PODS_ROOT' => '${SRCROOT}'})
@lib.xcconfig.to_hash['PODS_ROOT'].should == '${SRCROOT}'
end
it "returns the xcconfig name" do
@lib.xcconfig_name.should == 'Pods.xcconfig'
end
it "returns the absolute path of the xcconfig file" do
@lib.xcconfig_path.to_s.should.include?('Pods/Pods.xcconfig')
end
it "returns the path of the xcconfig file relative to the user project" do
@lib.xcconfig_relative_path.should == '../../../tmp/Pods/Pods.xcconfig'
end
it "returns the resources script name" do
@lib.copy_resources_script_name.should == 'Pods-resources.sh'
end
it "returns the absolute path of the resources script" do
@lib.copy_resources_script_path.to_s.should.include?('Pods/Pods-resources.sh')
end
it "returns the path of the resources script relative to the user project" do
@lib.copy_resources_script_relative_path.should == '${SRCROOT}/../../../tmp/Pods/Pods-resources.sh'
end
it "returns the prefix header file name" do
@lib.prefix_header_name.should == 'Pods-prefix.pch'
end
it "returns the absolute path of the prefix header file" do
@lib.prefix_header_path.to_s.should.include?('Pods/Pods-prefix.pch')
end
it "returns the bridge support file name" do
@lib.bridge_support_name.should == 'Pods.bridgesupport'
end
it "returns the absolute path of the bridge support file" do
@lib.bridge_support_path.to_s.should.include?('Pods/Pods.bridgesupport')
end
end end
end end
...@@ -6,17 +6,18 @@ module Pod ...@@ -6,17 +6,18 @@ module Pod
config.repos_dir = fixture('spec-repos') config.repos_dir = fixture('spec-repos')
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
pod 'BlocksKit' pod 'BlocksKit', '1.5.2'
end end
@resolver = Resolver.new(@podfile, nil, stub('sandbox')) @resolver = Resolver.new(config.sandbox, @podfile)
end end
it "holds the context state, such as cached specification sets" do it "holds the context state, such as cached specification sets" do
@resolver.resolve @resolver.resolve
@resolver.cached_sets.values.sort_by(&:name).should == [ cached_sets = @resolver.send(:cached_sets)
Pod::Source.search_by_name('A2DynamicDelegate').first, cached_sets.values.sort_by(&:name).should == [
Pod::Source.search_by_name('BlocksKit').first, Source.search_by_name('A2DynamicDelegate').first,
Pod::Source.search_by_name('libffi').first Source.search_by_name('BlocksKit').first,
Source.search_by_name('libffi').first
].sort_by(&:name) ].sort_by(&:name)
end end
...@@ -34,8 +35,9 @@ module Pod ...@@ -34,8 +35,9 @@ module Pod
end end
it "raises once any of the dependencies does not match the platform of its podfile target" do it "raises once any of the dependencies does not match the platform of its podfile target" do
set = Pod::Source.search_by_name('BlocksKit').first set = Source.search_by_name('BlocksKit').first
@resolver.cached_sets['BlocksKit'] = set cached_sets = @resolver.send(:cached_sets)
@resolver.stubs(:cached_sets).returns({'BlocksKit' => set})
def set.stub_platform=(platform); @stubbed_platform = platform; end def set.stub_platform=(platform); @stubbed_platform = platform; end
def set.specification; spec = super; spec.platform = @stubbed_platform; spec; end def set.specification; spec = super; spec.platform = @stubbed_platform; spec; end
...@@ -44,25 +46,25 @@ module Pod ...@@ -44,25 +46,25 @@ module Pod
set.stub_platform = :ios set.stub_platform = :ios
lambda { @resolver.resolve }.should.not.raise lambda { @resolver.resolve }.should.not.raise
set.stub_platform = :osx set.stub_platform = :osx
lambda { @resolver.resolve }.should.raise Informative lambda { @resolver.resolve }.should.raise Pod::StandardError
@podfile.platform :osx @podfile.platform :osx
set.stub_platform = :osx set.stub_platform = :osx
lambda { @resolver.resolve }.should.not.raise lambda { @resolver.resolve }.should.not.raise
set.stub_platform = :ios set.stub_platform = :ios
lambda { @resolver.resolve }.should.raise Informative lambda { @resolver.resolve }.should.raise Pod::StandardError
end end
it "raises once any of the dependencies does not have a deployment_target compatible with its podfile target" do it "raises once any of the dependencies does not have a deployment_target compatible with its podfile target" do
set = Pod::Source.search_by_name('BlocksKit').first set = Source.search_by_name('BlocksKit').first
@resolver.cached_sets['BlocksKit'] = set @resolver.stubs(:cached_sets).returns({'BlocksKit' => set})
@podfile.platform :ios, "4.0" @podfile.platform :ios, "4.0"
Specification.any_instance.stubs(:available_platforms).returns([ Platform.new(:ios, '4.0'), Platform.new(:osx, '10.7') ]) Specification.any_instance.stubs(:available_platforms).returns([ Platform.new(:ios, '4.0'), Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.not.raise lambda { @resolver.resolve }.should.not.raise
Specification.any_instance.stubs(:available_platforms).returns([ Platform.new(:ios, '5.0'), Platform.new(:osx, '10.7') ]) Specification.any_instance.stubs(:available_platforms).returns([ Platform.new(:ios, '5.0'), Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.raise Informative lambda { @resolver.resolve }.should.raise Pod::StandardError
end end
it "resolves subspecs" do it "resolves subspecs" do
...@@ -110,36 +112,46 @@ module Pod ...@@ -110,36 +112,46 @@ module Pod
} }
end end
it "it includes only the main subspec of a specification node" do # TODO inline podspecs are deprecated
xit "it includes only the main subspec of a specification node" do
spec = Spec.new do |s|
s.name = 'RestKit'
s.version = '9999990.10.0'
s.preferred_dependency = 'JSON'
s.subspec 'JSON' do |js|
js.dependency 'RestKit/Network'
js.dependency 'RestKit/UI'
js.dependency 'RestKit/ObjectMapping/JSON'
js.dependency 'RestKit/ObjectMapping/CoreData'
end
s.subspec 'Network' do |ns|
ns.dependency 'LibComponentLogging-NSLog', '>= 1.0.4'
end
s.subspec 'UI'
s.subspec 'ObjectMapping' do |os|
os.subspec 'JSON'
os.subspec 'XML'
os.subspec 'CoreData'
end
end
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
pod do |s| pod 'RestKit'
s.name = 'RestKit'
s.version = '0.10.0'
s.preferred_dependency = 'JSON'
s.subspec 'JSON' do |js|
js.dependency 'RestKit/Network'
js.dependency 'RestKit/UI'
js.dependency 'RestKit/ObjectMapping/JSON'
js.dependency 'RestKit/ObjectMapping/CoreData'
end
s.subspec 'Network' do |ns|
ns.dependency 'LibComponentLogging-NSLog', '>= 1.0.4'
end
s.subspec 'UI'
s.subspec 'ObjectMapping' do |os|
os.subspec 'JSON'
os.subspec 'XML'
os.subspec 'CoreData'
end
end
end end
Set.any_instance.stubs(:specification).returns(spec)
resolver = Resolver.new(@podfile, nil, stub('sandbox')) resolver = Resolver.new(@podfile, nil, stub('sandbox'))
resolver.find_cached_set()
specs = resolver.resolve.values.flatten.map(&:name).sort specs = resolver.resolve.values.flatten.map(&:name).sort
specs.should.not.include 'RestKit/ObjectMapping/XML' specs.should.not.include 'RestKit/ObjectMapping/XML'
spec = resolver.specs_by_target.values.first.first
spec.name.should == 'test'
spec.version.should == '9999990.10.0'
specs.should == %w{ specs.should == %w{
LibComponentLogging-Core LibComponentLogging-Core
LibComponentLogging-NSLog LibComponentLogging-NSLog
...@@ -172,7 +184,7 @@ module Pod ...@@ -172,7 +184,7 @@ module Pod
fss.subspec 'SecondSubSpec' fss.subspec 'SecondSubSpec'
end end
end end
@podfile.dependencies.first.external_source.stubs(:specification_from_sandbox).returns(spec) ExternalSources::GitSource.any_instance.stubs(:specification_from_sandbox).returns(spec)
resolver = Resolver.new(@podfile, nil, stub('sandbox')) resolver = Resolver.new(@podfile, nil, stub('sandbox'))
resolver.resolve.values.flatten.map(&:name).sort.should == %w{ MainSpec/FirstSubSpec MainSpec/FirstSubSpec/SecondSubSpec } resolver.resolve.values.flatten.map(&:name).sort.should == %w{ MainSpec/FirstSubSpec MainSpec/FirstSubSpec/SecondSubSpec }
end end
...@@ -200,7 +212,7 @@ module Pod ...@@ -200,7 +212,7 @@ module Pod
pod 'JSONKit', "1.5pre" pod 'JSONKit', "1.5pre"
end end
resolver = Resolver.new(podfile, nil, stub('sandbox')) resolver = Resolver.new(podfile, nil, stub('sandbox'))
lambda {resolver.resolve}.should.raise Pod::Informative lambda {resolver.resolve}.should.raise Pod::StandardError
end end
describe "Concerning Installation mode" do describe "Concerning Installation mode" do
...@@ -208,15 +220,15 @@ module Pod ...@@ -208,15 +220,15 @@ module Pod
config.repos_dir = fixture('spec-repos') config.repos_dir = fixture('spec-repos')
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
pod 'BlocksKit' pod 'BlocksKit', '1.5.2'
pod 'JSONKit' pod 'JSONKit'
end end
@specs = [ @specs = [
Pod::Specification.new do |s| Specification.new do |s|
s.name = "BlocksKit" s.name = "BlocksKit"
s.version = "1.0.0" s.version = "1.5.2"
end, end,
Pod::Specification.new do |s| Specification.new do |s|
s.name = "JSONKit" s.name = "JSONKit"
s.version = "1.4" s.version = "1.4"
end ] end ]
...@@ -246,11 +258,11 @@ module Pod ...@@ -246,11 +258,11 @@ module Pod
podfile = Podfile.new do podfile = Podfile.new do
platform :ios platform :ios
pod 'JSONKit', '1.5pre' pod 'JSONKit', '1.5pre'
pod 'BlocksKit' pod 'BlocksKit', '1.5.2'
end end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
installed = @resolver.resolve.values.flatten.map(&:to_s) installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "BlocksKit (1.0.0)" installed.should.include? "BlocksKit (1.5.2)"
installed.should.include? "JSONKit (1.5pre)" installed.should.include? "JSONKit (1.5pre)"
end end
...@@ -259,7 +271,7 @@ module Pod ...@@ -259,7 +271,7 @@ module Pod
platform :ios platform :ios
pod 'JSONKit' pod 'JSONKit'
pod 'BlocksKit' pod 'BlocksKit'
pod 'libPusher' # New pod pod 'libPusher', '1.3' # New pod
end end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
installed = @resolver.resolve.values.flatten.map(&:to_s) installed = @resolver.resolve.values.flatten.map(&:to_s)
...@@ -287,7 +299,7 @@ module Pod ...@@ -287,7 +299,7 @@ module Pod
s.name = 'libPusher' s.name = 'libPusher'
s.version = '1.3' s.version = '1.3'
end end
podfile.dependencies.first.external_source.stubs(:specification_from_sandbox).returns(spec) ExternalSources::GitSource.any_instance.stubs(:specification_from_sandbox).returns(spec)
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve @resolver.resolve
@resolver.should_install?("JSONKit").should.be.false @resolver.should_install?("JSONKit").should.be.false
...@@ -300,7 +312,7 @@ module Pod ...@@ -300,7 +312,7 @@ module Pod
pod 'JSONKit' pod 'JSONKit'
end end
config.skip_repo_update = false config.skip_repo_update = false
Pod::Command::Repo.any_instance.expects(:run).never Command::Repo.any_instance.expects(:run).never
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve @resolver.resolve
end end
...@@ -313,7 +325,7 @@ module Pod ...@@ -313,7 +325,7 @@ module Pod
pod 'libPusher' # New pod pod 'libPusher' # New pod
end end
config.skip_repo_update = false config.skip_repo_update = false
Pod::Command::Repo.any_instance.expects(:run).once Command::Repo::Update.any_instance.expects(:run).once
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve @resolver.resolve
end end
...@@ -326,7 +338,7 @@ module Pod ...@@ -326,7 +338,7 @@ module Pod
pod 'libPusher' # New pod pod 'libPusher' # New pod
end end
config.skip_repo_update = true config.skip_repo_update = true
Pod::Command::Repo.any_instance.expects(:run).never Command::Repo::Update.any_instance.expects(:run).never
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve @resolver.resolve
end end
...@@ -338,7 +350,7 @@ module Pod ...@@ -338,7 +350,7 @@ module Pod
pod 'JSONKit', :head #changed to head pod 'JSONKit', :head #changed to head
end end
config.skip_repo_update = false config.skip_repo_update = false
Pod::Command::Repo.any_instance.expects(:run).once Command::Repo::Update.any_instance.expects(:run).once
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve @resolver.resolve
end end
...@@ -347,23 +359,28 @@ module Pod ...@@ -347,23 +359,28 @@ module Pod
describe "Concerning Update mode" do describe "Concerning Update mode" do
before do before do
config.repos_dir = fixture('spec-repos') config.repos_dir = fixture('spec-repos')
@podfile = Podfile.new do previous_podfile = Podfile.new do
platform :ios platform :ios
pod 'BlocksKit'
pod 'JSONKit' pod 'JSONKit'
pod 'libPusher' pod 'libPusher'
end end
@specs = [ @specs = [
Pod::Specification.new do |s| Specification.new do |s|
s.name = "libPusher" s.name = "libPusher"
s.version = "1.3" s.version = "1.3"
end, end,
Pod::Specification.new do |s| Specification.new do |s|
s.name = "JSONKit" s.name = "JSONKit"
s.version = "1.4" s.version = "1.4"
end ] end ]
@specs.each { |s| s.activate_platform(:ios) } @specs.each { |s| s.activate_platform(:ios) }
@lockfile = Lockfile.generate(@podfile, @specs) @lockfile = Lockfile.generate(previous_podfile, @specs)
@podfile = Podfile.new do
platform :ios
pod 'BlocksKit', '1.5.2'
pod 'JSONKit'
pod 'libPusher'
end
@resolver = Resolver.new(@podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(@podfile, @lockfile, stub('sandbox'))
@resolver.update_mode = true @resolver.update_mode = true
end end
...@@ -377,7 +394,7 @@ module Pod ...@@ -377,7 +394,7 @@ module Pod
it "respects the constraints of the podfile" do it "respects the constraints of the podfile" do
podfile = Podfile.new do podfile = Podfile.new do
platform :ios platform :ios
pod 'BlocksKit' pod 'BlocksKit', '1.5.2'
pod 'JSONKit', '1.4' pod 'JSONKit', '1.4'
end end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
...@@ -411,7 +428,7 @@ module Pod ...@@ -411,7 +428,7 @@ module Pod
pod 'libPusher' pod 'libPusher'
end end
config.skip_repo_update = false config.skip_repo_update = false
Pod::Command::Repo.any_instance.expects(:run).once Command::Repo::Update.any_instance.expects(:run).once
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox')) @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.update_mode = true @resolver.update_mode = true
@resolver.resolve @resolver.resolve
......
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Source" do module Pod
before do describe Pod::Source do
@source = Pod::Source.new(fixture('spec-repos/master'))
end
it "return its name" do
@source.name.should == 'master'
end
it "returns the sets of all the available Pods" do
set_names = @source.pod_sets.map(&:name)
set_names.should.include('JSONKit')
set_names.should.include('Reachability')
end
it "returns the available versions of a Pod" do
@source.versions('Reachability').map(&:to_s).should == %w| 3.0.0 2.0.5 2.0.4 |
end
it "returns the specification of a given version of a Pod" do
spec = @source.specification('Reachability', Pod::Version.new('3.0.0'))
spec.name.should == 'Reachability'
spec.version.should.to_s == '3.0.0'
end
it "properly configures the sources of a set in seach by name" do
source = Pod::Source.new(fixture('spec-repos/test_repo'))
sets = source.search_by_name('monkey', true)
sets.count.should == 1
set = sets.first
set.name.should == 'BananaLib'
set.sources.map(&:name).should == %w| test_repo |
end
describe "Pod::Source::Aggregate" do
# BananaLib is available only in test_repo.
# JSONKit is in test repo has version 1.4 (duplicated) and the 999.999.999.
it "returns all the sources" do it "returns all the sources" do
Pod::Source.all.map(&:name).should == %w| master test_repo | Source.all.map(&:name).should == %w[master test_repo]
end
it "returns the name of all the available pods" do
pod_names = Pod::Source::Aggregate.new.all_pods
pod_names.should.include('JSONKit')
pod_names.should.include('BananaLib')
end
it "returns all the available sets with the sources configured" do
sets = Pod::Source.all_sets
banana_sets = sets.select{ |set| set.name == 'BananaLib' }
banana_sets.count.should == 1
banana_sets.first.sources.map(&:name).should == %w| test_repo |
json_set = sets.select{ |set| set.name == 'JSONKit' }
json_set.count.should == 1
json_set.first.sources.map(&:name).should == %w| master test_repo |
end
it "searches the sets by dependency" do
dep = Pod::Dependency.new('JSONKit')
set = Pod::Source.search(dep)
set.name.should == 'JSONKit'
set.sources.map(&:name).should == %w| master test_repo |
end
it "searches the sets specifing a dependency on a subspec" do
dep = Pod::Dependency.new('RestKit/JSON')
set = Pod::Source.search(dep)
set.name.should == 'RestKit'
set.sources.map(&:name).should == %w| master |
end end
it "raises if a specification set can't be found" do it "returns all the sets" do
lambda { Source.all_sets.map(&:name).should.include?('Chameleon')
dep = Pod::Dependency.new('DoesNotExist')
set = Pod::Source.search(dep)
}.should.raise Pod::Informative
end end
it "raises if a subspec can't be found" do it "searches for the set of a dependency" do
lambda { set = Source.search(Dependency.new('Chameleon'))
dep = Pod::Dependency.new('RestKit/DoesNotExist') set.class.should == Pod::Specification::Set
set = Pod::Source.search(dep) set.name.should == 'Chameleon'
}.should.raise Pod::Informative
end end
it "searches the sets by name" do it "searches sets by name" do
sets = Pod::Source.search_by_name('JSONKit') sets = Source.search_by_name('Chameleon')
sets.count.should == 1 sets.all?{ |s| s.class == Pod::Specification::Set}.should.be.true
set = sets.first sets.any?{ |s| s.name == 'Chameleon'}.should.be.true
set.name.should == 'JSONKit'
set.sources.map(&:name).should == %w| master test_repo |
end end
it "properly configures the sources of a set in search by name" do it "can perform a full text search of the sets" do
sets = Pod::Source.search_by_name('BananaLib') sets = Source.search_by_name('Drop in sharing', true)
sets.count.should == 1 sets.all?{ |s| s.class == Pod::Specification::Set}.should.be.true
set = sets.first sets.any?{ |s| s.name == 'ShareKit'}.should.be.true
set.name.should == 'BananaLib'
set.sources.map(&:name).should == %w| test_repo |
end end
end end
end end
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Specification::Set" do
describe "In general" do
before do
@source = Pod::Source.new(fixture('spec-repos/master'))
@set = Pod::Spec::Set.new('CocoaLumberjack', @source)
end
it "returns the name of the pod" do
@set.name.should == 'CocoaLumberjack'
end
it "returns the versions available for this pod ordered from highest to lowest" do
@set.versions.should == %w[1.6 1.3.3 1.3.2 1.3.1 1.3 1.2.3 1.2.2 1.2.1 1.2 1.1 1.0].map { |v| Pod::Version.new(v) }
end
it "checks if the dependency of the specification is compatible with existing requirements" do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '1.2'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.2.1'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '> 1.1'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '~> 1.2.0'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack'), 'Spec')
lambda {
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.0' ), 'Spec')
}.should.raise Pod::Informative
end
it "raises if the required version doesn't exist" do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.0'), 'Spec')
lambda { @set.required_version }.should.raise Pod::Informative
end
it "can test if it is equal to another set" do
@set.should == Pod::Spec::Set.new('CocoaLumberjack', @source)
@set.should.not == Pod::Spec::Set.new('RestKit', @source)
end
before do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.2.1'), 'Spec')
end
it "returns the version required for the dependency" do
@set.required_version.should == Pod::Version.new('1.2')
end
it "returns the specification for the required version" do
@set.specification.should == Pod::Spec.new { |s| s.name = 'CocoaLumberjack'; s.version = '1.2' }
end
it "ignores dotfiles when getting the version directories" do
`touch #{fixture('spec-repos/master/CocoaLumberjack/.DS_Store')}`
lambda { @set.versions }.should.not.raise
end
it "raises if a version is incompatible with the activated version" do
spec = Pod::Dependency.new('CocoaLumberjack', '1.2.1')
lambda { @set.required_by(spec, 'Spec') }.should.raise Pod::Informative
end
end
describe "Concerning multiple sources" do
before do
# JSONKit is in test repo has version 1.4 (duplicated) and the 999.999.999.
@set = Pod::Source.search_by_name('JSONKit').first
end
it "returns all the available versions sorted from biggest to lowest" do
@set.versions.map(&:to_s).should == %w| 999.999.999 1.5pre 1.4 |
end
it "returns all the available versions by source sorted from bigest to lowest" do
hash = {}
@set.versions_by_source.each { |source, versions| hash[source.name] = versions.map(&:to_s) }
hash['master'].should == %w| 1.5pre 1.4 |
hash['test_repo'].should == %w| 999.999.999 1.4 |
hash.keys.sort.should == %w| master test_repo |
end
it "returns the specification from the `master` source for the required version" do
dep = Pod::Dependency.new('JSONKit', '1.5pre')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '1.5pre'
spec.defined_in_file.should == fixture('spec-repos/master/JSONKit/1.5pre/JSONKit.podspec')
end
it "returns the specification from `test_repo` source for the required version" do
dep = Pod::Dependency.new('JSONKit', '999.999.999')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '999.999.999'
spec.defined_in_file.should == fixture('spec-repos/test_repo/JSONKit/999.999.999/JSONKit.podspec')
end
it "prefers sources by alphabetical order" do
dep = Pod::Dependency.new('JSONKit', '1.4')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '1.4'
spec.defined_in_file.should == fixture('spec-repos/master/JSONKit/1.4/JSONKit.podspec')
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
describe "A Pod::Specification loaded from a podspec" do
before do
fixture('banana-lib') # ensure the archive is unpacked
@spec = Pod::Specification.from_file(fixture('banana-lib/BananaLib.podspec'))
end
it "has no parent if it is the top level spec" do
@spec.parent.nil?.should == true
end
it "returns that it's not loaded from a podfile" do
@spec.should.not.be.podfile
end
it "returns the path to the podspec" do
@spec.defined_in_file.should == fixture('banana-lib/BananaLib.podspec')
end
it "returns the directory where the pod should be checked out to" do
@spec.pod_destroot.should == config.project_pods_root + 'BananaLib'
end
it "returns the pod's name" do
@spec.name.should == 'BananaLib'
end
it "returns the pod's version" do
@spec.version.should == Pod::Version.new('1.0')
end
it "returns a list of authors and their email addresses" do
@spec.authors.should == {
'Banana Corp' => nil,
'Monkey Boy' => 'monkey@banana-corp.local'
}
end
it "returns the pod's homepage" do
@spec.homepage.should == 'http://banana-corp.local/banana-lib.html'
end
it "returns the pod's summary" do
@spec.summary.should == 'Chunky bananas!'
end
it "returns the pod's description" do
@spec.description.should == 'Full of chunky bananas.'
end
it "returns the pod's source" do
@spec.source.should == {
:git => 'http://banana-corp.local/banana-lib.git',
:tag => 'v1.0'
}
end
it "returns the pod's source files" do
@spec.activate_platform(:ios).source_files.should == ['Classes/*.{h,m}', 'Vendor']
@spec.activate_platform(:osx).source_files.should == ['Classes/*.{h,m}', 'Vendor']
end
it "returns the pod's dependencies" do
expected = Pod::Dependency.new('monkey', '~> 1.0.1', '< 1.0.9')
@spec.activate_platform(:ios).dependencies.should == [expected]
@spec.activate_platform(:osx).dependencies.should == [expected]
end
it "returns the pod's xcconfig settings" do
@spec.activate_platform(:ios).xcconfig.should == { 'OTHER_LDFLAGS' => '-framework SystemConfiguration' }
end
it "has a shortcut to add frameworks to the xcconfig" do
@spec.frameworks = 'CFNetwork', 'CoreText'
@spec.activate_platform(:ios).xcconfig.should == {
'OTHER_LDFLAGS' => '-framework CFNetwork ' \
'-framework CoreText ' \
'-framework SystemConfiguration' }
end
it "has a shortcut to add weak frameworks to the xcconfig" do
@spec.weak_frameworks = 'Twitter'
@spec.activate_platform(:ios).xcconfig.should == {
"OTHER_LDFLAGS"=>"-framework SystemConfiguration -weak_framework Twitter"
}
end
it "has a shortcut to add libraries to the xcconfig" do
@spec.libraries = 'z', 'xml2'
@spec.activate_platform(:ios).xcconfig.should == {
'OTHER_LDFLAGS' => '-lxml2 -lz -framework SystemConfiguration'
}
end
it "returns that it's equal to another specification if the name and version are equal" do
@spec.should == Pod::Spec.new { |s| s.name = 'BananaLib'; s.version = '1.0' }
@spec.should.not == Pod::Spec.new { |s| s.name = 'OrangeLib'; s.version = '1.0' }
@spec.should.not == Pod::Spec.new { |s| s.name = 'BananaLib'; s.version = '1.1' }
@spec.should.not == Pod::Spec.new
end
it "never equals when it's from a Podfile" do
Pod::Spec.new.should.not == Pod::Spec.new
end
it "adds compiler flags if ARC is required" do
@spec.parent.should == nil
@spec.requires_arc = true
@spec.activate_platform(:ios).compiler_flags.should == "-fobjc-arc"
@spec.activate_platform(:osx).compiler_flags.should == "-fobjc-arc"
@spec.compiler_flags = "-Wunused-value"
@spec.activate_platform(:ios).compiler_flags.should == "-Wunused-value -fobjc-arc"
@spec.activate_platform(:osx).compiler_flags.should == "-Wunused-value -fobjc-arc"
end
end
describe "A Pod::Specification, in general," do
before do
@spec = Pod::Spec.new
end
it "returns the platform that the static library should be build for" do
@spec.platform = :ios
@spec.platform.should == :ios
end
it "returns the platform and the deployment target" do
@spec.platform = :ios, '4.0'
@spec.platform.should == :ios
@spec.platform.deployment_target.should == Pod::Version.new('4.0')
end
it "returns the available platforms for which the pod is supported" do
@spec.platform = :ios, '4.0'
@spec.available_platforms.count.should == 1
@spec.available_platforms.first.should == :ios
@spec.available_platforms.first.deployment_target.should == Pod::Version.new('4.0')
end
it "returns the license of the Pod" do
@spec.license = {
:type => 'MIT',
:file => 'LICENSE',
:text => 'Permission is hereby granted ...'
}
@spec.license.should == {
:type => 'MIT',
:file => 'LICENSE',
:text => 'Permission is hereby granted ...'
}
end
it "returns the license of the Pod specified in the old format" do
@spec.license = 'MIT'
@spec.license.should == {
:type => 'MIT',
}
end
it "returns the documentation of the Pod" do
@spec.documentation = {
:html => 'http://EXAMPLE/#{@name}/documentation',
:appledoc => ['--project-name', '#{@name}',
'--project-company', '"Company Name"',
'--company-id', 'com.company',
'--ignore', 'Common',
'--ignore', '.m']
}
@spec.documentation[:html].should == 'http://EXAMPLE/#{@name}/documentation'
@spec.documentation[:appledoc].should == ['--project-name', '#{@name}',
'--project-company', '"Company Name"',
'--company-id', 'com.company',
'--ignore', 'Common',
'--ignore', '.m']
end
it "takes a list of paths to clean" do
@spec.clean_paths = 'Demo', 'Doc'
@spec.clean_paths.should == %w{ Demo Doc }
end
it "takes any object for clean_paths as long as it responds to #glob (we provide this for Rake::FileList)" do
@spec.clean_paths = Pod::FileList['*'].exclude('Rakefile')
list = ROOT + @spec.clean_paths.first
list.glob.should == Pod::FileList[(ROOT + '*').to_s].exclude('Rakefile').map { |path| Pathname.new(path) }
end
it "takes a list of paths to preserve" do
@spec.preserve_paths = 'script.sh'
@spec.activate_platform(:ios).preserve_paths.should == %w{ script.sh }
end
it "takes any object for source_files as long as it responds to #glob (we provide this for Rake::FileList)" do
@spec.source_files = Pod::FileList['*'].exclude('Rakefile')
@spec.activate_platform(:ios)
list = ROOT + @spec.source_files.first
list.glob.should == Pod::FileList[(ROOT + '*').to_s].exclude('Rakefile').map { |path| Pathname.new(path) }
end
it "takes a prefix header path which will be appended to the Pods pch file" do
@spec.prefix_header_file.should == nil
@spec.prefix_header_file = 'Classes/Demo.pch'
@spec.prefix_header_file.should == Pathname.new('Classes/Demo.pch')
end
it "takes code that's to be appended to the Pods pch file" do
@spec.prefix_header_contents.should == nil
@spec.prefix_header_contents = '#import "BlocksKit.h"'
@spec.prefix_header_contents.should == '#import "BlocksKit.h"'
end
it "can be activated for a supported platorm" do
@spec.platform = :ios
lambda {@spec.activate_platform(:ios)}.should.not.raise Pod::Informative
end
it "raised if attempted to be activated for an unsupported platform" do
@spec.platform = :osx, '10.7'
lambda {@spec.activate_platform(:ios)}.should.raise Pod::Informative
lambda {@spec.activate_platform(:ios, '10.6')}.should.raise Pod::Informative
end
it "raises if not activated for a platform before accessing a multiplatform value" do
@spec.platform = :ios
lambda {@spec.source_files}.should.raise Pod::Informative
end
it "returns self on activation for method chainablity" do
@spec.platform = :ios
@spec.activate_platform(:ios).should == @spec
end
it "it handles local sources" do
@spec.activate_platform(:ios)
@spec.source = {:local => '/tmp/local/path'}
@spec.local?.should.be.true
end
end
describe "A Pod::Specification, hierarchy" do
before do
@spec = Pod::Spec.new do |s|
s.name = 'MainSpec'
s.version = '0.999'
s.dependency 'awesome_lib'
s.subspec 'SubSpec.0' do |fss|
fss.platform = :ios
fss.subspec 'SubSpec.0.0' do |sss|
end
end
s.subspec 'SubSpec.1'
end
@subspec = @spec.subspecs.first
@spec.activate_platform(:ios)
end
it "automatically includes all the compatible subspecs as a dependencis if not preference is given" do
@spec.dependencies.map { |s| s.name }.should == %w[ awesome_lib MainSpec/SubSpec.0 MainSpec/SubSpec.1 ]
@spec.activate_platform(:osx).dependencies.map { |s| s.name }.should == %w[ awesome_lib MainSpec/SubSpec.1 ]
end
it "uses the spec version for the dependencies" do
@spec.dependencies.
select { |d| d.name =~ /MainSpec/ }.
all? { |d| d.requirement.to_s == '= 0.999' }.
should.be.true
end
it "respecs the preferred dependency for subspecs, if specified" do
@spec.preferred_dependency = 'SubSpec.0'
@spec.dependencies.map { |s| s.name }.should == %w[ awesome_lib MainSpec/SubSpec.0 ]
end
it "raises if it has dependecy on a self or on an upstream subspec" do
lambda { @subspec.dependency('MainSpec/SubSpec.0') }.should.raise Pod::Informative
lambda { @subspec.dependency('MainSpec') }.should.raise Pod::Informative
end
it "inherits external dependecies from the parent" do
@subspec.dependencies.map { |s| s.name }.should == %w[ awesome_lib MainSpec/SubSpec.0/SubSpec.0.0 ]
end
it "it accepts a dependency on a subspec that is in the same level of the hierarchy" do
@subspec.dependency('MainSpec/SubSpec.1')
@subspec.dependencies.map { |s| s.name }.should == %w[ MainSpec/SubSpec.1 awesome_lib MainSpec/SubSpec.0/SubSpec.0.0 ]
end
end
describe "A Pod::Specification subspec" do
before do
@spec = Pod::Spec.new do |s|
s.name = 'MainSpec'
s.version = '1.2.3'
s.license = 'MIT'
s.author = 'Joe the Plumber'
s.source = { :git => '/some/url' }
s.requires_arc = true
s.source_files = 'spec.m'
s.resource = 'resource'
s.platform = :ios
s.library = 'xml'
s.framework = 'CoreData'
s.subspec 'FirstSubSpec' do |fss|
fss.ios.source_files = 'subspec_ios.m'
fss.osx.source_files = 'subspec_osx.m'
fss.framework = 'CoreGraphics'
fss.weak_framework = 'Twitter'
fss.library = 'z'
fss.subspec 'SecondSubSpec' do |sss|
sss.source_files = 'subsubspec.m'
sss.requires_arc = false
end
end
end
@subspec = @spec.subspecs.first
@subsubspec = @subspec.subspecs.first
end
it "returns the top level parent spec" do
@spec.subspecs.first.top_level_parent.should == @spec
@spec.subspecs.first.subspecs.first.top_level_parent.should == @spec
end
it "is named after the parent spec" do
@spec.subspecs.first.name.should == 'MainSpec/FirstSubSpec'
@spec.subspecs.first.subspecs.first.name.should == 'MainSpec/FirstSubSpec/SecondSubSpec'
end
it "correctly resolves the inheritance chain" do
@spec.subspecs.first.subspecs.first.parent.should == @spec.subspecs.first
@spec.subspecs.first.parent.should == @spec
end
it "automatically forwards top level attributes to the subspecs" do
@spec.activate_platform(:ios)
[:version, :license, :authors].each do |attr|
@spec.subspecs.first.send(attr).should == @spec.send(attr)
@spec.subspecs.first.subspecs.first.send(attr).should == @spec.send(attr)
end
end
it "resolves correctly chained attributes" do
@spec.activate_platform(:ios)
@spec.source_files.map { |f| f.to_s }.should == %w[ spec.m ]
@subspec.source_files.map { |f| f.to_s }.should == %w[ spec.m subspec_ios.m ]
@subsubspec.source_files.map { |f| f.to_s }.should == %w[ spec.m subspec_ios.m subsubspec.m ]
@subsubspec.resources.should == %w[ resource ]
@subsubspec.compiler_flags = '-Wdeprecated-implementations'
@subsubspec.compiler_flags.should == '-Wdeprecated-implementations'
end
it "allows to specify arc settings for subspecs" do
@spec.activate_platform(:ios)
@spec.requires_arc.should == true
@subspec.requires_arc.should == true
@subsubspec.requires_arc.should == false
end
it "returns empty arrays for chained attributes with no value in the chain" do
@spec = Pod::Spec.new do |s|
s.name = 'MainSpec'
s.platform = :ios
s.subspec 'FirstSubSpec' do |fss|
fss.subspec 'SecondSubSpec' do |sss|
sss.source_files = 'subsubspec.m'
end
end
end
@spec.activate_platform(:ios).source_files.should == []
@spec.subspecs.first.source_files.should == []
@spec.subspecs.first.subspecs.first.source_files.should == %w[ subsubspec.m ]
end
it "does not cache platform attributes and can activate another platform" do
@spec.stubs(:platform).returns nil
@spec.activate_platform(:ios)
@subsubspec.source_files.map { |f| f.to_s }.should == %w[ spec.m subspec_ios.m subsubspec.m ]
@spec.activate_platform(:osx)
@subsubspec.source_files.map { |f| f.to_s }.should == %w[ spec.m subspec_osx.m subsubspec.m ]
end
it "resolves correctly the available platforms" do
@spec.stubs(:platform).returns nil
@subspec.platform = :ios, '4.0'
@spec.available_platforms.map{ |p| p.to_sym }.should == [ :osx, :ios ]
@subspec.available_platforms.first.to_sym.should == :ios
@subsubspec.available_platforms.first.to_sym.should == :ios
@subsubspec.platform = :ios, '5.0'
@subspec.available_platforms.first.deployment_target.to_s.should == '4.0'
@subsubspec.available_platforms.first.deployment_target.to_s.should == '5.0'
end
it "resolves reports correctly the supported platforms" do
@spec.stubs(:platform).returns nil
@subspec.platform = :ios, '4.0'
@subsubspec.platform = :ios, '5.0'
@spec.supports_platform?(:ios).should.be.true
@spec.supports_platform?(:osx).should.be.true
@subspec.supports_platform?(:ios).should.be.true
@subspec.supports_platform?(:osx).should.be.false
@subspec.supports_platform?(:ios, '4.0').should.be.true
@subspec.supports_platform?(:ios, '5.0').should.be.true
@subsubspec.supports_platform?(:ios).should.be.true
@subsubspec.supports_platform?(:osx).should.be.false
@subsubspec.supports_platform?(:ios, '4.0').should.be.false
@subsubspec.supports_platform?(:ios, '5.0').should.be.true
@subsubspec.supports_platform?(Pod::Platform.new(:ios, '4.0')).should.be.false
@subsubspec.supports_platform?(Pod::Platform.new(:ios, '5.0')).should.be.true
end
it "raises a top level attribute is assigned to a spec with a parent" do
lambda { @subspec.version = '0.0.1' }.should.raise Pod::Informative
end
it "returns subspecs by name" do
@spec.subspec_by_name(nil).should == @spec
@spec.subspec_by_name('MainSpec').should == @spec
@spec.subspec_by_name('MainSpec/FirstSubSpec').should == @subspec
@spec.subspec_by_name('MainSpec/FirstSubSpec/SecondSubSpec').should == @subsubspec
end
it "has the same active platform accross the chain attributes" do
@spec.activate_platform(:ios)
@subspec.active_platform.should == :ios
@subsubspec.active_platform.should == :ios
@spec.stubs(:platform).returns nil
@subsubspec.activate_platform(:osx)
@subspec.active_platform.should == :osx
@spec.active_platform.should == :osx
end
it "resolves the libraries correctly" do
@spec.activate_platform(:ios)
@spec.libraries.should == %w[ xml ]
@subspec.libraries.should == %w[ xml z ]
@subsubspec.libraries.should == %w[ xml z ]
end
it "resolves the frameworks correctly" do
@spec.activate_platform(:ios)
@spec.frameworks.should == %w[ CoreData ]
@subspec.frameworks.should == %w[ CoreData CoreGraphics ]
@subsubspec.frameworks.should == %w[ CoreData CoreGraphics ]
end
it "resolves the weak frameworks correctly" do
@spec.activate_platform(:ios)
@spec.weak_frameworks.should == %w[ ]
@subspec.weak_frameworks.should == %w[ Twitter ]
end
it "resolves the xcconfig" do
@spec.activate_platform(:ios)
@spec.xcconfig = { 'OTHER_LDFLAGS' => "-Wl,-no_compact_unwind" }
@spec.xcconfig.should == {"OTHER_LDFLAGS"=>"-Wl,-no_compact_unwind -lxml -framework CoreData"}
@subspec.xcconfig.should == {"OTHER_LDFLAGS"=>"-Wl,-no_compact_unwind -lxml -lz -framework CoreData -framework CoreGraphics -weak_framework Twitter"}
@subsubspec.xcconfig.should == {"OTHER_LDFLAGS"=>"-Wl,-no_compact_unwind -lxml -lz -framework CoreData -framework CoreGraphics -weak_framework Twitter"}
@subsubspec.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
@spec.xcconfig.should == {"OTHER_LDFLAGS"=>"-Wl,-no_compact_unwind -lxml -framework CoreData"}
@subsubspec.xcconfig.should == {"OTHER_LDFLAGS"=>"-Wl,-no_compact_unwind -lxml -lz -framework CoreData -framework CoreGraphics -weak_framework Twitter", "HEADER_SEARCH_PATHS"=>"$(SDKROOT)/usr/include/libxml2"}
end
end
describe "A Pod::Specification with :local source" do
before do
@spec = Pod::Spec.new do |s|
s.name = 'MainSpec'
s.source = { :local => fixture("integration/JSONKit") }
s.source_files = "."
end
end
it "is marked as local" do
@spec.should.be.local
end
it "it returns the expanded local path" do
@spec.source.should == {:local => fixture("integration/JSONKit")}
end
end
describe "A Pod::Specification, concerning its attributes that support different values per platform," do
describe "when **no** platform specific values are given" do
before do
@spec = Pod::Spec.new do |s|
s.source_files = 'file1', 'file2'
s.resources = 'file1', 'file2'
s.xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }
s.framework = 'QuartzCore'
s.library = 'z'
s.compiler_flags = '-Wdeprecated-implementations'
s.requires_arc = true
s.dependency 'JSONKit'
s.dependency 'SSZipArchive'
end
end
it "returns the same list of source files for each platform" do
@spec.activate_platform(:ios).source_files.should == %w{ file1 file2 }
@spec.activate_platform(:osx).source_files.should == %w{ file1 file2 }
end
it "returns the same list of resources for each platform" do
@spec.activate_platform(:ios).resources.should == %w{ file1 file2 }
@spec.activate_platform(:osx).resources.should == %w{ file1 file2 }
end
it "returns the same list of xcconfig build settings for each platform" do
build_settings = { 'OTHER_LDFLAGS' => '-lObjC -lz -framework QuartzCore' }
@spec.activate_platform(:ios).xcconfig.should == build_settings
@spec.activate_platform(:osx).xcconfig.should == build_settings
end
it "returns the same list of compiler flags for each platform" do
compiler_flags = '-Wdeprecated-implementations -fobjc-arc'
@spec.activate_platform(:ios).compiler_flags.should == compiler_flags
@spec.activate_platform(:osx).compiler_flags.should == compiler_flags
end
it "returns the same list of dependencies for each platform" do
dependencies = %w{ JSONKit SSZipArchive }.map { |name| Pod::Dependency.new(name) }
@spec.activate_platform(:ios).dependencies.should == dependencies
@spec.activate_platform(:osx).dependencies.should == dependencies
end
end
describe "when platform specific values are given" do
before do
@spec = Pod::Spec.new do |s|
s.ios.source_files = 'file1'
s.osx.source_files = 'file1', 'file2'
s.ios.resource = 'file1'
s.osx.resources = 'file1', 'file2'
s.ios.xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }
s.osx.xcconfig = { 'OTHER_LDFLAGS' => '-lObjC -all_load' }
s.ios.framework = 'QuartzCore'
s.osx.frameworks = 'QuartzCore', 'CoreData'
s.ios.library = 'z'
s.osx.libraries = 'z', 'xml'
s.ios.compiler_flags = '-Wdeprecated-implementations'
s.osx.compiler_flags = '-Wfloat-equal'
s.requires_arc = true # does not take platform options, just here to check it's added to compiler_flags
s.ios.dependency 'JSONKit'
s.osx.dependency 'SSZipArchive'
s.ios.deployment_target = '4.0'
end
end
it "returns a different list of source files for each platform" do
@spec.activate_platform(:ios).source_files.should == %w{ file1 }
@spec.activate_platform(:osx).source_files.should == %w{ file1 file2 }
end
it "returns a different list of resources for each platform" do
@spec.activate_platform(:ios).resources.should == %w{ file1 }
@spec.activate_platform(:osx).resources.should == %w{ file1 file2 }
end
it "returns a different list of xcconfig build settings for each platform" do
@spec.activate_platform(:ios).xcconfig.should == { 'OTHER_LDFLAGS' => '-lObjC -lz -framework QuartzCore' }
@spec.activate_platform(:osx).xcconfig.should == { 'OTHER_LDFLAGS' => '-all_load -lObjC -lxml -lz -framework CoreData -framework QuartzCore' }
end
it "returns the list of the supported platfroms and deployment targets" do
@spec.available_platforms.count.should == 2
@spec.available_platforms.should.include? Pod::Platform.new(:osx)
@spec.available_platforms.should.include? Pod::Platform.new(:ios, '4.0')
end
it "returns the same list of compiler flags for each platform" do
@spec.activate_platform(:ios).compiler_flags.should == '-Wdeprecated-implementations -fobjc-arc'
@spec.activate_platform(:osx).compiler_flags.should == '-Wfloat-equal -fobjc-arc'
end
it "returns the same list of dependencies for each platform" do
@spec.activate_platform(:ios).dependencies.should == [Pod::Dependency.new('JSONKit')]
@spec.activate_platform(:osx).dependencies.should == [Pod::Dependency.new('SSZipArchive')]
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Version do
it "returns wether or not it's a `bleeding edge' version" do
version = Version.new('1.2.3')
version.should.not.be.head
version.head = true
version.should.be.head
end
it "serializes to and from a string" do
version = Version.from_string('1.2.3')
version.to_s.should == '1.2.3'
version.should.not.be.head
version = Version.from_string('HEAD based on 1.2.3')
version.should.be.head
version.to_s.should == 'HEAD based on 1.2.3'
end
it "supports the previous way that a HEAD version was described" do
version = Version.from_string('HEAD from 1.2.3')
version.should.be.head
version.to_s.should == 'HEAD based on 1.2.3'
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