cocoapods 0.39.0 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +261 -12
  3. data/lib/cocoapods.rb +1 -0
  4. data/lib/cocoapods/command.rb +1 -0
  5. data/lib/cocoapods/command/env.rb +66 -0
  6. data/lib/cocoapods/command/init.rb +1 -1
  7. data/lib/cocoapods/command/lib.rb +1 -1
  8. data/lib/cocoapods/command/project.rb +0 -4
  9. data/lib/cocoapods/command/repo/lint.rb +7 -6
  10. data/lib/cocoapods/command/repo/push.rb +22 -1
  11. data/lib/cocoapods/command/setup.rb +0 -24
  12. data/lib/cocoapods/command/spec/create.rb +3 -1
  13. data/lib/cocoapods/command/spec/edit.rb +14 -21
  14. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  15. data/lib/cocoapods/command/spec/lint.rb +1 -1
  16. data/lib/cocoapods/config.rb +1 -34
  17. data/lib/cocoapods/downloader.rb +9 -4
  18. data/lib/cocoapods/external_sources.rb +0 -4
  19. data/lib/cocoapods/external_sources/abstract_external_source.rb +38 -11
  20. data/lib/cocoapods/external_sources/path_source.rb +2 -2
  21. data/lib/cocoapods/gem_version.rb +2 -2
  22. data/lib/cocoapods/generator/acknowledgements.rb +1 -1
  23. data/lib/cocoapods/generator/acknowledgements/plist.rb +1 -1
  24. data/lib/cocoapods/generator/copy_resources_script.rb +28 -21
  25. data/lib/cocoapods/generator/info_plist_file.rb +34 -8
  26. data/lib/cocoapods/generator/module_map.rb +3 -18
  27. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +22 -10
  28. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +2 -1
  29. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +2 -1
  30. data/lib/cocoapods/hooks_manager.rb +3 -11
  31. data/lib/cocoapods/installer.rb +45 -25
  32. data/lib/cocoapods/installer/analyzer.rb +53 -25
  33. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +2 -13
  34. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +4 -0
  35. data/lib/cocoapods/installer/analyzer/target_inspector.rb +22 -19
  36. data/lib/cocoapods/installer/file_references_installer.rb +53 -6
  37. data/lib/cocoapods/installer/installation_options.rb +156 -0
  38. data/lib/cocoapods/installer/migrator.rb +1 -56
  39. data/lib/cocoapods/installer/pod_source_installer.rb +10 -8
  40. data/lib/cocoapods/installer/podfile_validator.rb +42 -1
  41. data/lib/cocoapods/installer/post_install_hooks_context.rb +19 -2
  42. data/lib/cocoapods/installer/target_installer.rb +6 -2
  43. data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +6 -5
  44. data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +82 -14
  45. data/lib/cocoapods/installer/user_project_integrator.rb +37 -16
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +14 -136
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +15 -22
  48. data/lib/cocoapods/project.rb +109 -19
  49. data/lib/cocoapods/resolver.rb +17 -15
  50. data/lib/cocoapods/resolver/lazy_specification.rb +4 -0
  51. data/lib/cocoapods/sandbox.rb +0 -32
  52. data/lib/cocoapods/sandbox/headers_store.rb +2 -2
  53. data/lib/cocoapods/sandbox/podspec_finder.rb +1 -1
  54. data/lib/cocoapods/sources_manager.rb +181 -50
  55. data/lib/cocoapods/target/aggregate_target.rb +17 -11
  56. data/lib/cocoapods/target/pod_target.rb +31 -4
  57. data/lib/cocoapods/user_interface.rb +32 -3
  58. data/lib/cocoapods/user_interface/error_report.rb +46 -36
  59. data/lib/cocoapods/validator.rb +132 -43
  60. metadata +164 -79
@@ -62,7 +62,7 @@ module Pod
62
62
  # use_frameworks!
63
63
  PLATFORM
64
64
 
65
- project.targets.each do |target|
65
+ project.native_targets.each do |target|
66
66
  podfile << target_module(target)
67
67
  end
68
68
  podfile << "\n"
@@ -164,7 +164,7 @@ module Pod
164
164
  validator.validate
165
165
 
166
166
  unless @clean
167
- UI.puts "Pods project available at `#{validator.validation_dir}/Pods/Pods.xcodeproj` for inspection."
167
+ UI.puts "Pods workspace available at `#{validator.validation_dir}/App.xcworkspace` for inspection."
168
168
  UI.puts
