Commit 064085ec authored by Fabio Pelosin's avatar Fabio Pelosin

Merge branch 'master' into lookback-pods-by-config

* master: (294 commits)
  Bundle: update cocoapods-core
  Bundle: update Xcodeproj
  Validator: check license only in root spec
  Bundle: udpate cocoapods-core
  Integration: update for Xcodeproj
  Specs: fix for changes to Xcodeproj
  Update integration specs for Xcodeproj
  Gem: update Xcodeproj dependency
  Integration: update acknowledgements
  Bundle: make xcodeproj faster on mac
  Update integration specs for Xcodeproj
  Bundle:update
  CI: disable Ruby 1.8.7 for now
  Xcodeproj: udpate
  Bundle: update cocoapods-trunk version
  [Sandbox] Evaluate podspecs from their original path
  [Install/Update] Clarify command description. Relates to #2270.
  [README] Flatten badges
  [Gemspec] Update to nap 0.8
  Pod::Command::Spec::Lint::description update
  ...

Conflicts:
	CHANGELOG.md
	Gemfile.lock
	spec/cocoapods-integration-specs
parents a009895b c2366c33
......@@ -30,4 +30,14 @@ examples/RelativePathProject/RelativePathProject/RelativePathProject.xcodeproj
coverage/
.coveralls.yml
# IDEs
*.xccheckout
.idea/
# RVM files
/.rvmrc
/.ruby-version
/.ruby-gemset
# Bundler files
/.bundle
[submodule "spec/fixtures/integration/ASIHTTPRequest"]
path = spec/fixtures/integration/ASIHTTPRequest
url = https://github.com/pokeb/asi-http-request.git
[submodule "spec/fixtures/integration/SSZipArchive"]
path = spec/fixtures/integration/SSZipArchive
url = https://github.com/samsoffes/ssziparchive.git
[submodule "spec/fixtures/integration/JSONKit"]
path = spec/fixtures/integration/JSONKit
url = https://github.com/johnezang/JSONKit.git
[submodule "spec/fixtures/integration/sstoolkit"]
path = spec/fixtures/integration/sstoolkit
url = https://github.com/samsoffes/sstoolkit.git
ignore = dirty
[submodule "spec/fixtures/spec-repos/master"]
path = spec/fixtures/spec-repos/master
url = https://github.com/CocoaPods/Specs.git
......
recipe :ruby
Kicker::Recipes::Ruby.runner_bin = 'bacon'
Kicker::Recipes::Ruby.runner_bin = 'bacon --quiet'
process do |files|
specs = files.take_and_map do |file|
......
# Sets Travis to run the Ruby specs on OS X machines which are required to
# build the native extensions of Xcodeproj.
#
language: objective-c
env:
# This is what 10.8.x comes with and we want to support that.
- RVM_RUBY_VERSION=system NOEXEC_DISABLE=1 XCODEPROJ_BUILD=1 BUNDLE_WITHOUT='debugging:documentation' RUBY_VERSION_SPECIFIC='sudo ln -s /usr/bin/llvm-gcc-4.2 /usr/bin/gcc-4.2' SSL_CERT_FILE=/usr/local/share/cacert.pem GIT_AUTHOR_NAME=CocoaPods GIT_AUTHOR_EMAIL=cocoapods@example.com PYTHONPATH=/usr/local/lib/python2.7/site-packages
- RVM_RUBY_VERSION=2.0.0-p247 NOEXEC_DISABLE=1 XCODEPROJ_BUILD=1 BUNDLE_WITHOUT='debugging:documentation' RUBY_VERSION_SPECIFIC='sudo gem install bundler --no-ri --no-rdoc' GIT_AUTHOR_NAME=CocoaPods GIT_AUTHOR_EMAIL=cocoapods@example.com PYTHONPATH=/usr/local/lib/python2.7/site-packages
- RVM_RUBY_VERSION=system
# - RVM_RUBY_VERSION=1.8.7-p358
before_install:
- export LANG=en_US.UTF-8
- curl http://curl.haxx.se/ca/cacert.pem -o /usr/local/share/cacert.pem
# - sh -c 'if [ "$RVM_RUBY_VERSION" != "system" ]; then rvm install $RVM_RUBY_VERSION --without-tcl --without-tk; fi'
- source ~/.rvm/scripts/rvm && rvm use $RVM_RUBY_VERSION
- brew update && brew install bzr
install: eval $RUBY_VERSION_SPECIFIC && rake bootstrap[use_bundle_dir]
script: bundle exec rake spec:ci
- source ~/.rvm/scripts/rvm
- if [[ $RVM_RUBY_VERSION != 'system' ]]; then rvm install $RVM_RUBY_VERSION; fi
- rvm use $RVM_RUBY_VERSION
- if [[ $RVM_RUBY_VERSION == 'system' ]]; then export ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future; fi
- if [[ $RVM_RUBY_VERSION == 'system' ]]; then sudo gem install bundler --no-ri --no-rdoc; else gem install bundler --no-ri --no-rdoc; fi
install:
- bundle install --without=debugging documentation --path ./travis_bundle_dir
# CocoaPods/CocoaPods specific
- ./bin/pod repo update --silent
script: rake spec
notifications:
campfire:
on_success: change
on_failure: always
rooms:
- secure: "qOE5zmgaHe/qQu3W9rmj7wygA5Ivl+cx50fqWGag2bdRl8ly5yj1NVoOKk/O\nZmQc4Lze+301uvTXi+r5v8A/tF6W1kUZw7yBiKuXoYFUGmDiVR9o2I/FPwkL\ngSzPJttrXTQfkQ4PbnrkX+JO+5bLWrKaO0hKXT4B2yUu4UXLVk0="
This diff is collapsed.
# Do’s and Don’ts
* **Search the solutions in the [troubleshooting guide](http://guides.cocoapods.org/using/troubleshooting.html).** Or any of the many other [guides](http://guides.cocoapods.org).
* **Search tickets before you file a new one.** Add to tickets if you have new information about the issue.
* **Only file tickets about the CocoaPods tool itself.** This includes [CocoaPods](https://github.com/CocoaPods/CocoaPods/issues),
[CocoaPods/Core](https://github.com/CocoaPods/Core/issues), and [Xcodeproj](https://github.com/CocoaPods/Xcodeproj/issues).
......@@ -48,7 +49,7 @@ Should you require a feature isn't suited for mainstream users, consider suggest
## Pull Requests
We **love** pull requests and if a contribution is significant we tend to offer
push access.
push access. We suggest you take a look at our [Contributing guide](http://guides.cocoapods.org/contributing/contribute-to-cocoapods.html) for info on development setup, and some of our best practices.
All contributions _will_ be licenced under the MIT license.
......
......@@ -10,31 +10,41 @@ group :development do
# For more info see http://bundler.io/git.html#local
gem 'cocoapods-core', :git => "https://github.com/CocoaPods/Core.git", :branch => 'lookback-pods-by-config'
gem 'xcodeproj', :git => "https://github.com/CocoaPods/Xcodeproj.git", :branch => 'master'
gem 'cocoapods-downloader', :git => "https://github.com/CocoaPods/cocoapods-downloader.git", :branch => 'master'
gem 'claide', :git => 'https://github.com/CocoaPods/CLAide.git', :branch => 'master'
gem 'cocoapods-downloader', :git => "https://github.com/CocoaPods/cocoapods-downloader.git", :branch => 'master'
gem 'cocoapods-try', :git => 'https://github.com/CocoaPods/cocoapods-try.git', :branch => 'master'
gem 'cocoapods-plugins', :git => 'https://github.com/CocoaPods/cocoapods-plugins.git', :branch => 'master'
gem 'cocoapods-trunk', :git => 'https://github.com/CocoaPods/cocoapods-trunk.git', :branch => 'master'
gem "mocha"
gem 'rake', '~> 10.1.0' # Ruby 1.8.7
gem "mocha", '~> 1.0.0' # Issues with Ruby 2.0.0 on Travis
gem "bacon"
gem "mocha-on-bacon"
gem 'prettybacon', :git => 'https://github.com/irrationalfab/PrettyBacon.git', :branch => 'master'
gem "rake"
gem 'prettybacon'
gem 'webmock', "< 1.16"
# For the integration tests
gem "diffy"
# Lock the current lowest requirement for ActiveSupport 3 to ensure we don't
# re-introduce https://github.com/CocoaPods/CocoaPods/issues/1950
gem 'i18n', '0.6.4'
gem 'mime-types', '< 2' # v2 is 1.9.x only
gem 'coveralls', :require => false
# Explicitly add this, otherwise it might sometimes be missing:
# https://github.com/lemurheavy/coveralls-ruby/blob/master/coveralls-ruby.gemspec#L23.
gem 'simplecov'
if RUBY_PLATFORM.include?('darwin')
# Make Xcodeproj faster
gem 'libxml-ruby'
end
end
group :debugging do
# Only while we test the trunk app.
gem 'cocoapods-trunk', :git => "https://github.com/alloy/cocoapods-trunk.git"
gem "rb-fsevent"
gem "kicker", :git => "https://github.com/alloy/kicker.git", :branch => "master"
gem "kicker"
gem "awesome_print"
gem "pry"
# The released gem leads to stack too deep when profiling a full run.
......
GIT
remote: https://github.com/CocoaPods/CLAide.git
revision: f5e4752d8cc4ba055e1d96713275e9955fea9f37
revision: 2d1ade5e062be937e630920c7399dbe1bee48d93
branch: master
specs:
claide (0.4.0)
claide (0.6.1)
GIT
remote: https://github.com/CocoaPods/Core.git
revision: 6d775a30b10246ee0f87dc241788ab0b5fe89447
revision: 1f6273aeb346b9d21008438b37594106fca4b7f6
branch: lookback-pods-by-config
specs:
cocoapods-core (0.29.0)
activesupport (>= 3.2.15, < 4)
cocoapods-core (0.33.1)
activesupport (>= 3.2.15)
fuzzy_match (~> 2.0.4)
json_pure (~> 1.8)
nap (~> 0.5)
GIT
remote: https://github.com/CocoaPods/Xcodeproj.git
revision: 0704b7772370feb8be154ace0ce48e09f215aeaf
revision: f835e6e1145812ac04ac4b658321c727c2967547
branch: master
specs:
xcodeproj (0.14.1)
xcodeproj (0.18.0)
CFPropertyList (~> 2.2)
activesupport (~> 3.0)
colored (~> 1.2)
rake
GIT
remote: https://github.com/CocoaPods/cocoapods-downloader.git
revision: 4a95877b20893b374dfd43624e12bac167feef05
revision: 27a5c58d7d7aaf8886c47624260d167fa776175c
branch: master
specs:
cocoapods-downloader (0.3.0)
cocoapods-downloader (0.6.1)
GIT
remote: https://github.com/alloy/cocoapods-trunk.git
revision: 20b9a8bb60ad6e59df4df7d4a960a4dd4a41afa0
remote: https://github.com/CocoaPods/cocoapods-plugins.git
revision: 0740e01bc8b99cbd8249e766fc4a87eae71e995e
branch: master
specs:
cocoapods-trunk (0.0.1)
json (~> 1.8)
nap (>= 0.6)
netrc
cocoapods-plugins (0.2.0)
nap
GIT
remote: https://github.com/alloy/kicker.git
revision: 87b0047202c0320d4ef62e1f1a4b2cbdefadf008
remote: https://github.com/CocoaPods/cocoapods-trunk.git
revision: c62f86f83bf77faf8baf80359cc511dd1014fcfb
branch: master
specs:
kicker (3.0.0)
listen (~> 1.3.0)
notify (~> 0.5.2)
cocoapods-trunk (0.1.4)
json_pure (~> 1.8)
nap (>= 0.6)
netrc
GIT
remote: https://github.com/irrationalfab/PrettyBacon.git
revision: eaf7e6c786fd5ccc6fb88e943bf7c5e6c27569a3
remote: https://github.com/CocoaPods/cocoapods-try.git
revision: 754e53f3c3eec4c5ba129d6955484fb27631d1d5
branch: master
specs:
prettybacon (0.0.1)
bacon (~> 1.2)
cocoapods-try (0.3.0)
GIT
remote: https://github.com/ruby-prof/ruby-prof.git
revision: b56c1268ba001f5eb55f940ca1c83bc6b83a9752
revision: e3317c4bf0b58dceee86e5dd9cf03165fcfd964f
specs:
ruby-prof (0.14.2)
ruby-prof (0.15.1)
PATH
remote: .
specs:
cocoapods (0.29.0)
cocoapods (0.33.1)
activesupport (>= 3.2.15, < 4)
claide (~> 0.4.0)
cocoapods-core (= 0.29.0)
cocoapods-downloader (~> 0.3.0)
cocoapods-try-release-fix (~> 0.1.1)
claide (~> 0.6.1)
cocoapods-core (= 0.33.1)
cocoapods-downloader (~> 0.6.1)
cocoapods-plugins (~> 0.2.0)
cocoapods-trunk (~> 0.1.4)
cocoapods-try (~> 0.3.0)
colored (~> 1.2)
escape (~> 0.0.4)
json_pure (~> 1.8)
nap (~> 0.5)
nap (~> 0.8)
open4 (~> 1.3)
xcodeproj (~> 0.14.1)
xcodeproj (~> 0.18.0)
GEM
remote: http://rubygems.org/
specs:
activesupport (3.2.16)
CFPropertyList (2.2.8)
activesupport (3.2.19)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
addressable (2.3.6)
awesome_print (1.2.0)
bacon (1.2.0)
cocoapods-try-release-fix (0.1.1)
coderay (1.1.0)
colored (1.2)
coveralls (0.7.0)
......@@ -98,60 +100,73 @@ GEM
simplecov (>= 0.7)
term-ansicolor
thor
diffy (3.0.1)
docile (1.1.3)
crack (0.4.2)
safe_yaml (~> 1.0.0)
diffy (3.0.6)
docile (1.1.5)
escape (0.0.4)
ffi (1.9.3)
fuzzy_match (2.0.4)
github-markup (1.0.1)
i18n (0.6.9)
json (1.8.1)
github-markup (1.2.1)
posix-spawn (~> 0.3.8)
i18n (0.6.4)
json_pure (1.8.1)
kicker (3.0.0)
listen (~> 1.3.0)
notify (~> 0.5.2)
libxml-ruby (2.7.0)
listen (1.3.1)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
metaclass (0.0.2)
metaclass (0.0.4)
method_source (0.8.2)
mime-types (1.25.1)
mocha (1.0.0)
metaclass (~> 0.0.1)
mocha-on-bacon (0.2.2)
mocha (>= 0.13.0)
multi_json (1.8.4)
nap (0.6.0)
multi_json (1.10.1)
nap (0.8.0)
netrc (0.7.7)
notify (0.5.2)
open4 (1.3.0)
open4 (1.3.4)
posix-spawn (0.3.8)
pry (0.9.12.6)
coderay (~> 1.0)
method_source (~> 0.8)
prettybacon (0.0.2)
bacon (~> 1.2)
pry (0.10.0)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pygments.rb (0.5.4)
pygments.rb (0.6.0)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
rake (10.1.1)
rb-fsevent (0.9.4)
rb-inotify (0.9.3)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rb-kqueue (0.2.0)
rb-kqueue (0.2.3)
ffi (>= 0.5.0)
redcarpet (2.3.0)
rest-client (1.6.7)
mime-types (>= 1.16)
simplecov (0.8.2)
rest-client (1.7.2)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
safe_yaml (1.0.3)
simplecov (0.9.0)
docile (~> 1.1.0)
multi_json
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
slop (3.4.7)
term-ansicolor (1.2.2)
tins (~> 0.8)
thor (0.18.1)
tins (0.13.2)
slop (3.6.0)
term-ansicolor (1.3.0)
tins (~> 1.0)
thor (0.19.1)
tins (1.3.0)
webmock (1.15.2)
addressable (>= 2.2.7)
crack (>= 0.3.2)
yajl-ruby (1.1.0)
yard (0.8.7.3)
yard (0.8.7.4)
PLATFORMS
ruby
......@@ -163,21 +178,26 @@ DEPENDENCIES
cocoapods!
cocoapods-core!
cocoapods-downloader!
cocoapods-plugins!
cocoapods-trunk!
cocoapods-try!
coveralls
diffy
github-markup
kicker!
i18n (= 0.6.4)
kicker
libxml-ruby
mime-types (< 2)
mocha
mocha (~> 1.0.0)
mocha-on-bacon
prettybacon!
prettybacon
pry
pygments.rb
rake
rake (~> 10.1.0)
rb-fsevent
redcarpet (< 3.0.0)
ruby-prof!
simplecov
webmock (< 1.16)
xcodeproj!
yard
......@@ -2,9 +2,9 @@
### CocoaPods: The Objective-C dependency manager
[![Build Status](http://img.shields.io/travis/CocoaPods/CocoaPods/master.svg)](https://travis-ci.org/CocoaPods/CocoaPods)
[![Gem Version](http://img.shields.io/gem/v/cocoapods.svg)](http://badge.fury.io/rb/cocoapods)
[![Code Climate](http://img.shields.io/codeclimate/github/CocoaPods/CocoaPods.svg)](https://codeclimate.com/github/CocoaPods/CocoaPods)
[![Build Status](http://img.shields.io/travis/CocoaPods/CocoaPods/master.svg?style=flat)](https://travis-ci.org/CocoaPods/CocoaPods)
[![Gem Version](http://img.shields.io/gem/v/cocoapods.svg?style=flat)](http://badge.fury.io/rb/cocoapods)
[![Code Climate](http://img.shields.io/codeclimate/github/CocoaPods/CocoaPods.svg?style=flat)](https://codeclimate.com/github/CocoaPods/CocoaPods)
CocoaPods manages dependencies for your Xcode projects.
......@@ -50,10 +50,10 @@ CocoaPods is composed by the following projects:
| Status | Project | Description | Info |
| :----- | :------ | :--- | :--- |
| [![Build Status](http://img.shields.io/travis/CocoaPods/CocoaPods/master.svg)](http://travis-ci.org/CocoaPods/CocoaPods) | [CocoaPods](https://github.com/CocoaPods/CocoaPods) | The CocoaPods command line tool. | [docs](http://docs.cocoapods.org/cocoapods)
| [![Build Status](http://img.shields.io/travis/CocoaPods/Core/master.svg)](http://travis-ci.org/CocoaPods/Core) | [CocoaPods Core](https://github.com/CocoaPods/Core) | Support for working with specifications and podfiles. | [docs](http://docs.cocoapods.org/cocoapods_core)
| [![Build Status](http://img.shields.io/travis/CocoaPods/cocoapods-downloader/master.svg)](http://travis-ci.org/CocoaPods/cocoapods-downloader) |[CocoaPods Downloader](https://github.com/CocoaPods/cocoapods-downloader) | Downloaders for various source types. | [docs](http://docs.cocoapods.org/cocoapods_downloader/index.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/Xcodeproj/master.svg)](https://travis-ci.org/CocoaPods/Xcodeproj) | [Xcodeproj](https://github.com/CocoaPods/Xcodeproj) | Create and modify Xcode projects from Ruby. | [docs](http://docs.cocoapods.org/xcodeproj/index.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/CLAide/master.svg)](https://travis-ci.org/CocoaPods/CLAide) | [CLAide](https://github.com/CocoaPods/CLAide) | A small command-line interface framework. | [docs](http://docs.cocoapods.org/claide/index.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/Specs/master.svg)](http://travis-ci.org/CocoaPods/Specs) | [Master Repo ](https://github.com/CocoaPods/Specs) | Master repository of specifications. | [guide](http://docs.cocoapods.org/guides/contributing_to_the_master_repo.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/CocoaPods/master.svg?style=flat)](http://travis-ci.org/CocoaPods/CocoaPods) | [CocoaPods](https://github.com/CocoaPods/CocoaPods) | The CocoaPods command line tool. | [docs](http://docs.cocoapods.org/cocoapods)
| [![Build Status](http://img.shields.io/travis/CocoaPods/Core/master.svg?style=flat)](http://travis-ci.org/CocoaPods/Core) | [CocoaPods Core](https://github.com/CocoaPods/Core) | Support for working with specifications and podfiles. | [docs](http://docs.cocoapods.org/cocoapods_core)
| [![Build Status](http://img.shields.io/travis/CocoaPods/cocoapods-downloader/master.svg?style=flat)](http://travis-ci.org/CocoaPods/cocoapods-downloader) |[CocoaPods Downloader](https://github.com/CocoaPods/cocoapods-downloader) | Downloaders for various source types. | [docs](http://docs.cocoapods.org/cocoapods_downloader/index.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/Xcodeproj/master.svg?style=flat)](https://travis-ci.org/CocoaPods/Xcodeproj) | [Xcodeproj](https://github.com/CocoaPods/Xcodeproj) | Create and modify Xcode projects from Ruby. | [docs](http://docs.cocoapods.org/xcodeproj/index.html)
| [![Build Status](http://img.shields.io/travis/CocoaPods/CLAide/master.svg?style=flat)](https://travis-ci.org/CocoaPods/CLAide) | [CLAide](https://github.com/CocoaPods/CLAide) | A small command-line interface framework. | [docs](http://docs.cocoapods.org/claide/index.html)
| | [Master Repo ](https://github.com/CocoaPods/Specs) | Master repository of specifications. | [guide](http://docs.cocoapods.org/guides/contributing_to_the_master_repo.html)
This diff is collapsed.
#!/usr/bin/env ruby
if RUBY_VERSION > '1.8.7' && Encoding.default_external != Encoding::UTF_8
puts <<-DOC
\e[33mWARNING: CocoaPods requires your terminal to be using UTF-8 encoding.
puts "\e[33mWARNING: CocoaPods requires your terminal to be using UTF-8 encoding."
if ENV["TRAVIS"]
puts <<-DOC
Consider adding the following settings to .travis.yml
before_script:
- export LANG=en_US.UTF-8\e[0m\n
DOC
else
puts <<-DOC
See https://github.com/CocoaPods/guides.cocoapods.org/issues/26 for
possible solutions.\e[0m\n
DOC
DOC
end
end
if $PROGRAM_NAME == __FILE__ && !ENV['COCOAPODS_NO_BUNDLER']
......
......@@ -27,18 +27,20 @@ s.files = Dir["lib/**/*.rb"] + %w{ bin/pod bin/sandbox-pod README.md LICENSE CHA
s.require_paths = %w{ lib }
# Link with the version of CocoaPods-Core
s.add_runtime_dependency 'cocoapods-core', "= #{Pod::VERSION}"
s.add_runtime_dependency 'claide', '~> 0.4.0'
s.add_runtime_dependency 'cocoapods-downloader', '~> 0.3.0'
s.add_runtime_dependency 'xcodeproj', '~> 0.14.1'
s.add_runtime_dependency 'cocoapods-try-release-fix', '~> 0.1.1'
s.add_runtime_dependency 'cocoapods-core', "= #{Pod::VERSION}"
s.add_runtime_dependency 'claide', '~> 0.6.1'
s.add_runtime_dependency 'xcodeproj', '~> 0.18.0'
s.add_runtime_dependency 'cocoapods-downloader', '~> 0.6.1'
s.add_runtime_dependency 'cocoapods-plugins', '~> 0.2.0'
s.add_runtime_dependency 'cocoapods-try', '~> 0.3.0'
s.add_runtime_dependency 'cocoapods-trunk', '~> 0.1.4'
s.add_runtime_dependency 'colored', '~> 1.2'
s.add_runtime_dependency 'escape', '~> 0.0.4'
s.add_runtime_dependency 'json_pure', '~> 1.8'
s.add_runtime_dependency 'open4', '~> 1.3'
s.add_runtime_dependency 'activesupport', '>= 3.2.15', '< 4'
s.add_runtime_dependency 'nap', '~> 0.5'
s.add_runtime_dependency 'nap', '~> 0.8'
s.add_development_dependency 'bacon', '~> 1.1'
......
......@@ -9,7 +9,10 @@ require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/array/conversions'
# TODO check what this actually does by the time we're going to add support for
# other locales.
I18n.enforce_available_locales = false
require 'i18n'
if I18n.respond_to?(:enforce_available_locales=)
I18n.enforce_available_locales = false
end
module Pod
require 'pathname'
......@@ -19,6 +22,11 @@ module Pod
require 'cocoapods/config'
require 'cocoapods/downloader'
# Loaded immediately after dependencies to ensure proper override of their
# UI methods.
#
require 'cocoapods/user_interface'
# Indicates an user error. This is defined in cocoapods-core.
#
class Informative < PlainInformative
......@@ -38,7 +46,6 @@ module Pod
autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox'
autoload :UI, 'cocoapods/user_interface'
autoload :Validator, 'cocoapods/validator'
module Generator
......
......@@ -14,23 +14,24 @@ module Pod
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'
require 'cocoapods/command/init'
# TODO: remove
require 'cocoapods/command/push'
self.abstract_command = true
self.default_subcommand = 'install'
self.command = 'pod'
self.version = VERSION
self.description = 'CocoaPods, the Objective-C library package manager.'
self.plugin_prefix = 'cocoapods'
def self.options
[
['--silent', 'Show nothing'],
['--version', 'Show the version of CocoaPods'],
].concat(super)
end
......@@ -43,11 +44,7 @@ module Pod
end
def self.run(argv)
argv = CLAide::ARGV.new(argv)
if argv.flag?('version')
UI.puts VERSION
exit 0
end
help! "You cannot run CocoaPods as root." if Process.uid == 0
super(argv)
UI.print_warnings
end
......
......@@ -2,7 +2,9 @@ module Pod
class Command
class Help < Command
self.summary = 'Show help for the given command.'
self.arguments = '[COMMAND]'
self.arguments = [
CLAide::Argument.new('COMMAND', false)
]
def initialize(argv)
@help_command = Pod::Command.parse(argv)
......
......@@ -8,16 +8,18 @@ module Pod
self.summary = 'Generate a Podfile for the current directory.'
self.description = <<-DESC
Creates a Podfile for the current directory if none currently exists. If
an Xcode project file is specified or if there is only a single project
file in the current directory, targets will be automatically generated
based on targets defined in the project.
an `XCODEPROJ` project file is specified or if there is only a single
project file in the current directory, targets will be automatically
generated based on targets defined in the project.
It is possible to specify a list of dependencies which will be used by
the template in the `Podfile.default` (normal targets) `Podfile.test`
(test targets) files which should be stored in the
`~/.cocoapods/templates` folder.
DESC
self.arguments = '[XCODEPROJ]'
self.arguments = [
CLAide::Argument.new('XCODEPROJ', :false)
]
def initialize(argv)
@podfile_path = Pathname.pwd + "Podfile"
......@@ -31,12 +33,13 @@ module Pod
raise Informative, "Existing Podfile found in directory" unless config.podfile.nil?
if @project_path
help! "Xcode project at #{@project_path} does not exist" unless File.exist? @project_path
project_path = @project_path
else
raise Informative, "No xcode project found, please specify one" unless @project_paths.length > 0
raise Informative, "Multiple xcode projects found, please specify one" unless @project_paths.length == 1
@project_path = @project_paths.first
project_path = @project_paths.first
end
@xcode_project = Xcodeproj::Project.open(@project_path)
@xcode_project = Xcodeproj::Project.open(project_path)
end
def run
......@@ -51,7 +54,9 @@ module Pod
# @return [String] the text of the Podfile for the provided project
#
def podfile_template(project)
podfile = <<-PLATFORM.strip_heredoc
podfile = ''
podfile << "xcodeproj '#{@project_path}'\n\n" if @project_path
podfile << <<-PLATFORM.strip_heredoc
# Uncomment this line to define a global platform for your project
# platform :ios, "6.0"
PLATFORM
......
......@@ -15,7 +15,9 @@ module Pod
self.summary = 'Converts a podspec to JSON.'
self.description = 'Converts a podspec to JSON and prints it to STDOUT.'
self.arguments = 'PATH'
self.arguments = [
CLAide::Argument.new('PATH', true)
]
def initialize(argv)
@path = argv.shift_argument
......@@ -40,7 +42,9 @@ module Pod
self.summary = 'Converts a Podfile to YAML.'
self.description = 'Converts a Podfile to YAML and prints it to STDOUT.'
self.arguments = 'PATH'
self.arguments = [
CLAide::Argument.new('PATH', true)
]
def initialize(argv)
@path = argv.shift_argument
......@@ -63,11 +67,11 @@ module Pod
class List < IPC
self.summary = 'Lists the specifications know to CocoaPods.'
self.summary = 'Lists the specifications known to CocoaPods.'
self.description = <<-DESC
Prints to STDOUT a YAML dictionary where the keys are the name of the
specifications and the values are a dictionary with the following
keys.
specifications and each corresponding value is a dictionary with
the following keys:
- defined_in_file
- version
......
......@@ -10,13 +10,20 @@ module Pod
self.summary = 'Creates a new Pod'
self.description = <<-DESC
Creates a new Pod with the given name from the template in the working directory.
Creates a scaffold for the development of a new Pod named `NAME`
according to the CocoaPods best practices.
If a `TEMPLATE_URL`, pointing to a git repo containing a compatible
template, is specified, it will be used in place of the default one.
DESC
self.arguments = '[NAME]'
self.arguments = [
CLAide::Argument.new('NAME', true),
CLAide::Argument.new('TEMPLATE_URL', false)
]
def initialize(argv)
@name = argv.shift_argument
@template_url = argv.shift_argument
super
end
......@@ -24,6 +31,7 @@ module Pod
super
help! "A name for the Pod is required." unless @name
help! "The Pod name cannot contain spaces." if @name.match(/\s/)
help! "The Pod name cannot begin with a '.'" if @name[0, 1] == '.'
end
def run
......@@ -52,8 +60,8 @@ module Pod
# @return [void]
#
def clone_template
UI.section("Creating `#{@name}` Pod") do
git!"clone '#{TEMPLATE_REPO}' #{@name}"
UI.section("Cloning `#{template_repo_url}` into `#{@name}`.") do
git!"clone '#{template_repo_url}' #{@name}"
end
end
......@@ -62,9 +70,13 @@ module Pod
# @return [void]
#
def configure_template
UI.section("Configuring template") do
UI.section("Configuring #{@name} template.") do
Dir.chdir(@name) do
ruby! "_CONFIGURE.rb #{@name}"
if File.exists? "configure"
system "./configure #{@name}"
else
UI.warn "Template does not have a configure file."
end
end
end
end
......@@ -74,10 +86,17 @@ module Pod
# @return [void]
#
def print_info
UI.puts "\nTo learn more about the template see `#{TEMPLATE_INFO_URL}`."
UI.puts "\nTo learn more about the template see `#{template_repo_url}`."
UI.puts "To learn more about creating a new pod, see `#{CREATE_NEW_POD_INFO_URL}`."
end
# Checks if a template URL is given else returns the TEMPLATE_REPO URL
#
# @return String
#
def template_repo_url
@template_url || TEMPLATE_REPO
end
end
#-----------------------------------------------------------------------#
......
......@@ -24,7 +24,7 @@ module Pod
update_if_necessary!
sets = SourcesManager.all_sets
sets.each { |set| UI.pod(set, :name) }
sets.each { |set| UI.pod(set, :name_and_version) }
UI.puts "\n#{sets.count} pods were found"
end
......
......@@ -23,21 +23,6 @@ module Pod
# @todo fix.
#
def run
verify_podfile_exists!
verify_lockfile_exists!
lockfile = config.lockfile
pods = lockfile.pod_names
updates = []
pods.each do |pod_name|
set = SourcesManager.search(Dependency.new(pod_name))
next unless set
source_version = set.versions.first
lockfile_version = lockfile.version(pod_name)
if source_version > lockfile_version
updates << [pod_name, lockfile_version, source_version]
end
end
if updates.empty?
UI.puts "No updates are available.".yellow
......@@ -48,7 +33,71 @@ module Pod
end
end
end
if deprecated_pods.any?
UI.section 'The following pods are deprecated:' do
deprecated_pods.each do |spec|
if spec.deprecated_in_favor_of
UI.puts "- #{spec.name}" \
" (in favor of #{spec.deprecated_in_favor_of})"
else
UI.puts "- #{spec.name}"
end
end
end
end
end
private
def updates
@updates ||= begin
spec_sets.map do |set|
spec = set.specification
source_version = set.versions.first
pod_name = spec.root.name
lockfile_version = lockfile.version(pod_name)
if source_version > lockfile_version
[pod_name, lockfile_version, source_version]
else
nil
end
end.compact.uniq
end
end
def deprecated_pods
@deprecated_pods ||= begin
spec_sets.map(&:specification).select do |spec|
spec.deprecated || spec.deprecated_in_favor_of
end.compact.uniq
end
end
def spec_sets
@spec_sets ||= begin
installed_pods.map do |pod_name|
SourcesManager.search(Dependency.new(pod_name))
end.compact.uniq
end
end
def installed_pods
@installed_pods ||= begin
verify_podfile_exists!
lockfile.pod_names
end
end
def lockfile
@lockfile ||= begin
verify_lockfile_exists!
config.lockfile
end
end
end
end
end
......
......@@ -8,7 +8,7 @@ module Pod
module Options
def 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"],
["--no-integrate", "Skip integration of the Pods libraries in the Xcode project(s)"],
["--no-repo-update", "Skip running `pod repo update` before install"],
].concat(super)
......@@ -28,13 +28,15 @@ module Pod
# Runs the installer.
#
# @param [update] whether the installer should be run in update mode.
# @param [Hash, Boolean, nil] update
# Pods that have been requested to be updated or true if all Pods
# should be updated
#
# @return [void]
#
def run_install_with_update(update)
installer = Installer.new(config.sandbox, config.podfile, config.lockfile)
installer.update_mode = update
installer.update = update
installer.install!
end
end
......@@ -44,18 +46,18 @@ module Pod
class Install < Command
include Project
self.summary = 'Install project dependencies'
self.summary = 'Install project dependencies to Podfile.lock versions'
self.description = <<-DESC
Downloads all dependencies defined in `Podfile' and creates an Xcode
Pods library project in `./Pods'.
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'
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
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,
......@@ -74,12 +76,45 @@ module Pod
class Update < Command
include Project
self.summary = 'Update outdated project dependencies'
self.summary = 'Update outdated project dependencies and create new Podfile.lock'
self.description = <<-DESC
Updates the Pods identified by the specified `POD_NAMES`. If no
`POD_NAMES` are specified it updates all the Pods ignoring the contents
of the Podfile.lock.
This command is reserved to the update of dependencies and pod install
should be used to install changes to the Podfile.
DESC
self.arguments = [
CLAide::Argument.new('POD_NAMES', false, true),
]
def initialize(argv)
@pods = argv.arguments! unless argv.arguments.empty?
super
end
def run
verify_podfile_exists!
verify_lockfile_exists!
run_install_with_update(true)
if @pods
verify_lockfile_exists!
# Check if all given pods are installed
missing_pods = @pods.select { |pod| !config.lockfile.pod_names.include?(pod) }
if missing_pods.length > 0
raise Informative, (missing_pods.length > 1 \
? "Pods %s are not installed and cannot be updated" \
: "Pod %s is not installed and cannot be updated"
) % missing_pods.map { |p| "`#{p}`" }.join(', ')
end
run_install_with_update(:pods => @pods)
else
UI.puts "Update all pods".yellow unless @pods
run_install_with_update(true)
end
end
end
......
require 'fileutils'
require 'active_support/core_ext/string/inflections'
module Pod
class Command
class Push < Command
self.summary = 'Push new specifications to a spec-repo'
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/repos/[REPO]), copies the podspec file into the version
directory, and finally it pushes REPO to its remote.
DESC
self.summary = 'Temporary alias for the `pod repo push` command'
self.arguments = 'REPO [NAME.podspec]'
def self.options
[ ["--allow-warnings", "Allows pushing even if there are warnings"],
["--local-only", "Does not perform the step of pushing REPO to its remote"] ].concat(super)
end
def initialize(argv)
@allow_warnings = argv.flag?('allow-warnings')
@local_only = argv.flag?('local-only')
@repo = argv.shift_argument
if @repo.nil?
@repo = "master"
elsif @repo.end_with? ".podspec"
@podspec = @repo
@repo = "master"
else
@podspec = argv.shift_argument
end
@push_command = Repo::Push.new(argv)
super
end
def validate!
super
help! "A spec-repo name is required." unless @repo
UI.puts '[!] The `pod push` command has been moved to `pod repo push`.'.ansi.yellow
@push_command.validate!
end
def run
validate_podspec_files
test_trunk
check_repo_status
update_repo
add_specs_to_repo
push_repo unless @local_only
end
#-----------------------------------------------------------------------#
private
# @!group Push sub-steps
extend Executable
executable :git
# @return [void] Silently test the CocoaPods trunk service.
#
def test_trunk
return unless @repo == "master"
require 'rest'
base_url = 'https://trunk.cocoapods.org/api/v1'
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
REST.post("#{base_url}/pods", spec.to_json, 'Content-Type' => 'application/json; charset=utf-8',
'Authorization' => "Token 9300632274827cd3e6dde24bf9c608c3")
end
rescue Exception
# Nothing
end
# Performs a full lint against the podspecs.
#
def validate_podspec_files
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
podspec_files.each do |podspec|
validator = Validator.new(podspec)
validator.only_errors = @allow_warnings
begin
validator.validate
rescue Exception
raise Informative, "The `#{podspec}` specification does not validate."
end
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
end
end
# Checks that the repo is clean.
#
# @raise If the repo is not clean.
#
# @todo Add specs for staged and unstaged files.
#
# @todo Gracefully handle the case where source is not under git
# source control.
#
# @return [void]
#
def check_repo_status
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "The repo `#{@repo}` is not clean" unless clean
end
# Updates the git repo against the remote.
#
# @return [void]
#
def update_repo
UI.puts "Updating the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
@push_command.run
end
# Commits the podspecs to the source, which should be a git repo.
#
# @note The pre commit hook of the repo is skipped as the podspecs have
# already been linted.
#
# @return [void]
#
def add_specs_to_repo
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
if Pathname.new(output_path).exist?
message = "[Fix] #{spec}"
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
message = "[Update] #{spec}"
else
message = "[Add] #{spec}"
end
FileUtils.mkdir_p(output_path)
FileUtils.cp(spec_file, output_path)
Dir.chdir(repo_dir) do
# only commit if modified
if git!("status --porcelain 2>&1") =~ /#{spec.name}/
UI.puts " - #{message}"
git!("add #{spec.name}")
git!("commit --no-verify -m '#{message}'")
else
UI.puts " - [No change] #{spec}"
end
end
end
end
# Pushes the git repo against the remote.
#
# @return [void]
#
def push_repo
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git push origin master 2>&1` }
end
#-----------------------------------------------------------------------#
private
# @!group Private helpers
# @return [Pathname] The directory of the repository.
#
def repo_dir
dir = config.repos_dir + @repo
raise Informative, "`#{@repo}` repo not found" unless dir.exist?
dir
end
# @return [Array<Pathname>] The path of the specifications to push.
#
def podspec_files
files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
files
end
# @return [Integer] The number of the podspec files to push.
#
def count
podspec_files.count
end
#-----------------------------------------------------------------------#
end
end
end
require 'fileutils'
require 'cocoapods/command/repo/push'
module Pod
class Command
......@@ -17,9 +18,20 @@ module Pod
remote can later be referred to by `NAME`.
DESC
self.arguments = 'NAME URL [BRANCH]'
self.arguments = [
CLAide::Argument.new('NAME', true),
CLAide::Argument.new('URL', true),
CLAide::Argument.new('BRANCH', false)
]
def self.options
[
["--shallow", "Create a shallow clone (fast clone, but no push capabilities)"],
].concat(super)
end
def initialize(argv)
@shallow = argv.flag?('shallow', false)
@name, @url, @branch = argv.shift_argument, argv.shift_argument, argv.shift_argument
super
end
......@@ -32,9 +44,14 @@ module Pod
end
def run
UI.section("Cloning spec repo `#{@name}` from `#{@url}`#{" (branch `#{@branch}`)" if @branch}") do
prefix = @shallow ? 'Creating shallow clone of' : 'Cloning'
UI.section("#{prefix} spec repo `#{@name}` from `#{@url}`#{" (branch `#{@branch}`)" if @branch}") do
config.repos_dir.mkpath
Dir.chdir(config.repos_dir) { git!("clone '#{@url}' #{@name}") }
Dir.chdir(config.repos_dir) do
command = "clone '#{@url}' #{@name}"
command << ' --depth=1' if @shallow
git!(command)
end
Dir.chdir(dir) { git!("checkout #{@branch}") } if @branch
SourcesManager.check_version_information(dir)
end
......@@ -51,7 +68,9 @@ module Pod
this will update all spec-repos in `~/.cocoapods/repos`.
DESC
self.arguments = '[NAME]'
self.arguments = [
CLAide::Argument.new('NAME', false)
]
def initialize(argv)
@name = argv.shift_argument
......@@ -74,7 +93,9 @@ module Pod
will lint all the spec-repos known to CocoaPods.
DESC
self.arguments = '[ NAME | DIRECTORY ]'
self.arguments = [
CLAide::Argument.new(%w(NAME DIRECTORY), false)
]
def self.options
[["--only-errors", "Lint presents only the errors"]].concat(super)
......@@ -140,7 +161,9 @@ module Pod
Deletes the remote named `NAME` from the local spec-repos directory at `~/.cocoapods/repos/.`
DESC
self.arguments = 'NAME'
self.arguments = [
CLAide::Argument.new('NAME', true)
]
def initialize(argv)
@name = argv.shift_argument
......@@ -151,6 +174,8 @@ module Pod
super
help! 'Deleting a repo needs a `NAME`.' unless @name
help! "repo #{@name} does not exist" unless File.directory?(dir)
help! "You do not have permission to delete the #{@name} repository." \
"Perhaps try prefixing this command with sudo." unless File.writable?(dir)
end
def run
......
require 'fileutils'
require 'active_support/core_ext/string/inflections'
module Pod
class Command
class Repo < Command
class Push < Repo
self.summary = 'Push new specifications to a spec-repo'
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/repos/[REPO]), copies the podspec file into the
version directory, and finally it pushes `REPO` to its remote.
DESC
self.arguments = [
CLAide::Argument.new('REPO', true),
CLAide::Argument.new('NAME.podspec', false)
]
def self.options
[ ["--allow-warnings", "Allows pushing even if there are warnings"],
["--local-only", "Does not perform the step of pushing REPO to its remote"] ].concat(super)
end
def initialize(argv)
@allow_warnings = argv.flag?('allow-warnings')
@local_only = argv.flag?('local-only')
@repo = argv.shift_argument
@podspec = argv.shift_argument
super
end
def validate!
super
help! "A spec-repo name is required." unless @repo
end
def run
check_if_master_repo
validate_podspec_files
check_repo_status
update_repo
add_specs_to_repo
push_repo unless @local_only
end
#---------------------------------------------------------------------#
private
# @!group Push sub-steps
extend Executable
executable :git
# Temporary check to ensure that users do not push accidentally private
# specs to the master repo.
#
def check_if_master_repo
remotes = Dir.chdir(repo_dir) { `git remote -v 2>&1` }
master_repo_urls = [
'git@github.com:CocoaPods/Specs.git',
'https://github.com/CocoaPods/Specs.git',
]
is_master_repo = master_repo_urls.any? do |url|
remotes.include?(url)
end
if is_master_repo
raise Informative, "To push to the CocoaPods master repo use " \
"the `pod trunk push` command.\n\nIf you are using a fork of " \
"the master repo for private purposes we recommend to migrate " \
"to a clean private repo. To disable this check remove the " \
"remote pointing to the CocoaPods master repo."
end
end
# Performs a full lint against the podspecs.
#
def validate_podspec_files
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
podspec_files.each do |podspec|
validator = Validator.new(podspec)
validator.only_errors = @allow_warnings
begin
validator.validate
rescue Exception
raise Informative, "The `#{podspec}` specification does not validate."
end
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
end
end
# Checks that the repo is clean.
#
# @raise If the repo is not clean.
#
# @todo Add specs for staged and unstaged files.
#
# @todo Gracefully handle the case where source is not under git
# source control.
#
# @return [void]
#
def check_repo_status
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "The repo `#{@repo}` is not clean" unless clean
end
# Updates the git repo against the remote.
#
# @return [void]
#
def update_repo
UI.puts "Updating the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
end
# Commits the podspecs to the source, which should be a git repo.
#
# @note The pre commit hook of the repo is skipped as the podspecs have
# already been linted.
#
# @return [void]
#
def add_specs_to_repo
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
if Pathname.new(output_path).exist?
message = "[Fix] #{spec}"
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
message = "[Update] #{spec}"
else
message = "[Add] #{spec}"
end
FileUtils.mkdir_p(output_path)
FileUtils.cp(spec_file, output_path)
Dir.chdir(repo_dir) do
# only commit if modified
if git!("status --porcelain 2>&1").include?(spec.name)
UI.puts " - #{message}"
git!("add #{spec.name}")
git!("commit --no-verify -m '#{message}'")
else
UI.puts " - [No change] #{spec}"
end
end
end
end
# Pushes the git repo against the remote.
#
# @return [void]
#
def push_repo
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git push origin master 2>&1` }
end
#---------------------------------------------------------------------#
private
# @!group Private helpers
# @return [Pathname] The directory of the repository.
#
def repo_dir
specs_dir = Pathname.new(File.join(config.repos_dir, @repo, 'Specs'))
dir = config.repos_dir + @repo
if specs_dir.exist?
dir = specs_dir
elsif dir.exist?
dir
else
raise Informative, "`#{@repo}` repo not found either in #{specs_dir} or #{dir}"
end
dir
end
# @return [Array<Pathname>] The path of the specifications to push.
#
def podspec_files
files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
files
end
# @return [Integer] The number of the podspec files to push.
#
def count
podspec_files.count
end
#---------------------------------------------------------------------#
end
end
end
end
......@@ -4,12 +4,14 @@ module Pod
self.summary = 'Searches for pods'
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
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
self.arguments = '[QUERY]'
self.arguments = [
CLAide::Argument.new('QUERY', true)
]
def self.options
[
......@@ -35,6 +37,14 @@ module Pod
def validate!
super
help! "A search query is required." unless @query
unless @web
begin
/#{@query.join(' ').strip}/
rescue RegexpError
help! "A valid regular expression is required."
end
end
end
def run
......@@ -50,11 +60,11 @@ module Pod
def web_search
query_parameter = [
('on%3Aosx' if @supported_on_osx),
('on%3Aios' if @supported_on_ios),
('on:osx' if @supported_on_osx),
('on:ios' if @supported_on_ios),
@query
].compact.flatten.join('%20')
url = "http://cocoapods.org/?q=#{query_parameter}"
].compact.flatten.join(' ')
url = "http://cocoapods.org/?q=#{CGI.escape(query_parameter).gsub("+", "%20")}"
UI.puts("Opening #{url}")
open!(url)
end
......
......@@ -15,14 +15,18 @@ module Pod
DESC
def self.options
[["--push", "Use this option to enable push access once granted"]].concat(super)
[
["--no-shallow", "Clone full history so push will work"],
["--push", "Use this option to enable push access once granted"],
].concat(super)
end
extend Executable
executable :git
def initialize(argv)
@push_option = argv.flag?('push')
@push_option = argv.flag?('push')
@shallow = argv.flag?('shallow', !@push_option)
super
end
......@@ -77,7 +81,9 @@ module Pod
# @return [void]
#
def add_master_repo
@command ||= Repo::Add.parse(['master', url, 'master']).run
cmd = ['master', url, 'master']
cmd << '--shallow' if @shallow
Repo::Add.parse(cmd).run
end
# Updates the master repo against the remote.
......@@ -109,7 +115,7 @@ module Pod
# be enabled.
#
def url
(push?) ? read_write_url : read_only_url
push? ? read_write_url : read_only_url
end
# @return [String] the read only url of the master repo.
......
......@@ -18,7 +18,9 @@ module Pod
If a GitHub url is passed the spec is prepopulated.
DESC
self.arguments = '[ NAME | https://github.com/USER/REPO ]'
self.arguments = [
CLAide::Argument.new(%w(NAME https://github.com/USER/REPO), false)
]
def initialize(argv)
@name_or_url, @url = argv.shift_argument, argv.shift_argument
......@@ -51,12 +53,14 @@ module Pod
self.summary = 'Validates a spec file.'
self.description = <<-DESC
Validates `NAME.podspec'. If a directory is provided it validates
Validates `NAME.podspec`. If a `DIRECTORY` is provided, it validates
the podspec files found, including subfolders. In case
the argument is omitted, it defaults to the current working dir.
DESC
self.arguments = '[ NAME.podspec | DIRECTORY | http://PATH/NAME.podspec, ... ]'
self.arguments = [
CLAide::Argument.new(%w(NAME.podspec DIRECTORY http://PATH/NAME.podspec), false, true),
]
def self.options
[ ["--quick", "Lint skips checks that would require to download and build the spec"],
......@@ -122,17 +126,17 @@ module Pod
end
files << output_path
else if (pathname = Pathname.new(path)).directory?
files += Pathname.glob(pathname + '**/*.podspec')
raise Informative, "No specs found in the current directory." if files.empty?
else
files << (pathname = Pathname.new(path))
raise Informative, "Unable to find a spec named `#{path}'." unless pathname.exist? && path.include?('.podspec')
end
files += Pathname.glob(pathname + '**/*.podspec{.json,}')
raise Informative, "No specs found in the current directory." if files.empty?
else
files << (pathname = Pathname.new(path))
raise Informative, "Unable to find a spec named `#{path}'." unless pathname.exist? && path.include?('.podspec')
end
end
files
end
files
end
end
def podspecs_tmp_dir
Pathname.new(File.join(Pathname.new('/tmp').realpath, '/CocoaPods/Lint_podspec'))
......@@ -148,7 +152,9 @@ module Pod
Prints the path of 'NAME.podspec'
DESC
self.arguments = '[ NAME ]'
self.arguments = [
CLAide::Argument.new('NAME', false)
]
def self.options
[["--show-all", "Print all versions of the given podspec"]].concat(super)
......@@ -180,7 +186,9 @@ module Pod
Prints 'NAME.podspec' to standard output.
DESC
self.arguments = '[ NAME ]'
self.arguments = [
CLAide::Argument.new('NAME', false)
]
def self.options
[["--show-all", "Pick from all versions of the given podspec"]].concat(super)
......@@ -207,7 +215,7 @@ module Pod
get_path_of_spec(@spec)
end
UI.puts File.open(filepath).read
UI.puts File.read(filepath)
end
end
......@@ -220,7 +228,9 @@ module Pod
Opens 'NAME.podspec' to be edited.
DESC
self.arguments = '[ NAME ]'
self.arguments = [
CLAide::Argument.new('NAME', false)
]
def self.options
[["--show-all", "Pick which spec to edit from all available versions of the given podspec"]].concat(super)
......@@ -342,7 +352,7 @@ module Pod
# @return [Pathname] the absolute path of the given spec and source
#
def pathname_from_spec(spec, source)
config.repos_dir + "#{source}/#{spec.name}/#{spec.version}/#{spec.name}.podspec"
Pathname(spec.defined_in_file)
end
# @return [String] of spec paths one on each line
......@@ -370,16 +380,21 @@ module Pod
def spec_and_source_from_set(set)
sources = set.sources
best_source = sources.first
best_version = best_source.versions(set.name).first
best_source = best_version = nil
sources.each do |source|
version = source.versions(set.name).first
if version > best_version
versions = source.versions(set.name)
versions.each do |version|
if !best_version or version > best_version
best_source = source
best_version = version
end
end
end
if !best_source or !best_version
raise Informative, "Unable to locate highest known specification for `#{ set.name }'"
end
return best_source.specification(set.name, best_version), best_source
end
......@@ -475,7 +490,7 @@ Pod::Spec.new do |s|
DESC
s.homepage = "#{data[:homepage]}"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
# s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
# ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
......@@ -485,24 +500,24 @@ Pod::Spec.new do |s|
# Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
#
s.license = 'MIT (example)'
# s.license = { :type => 'MIT', :file => 'FILE_LICENSE' }
s.license = "MIT (example)"
# s.license = { :type => "MIT", :file => "FILE_LICENSE" }
# ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# Specify the authors of the library, with email addresses. Email addresses
# of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
# accepts just a name if you'd rather not provide an email addresses.
# accepts just a name if you'd rather not provide an email address.
#
# Specify a social_media_url where others can refer to, for example a twitter
# profile URL.
#
s.author = { "#{data[:author_name]}" => "#{data[:author_email]}" }
# Or just: s.author = '#{data[:author_name]}'
# s.authors = { "#{data[:author_name]}" => "#{data[:author_email]}" }
# s.social_media_url = "http://twitter.com/#{data[:author_name]}"
# Or just: s.author = "#{data[:author_name]}"
# s.authors = { "#{data[:author_name]}" => "#{data[:author_email]}" }
# s.social_media_url = "http://twitter.com/#{data[:author_name]}"
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
......@@ -511,11 +526,11 @@ Pod::Spec.new do |s|
#
# s.platform = :ios
# s.platform = :ios, '5.0'
# s.platform = :ios, "5.0"
# When using multiple platforms
# s.ios.deployment_target = '5.0'
# s.osx.deployment_target = '10.7'
# s.ios.deployment_target = "5.0"
# s.osx.deployment_target = "10.7"
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
......@@ -535,10 +550,10 @@ Pod::Spec.new do |s|
# Not including the public_header_files will make all headers public.
#
s.source_files = 'Classes', 'Classes/**/*.{h,m}'
s.exclude_files = 'Classes/Exclude'
s.source_files = "Classes", "Classes/**/*.{h,m}"
s.exclude_files = "Classes/Exclude"
# s.public_header_files = 'Classes/**/*.h'
# s.public_header_files = "Classes/**/*.h"
# ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
......@@ -561,11 +576,11 @@ Pod::Spec.new do |s|
# the lib prefix of their name.
#
# s.framework = 'SomeFramework'
# s.frameworks = 'SomeFramework', 'AnotherFramework'
# s.framework = "SomeFramework"
# s.frameworks = "SomeFramework", "AnotherFramework"
# s.library = 'iconv'
# s.libraries = 'iconv', 'xml2'
# s.library = "iconv"
# s.libraries = "iconv", "xml2"
# ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
......@@ -576,8 +591,8 @@ Pod::Spec.new do |s|
# s.requires_arc = true
# s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
# s.dependency 'JSONKit', '~> 1.4'
# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
# s.dependency "JSONKit", "~> 1.4"
end
SPEC
......
......@@ -71,7 +71,7 @@ module Pod
output = stdout.join("\n") + stderr.join("\n")
unless status.success?
if raise_on_failure
raise Informative, "#{name} #{command}\n\n#{output}"
raise Informative, "#{full_command}\n\n#{output}"
else
UI.message("[!] Failed: #{full_command}".red)
end
......
This diff is collapsed.
module Pod
module ExternalSources
# Abstract class that defines the common behaviour of external sources.
#
class AbstractExternalSource
# @return [String] the name of the Pod described by this external source.
#
attr_reader :name
# @return [Hash{Symbol => String}] the hash representation of the
# external source.
#
attr_reader :params
# @return [String] the path where the podfile is defined to resolve
# relative paths.
#
attr_reader :podfile_path
# @param [String] name @see name
# @param [Hash] params @see params
# @param [String] podfile_path @see podfile_path
#
def initialize(name, params, podfile_path)
@name = name
@params = params
@podfile_path = podfile_path
end
# @return [Bool] whether an external source source is equal to another
# according to the {#name} and to the {#params}.
#
def ==(other)
return false if other.nil?
name == other.name && params == other.params
end
public
# @!group Subclasses hooks
# Fetches the external source from the remote according to the params.
#
# @param [Sandbox] sandbox
# the sandbox where the specification should be stored.
#
# @return [void]
#
def fetch(sandbox)
raise "Abstract method"
end
# @return [String] a string representation of the source suitable for UI.
#
def description
raise "Abstract method"
end
protected
# @return [String] The uri of the podspec appending the name of the file
# and expanding it if necessary.
#
# @note If the declared path is expanded only if the represents a path
# relative to the file system.
#
def normalized_podspec_path(declared_path)
extension = File.extname(declared_path)
if extension == '.podspec' || extension == '.json'
path_with_ext = declared_path
else
path_with_ext = "#{declared_path}/#{name}.podspec"
end
podfile_dir = File.dirname(podfile_path || '')
File.expand_path(path_with_ext, podfile_dir)
end
private
# @! Subclasses helpers
# Pre-downloads a Pod passing the options to the downloader and informing
# the sandbox.
#
# @param [Sandbox] sandbox
# The sandbox where the Pod should be downloaded.
#
# @note To prevent a double download of the repository the pod is
# marked as pre-downloaded indicating to the installer that only
# clean operations are needed.
#
# @todo The downloader configuration is the same of the
# #{PodSourceInstaller} and it needs to be kept in sync.
#
# @return [void]
#
def pre_download(sandbox)
title = "Pre-downloading: `#{name}` #{description}"
UI.titled_section(title, { :verbose_prefix => "-> " }) do
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Config.instance.downloader(target, params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
sandbox.store_pre_downloaded_pod(name)
if downloader.options_specific?
source = params
else
source = downloader.checkout_options
end
sandbox.store_checkout_source(name, source)
end
end
# Stores the podspec in the sandbox and marks it as from an external
# source.
#
# @param [Sandbox] sandbox
# The sandbox where the specification should be stored.
#
# @param [Pathname, String] spec
# The path of the specification or its contents.
#
# @note All the concrete implementations of #{fetch} should invoke this
# method.
#
# @note The sandbox ensures that the podspec exists and that the names
# match.
#
# @return [void]
#
def store_podspec(sandbox, spec, json = false)
sandbox.store_podspec(name, spec, true, json)
end
end
end
end
module Pod
module ExternalSources
# Provides support for fetching a specification file from a source handled
# by the downloader. Supports all the options of the downloader
#
# @note The podspec must be in the root of the repository and should have a
# name matching the one of the dependency.
#
class DownloaderSource < AbstractExternalSource
# @see AbstractExternalSource#fetch
#
def fetch(sandbox)
pre_download(sandbox)
end
# @see AbstractExternalSource#description
#
def description
strategy = Downloader.strategy_from_options(params)
options = params.dup
url = options.delete(strategy)
result = "from `#{url}`"
options.each do |key, value|
result << ", #{key} `#{value}`"
end
result
end
end
end
end
module Pod
module ExternalSources
# Provides support for fetching a specification file from a path local to
# the machine running the installation.
#
# Works with the {LocalPod::LocalSourcedPod} class.
#
class PathSource < AbstractExternalSource
# @see AbstractExternalSource#fetch
#
def fetch(sandbox)
title = "Fetching podspec for `#{name}` #{description}"
UI.titled_section(title, { :verbose_prefix => "-> " }) do
podspec = podspec_path
unless podspec.exist?
raise Informative, "No podspec found for `#{name}` in " \
"`#{declared_path}`"
end
store_podspec(sandbox, podspec)
is_absolute = absolute?(declared_path)
sandbox.store_local_path(name, podspec.dirname, is_absolute)
end
end
# @see AbstractExternalSource#description
#
def description
"from `#{params[:path] || params[:local]}`"
end
private
# @!group Helpers
# @return [String] The path as declared by the user.
#
def declared_path
result = params[:path] || params[:local]
result.to_s if result
end
# @return [Pathname] The absolute path of the podspec.
#
def podspec_path
Pathname(normalized_podspec_path(declared_path))
end
# @return [Bool]
#
def absolute?(path)
Pathname(path).absolute? || path.to_s.start_with?('~')
end
end
end
end
module Pod
module ExternalSources
# Provides support for fetching a specification file from an URL. Can be
# http, file, etc.
#
class PodspecSource < AbstractExternalSource
# @see AbstractExternalSource#fetch
#
def fetch(sandbox)
title = "Fetching podspec for `#{name}` #{description}"
UI.titled_section(title, { :verbose_prefix => "-> " }) do
is_json = podspec_uri.split('.').last == 'json'
require 'open-uri'
open(podspec_uri) { |io| store_podspec(sandbox, io.read, is_json) }
end
end
# @see AbstractExternalSource#description
#
def description
"from `#{params[:podspec]}`"
end
private
# @!group Helpers
# @return [String] The uri of the podspec appending the name of the file
# and expanding it if necessary.
#
# @note If the declared path is expanded only if the represents a path
# relative to the file system.
#
def podspec_uri
declared_path = params[:podspec].to_s
if declared_path.match(%r{^.+://})
declared_path
else
normalized_podspec_path(declared_path)
end
end
end
end
end
module Pod
# The version of the cocoapods command line tool.
#
VERSION = '0.29.0' unless defined? Pod::VERSION
VERSION = '0.33.1' unless defined? Pod::VERSION
end
......@@ -40,9 +40,12 @@ module Pod
# added to the top of the prefix header. For OS X `Cocoa/Cocoa.h`
# is imported.
#
# @note Only unique prefix_header_contents are added to the prefix header.
#
# @return [String]
#
# @todo Subspecs can specify prefix header information too.
# @todo Check to see if we have a similar duplication issue with file_accessor.prefix_header.
#
def generate
result = "#ifdef __OBJC__\n"
......@@ -53,12 +56,18 @@ module Pod
result << %|\n#import "#{import}"|
end
file_accessors.each do |file_accessor|
unique_prefix_header_contents = file_accessors.collect do |file_accessor|
file_accessor.spec_consumer.prefix_header_contents
end.compact.uniq
result << "\n"
unique_prefix_header_contents.each do |prefix_header_contents|
result << prefix_header_contents
result << "\n"
if prefix_header_contents = file_accessor.spec_consumer.prefix_header_contents
result << prefix_header_contents
result << "\n"
end
end
file_accessors.each do |file_accessor|
if prefix_header = file_accessor.prefix_header
result << Pathname(prefix_header).read
end
......
......@@ -64,11 +64,12 @@ module Pod
@lockfile = lockfile
end
# @return [Bool] Whether the installer is in update mode. In update mode
# the contents of the Lockfile are not taken into account for
# deciding what Pods to install.
# @return [Hash, Boolean, nil] Pods that have been requested to be
# updated or true if all Pods should be updated.
# If all Pods should been updated the contents of the Lockfile are
# not taken into account for deciding what Pods to install.
#
attr_accessor :update_mode
attr_accessor :update
# Installs the Pods.
#
......@@ -89,6 +90,7 @@ module Pod
download_dependencies
generate_pods_project
integrate_user_project if config.integrate_targets?
perform_post_install_actions
end
def resolve_dependencies
......@@ -164,13 +166,14 @@ module Pod
#
def analyze
if lockfile && lockfile.cocoapods_version > Version.new(VERSION)
STDERR.puts '[!] The version of CocoaPods used to generate the lockfile is '\
'higher than the version of the current executable. Incompatibility ' \
'issues may arise.'.yellow
STDERR.puts '[!] The version of CocoaPods used to generate ' \
"the lockfile (#{lockfile.cocoapods_version}) is "\
"higher than the version of the current executable (#{VERSION}). " \
'Incompatibility issues may arise.'.yellow
end
analyzer = Analyzer.new(sandbox, podfile, lockfile)
analyzer.update_mode = update_mode
analyzer.update = update
@analysis_result = analyzer.analyze
@aggregate_targets = analyzer.result.targets
end
......@@ -249,7 +252,13 @@ module Pod
title_options = { :verbose_prefix => "-> ".green }
root_specs.sort_by(&:name).each do |spec|
if pods_to_install.include?(spec.name)
UI.titled_section("Installing #{spec}".green, title_options) do
if sandbox_state.changed.include?(spec.name) && sandbox.manifest
previous = sandbox.manifest.version(spec.name)
title = "Installing #{spec.name} #{spec.version} (was #{previous})"
else
title = "Installing #{spec}"
end
UI.titled_section(title.green, title_options) do
install_source_of_pod(spec.name)
end
else
......@@ -293,6 +302,32 @@ module Pod
end
end
# Performs any post-installation actions
#
# @return [void]
#
def perform_post_install_actions
warn_for_deprecations
end
# Prints a warning for any pods that are deprecated
#
# @return [void]
#
def warn_for_deprecations
deprecated_pods = root_specs.select do |spec|
spec.deprecated || spec.deprecated_in_favor_of
end
deprecated_pods.each do |spec|
if spec.deprecated_in_favor_of
UI.warn "#{spec.name} has been deprecated in " \
"favor of #{spec.deprecated_in_favor_of}"
else
UI.warn "#{spec.name} has been deprecated"
end
end
end
# Creates the Pods project from scratch if it doesn't exists.
#
# @return [void]
......@@ -309,9 +344,10 @@ module Pod
pod_names = pod_targets.map(&:pod_name).uniq
pod_names.each do |pod_name|
path = sandbox.pod_dir(pod_name)
local = sandbox.local?(pod_name)
@pods_project.add_pod_group(pod_name, path, local)
path = sandbox.pod_dir(pod_name)
was_absolute = sandbox.local_path_was_absolute?(pod_name)
@pods_project.add_pod_group(pod_name, path, local, was_absolute)
end
if config.podfile_path
......@@ -458,42 +494,11 @@ module Pod
#
def run_pre_install_hooks
UI.message "- Running pre install hooks" do
analysis_result.specifications.each do |spec|
executed = false
libraries_using_spec(spec).each do |lib|
lib_representation = library_rep(lib)
executed ||= run_spec_pre_install_hook(spec, lib_representation)
end
UI.message "- #{spec.name}" if executed
end
executed = run_podfile_pre_install_hook
UI.message "- Podfile" if executed
end
end
# Runs the pre install hook of the given specification with the given
# library representation.
#
# @param [Specification] spec
# The spec for which the pre install hook should be run.
#
# @param [Hooks::LibraryRepresentation] lib_representation
# The library representation to be passed as an argument to the
# hook.
#
# @raise Raises an informative if the hooks raises.
#
# @return [Bool] Whether the hook was run.
#
def run_spec_pre_install_hook(spec, lib_representation)
spec.pre_install!(pod_rep(spec.root.name), lib_representation)
rescue => e
raise Informative, "An error occurred while processing the pre-install " \
"hook of #{spec}." \
"\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
end
# Runs the pre install hook of the Podfile
#
# @raise Raises an informative if the hooks raises.
......@@ -517,42 +522,11 @@ module Pod
#
def run_post_install_hooks
UI.message "- Running post install hooks" do
analysis_result.specifications.each do |spec|
executed = false
libraries_using_spec(spec).each do |lib|
lib_representation = library_rep(lib)
executed ||= run_spec_post_install_hook(spec, lib_representation)
end
UI.message "- #{spec.name}" if executed
end
executed = run_podfile_post_install_hook
UI.message "- Podfile" if executed
end
end
# Runs the post install hook of the given specification with the given
# library representation.
#
# @param [Specification] spec
# The spec for which the post install hook should be run.
#
# @param [Hooks::LibraryRepresentation] lib_representation
# The library representation to be passed as an argument to the
# hook.
#
# @raise Raises an informative if the hooks raises.
#
# @return [Bool] Whether the hook was run.
#
def run_spec_post_install_hook(spec, lib_representation)
spec.post_install!(lib_representation)
rescue => e
raise Informative, "An error occurred while processing the post-install " \
"hook of #{spec}." \
"\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
end
# Runs the post install hook of the Podfile
#
# @raise Raises an informative if the hooks raises.
......
......@@ -33,7 +33,7 @@ module Pod
@podfile = podfile
@lockfile = lockfile
@update_mode = false
@update = false
@allow_pre_downloads = true
@archs_by_target_def = {}
end
......@@ -91,11 +91,30 @@ module Pod
# @!group Configuration
# @return [Hash, Boolean, nil] Pods that have been requested to be
# updated or true if all Pods should be updated
#
attr_accessor :update
# @return [Bool] Whether the version of the dependencies which did non
# change in the Podfile should be locked.
#
attr_accessor :update_mode
alias_method :update_mode?, :update_mode
def update_mode?
!!update
end
# @return [Symbol] Whether and how the dependencies in the Podfile
# should be updated.
#
def update_mode
if !update
:none
elsif update == true
:all
elsif update[:pods] != nil
:selected
end
end
# @return [Bool] Whether the analysis allows pre-downloads and thus
# modifications to the sandbox.
......@@ -219,10 +238,15 @@ module Pod
# that prevent the resolver to update a Pod.
#
def generate_version_locking_dependencies
if update_mode?
if update_mode == :all
[]
else
result.podfile_state.unchanged.map do |pod|
locking_pods = result.podfile_state.unchanged
if update_mode == :selected
# If selected Pods should been updated, filter them out of the list
locking_pods = locking_pods.select { |pod| !update[:pods].include?(pod) }
end
locking_pods.map do |pod|
lockfile.dependency_to_lock_pod_named(pod)
end
end
......@@ -252,10 +276,14 @@ module Pod
deps_to_fetch = []
deps_to_fetch_if_needed = []
deps_with_external_source = podfile.dependencies.select { |dep| dep.external_source }
if update_mode?
if update_mode == :all
deps_to_fetch = deps_with_external_source
else
pods_to_fetch = result.podfile_state.added + result.podfile_state.changed
if update_mode == :selected
pods_to_fetch += update[:pods]
end
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) }
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.root_name) }
deps_to_fetch += deps_to_fetch_if_needed.select { |dep| sandbox.specification(dep.root_name).nil? || !dep.external_source[:local].nil? || !dep.external_source[:path].nil? }
......@@ -316,7 +344,7 @@ module Pod
def generate_sandbox_state
sandbox_state = nil
UI.section "Comparing resolved specification to the sandbox manifest" do
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode, lockfile)
sandbox_analyzer = SandboxAnalyzer.new(sandbox, result.specifications, update_mode?, lockfile)
sandbox_state = sandbox_analyzer.analyze
sandbox_state.print
end
......
......@@ -63,6 +63,12 @@ module Pod
def install!
download_source unless predownloaded? || local?
run_prepare_command
rescue Informative
raise
rescue Object => e
UI.notice("Error installing #{root_spec.name}")
clean!
raise
end
# Cleans the installations if appropriate.
......@@ -95,8 +101,18 @@ module Pod
def download_source
root.rmtree if root.exist?
if head_pod?
downloader.download_head
@specific_source = downloader.checkout_options
begin
downloader.download_head
@specific_source = downloader.checkout_options
rescue RuntimeError => e
if e.message == 'Abstract method'
raise Informative, "The pod '" + root_spec.name + "' does not " +
"support the :head option, as it uses a " + downloader.name +
" source. Remove that option to use this pod."
else
raise
end
end
else
downloader.download
unless downloader.options_specific?
......@@ -114,12 +130,17 @@ module Pod
# Runs the prepare command bash script of the spec.
#
# @note Unsets the `CDPATH` env variable before running the
# shell script to avoid issues with relative paths
# (issue #1694).
#
# @return [void]
#
def run_prepare_command
return unless root_spec.prepare_command
UI.section(" > Running prepare command", '', 1) do
Dir.chdir(root) do
ENV.delete('CDPATH')
prepare_command = root_spec.prepare_command.strip_heredoc.chomp
full_command = "\nset -e\n" + prepare_command
bash!(full_command)
......
......@@ -15,7 +15,6 @@ module Pod
add_target
add_files_to_build_phases
add_resources_bundle_targets
# create_suport_files_group
create_xcconfig_file
create_prefix_header
create_dummy_source
......
......@@ -81,21 +81,22 @@ module Pod
#
def create_workspace
all_projects = user_project_paths.sort.push(sandbox.project_path).uniq
projpaths = all_projects.map do |path|
path.relative_path_from(workspace_path.dirname).to_s
file_references = all_projects.map do |path|
relative_path = path.relative_path_from(workspace_path.dirname).to_s
Xcodeproj::Workspace::FileReference.new(relative_path, 'group')
end
if workspace_path.exist?
workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
new_projpaths = projpaths - workspace.projpaths
unless new_projpaths.empty?
workspace.projpaths.concat(new_projpaths)
new_file_references = file_references - workspace.file_references
unless new_file_references.empty?
workspace.file_references.concat(new_file_references)
workspace.save_as(workspace_path)
end
else
UI.notice "From now on use `#{workspace_path.basename}`."
workspace = Xcodeproj::Workspace.new(*projpaths)
workspace = Xcodeproj::Workspace.new(*file_references)
workspace.save_as(workspace_path)
end
end
......
......@@ -69,6 +69,7 @@ module Pod
@head_pods = []
@checkout_sources = {}
@development_pods = {}
@pods_with_absolute_path = []
end
# @return [Lockfile] the manifest which contains the information about the
......@@ -159,6 +160,16 @@ module Pod
end
end
# Returns true if the path as originally specified was absolute.
#
# @param [String] name
#
# @return [Bool] true if originally absolute
#
def local_path_was_absolute?(name)
@pods_with_absolute_path.include? name
end
# @return [Pathname] the directory where to store the documentation.
#
def documentation_dir
......@@ -180,7 +191,8 @@ module Pod
#
def specification(name)
if file = specification_path(name)
Specification.from_file(file)
original_path = development_pods[name]
Dir.chdir(original_path || Dir.pwd) { Specification.from_file(file) }
end
end
......@@ -206,7 +218,16 @@ module Pod
#
def specification_path(name)
path = specifications_dir + "#{name}.podspec"
path.exist? ? path : nil
if path.exist?
path
else
path = specifications_dir + "#{name}.podspec.json"
if path.exist?
path
else
nil
end
end
end
# Stores a specification in the `Local Podspecs` folder.
......@@ -221,8 +242,9 @@ module Pod
# @todo Store all the specifications (including those not originating
# from external sources) so users can check them.
#
def store_podspec(name, podspec, external_source = false)
output_path = specifications_dir(external_source) + "#{name}.podspec"
def store_podspec(name, podspec, external_source = false, json = false)
file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
output_path = specifications_dir(external_source) + file_name
output_path.dirname.mkpath
if podspec.is_a?(String)
output_path.open('w') { |f| f.puts(podspec) }
......@@ -232,9 +254,13 @@ module Pod
end
FileUtils.copy(podspec, output_path)
end
spec = Specification.from_file(output_path)
unless spec.name == name
raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
Dir.chdir(podspec.is_a?(Pathname) ? File.dirname(podspec) : Dir.pwd) do
spec = Specification.from_file(output_path)
unless spec.name == name
raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
end
end
end
......@@ -338,11 +364,15 @@ module Pod
# @param [#to_s] path
# The local path where the Pod is stored.
#
# @param [Bool] was_absolute
# True if the specified local path was absolute.
#
# @return [void]
#
def store_local_path(name, path)
def store_local_path(name, path, was_absolute = false)
root_name = Specification.root_name(name)
development_pods[root_name] = path.to_s
@pods_with_absolute_path << root_name if was_absolute
end
# @return [Hash{String=>String}] The path of the Pods with a local source
......
......@@ -152,8 +152,13 @@ module Pod
sources.each do |source|
UI.section "Updating spec repo `#{source.name}`" do
Dir.chdir(source.data_provider.repo) do
output = git!("pull")
UI.puts output if show_output && !config.verbose?
begin
output = git!("pull --ff-only")
UI.puts output if show_output && !config.verbose?
rescue Informative => e
raise Informative, 'An error occurred while performing ' \
"`git pull` on repo `#{source.name}`.\n" + e.message
end
end
check_version_information(source.data_provider.repo)
end
......@@ -201,12 +206,16 @@ module Pod
min, max = versions['min'], versions['max']
version_msg = ( min == max ) ? min : "#{min} - #{max}"
raise Informative, "The `#{dir.basename}` repo requires " \
"CocoaPods #{version_msg}\n".red +
"CocoaPods #{version_msg} (currently using #{Pod::VERSION})\n".red +
"Update CocoaPods, or checkout the appropriate tag in the repo."
end
needs_sudo = path_writable?(__FILE__)
if config.new_version_message? && cocoapods_update?(versions)
UI.puts "\nCocoaPods #{versions['last']} is available.\n".green
UI.puts "\nCocoaPods #{versions['last']} is available.\n" \
"To update use: #{needs_sudo ? 'sudo ' : ''}" \
'gem install cocoapods\n'.green
end
end
......@@ -258,7 +267,16 @@ module Pod
def version_information(dir)
require 'yaml'
yaml_file = dir + 'CocoaPods-version.yml'
yaml_file.exist? ? YAML.load_file(yaml_file) : {}
return {} unless yaml_file.exist?
begin
yaml = Pathname.new(yaml_file).read
YAMLHelper.load(yaml)
rescue Informative => e
raise Informative, "There was an error reading '#{yaml_file}'.\n" \
'Please consult http://blog.cocoapods.org/' \
'Repairing-Our-Broken-Specs-Repository/ ' \
'for more information.'
end
end
public
......@@ -283,6 +301,12 @@ module Pod
#-----------------------------------------------------------------------#
private
def path_writable?(path)
Pathname(path).dirname.writable?
end
end
end
end
......
......@@ -158,8 +158,8 @@ module Pod
# Prints the textual representation of a given set.
#
def pod(set, mode = :normal, statistics_provider = nil)
if mode == :name
puts_indented set.name
if mode == :name_and_version
puts_indented "#{set.name} #{set.versions.first.version}"
else
pod = Specification::Set::Presenter.new(set, statistics_provider)
title("\n-> #{pod.name} (#{pod.version})".green, '', 1) do
......@@ -184,10 +184,10 @@ module Pod
# Prints a message with a label.
#
def labeled(label, value)
def labeled(label, value, justification = 16)
if value
''.tap do |t|
t << " - #{label}:".ljust(16)
t << " - #{label}:".ljust(justification)
if value.is_a?(Array)
separator = "\n - "
puts_indented t << separator << value.join(separator)
......
......@@ -45,7 +45,7 @@ Repositories : #{repo_information.join("\n ")}
#{'[!] Oh no, an error occurred.'.red}
#{error_from_podfile(exception)}
#{'Search for existing github issues similar to yours:'.yellow}
#{"https://github.com/CocoaPods/CocoaPods/search?q=#{CGI.escape(exception.message)}&type=Issues"}
#{issues_url(exception)}
#{'If none exists, create a ticket, with the template displayed above, on:'.yellow}
https://github.com/CocoaPods/CocoaPods/issues/new
......@@ -57,6 +57,10 @@ EOS
private
def pathless_exception_message(message)
message.gsub(/- \(.*\):/, '-')
end
def markdown_podfile
return '' unless Config.instance.podfile_path && Config.instance.podfile_path.exist?
<<-EOS
......@@ -75,6 +79,16 @@ EOS
end
end
def remove_color(string)
string.gsub(/\e\[(\d+)m/, '')
end
def issues_url(exception)
message = remove_color(pathless_exception_message(exception.message))
'https://github.com/CocoaPods/CocoaPods/search?q=' \
"#{CGI.escape(message)}&type=Issues"
end
def host_information
product, version, build =`sw_vers`.strip.split("\n").map { |line| line.split(":").last.strip }
"#{product} #{version} (#{build})"
......
......@@ -60,8 +60,8 @@ module Pod
# Replace default spec with a subspec if asked for
a_spec = spec
if spec && @only_subspec
a_spec = spec.subspec_by_name(@only_subspec)
@subspec_name = a_spec.name
a_spec = spec.subspec_by_name(@only_subspec)
@subspec_name = a_spec.name
end
UI.print " -> #{a_spec ? a_spec.name : file.basename}\r" unless config.silent?
......@@ -196,6 +196,12 @@ module Pod
# Perform analysis for a given spec (or subspec)
#
def perform_extensive_analysis(spec)
validate_homepage(spec)
validate_screenshots(spec)
validate_social_media_url(spec)
validate_documentation_url(spec)
validate_docset_url(spec)
spec.available_platforms.each do |platform|
UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
@consumer = spec.consumer(platform)
......@@ -208,18 +214,69 @@ module Pod
perform_extensive_subspec_analysis(spec) unless @no_subspecs
end
# Recurively perform the extensive analysis on all subspecs
# Recursively perform the extensive analysis on all subspecs
#
def perform_extensive_subspec_analysis(spec)
spec.subspecs.each do |subspec|
@subspec_name = subspec.name
perform_extensive_analysis(subspec)
end
spec.subspecs.each do |subspec|
@subspec_name = subspec.name
perform_extensive_analysis(subspec)
end
end
attr_accessor :consumer
attr_accessor :subspec_name
# Performs validation of a URL
#
def validate_url(url)
resp = Pod::HTTP::validate_url(url)
if !resp
warning "There was a problem validating the URL #{url}."
elsif !resp.success?
warning "The URL (#{url}) is not reachable."
end
resp
end
# Performs validations related to the `homepage` attribute.
#
def validate_homepage(spec)
if spec.homepage
validate_url(spec.homepage)
end
end
# Performs validation related to the `screenshots` attribute.
#
def validate_screenshots(spec)
spec.screenshots.compact.each do |screenshot|
request = validate_url(screenshot)
if request && !(request.headers['content-type'] && request.headers['content-type'].first =~ /image\/.*/i)
warning "The screenshot #{screenshot} is not a valid image."
end
end
end
# Performs validations related to the `social_media_url` attribute.
#
def validate_social_media_url(spec)
validate_url(spec.social_media_url) if spec.social_media_url
end
# Performs validations related to the `documentation_url` attribute.
#
def validate_documentation_url(spec)
validate_url(spec.documentation_url) if spec.documentation_url
end
# Performs validations related to the `docset_url` attribute.
#
def validate_docset_url(spec)
validate_url(spec.docset_url) if spec.docset_url
end
def setup_validation_environment
validation_dir.rmtree if validation_dir.exist?
validation_dir.mkpath
......@@ -294,8 +351,10 @@ module Pod
end
end
unless file_accessor.license || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
warning "Unable to find a license file"
if consumer.spec.root?
unless file_accessor.license || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
warning "Unable to find a license file"
end
end
end
......@@ -392,9 +451,10 @@ module Pod
end
# @return [String] Executes xcodebuild in the current working directory and
# returns its output (bot STDOUT and STDERR).
# returns its output (both STDOUT and STDERR).
#
def xcodebuild
UI.puts 'xcodebuild clean build -target Pods' if config.verbose?
`xcodebuild clean build -target Pods 2>&1`
end
......
Subproject commit 05902614470a36022b0eb7854641191fd3971254
Subproject commit 9ff0ddd87c25f7357a70e8863cef47b0e2557eca
This is a Bazaar control directory.
Do not change any files in this directory.
See http://bazaar.canonical.com/ for more information about Bazaar.
Bazaar-NG meta directory, format 1
Bazaar Branch Format 7 (needs bzr 1.6)
2 fred@sharpnoodles.com-20131030202140-gg5dfrrtaotfxlrh
Bazaar Working Tree Format 6 (bzr 1.14)
Bazaar repository format 2a (needs bzr 1.16 or later)
B+Tree Graph Index 2
node_ref_lists=1
key_elements=1
len=1
row_lengths=1
xQ
;0޺tK-R4n?'oCwK;l-W.6l
"ǰ^c:BMF@,B
\ No newline at end of file
B+Tree Graph Index 2
node_ref_lists=0
key_elements=1
len=0
row_lengths=
B+Tree Graph Index 2
node_ref_lists=1
key_elements=2
len=3
row_lengths=1
xM0@a֜ Lg ԅ71P,ȏ-+M W'ܦ5CH>xi& ("ükA boax{oļ#PB][а^IR`2
4i,FE;;t
"tJ57sL :*7}v e
\ No newline at end of file
B+Tree Graph Index 2
node_ref_lists=0
key_elements=1
len=1
row_lengths=1
x PLZ
8'@8x0ы&V|6Hcr7eyhZCbr"&s?-
\ No newline at end of file
B+Tree Graph Index 2
node_ref_lists=0
key_elements=1
len=0
row_lengths=
Pod::Spec.new do |s|
s.name = "BazaarSource"
s.version = "0.0.1"
s.summary = "A short description of BazaarSource."
s.homepage = "http://EXAMPLE/BazaarSource"
s.license = 'MIT (example)'
s.author = { "Fred McCann" => "fred@sharpnoodles.com" }
s.source = { :git => "http://EXAMPLE/BazaarSource.git", :tag => "0.0.1" }
s.source_files = 'Classes', 'Classes/**/*.{h,m}'
end
Subproject commit 90e5fbce17d66e5341f105c1eb26133a01686838
Subproject commit 65a8282c0b5a6f84bc6266d73bbe7475ef75659d
Subproject commit 287a78804972c1c4ce41d9e2771e4beb63764a16
[ui]
username = Eloy Duran <eloy.de.enige@gmail.com>
Removed comments.
\ No newline at end of file
data/MercurialSource.podspec.i
data/README.i
1 3d2759856083e6dbb5b5d0b702aa625b5b21a10a
Pod::Spec.new do |s|
s.name = "MercurialSource"
s.version = "0.0.1"
s.summary = "A short description of MercurialSource."
s.homepage = "http://EXAMPLE/MercurialSource"
s.license = 'MIT (example)'
s.author = { "Dan Cutting" => "dcutting@gmail.com" }
s.source = { :git => "http://EXAMPLE/MercurialSource.git", :tag => "0.0.1" }
s.source_files = 'Classes', 'Classes/**/*.{h,m}'
end
Subproject commit ee564d9da8878957e7b77cac987d9601eb04eca5
Subproject commit b0f4e85738f1f911e32e2914b39e9acdce7c7ed9
......@@ -18,11 +18,4 @@ Pod::Spec.new do |s|
:file => 'LICENSE',
:text => 'Permission is hereby granted ...'
}
s.documentation = {
:html => 'http://banana-corp.local/banana-lib/docs.html',
:appledoc => [
'--project-company', 'Banana Corp',
'--company-id', 'com.banana',
]
}
end
This is a Subversion repository; use the 'svnadmin' tool to examine
it. Do not add, delete, or modify files here unless you know how
to avoid corrupting the repository.
Visit http://subversion.tigris.org/ for more information.
### This file is an example authorization file for svnserve.
### Its format is identical to that of mod_authz_svn authorization
### files.
### As shown below each section defines authorizations for the path and
### (optional) repository specified by the section name.
### The authorizations follow. An authorization line can refer to:
### - a single user,
### - a group of users defined in a special [groups] section,
### - an alias defined in a special [aliases] section,
### - all authenticated users, using the '$authenticated' token,
### - only anonymous users, using the '$anonymous' token,
### - anyone, using the '*' wildcard.
###
### A match can be inverted by prefixing the rule with '~'. Rules can
### grant read ('r') access, read-write ('rw') access, or no access
### ('').
[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average
[groups]
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe
# [/foo/bar]
# harry = rw
# &joe = r
# * =
# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r
### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.
[users]
# harry = harryssecret
# sally = sallyssecret
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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