cocoapods 0.5.1 → 0.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.md +229 -2
  2. data/README.md +50 -20
  3. data/bin/pod +3 -2
  4. data/lib/cocoapods.rb +23 -9
  5. data/lib/cocoapods/command.rb +71 -30
  6. data/lib/cocoapods/command/error_report.rb +102 -0
  7. data/lib/cocoapods/command/install.rb +27 -19
  8. data/lib/cocoapods/command/list.rb +51 -8
  9. data/lib/cocoapods/command/presenter.rb +61 -0
  10. data/lib/cocoapods/command/presenter/cocoa_pod.rb +123 -0
  11. data/lib/cocoapods/command/push.rb +102 -0
  12. data/lib/cocoapods/command/repo.rb +70 -14
  13. data/lib/cocoapods/command/search.rb +7 -10
  14. data/lib/cocoapods/command/setup.rb +76 -15
  15. data/lib/cocoapods/command/spec.rb +581 -97
  16. data/lib/cocoapods/config.rb +23 -26
  17. data/lib/cocoapods/dependency.rb +86 -40
  18. data/lib/cocoapods/downloader.rb +30 -18
  19. data/lib/cocoapods/downloader/git.rb +125 -15
  20. data/lib/cocoapods/downloader/http.rb +73 -0
  21. data/lib/cocoapods/downloader/mercurial.rb +3 -9
  22. data/lib/cocoapods/downloader/subversion.rb +3 -9
  23. data/lib/cocoapods/executable.rb +26 -3
  24. data/lib/cocoapods/generator/acknowledgements.rb +37 -0
  25. data/lib/cocoapods/generator/acknowledgements/markdown.rb +38 -0
  26. data/lib/cocoapods/generator/acknowledgements/plist.rb +63 -0
  27. data/lib/cocoapods/generator/copy_resources_script.rb +8 -4
  28. data/lib/cocoapods/generator/documentation.rb +99 -0
  29. data/lib/cocoapods/generator/dummy_source.rb +14 -0
  30. data/lib/cocoapods/installer.rb +140 -109
  31. data/lib/cocoapods/installer/target_installer.rb +78 -83
  32. data/lib/cocoapods/installer/user_project_integrator.rb +162 -0
  33. data/lib/cocoapods/local_pod.rb +240 -0
  34. data/lib/cocoapods/platform.rb +41 -18
  35. data/lib/cocoapods/podfile.rb +234 -21
  36. data/lib/cocoapods/project.rb +67 -0
  37. data/lib/cocoapods/resolver.rb +62 -32
  38. data/lib/cocoapods/sandbox.rb +63 -0
  39. data/lib/cocoapods/source.rb +42 -20
  40. data/lib/cocoapods/specification.rb +294 -271
  41. data/lib/cocoapods/specification/set.rb +10 -28
  42. data/lib/cocoapods/specification/statistics.rb +112 -0
  43. metadata +124 -11
  44. data/lib/cocoapods/xcodeproj_pods.rb +0 -111
@@ -0,0 +1,73 @@
1
+ require 'open-uri'
2
+ require 'tempfile'
3
+ require 'zlib'
4
+ require 'yaml'
5
+
6
+ module Pod
7
+ class Downloader
8
+ class Http < Downloader
9
+ class UnsupportedFileTypeError < StandardError; end
10
+
11
+ executable :curl
12
+ executable :unzip
13
+ executable :tar
14
+
15
+ attr_accessor :filename, :download_path
16
+ def download
17
+ @filename = filename_with_type type
18
+ @download_path = target_path + @filename
19
+
20
+ download_file @download_path
21
+ extract_with_type @download_path, type
22
+ end
23
+
24
+ def type
25
+ options[:type] || type_with_url(url)
26
+ end
27
+
28
+ private
29
+ def type_with_url(url)
30
+ if url =~ /.zip$/
31
+ :zip
32
+ elsif url =~ /.tgz$/
33
+ :tgz
34
+ elsif url =~ /.tar$/
35
+ :tar
36
+ else
37
+ nil
38
+ end
39
+ end
40
+
41
+ def filename_with_type(type=:zip)
42
+ case type
43
+ when :zip
44
+ "file.zip"
45
+ when :tgz
46
+ "file.tgz"
47
+ when :tar
48
+ "file.tar"
49
+ else
50
+ raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
51
+ end
52
+ end
53
+
54
+ def download_file(full_filename)
55
+ curl "-L -o '#{full_filename}' '#{url}'"
56
+ end
57
+
58
+ def extract_with_type(full_filename, type=:zip)
59
+ case type
60
+ when :zip
61
+ unzip "'#{full_filename}' -d #{target_path}"
62
+ when :tgz
63
+ tar "xfz '#{full_filename}' -C #{target_path}"
64
+ when :tar
65
+ tar "xf '#{full_filename}' -C #{target_path}"
66
+ else
67
+ raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -4,8 +4,7 @@ module Pod
4
4
  executable :hg