169
169
  end
170
170
  if validator.validated?
@@ -39,8 +39,6 @@ module Pod
39
39
  module Options
40
40
  def options
41
41
  [
42
- ['--no-clean', 'Leave SCM dirs like `.git` and `.svn` intact after downloading'],
43
- ['--no-integrate', 'Skip integration of the Pods libraries in the Xcode project(s)'],
44
42
  ['--no-repo-update', 'Skip running `pod repo update` before install'],
45
43
  ].concat(super)
46
44
  end
@@ -51,8 +49,6 @@ module Pod
51
49
  end
52
50
 
53
51
  def initialize(argv)
54
- config.clean = argv.flag?('clean', config.clean)
55
- config.integrate_targets = argv.flag?('integrate', config.integrate_targets)
56
52
  config.skip_repo_update = !argv.flag?('repo-update', !config.skip_repo_update)
57
53
  super
58
54
  end
@@ -35,15 +35,16 @@ module Pod
35
35
  #
36
36
  def run
37
37
  if @name
38
- dirs = File.exist?(@name) ? [Pathname.new(@name)] : [dir]
38
+ sources = SourcesManager.sources([@name])
39
39
  else
40
- dirs = config.repos_dir.children.select(&:directory?)
40
+ sources = SourcesManager.aggregate.sources
41
41
  end
42
- dirs.each do |dir|
43
- SourcesManager.check_version_information(dir)
44
- UI.puts "\nLinting spec repo `#{dir.realpath.basename}`\n".yellow
45
42
 
46
- validator = Source::HealthReporter.new(dir)
43
+ sources.each do |source|
44
+ SourcesManager.check_version_information(source.repo)
45
+ UI.puts "\nLinting spec repo `#{source.repo.basename}`\n".yellow
46
+
47
+ validator = Source::HealthReporter.new(source.repo)
47
48
  validator.pre_check do |_name, _version|
48
49
  UI.print '.'
49
50
  end
@@ -1,3 +1,4 @@
1
+ require 'tempfile'
1
2
  require 'fileutils'
2
3
  require 'active_support/core_ext/string/inflections'
3
4
 
@@ -28,6 +29,8 @@ module Pod
28
29
  'Multiple sources must be comma-delimited.'],
29
30
  ['--local-only', 'Does not perform the step of pushing REPO to its remote'],
30
31
  ['--no-private', 'Lint includes checks that apply only to public repos'],
32
+ ['--commit-message="Fix bug in pod"', 'Add custom commit message. ' \
33
+ 'Opens default editor if no commit message is specified.'],
31
34
  ].concat(super)
32
35
  end
33
36
 
@@ -39,6 +42,8 @@ module Pod
39
42
  @podspec = argv.shift_argument
40
43
  @use_frameworks = !argv.flag?('use-libraries')
41
44
  @private = argv.flag?('private', true)
45
+ @message = argv.option('commit-message')
46
+ @commit_message = argv.flag?('commit-message', false)
42
47
  super
43
48
  end
44
49
 
@@ -48,6 +53,7 @@ module Pod
48
53
  end
49
54
 
50
55
  def run
56
+ open_editor if @commit_message && @message.nil?
51
57
  check_if_master_repo
52
58
  validate_podspec_files
53
59
  check_repo_status
@@ -65,6 +71,19 @@ module Pod
65
71
  extend Executable
66
72
  executable :git
67
73
 
74
+ # Open default editor to allow users to enter commit message
75
+ #
76
+ def open_editor
77
+ return if ENV['EDITOR'].nil?
78
+
79
+ file = Tempfile.new('cocoapods')
80
+ File.chmod(0777, file.path)
81
+ file.close
82
+
83
+ system("#{ENV['EDITOR']} #{file.path}")
84
+ @message = File.read file.path
85
+ end
86
+
68
87
  # Temporary check to ensure that users do not push accidentally private
69
88
  # specs to the master repo.
70
89
  #
@@ -143,7 +162,9 @@ module Pod
143
162
  podspec_files.each do |spec_file|
144
163
  spec = Pod::Specification.from_file(spec_file)
145
164
  output_path = File.join(repo_dir, spec.name, spec.version.to_s)
