xcocoapods 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6303 -0
  3. data/LICENSE +28 -0
  4. data/README.md +80 -0
  5. data/bin/pod +56 -0
  6. data/bin/sandbox-pod +168 -0
  7. data/lib/cocoapods.rb +73 -0
  8. data/lib/cocoapods/command.rb +175 -0
  9. data/lib/cocoapods/command/cache.rb +28 -0
  10. data/lib/cocoapods/command/cache/clean.rb +90 -0
  11. data/lib/cocoapods/command/cache/list.rb +69 -0
  12. data/lib/cocoapods/command/env.rb +66 -0
  13. data/lib/cocoapods/command/init.rb +128 -0
  14. data/lib/cocoapods/command/install.rb +45 -0
  15. data/lib/cocoapods/command/ipc.rb +19 -0
  16. data/lib/cocoapods/command/ipc/list.rb +40 -0
  17. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  18. data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
  19. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  20. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  21. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  22. data/lib/cocoapods/command/lib.rb +11 -0
  23. data/lib/cocoapods/command/lib/create.rb +105 -0
  24. data/lib/cocoapods/command/lib/lint.rb +121 -0
  25. data/lib/cocoapods/command/list.rb +39 -0
  26. data/lib/cocoapods/command/options/project_directory.rb +36 -0
  27. data/lib/cocoapods/command/options/repo_update.rb +34 -0
  28. data/lib/cocoapods/command/outdated.rb +140 -0
  29. data/lib/cocoapods/command/repo.rb +29 -0
  30. data/lib/cocoapods/command/repo/add.rb +103 -0
  31. data/lib/cocoapods/command/repo/lint.rb +82 -0
  32. data/lib/cocoapods/command/repo/list.rb +93 -0
  33. data/lib/cocoapods/command/repo/push.rb +281 -0
  34. data/lib/cocoapods/command/repo/remove.rb +36 -0
  35. data/lib/cocoapods/command/repo/update.rb +28 -0
  36. data/lib/cocoapods/command/setup.rb +103 -0
  37. data/lib/cocoapods/command/spec.rb +112 -0
  38. data/lib/cocoapods/command/spec/cat.rb +51 -0
  39. data/lib/cocoapods/command/spec/create.rb +283 -0
  40. data/lib/cocoapods/command/spec/edit.rb +87 -0
  41. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  42. data/lib/cocoapods/command/spec/lint.rb +137 -0
  43. data/lib/cocoapods/command/spec/which.rb +43 -0
  44. data/lib/cocoapods/command/update.rb +101 -0
  45. data/lib/cocoapods/config.rb +347 -0
  46. data/lib/cocoapods/core_overrides.rb +1 -0
  47. data/lib/cocoapods/downloader.rb +190 -0
  48. data/lib/cocoapods/downloader/cache.rb +233 -0
  49. data/lib/cocoapods/downloader/request.rb +86 -0
  50. data/lib/cocoapods/downloader/response.rb +16 -0
  51. data/lib/cocoapods/executable.rb +222 -0
  52. data/lib/cocoapods/external_sources.rb +57 -0
  53. data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
  54. data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
  55. data/lib/cocoapods/external_sources/path_source.rb +55 -0
  56. data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
  57. data/lib/cocoapods/gem_version.rb +5 -0
  58. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  59. data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
  60. data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
  61. data/lib/cocoapods/generator/app_target_helper.rb +244 -0
  62. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  63. data/lib/cocoapods/generator/constant.rb +19 -0
  64. data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
  65. data/lib/cocoapods/generator/dummy_source.rb +31 -0
  66. data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
  67. data/lib/cocoapods/generator/header.rb +103 -0
  68. data/lib/cocoapods/generator/info_plist_file.rb +116 -0
  69. data/lib/cocoapods/generator/module_map.rb +99 -0
  70. data/lib/cocoapods/generator/prefix_header.rb +60 -0
  71. data/lib/cocoapods/generator/umbrella_header.rb +46 -0
  72. data/lib/cocoapods/hooks_manager.rb +132 -0
  73. data/lib/cocoapods/installer.rb +703 -0
  74. data/lib/cocoapods/installer/analyzer.rb +972 -0
  75. data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
  76. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
  77. data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
  78. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
  79. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  80. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
  81. data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
  82. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
  83. data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
  84. data/lib/cocoapods/installer/installation_options.rb +158 -0
  85. data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
  86. data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
  87. data/lib/cocoapods/installer/podfile_validator.rb +139 -0
  88. data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
  89. data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
  90. data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
  91. data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
  92. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
  93. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
  94. data/lib/cocoapods/installer/xcode.rb +8 -0
  95. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
  96. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
  97. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
  98. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
  99. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
  100. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
  101. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
  102. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
  103. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
  104. data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
  105. data/lib/cocoapods/open-uri.rb +33 -0
  106. data/lib/cocoapods/project.rb +414 -0
  107. data/lib/cocoapods/resolver.rb +585 -0
  108. data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
  109. data/lib/cocoapods/sandbox.rb +404 -0
  110. data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
  111. data/lib/cocoapods/sandbox/headers_store.rb +146 -0
  112. data/lib/cocoapods/sandbox/path_list.rb +220 -0
  113. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
  114. data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
  115. data/lib/cocoapods/sources_manager.rb +157 -0
  116. data/lib/cocoapods/target.rb +261 -0
  117. data/lib/cocoapods/target/aggregate_target.rb +338 -0
  118. data/lib/cocoapods/target/build_settings.rb +1075 -0
  119. data/lib/cocoapods/target/pod_target.rb +559 -0
  120. data/lib/cocoapods/user_interface.rb +459 -0
  121. data/lib/cocoapods/user_interface/error_report.rb +187 -0
  122. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  123. data/lib/cocoapods/validator.rb +981 -0
  124. metadata +533 -0