5
5
 
6
6
  def download
7
- @pod_root.dirname.mkpath
8
- if @options[:revision]
7
+ if options[:revision]
9
8
  download_revision
10
9
  else
11
10
  download_head
@@ -13,16 +12,11 @@ module Pod
13
12
  end
14
13
 
15
14
  def download_head
16
- hg "clone '#{@url}' '#{@pod_root}'"
15
+ hg "clone '#{url}' '#{target_path}'"
17
16
  end
18
17
 
19
18
  def download_revision
20
- hg "clone '#{@url}' --rev '#{@options[:revision]}' '#{@pod_root}'"
21
- end
22
-
23
- def clean(clean_paths = [])
24
- super
25
- (@pod_root + '.hg').rmtree
19
+ hg "clone '#{url}' --rev '#{options[:revision]}' '#{target_path}'"
26
20
  end
27
21
  end
28
22
  end
@@ -4,8 +4,7 @@ module Pod
4
4
  executable :svn
5
5
 
6
6
  def download
7
- @pod_root.dirname.mkpath
8
- if @options[:revision]
7
+ if options[:revision]
9
8
  download_revision
10
9
  else
11
10
  download_head
@@ -13,16 +12,11 @@ module Pod
13
12
  end
14
13
 
15
14
  def download_head
16
- svn "checkout '#{@url}' '#{@pod_root}'"
15
+ svn "checkout '#{url}' '#{target_path}'"
17
16
  end
18
17
 
19
18
  def download_revision
20
- svn "checkout '#{@url}' -r '#{@options[:revision]}' '#{@pod_root}'"
21
- end
22
-
23
- def clean(clean_paths = [])
24
- super
25
- @pod_root.glob('**/.svn').each(&:rmtree)
19
+ svn "checkout '#{url}' -r '#{options[:revision]}' '#{target_path}'"
26
20
  end
27
21
  end
28
22
  end
@@ -1,17 +1,40 @@
1
+ require 'open4'
2
+
1
3
  module Pod
2
4
  module Executable
5
+ class Indenter < ::Array
6
+ attr_accessor :indent
7
+ attr_accessor :io
8
+
9
+ def initialize(io = nil, indent = ' ')
10
+ @io = io
11
+ @indent = indent
12
+ end
13
+
14
+ def <<(value)
15
+ super
16
+ ensure
17
+ @io << "#{ indent }#{ value }" if @io
18
+ end
19
+ end
20
+
3
21
  def executable(name)
4
22
  bin = `which #{name}`.strip
5
23
  define_method(name) do |command|
6
24
  if bin.empty?
7
25
  raise Informative, "Unable to locate the executable `#{name}'"
8
26
  end
27
+ full_command = "#{bin} #{command}"
9
28
  if Config.instance.verbose?
10
- puts "#{bin} #{command}"
11
- `#{bin} #{command} 1>&2`
29
+ puts " $ #{full_command}"
30
+ stdout, stderr = Indenter.new(STDOUT), Indenter.new(STDERR)
12
31
  else
13
- `#{bin} #{command} 2> /dev/null`
32
+ stdout, stderr = Indenter.new, Indenter.new
14
33
  end
34
+ status = Open4.spawn(full_command, :stdout => stdout, :stderr => stderr, :status => true)
35
+ # TODO not sure that we should be silent in case of a failure.
36
+ puts (Config.instance.verbose? ? ' ' : '') << "[!] Failed: #{full_command}".red unless status.success? || Config.instance.silent?
37
+ stdout.join("\n") + stderr.join("\n") # TODO will this suffice?
15
38
  end