146
- if Pathname.new(output_path).exist?
165
+ if @message && !@message.empty?
166
+ message = @message
167
+ elsif Pathname.new(output_path).exist?
147
168
  message = "[Fix] #{spec}"
148
169
  elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
149
170
  message = "[Update] #{spec}"
@@ -34,8 +34,6 @@ module Pod
34
34
  set_master_repo_url
35
35
  set_master_repo_branch
36
36
  update_master_repo
37
- elsif old_master_repo_dir.exist?
38
- migrate_repos
39
37
  else
40
38
  add_master_repo
41
39
  end
@@ -48,22 +46,6 @@ module Pod
48
46
 
49
47
  # @!group Setup steps
50
48
 
51
- # Migrates any repos from the old directory structure to the new
52
- # directory structure.
53
- #
54
- # @todo: Remove by 1.0
55
- #
56
- def migrate_repos
57
- config.repos_dir.mkpath
58
- Dir.foreach old_master_repo_dir.parent do |repo_dir|
59
- source_repo_dir = old_master_repo_dir.parent + repo_dir
60
- target_repo_dir = config.repos_dir + repo_dir
61
- if repo_dir !~ /\.+/ && source_repo_dir != config.repos_dir
62
- FileUtils.mv source_repo_dir, target_repo_dir
63
- end
64
- end
65
- end
66
-
67
49
  # Sets the url of the master repo according to whether it is push.
68
50
  #
69
51
  # @return [void]
@@ -127,12 +109,6 @@ module Pod
127
109
  def master_repo_dir
128
110
  SourcesManager.master_repo_dir
129
111
  end
130
-
131
- # @return [Pathname] the directory of the old master repo.
132
- #
133
- def old_master_repo_dir
134
- Pathname.new('~/.cocoapods/master').expand_path
135
- end
136
112
  end
137
113
  end
138
114
  end
@@ -60,7 +60,7 @@ module Pod
60
60
  data[:author_email] = `git config --get user.email`.strip
61
61
  data[:source_url] = "http://EXAMPLE/#{name}.git"
62
62
  data[:ref_type] = ':tag'
63
- data[:ref] = '0.0.1'
63
+ data[:ref] = '#{s.version}'
64
64
  data
65
65
  end
66
66
 
@@ -100,6 +100,8 @@ module Pod
100
100
  else
101
101
  data[:ref_type] = ':tag'
102
102
  data[:ref] = versions_tags[version]
103
+ data[:ref] = '#{s.version}' if "#{version}" == versions_tags[version]
104
+ data[:ref] = 'v#{s.version}' if "v#{version}" == versions_tags[version]
103
105
  end
104
106
  data
105
107
  end
@@ -48,32 +48,25 @@ module Pod
48
48
  raise Informative, "#{filepath} doesn't exist."
49
49
  end
50
50
 
51
- # Looks up an executable in the search paths
52
- #
53
- # @note
54
- # Thank you homebrew
55
- #
56
- # @param [String] cmd
57
- # the executable to look up
58
- #
59
- def which(cmd)
60
- dir = ENV['PATH'].split(':').find { |p| File.executable? File.join(p, cmd) }
61
- Pathname.new(File.join(dir, cmd)) unless dir.nil?
62
- end
63
-
64
51
  def which_editor
65
52
  editor = ENV['EDITOR']
66
53
  # If an editor wasn't set, try to pick a sane default
67
54
  return editor unless editor.nil?
68
55
 
69
- # Find Sublime Text 2
70
- return 'subl' if which 'subl'
71
- # Find Textmate
72
- return 'mate' if which 'mate'
73
- # Find # BBEdit / TextWrangler
74
- return 'edit' if which 'edit'
75
- # Default to vim
76
- return 'vim' if which 'vim'
56
+ editors = [
57
+ # Find Sublime Text 2
58
+ 'subl',
59
+ # Find Textmate
60
+ 'mate',
61
+ # Find BBEdit / TextWrangler
62
+ 'edit',
63
+ # Find Atom
64
+ 'atom',
65
+ # Default to vim
66
+ 'vim',
67
+ ]
68
+ editor = editors.find { |e| Pod::Executable.which(e) }
69
+ return editor if editor
77
70
 
78
71
  raise Informative, "Failed to open editor. Set your 'EDITOR' environment variable."
79
72
  end