@@ -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
@@ -0,0 +1,137 @@
1
+ module Pod
2
+ class Command
3
+ class Spec < Command
4
+ class Lint < Spec
5
+ self.summary = 'Validates a spec file'
6
+
7
+ self.description = <<-DESC
8
+ Validates `NAME.podspec`. If a `DIRECTORY` is provided, it validates
9
+ the podspec files found, including subfolders. In case
10
+ the argument is omitted, it defaults to the current working dir.
11
+ DESC
12
+
13
+ self.arguments = [
14
+ CLAide::Argument.new(%w(NAME.podspec DIRECTORY http://PATH/NAME.podspec), false, true),
15
+ ]
16
+
17
+ def self.options
18
+ [
19
+ ['--quick', 'Lint skips checks that would require to download and build the spec'],
20
+ ['--allow-warnings', 'Lint validates even if warnings are present'],
21
+ ['--subspec=NAME', 'Lint validates only the given subspec'],
22
+ ['--no-subspecs', 'Lint skips validation of subspecs'],
23
+ ['--no-clean', 'Lint leaves the build directory intact for inspection'],
24
+ ['--fail-fast', 'Lint stops on the first failing platform or subspec'],
25
+ ['--use-libraries', 'Lint uses static libraries to install the spec'],
26
+ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependent pods ' \
27
+ '(defaults to https://github.com/CocoaPods/Specs.git). ' \
28
+ 'Multiple sources must be comma-delimited.'],
29
+ ['--platforms=ios,macos', 'Lint against specific platforms' \
30
+ '(defaults to all platforms supported by the podspec).' \
31
+ 'Multiple platforms must be comma-delimited'],
32
+ ['--private', 'Lint skips checks that apply only to public specs'],
33
+ ['--swift-version=VERSION', 'The SWIFT_VERSION that should be used to lint the spec. ' \
34
+ 'This takes precedence over a .swift-version file.'],
35
+ ['--skip-import-validation', 'Lint skips validating that the pod can be imported'],
36
+ ['--skip-tests', 'Lint skips building and running tests during validation'],
37
+ ].concat(super)
38
+ end
39
+
40
+ def initialize(argv)
41
+ @quick = argv.flag?('quick')
42
+ @allow_warnings = argv.flag?('allow-warnings')
43
+ @clean = argv.flag?('clean', true)
44
+ @fail_fast = argv.flag?('fail-fast', false)
45
+ @subspecs = argv.flag?('subspecs', true)
46
+ @only_subspec = argv.option('subspec')
47
+ @use_frameworks = !argv.flag?('use-libraries')
48
+ @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
49
+ @platforms = argv.option('platforms', '').split(',')
50
+ @private = argv.flag?('private', false)
51
+ @swift_version = argv.option('swift-version', nil)
52
+ @skip_import_validation = argv.flag?('skip-import-validation', false)
53
+ @skip_tests = argv.flag?('skip-tests', false)
54
+ @podspecs_paths = argv.arguments!
55
+ super
56
+ end
57
+
58
+ def run
59
+ UI.puts
60
+ failure_reasons = []
61
+ podspecs_to_lint.each do |podspec|
62
+ validator = Validator.new(podspec, @source_urls, @platforms)
63
+ validator.quick = @quick
64
+ validator.no_clean = !@clean
65
+ validator.fail_fast = @fail_fast
66
+ validator.allow_warnings = @allow_warnings
67
+ validator.no_subspecs = !@subspecs || @only_subspec
68
+ validator.only_subspec = @only_subspec
69
+ validator.use_frameworks = @use_frameworks
70
+ validator.ignore_public_only_results = @private
71
+ validator.swift_version = @swift_version
72
+ validator.skip_import_validation = @skip_import_validation
73
+ validator.skip_tests = @skip_tests
74
+ validator.validate
75
+ failure_reasons << validator.failure_reason
76
+
77
+ unless @clean
78
+ UI.puts "Pods workspace available at `#{validator.validation_dir}/App.xcworkspace` for inspection."
79
+ UI.puts
80
+ end
81
+ end
82
+
83
+ count = podspecs_to_lint.count
84
+ UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n"
85
+
86
+ failure_reasons.compact!
87
+ if failure_reasons.empty?
88
+ lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : 'All the specs passed validation.'
89
+ UI.puts lint_passed_message.green << "\n\n"
90
+ else
91
+ raise Informative, if count == 1
92
+ "The spec did not pass validation, due to #{failure_reasons.first}."
93
+ else
94
+ "#{failure_reasons.count} out of #{count} specs failed validation."
95
+ end
96
+ end
97
+ podspecs_tmp_dir.rmtree if podspecs_tmp_dir.exist?
98
+ end
99
+
100
+ private
101
+
102
+ def podspecs_to_lint
103
+ @podspecs_to_lint ||= begin
104
+ files = []
105
+ @podspecs_paths << '.' if @podspecs_paths.empty?
106
+ @podspecs_paths.each do |path|
107
+ if path =~ %r{https?://}
108
+ require 'cocoapods/open-uri'
109
+ output_path = podspecs_tmp_dir + File.basename(path)
110
+ output_path.dirname.mkpath
111
+ begin
112
+ open(path) do |io|
113
+ output_path.open('w') { |f| f << io.read }
114
+ end
115
+ rescue => e
116
+ raise Informative, "Downloading a podspec from `#{path}` failed: #{e}"
117
+ end
118
+ files << output_path
119
+ elsif (pathname = Pathname.new(path)).directory?
120
+ files += Pathname.glob(pathname + '*.podspec{.json,}')
121
+ raise Informative, 'No specs found in the current directory.' if files.empty?
122
+ else
123
+ files << (pathname = Pathname.new(path))
124
+ raise Informative, "Unable to find a spec named `#{path}'." unless pathname.exist? && path.include?('.podspec')
125
+ end
126
+ end
127
+ files
128
+ end
129
+ end
130
+
131
+ def podspecs_tmp_dir
132
+ Pathname.new(Dir.tmpdir) + 'CocoaPods/Lint_podspec'
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,43 @@
1
+ module Pod
2
+ class Command
3
+ class Spec < Command
4
+ class Which < Spec
5
+ self.summary = 'Prints the path of the given spec'
6
+
7
+ self.description = <<-DESC
8
+ Prints the path of the .podspec file(s) whose name matches `QUERY`
9
+ DESC
10
+
11
+ self.arguments = [
12
+ CLAide::Argument.new('QUERY', false),
13
+ ]
14
+
15
+ def self.options
16
+ [
17
+ ['--regex', 'Interpret the `QUERY` as a regular expression'],
18
+ ['--show-all', 'Print all versions of the given podspec'],
19
+ ].concat(super)
20
+ end
21
+
22
+ def initialize(argv)
23
+ @use_regex = argv.flag?('regex')
24
+ @show_all = argv.flag?('show-all')
25
+ @query = argv.shift_argument
26
+ @query = @query.gsub('.podspec', '') unless @query.nil?
27
+ super
28
+ end
29
+
30
+ def validate!
31
+ super
32
+ help! 'A podspec name is required.' unless @query
33
+ validate_regex!(@query) if @use_regex
34
+ end
35
+
36
+ def run
37
+ query = @use_regex ? @query : Regexp.escape(@query)
38
+ UI.puts get_path_of_spec(query, @show_all)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,101 @@
1
+ module Pod
2
+ class Command
3
+ class Update < Command
4
+ include RepoUpdate
5
+ include ProjectDirectory
6
+
7
+ self.summary = 'Update outdated project dependencies and create new ' \
8
+ 'Podfile.lock'
9
+
10
+ self.description = <<-DESC
11
+ Updates the Pods identified by the specified `POD_NAMES`, which is a
12
+ space-delimited list of pod names. If no `POD_NAMES` are specified, it
13
+ updates all the Pods, ignoring the contents of the Podfile.lock. This
14
+ command is reserved for the update of dependencies; pod install should
15
+ be used to install changes to the Podfile.
16
+ DESC
17
+
18
+ self.arguments = [
19
+ CLAide::Argument.new('POD_NAMES', false, true),
20
+ ]
21
+
22
+ def self.options
23
+ [
24
+ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to update dependent pods. ' \
25
+ 'Multiple sources must be comma-delimited. The master repo will not be included by default with this option.'],
26
+ ['--exclude-pods=podName', 'Pods to exclude during update. Multiple pods must be comma-delimited.'],
27
+ ].concat(super)
28
+ end
29
+
30
+ def initialize(argv)
31
+ @pods = argv.arguments! unless argv.arguments.empty?
32
+
33
+ source_urls = argv.option('sources', '').split(',')
34
+ excluded_pods = argv.option('exclude-pods', '').split(',')
35
+ unless source_urls.empty?
36
+ source_pods = source_urls.flat_map { |url| config.sources_manager.source_with_name_or_url(url).pods }
37
+ unless source_pods.empty?
38
+ source_pods = source_pods.select { |pod| config.lockfile.pod_names.include?(pod) }
39
+ if @pods
40
+ @pods += source_pods
41
+ else
42
+ @pods = source_pods unless source_pods.empty?
43
+ end
44
+ end
45
+ end
46
+
47
+ unless excluded_pods.empty?
48
+ @pods ||= config.lockfile.pod_names.dup
49
+
50
+ non_installed_pods = (excluded_pods - @pods)
51
+ unless non_installed_pods.empty?
52
+ pluralized_words = non_installed_pods.length > 1 ? %w(Pods are) : %w(Pod is)
53
+ message = "Trying to skip `#{non_installed_pods.join('`, `')}` #{pluralized_words.first} " \
54
+ "which #{pluralized_words.last} not installed"
55
+ raise Informative, message
56
+ end
57
+
58
+ @pods.delete_if { |pod| excluded_pods.include?(pod) }
59
+ end
60
+
61
+ super
62
+ end
63
+
64
+ # Check if all given pods are installed
65
+ #
66
+ def verify_pods_are_installed!
67
+ lockfile_roots = config.lockfile.pod_names.map { |p| Specification.root_name(p) }
68
+ missing_pods = @pods.map { |p| Specification.root_name(p) }.select do |pod|
69
+ !lockfile_roots.include?(pod)
70
+ end
71
+
72
+ unless missing_pods.empty?
73
+ message = if missing_pods.length > 1
74
+ "Pods `#{missing_pods.join('`, `')}` are not " \
75
+ 'installed and cannot be updated'
76
+ else
77
+ "The `#{missing_pods.first}` Pod is not installed " \
78
+ 'and cannot be updated'
79
+ end
80
+ raise Informative, message
81
+ end
82
+ end
83
+
84
+ def run
85
+ verify_podfile_exists!
86
+
87
+ installer = installer_for_config
88
+ installer.repo_update = repo_update?(:default => true)
89
+ if @pods
90
+ verify_lockfile_exists!
91
+ verify_pods_are_installed!
92
+ installer.update = { :pods => @pods }
93
+ else
94
+ UI.puts 'Update all pods'.yellow
95
+ installer.update = true
96
+ end
97
+ installer.install!
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,347 @@
1
+ require 'active_support/multibyte/unicode'
2
+
3
+ module Pod
4
+ # Stores the global configuration of CocoaPods.
5
+ #
6
+ class Config
7
+ # The default settings for the configuration.
8
+ #
9
+ # Users can specify custom settings in `~/.cocoapods/config.yaml`.
10
+ # An example of the contents of this file might look like:
11
+ #
12
+ # ---
13
+ # skip_repo_update: true
14
+ # new_version_message: false
15
+ #
16
+ DEFAULTS = {
17
+ :verbose => false,
18
+ :silent => false,
19
+ :skip_download_cache => !ENV['COCOAPODS_SKIP_CACHE'].nil?,
20
+
21
+ :new_version_message => ENV['COCOAPODS_SKIP_UPDATE_MESSAGE'].nil?,
22
+
23
+ :cache_root => Pathname.new(Dir.home) + 'Library/Caches/CocoaPods',
24
+ }
25
+
26
+ # Applies the given changes to the config for the duration of the given
27
+ # block.
28
+ #
29
+ # @param [Hash<#to_sym,Object>] changes
30
+ # the changes to merge temporarily with the current config
31
+ #
32
+ # @yield [] is called while the changes are applied
33
+ #
34
+ def with_changes(changes)
35
+ old = {}
36
+ changes.keys.each do |key|
37
+ key = key.to_sym
38
+ old[key] = send(key) if respond_to?(key)
39
+ end
40
+ configure_with(changes)
41
+ yield if block_given?
42
+ ensure
43
+ configure_with(old)
44
+ end
45
+
46
+ public
47
+
48
+ #-------------------------------------------------------------------------#
49
+
50
+ # @!group UI
51
+
52
+ # @return [Bool] Whether CocoaPods should provide detailed output about the
53
+ # performed actions.
54
+ #
55
+ attr_accessor :verbose
56
+ alias_method :verbose?, :verbose
57
+
58
+ # @return [Bool] Whether CocoaPods should produce not output.
59
+ #
60
+ attr_accessor :silent
61
+ alias_method :silent?, :silent
62
+
63
+ # @return [Bool] Whether a message should be printed when a new version of
64
+ # CocoaPods is available.
65
+ #
66
+ attr_accessor :new_version_message
67
+ alias_method :new_version_message?, :new_version_message
68
+
69
+ #-------------------------------------------------------------------------#
70
+
71
+ # @!group Installation
72
+
73
+ # @return [Bool] Whether the installer should skip the download cache.
74
+ #
75
+ attr_accessor :skip_download_cache
76
+ alias_method :skip_download_cache?, :skip_download_cache
77
+
78
+ public
79
+
80
+ #-------------------------------------------------------------------------#
81
+
82
+ # @!group Cache
83
+
84
+ # @return [Pathname] The directory where CocoaPods should cache remote data
85
+ # and other expensive to compute information.
86
+ #
87
+ attr_accessor :cache_root
88
+
89
+ def cache_root
90
+ @cache_root.mkpath unless @cache_root.exist?
91
+ @cache_root
92
+ end
93
+
94
+ public
95
+
96
+ #-------------------------------------------------------------------------#
97
+
98
+ # @!group Initialization
99
+
100
+ def initialize(use_user_settings = true)
101
+ configure_with(DEFAULTS)
102
+
103
+ unless ENV['CP_HOME_DIR'].nil?
104
+ @cache_root = home_dir + 'cache'
105
+ end
106
+
107
+ if use_user_settings && user_settings_file.exist?
108
+ require 'yaml'
109
+ user_settings = YAML.load_file(user_settings_file)
110
+ configure_with(user_settings)
111
+ end
112
+
113
+ unless ENV['CP_CACHE_DIR'].nil?
114
+ @cache_root = Pathname.new(ENV['CP_CACHE_DIR']).expand_path
115
+ end
116
+ end
117
+
118
+ def verbose
119
+ @verbose && !silent
120
+ end
121
+
122
+ public
123
+
124
+ #-------------------------------------------------------------------------#
125
+
126
+ # @!group Paths
127
+
128
+ # @return [Pathname] the directory where repos, templates and configuration
129
+ # files are stored.
130
+ #
131
+ def home_dir
132
+ @home_dir ||= Pathname.new(ENV['CP_HOME_DIR'] || '~/.cocoapods').expand_path
133
+ end
134
+
135
+ # @return [Pathname] the directory where the CocoaPods sources are stored.
136
+ #
137
+ def repos_dir
138
+ @repos_dir ||= Pathname.new(ENV['CP_REPOS_DIR'] || (home_dir + 'repos')).expand_path
139
+ end
140
+
141
+ attr_writer :repos_dir
142
+
143
+ def sources_manager
144
+ return @sources_manager if @sources_manager && @sources_manager.repos_dir == repos_dir
145
+ @sources_manager = Source::Manager.new(repos_dir)
146
+ end
147
+
148
+ # @return [Pathname] the directory where the CocoaPods templates are stored.
149
+ #
150
+ def templates_dir
151
+ @templates_dir ||= Pathname.new(ENV['CP_TEMPLATES_DIR'] || (home_dir + 'templates')).expand_path
152
+ end
153
+
154
+ # @return [Pathname] the root of the CocoaPods installation where the
155
+ # Podfile is located.
156
+ #
157
+ def installation_root
158
+ current_dir = ActiveSupport::Multibyte::Unicode.normalize(Dir.pwd)
159
+ current_path = Pathname.new(current_dir)
160
+ unless @installation_root
161
+ until current_path.root?
162
+ if podfile_path_in_dir(current_path)
163
+ @installation_root = current_path
164
+ unless current_path == Pathname.pwd
165
+ UI.puts("[in #{current_path}]")
166
+ end
167
+ break
168
+ else
169
+ current_path = current_path.parent
170
+ end
171
+ end
172
+ @installation_root ||= Pathname.pwd
173
+ end
174
+ @installation_root
175
+ end
176
+
177
+ attr_writer :installation_root
178
+ alias_method :project_root, :installation_root
179
+
180
+ # @return [Pathname] The root of the sandbox.
181
+ #
182
+ def sandbox_root
183
+ @sandbox_root ||= installation_root + 'Pods'
184
+ end
185
+
186
+ attr_writer :sandbox_root
187
+ alias_method :project_pods_root, :sandbox_root
188
+
189
+ # @return [Sandbox] The sandbox of the current project.
190
+ #
191
+ def sandbox
192
+ @sandbox ||= Sandbox.new(sandbox_root)
193
+ end
194
+
195
+ # @return [Podfile] The Podfile to use for the current execution.
196
+ # @return [Nil] If no Podfile is available.
197
+ #
198
+ def podfile
199
+ @podfile ||= Podfile.from_file(podfile_path) if podfile_path
200
+ end
201
+ attr_writer :podfile
202
+
203
+ # @return [Lockfile] The Lockfile to use for the current execution.
204
+ # @return [Nil] If no Lockfile is available.
205
+ #
206
+ def lockfile
207
+ @lockfile ||= Lockfile.from_file(lockfile_path) if lockfile_path
208
+ end
209
+
210
+ # Returns the path of the Podfile.
211
+ #
212
+ # @note The Podfile can be named either `CocoaPods.podfile.yaml`,
213
+ # `CocoaPods.podfile` or `Podfile`. The first two are preferred as
214
+ # they allow to specify an OS X UTI.
215
+ #
216
+ # @return [Pathname]
217
+ # @return [Nil]
218
+ #
219
+ def podfile_path
220
+ @podfile_path ||= podfile_path_in_dir(installation_root)
221
+ end
222
+
223
+ # Returns the path of the Lockfile.
224
+ #
225
+ # @note The Lockfile is named `Podfile.lock`.
226
+ #
227
+ def lockfile_path
228
+ @lockfile_path ||= installation_root + 'Podfile.lock'
229
+ end
230
+
231
+ # Returns the path of the default Podfile pods.
232
+ #
233
+ # @note The file is expected to be named Podfile.default
234
+ #
235
+ # @return [Pathname]
236
+ #
237
+ def default_podfile_path
238
+ @default_podfile_path ||= templates_dir + 'Podfile.default'
239
+ end
240
+
241
+ # Returns the path of the default Podfile test pods.
242
+ #
243
+ # @note The file is expected to be named Podfile.test
244
+ #
245
+ # @return [Pathname]
246
+ #
247
+ def default_test_podfile_path
248
+ @default_test_podfile_path ||= templates_dir + 'Podfile.test'
249
+ end
250
+
251
+ # @return [Pathname] The file to use to cache the search data.
252
+ #
253
+ def search_index_file
254
+ cache_root + 'search_index.json'
255
+ end
256
+
257
+ private
258
+
259
+ #-------------------------------------------------------------------------#
260
+
261
+ # @!group Private helpers
262
+
263
+ # @return [Pathname] The path of the file which contains the user settings.
264
+ #
265
+ def user_settings_file
266
+ home_dir + 'config.yaml'
267
+ end
268
+
269
+ # Sets the values of the attributes with the given hash.
270
+ #
271
+ # @param [Hash{String,Symbol => Object}] values_by_key
272
+ # The values of the attributes grouped by key.
273
+ #
274
+ # @return [void]
275
+ #
276
+ def configure_with(values_by_key)
277
+ return unless values_by_key
278
+ values_by_key.each do |key, value|
279
+ if key == :cache_root
280
+ value = Pathname.new(value).expand_path
281
+ end
282
+ instance_variable_set("@#{key}", value)
283
+ end
284
+ end
285
+
286
+ # @return [Array<String>] The filenames that the Podfile can have ordered
287
+ # by priority.
288
+ #
289
+ PODFILE_NAMES = [
290
+ 'CocoaPods.podfile.yaml',
291
+ 'CocoaPods.podfile',
292
+ 'Podfile',
293
+ ].freeze
294
+
295
+ public
296
+
297
+ # Returns the path of the Podfile in the given dir if any exists.
298
+ #
299
+ # @param [Pathname] dir
300
+ # The directory where to look for the Podfile.
301
+ #
302
+ # @return [Pathname] The path of the Podfile.
303
+ # @return [Nil] If not Podfile was found in the given dir
304
+ #
305
+ def podfile_path_in_dir(dir)
306
+ PODFILE_NAMES.each do |filename|
307
+ candidate = dir + filename
308
+ if candidate.exist?
309
+ return candidate
310
+ end
311
+ end
312
+ nil
313
+ end
314
+
315
+ public
316
+
317
+ #-------------------------------------------------------------------------#
318
+
319
+ # @!group Singleton
320
+
321
+ # @return [Config] the current config instance creating one if needed.
322
+ #
323
+ def self.instance
324
+ @instance ||= new
325
+ end
326
+
327
+ # Sets the current config instance. If set to nil the config will be
328
+ # recreated when needed.
329
+ #
330
+ # @param [Config, Nil] the instance.
331
+ #
332
+ # @return [void]
333
+ #
334
+ class << self
335
+ attr_writer :instance
336
+ end
337
+
338
+ # Provides support for accessing the configuration instance in other
339
+ # scopes.
340
+ #
341
+ module Mixin
342
+ def config
343
+ Config.instance
344
+ end
345
+ end
346
+ end
347
+ end