16
39
  private name
17
40
  end
@@ -0,0 +1,37 @@
1
+ module Pod
2
+ module Generator
3
+
4
+ class Acknowledgements
5
+
6
+ def self.generators
7
+ [Plist, Markdown]
8
+ end
9
+
10
+ def initialize(target_definition, pods)
11
+ @target_definition, @pods = target_definition, pods
12
+ end
13
+
14
+ def save_as(path)
15
+ Acknowledgements.generators.each do |generator|
16
+ generator.new(@target_definition, @pods).save_as(path)
17
+ end
18
+ end
19
+
20
+ def header_title
21
+ "Acknowledgements"
22
+ end
23
+
24
+ def header_text
25
+ "This application makes use of the following third party libraries:"
26
+ end
27
+
28
+ def footnote_title
29
+ ""
30
+ end
31
+
32
+ def footnote_text
33
+ "Generated by CocoaPods - http://cocoapods.org"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ module Pod
2
+ module Generator
3
+
4
+ class Markdown < Acknowledgements
5
+
6
+ def save_as(path)
7
+ if (path.extname != ".markdown")
8
+ path = Pathname.new(path.dirname + "#{path.basename.to_s}.markdown")
9
+ end
10
+ file = File.new(path, "w")
11
+ file.write(licenses)
12
+ file.close
13
+ end
14
+
15
+ def title_from_string(string, level)
16
+ if !string.empty?
17
+ "#" * level << " #{string}"
18
+ end
19
+ end
20
+
21
+ def string_for_pod(pod)
22
+ if (license_text = pod.license_text)
23
+ "\n" << title_from_string(pod.name, 2) << "\n\n" << license_text << "\n"
24
+ end
25
+ end
26
+
27
+ def licenses
28
+ licenses_string = "#{title_from_string(header_title, 1)}\n#{header_text}\n"
29
+ @pods.each do |pod|
30
+ if (license = string_for_pod(pod))
31
+ licenses_string += license
32
+ end
33
+ end
34
+ licenses_string += "#{title_from_string(footnote_title, 2)}#{footnote_text}\n"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ module Pod
2
+ module Generator
3
+
4
+ class Plist < Acknowledgements
5
+ require "xcodeproj/xcodeproj_ext"
6
+
7
+ def save_as(path)
8
+ if (path.extname != ".plist")
9
+ path = Pathname.new(path.dirname + "#{path.basename.to_s}.plist")
10
+ end
11
+ Xcodeproj.write_plist(plist, path)
12
+ end
13
+
14
+ def plist
15
+ {
16
+ :Title => plist_title,
17
+ :StringsTable => plist_title,
18
+ :PreferenceSpecifiers => licenses
19
+ }
20
+ end
21
+
22
+ def plist_title
23
+ "Acknowledgements"
24
+ end
25
+
26
+ def licenses
27
+ licences_array = [header_hash]
28
+ @pods.each do |pod|
29
+ if (hash = hash_for_pod(pod))
30
+ licences_array << hash
31
+ end
32
+ end
33
+ licences_array << footnote_hash
34
+ end
35
+
36
+ def hash_for_pod(pod)
37
+ if (license = pod.license_text)
38
+ {
39
+ :Type => "PSGroupSpecifier",
40
+ :Title => pod.name,
41
+ :FooterText => license
42
+ }
43
+ end
44
+ end
45
+
46
+ def header_hash
47
+ {
48
+ :Type => "PSGroupSpecifier",
49
+ :Title => header_title,
50
+ :FooterText => header_text
51
+ }
52
+ end
53
+
54
+ def footnote_hash
55
+ {
56
+ :Type => "PSGroupSpecifier",
57
+ :Title => footnote_title,
58
+ :FooterText => footnote_text
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
@@ -7,13 +7,17 @@ module Pod
7
7
  install_resource()
8
8
  {
9
9
  case $1 in
10
+ *\.storyboard)
11
+ echo "ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
12
+ ibtool --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
13
+ ;;
10
14
  *\.xib)