@@ -0,0 +1,53 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::Env do
5
+ describe 'In general' do
6
+ before do
7
+ @report = Command::Env
8
+ end
9
+
10
+ it 'returns a well-structured environment report' do
11
+ expected = <<-EOS
12
+
13
+ ### Stack
14
+
15
+ ```
16
+ CocoaPods : #{Pod::VERSION}
17
+ Ruby : #{RUBY_DESCRIPTION}
18
+ RubyGems : #{Gem::VERSION}
19
+ Host : :host_information
20
+ Xcode : :xcode_information
21
+ Git : :git_information
22
+ Ruby lib dir : #{RbConfig::CONFIG['libdir']}
23
+ Repositories : repo_1
24
+ repo_2
25
+ ```
26
+
27
+ ### Installation Source
28
+
29
+ ```
30
+ Executable Path: /usr/bin/command
31
+ ```
32
+
33
+ ### Plugins
34
+
35
+ ```
36
+ cocoapods : #{Pod::VERSION}
37
+ cocoapods-core : #{Pod::VERSION}
38
+ cocoapods-plugins : 1.2.3
39
+ ```
40
+
41
+ ### Podfile
42
+
43
+ ```ruby
44
+
45
+ ```
46
+ EOS
47
+
48
+ @report.stubs(:actual_path).returns('/usr/bin/command')
49
+ report.should == expected
50
+ end
51
+ end
52
+ end
53
+ end
@@ -61,7 +61,7 @@ module Pod
61
61
  failure_reasons << validator.failure_reason
62
62
 
63
63
  unless @clean
64
- UI.puts "Pods project available at `#{validator.validation_dir}/Pods/Pods.xcodeproj` for inspection."
64
+ UI.puts "Pods workspace available at `#{validator.validation_dir}/App.xcworkspace` for inspection."
65
65
  UI.puts
66
66
  end
67
67
  end
@@ -17,11 +17,6 @@ module Pod
17
17
  :skip_repo_update => false,
18
18
  :skip_download_cache => !ENV['COCOAPODS_SKIP_CACHE'].nil?,
19
19
 
20
- :clean => true,
21
- :integrate_targets => true,
22
- :deduplicate_targets => true,
23
- :deterministic_uuids => ENV['COCOAPODS_DISABLE_DETERMINISTIC_UUIDS'].nil?,
24
- :lock_pod_source => true,
25
20
  :new_version_message => ENV['COCOAPODS_SKIP_UPDATE_MESSAGE'].nil?,
26
21
 
27
22
  :cache_root => Pathname.new(Dir.home) + 'Library/Caches/CocoaPods',
@@ -74,34 +69,6 @@ module Pod
74
69
 
75
70
  # @!group Installation
76
71
 
77
- # @return [Bool] Whether the installer should clean after the installation.
78
- #
79
- attr_accessor :clean
80
- alias_method :clean?, :clean
81
-
82
- # @return [Bool] Whether the installer should remove write permissions for
83
- # installed pod source files after the installation.
84
- #
85
- attr_accessor :lock_pod_source
86
- alias_method :lock_pod_source?, :lock_pod_source
87
-
88
- # @return [Bool] Whether CocoaPods should integrate a user target and build
89
- # the workspace or just create the Pods project.
90
- #
91
- attr_accessor :integrate_targets
92
- alias_method :integrate_targets?, :integrate_targets
93
-
94
- # @return [Bool] Whether CocoaPods should deduplicate pod targets.
95
- #
96
- attr_accessor :deduplicate_targets
97
- alias_method :deduplicate_targets?, :deduplicate_targets
98
-
99
- # @return [Bool] Whether CocoaPods should give the pods project
100
- # deterministic UUIDs.
101
- #
102
- attr_accessor :deterministic_uuids
103
- alias_method :deterministic_uuids?, :deterministic_uuids
104
-
105
72
  # @return [Bool] Whether the installer should skip the repos update.
106
73
  #
107
74
  attr_accessor :skip_repo_update
@@ -274,7 +241,7 @@ module Pod
274
241
  # @return [Pathname] The file to use to cache the search data.
275
242
  #
276
243
  def search_index_file
277
- cache_root + 'search_index.yaml'
244
+ cache_root + 'search_index.json'
278
245
  end
279
246
 
280
247
  private
@@ -20,16 +20,21 @@ module Pod
20
20
  # the location to which this pod should be downloaded. If `nil`,
21
21
  # then the pod will only be cached.
22
22
  #