11
- echo "ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib ${SRCROOT}/Pods/$1 --sdk ${SDKROOT}"
12
- ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename $1 .xib`.nib ${SRCROOT}/Pods/$1 --sdk ${SDKROOT}
15
+ 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}"
16
+ 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}"
13
17
  ;;
14
18
  *)
15
- echo "cp -R ${SRCROOT}/Pods/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
16
- cp -R "${SRCROOT}/Pods/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
19
+ echo "cp -R ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
20
+ cp -R "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
17
21
  ;;
18
22
  esac
19
23
  }
@@ -0,0 +1,99 @@
1
+ require 'escape'
2
+
3
+ module Pod
4
+ module Generator
5
+
6
+ class Documentation
7
+ include Config::Mixin
8
+ extend Executable
9
+
10
+ executable :appledoc
11
+ attr_reader :pod, :specification, :target_path, :options
12
+
13
+ def initialize(pod)
14
+ @pod = pod
15
+ @specification = pod.top_specification
16
+ @target_path = pod.sandbox.root + 'Documentation' + pod.name
17
+ @options = @specification.documentation || {}
18
+ end
19
+
20
+ def name
21
+ @specification.name + ' ' + @specification.version.to_s
22
+ end
23
+
24
+ def company
25
+ if @specification.authors
26
+ @specification.authors.keys.sort.join(', ')
27
+ else
28
+ 'no-company'
29
+ end
30
+ end
31
+
32
+ def copyright
33
+ company
34
+ end
35
+
36
+ def description
37
+ @specification.description || 'Generated by CocoaPods.'
38
+ end
39
+
40
+ def docs_id
41
+ 'org.cocoapods'
42
+ end
43
+
44
+ def files
45
+ @pod.all_specs_public_header_files.map{ |f| f.relative_path_from(@pod.root).to_s }
46
+ end
47
+
48
+ def index_file
49
+ @pod.readme_file.relative_path_from(@pod.root).to_s if @pod.readme_file
50
+ end
51
+
52
+ def spec_appledoc_options
53
+ @options[:appledoc] || []
54
+ end
55
+
56
+ def appledoc_options
57
+ options = [
58
+ '--project-name', name,
59
+ '--docset-desc', description,
60
+ '--project-company', company,
61
+ '--docset-copyright', copyright,
62
+ '--company-id', docs_id,
63
+ '--ignore', '.m',
64
+ '--keep-undocumented-objects',
65
+ '--keep-undocumented-members',
66
+ '--keep-intermediate-files',
67
+ '--exit-threshold', '2' # appledoc terminates with an exits status of 1 if a warning was logged
68
+ ]
69
+ options += ['--index-desc', index_file] if index_file
70
+ options += spec_appledoc_options
71
+ end
72
+
73
+ def already_installed?
74
+ Pathname.new(File.expand_path("~/Library/Developer/Shared/Documentation/DocSets/org.cocoapods.#{name.gsub(/ /,'-')}.docset")).exist?
75
+ end
76
+
77
+ def generate(install = false)
78
+ options = appledoc_options
79
+ options += ['--output', @target_path.to_s]
80
+ options += install ? ['--create-docset'] : ['--no-create-docset']
81
+ # TODO: passing the files explicitly clutters output and chokes on very long list (AWSiOSSDK Spec).
82
+ # It is possible to just pass the dir of the pod, however this would include other files like demo projects.
83
+ options += files
84
+
85
+ @target_path.mkpath
86
+ @pod.chdir do
87
+ appledoc Escape.shell_command(options)
88
+ end
89
+
90
+ if $?.exitstatus != 0
91
+ puts "[!] Appledoc encountered an error (exitstatus: #{$?.exitstatus}), an update might be available to solve the issue." unless config.silent?
92
+ end
93
+
94
+ rescue Informative
95
+ puts "[!] Skipping documentation generation because appledoc can't be found." if config.verbose?
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,14 @@
1
+ module Pod
2
+ module Generator
3
+ class DummySource
4
+ def save_as(pathname)
5
+ pathname.open('w') do |source|
6
+ source.puts "@interface PodsDummy : NSObject"
7
+ source.puts "@end"
8
+ source.puts "@implementation PodsDummy"
9
+ source.puts "@end"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end