23
+ # @param [Boolean] can_cache
24
+ # whether caching is allowed.
25
+ #
23
26
  # @param [Pathname,Nil] cache_path
24
- # the path used to cache pod downloads. If `nil`, then no caching
25
- # will be done.
27
+ # the path used to cache pod downloads.
26
28
  #
27
29
  def self.download(
28
30
  request,
29
31
  target,
30
- cache_path: !Config.instance.skip_download_cache && Config.instance.clean? && Config.instance.cache_root + 'Pods'
32
+ can_cache: true,
33
+ cache_path: Config.instance.cache_root + 'Pods'
31
34
  )
32
- if cache_path
35
+ can_cache &&= !Config.instance.skip_download_cache
36
+ if can_cache
37
+ raise ArgumentError, 'Must provide a `cache_path` when caching.' unless cache_path
33
38
  cache = Cache.new(cache_path)
34
39
  result = cache.download_pod(request)
35
40
  else
@@ -46,10 +46,6 @@ module Pod
46
46
  PodspecSource
47
47
  elsif params.key?(:path)
48
48
  PathSource
49
- elsif params.key?(:local)
50
- UI.warn 'The `:local` option of the Podfile has been ' \
51
- 'renamed to `:path` and it is deprecated.'
52
- PathSource
53
49
  elsif Downloader.strategy_from_options(params)
54
50
  DownloaderSource
55
51
  end
@@ -17,6 +17,11 @@ module Pod
17
17
  #
18
18
  attr_reader :podfile_path
19
19
 
20
+ # @return [Boolean] Whether the source is allowed to touch the cache.
21
+ #
22
+ attr_accessor :can_cache
23
+ alias_method :can_cache?, :can_cache
24
+
20
25
  # Initialize a new instance
21
26
  #
22
27
  # @param [String] name @see name
@@ -27,6 +32,7 @@ module Pod
27
32
  @name = name
28
33
  @params = params
29
34
  @podfile_path = podfile_path
35
+ @can_cache = true
30
36
  end
31
37
 
32
38
  # @return [Bool] whether an external source source is equal to another
@@ -105,7 +111,7 @@ module Pod
105
111
  title = "Pre-downloading: `#{name}` #{description}"
106
112
  UI.titled_section(title, :verbose_prefix => '-> ') do
107
113
  target = sandbox.pod_dir(name)
108
- download_result = Downloader.download(download_request, target)
114
+ download_result = Downloader.download(download_request, target, :can_cache => can_cache)
109
115
  spec = download_result.spec
110
116
 
111
117
  raise Informative, "Unable to find a specification for '#{name}'." unless spec
@@ -141,17 +147,38 @@ module Pod
141
147
  # @return [void]
142
148
  #
143
149
  def store_podspec(sandbox, spec, json = false)
144
- if spec.is_a? Pathname
145
- spec = Specification.from_file(spec).to_pretty_json
146
- json = true
147
- elsif spec.is_a?(String) && !json
148
- spec = Specification.from_string(spec, 'spec.podspec').to_pretty_json
149
- json = true
150
- elsif spec.is_a?(Specification)
151
- spec = spec.to_pretty_json
152
- json = true
150
+ spec = case spec
151
+ when Pathname
152
+ Specification.from_file(spec)
153
+ when String
154
+ path = "#{name}.podspec"
155
+ path << '.json' if json
156
+ Specification.from_string(spec, path)
157
+ when Specification
158
+ spec.dup
159
+ else
160
+ raise "Unknown spec type: #{spec}"
161
+ end
162
+ spec.defined_in_file = nil
163
+ validate_podspec(spec)
164
+ sandbox.store_podspec(name, spec.to_pretty_json, true, true)
165
+ end
166
+
167
+ def validate_podspec(podspec)
168
+ validator = validator_for_podspec(podspec)
169
+ validator.quick = true
170
+ validator.allow_warnings = true
171
+ validator.ignore_public_only_results = true
172
+ Config.instance.with_changes(:silent => true) do
173
+ validator.validate
174
+ end
175
+ unless validator.validated?
176
+ raise Informative, "The `#{name}` pod failed to validate due to #{validator.failure_reason}:\n#{validator.results_message}"
153
177
  end
154
- sandbox.store_podspec(name, spec, true, json)
178
+ end
179
+
180
+ def validator_for_podspec(podspec)
181
+ Validator.new(podspec, [])
155
182
  end
156
183
  end
157
184
  end