xcocoapods 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +6303 -0
- data/LICENSE +28 -0
- data/README.md +80 -0
- data/bin/pod +56 -0
- data/bin/sandbox-pod +168 -0
- data/lib/cocoapods.rb +73 -0
- data/lib/cocoapods/command.rb +175 -0
- data/lib/cocoapods/command/cache.rb +28 -0
- data/lib/cocoapods/command/cache/clean.rb +90 -0
- data/lib/cocoapods/command/cache/list.rb +69 -0
- data/lib/cocoapods/command/env.rb +66 -0
- data/lib/cocoapods/command/init.rb +128 -0
- data/lib/cocoapods/command/install.rb +45 -0
- data/lib/cocoapods/command/ipc.rb +19 -0
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -0
- data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
- data/lib/cocoapods/command/ipc/repl.rb +51 -0
- data/lib/cocoapods/command/ipc/spec.rb +29 -0
- data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
- data/lib/cocoapods/command/lib.rb +11 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +121 -0
- data/lib/cocoapods/command/list.rb +39 -0
- data/lib/cocoapods/command/options/project_directory.rb +36 -0
- data/lib/cocoapods/command/options/repo_update.rb +34 -0
- data/lib/cocoapods/command/outdated.rb +140 -0
- data/lib/cocoapods/command/repo.rb +29 -0
- data/lib/cocoapods/command/repo/add.rb +103 -0
- data/lib/cocoapods/command/repo/lint.rb +82 -0
- data/lib/cocoapods/command/repo/list.rb +93 -0
- data/lib/cocoapods/command/repo/push.rb +281 -0
- data/lib/cocoapods/command/repo/remove.rb +36 -0
- data/lib/cocoapods/command/repo/update.rb +28 -0
- data/lib/cocoapods/command/setup.rb +103 -0
- data/lib/cocoapods/command/spec.rb +112 -0
- data/lib/cocoapods/command/spec/cat.rb +51 -0
- data/lib/cocoapods/command/spec/create.rb +283 -0
- data/lib/cocoapods/command/spec/edit.rb +87 -0
- data/lib/cocoapods/command/spec/env_spec.rb +53 -0
- data/lib/cocoapods/command/spec/lint.rb +137 -0
- data/lib/cocoapods/command/spec/which.rb +43 -0
- data/lib/cocoapods/command/update.rb +101 -0
- data/lib/cocoapods/config.rb +347 -0
- data/lib/cocoapods/core_overrides.rb +1 -0
- data/lib/cocoapods/downloader.rb +190 -0
- data/lib/cocoapods/downloader/cache.rb +233 -0
- data/lib/cocoapods/downloader/request.rb +86 -0
- data/lib/cocoapods/downloader/response.rb +16 -0
- data/lib/cocoapods/executable.rb +222 -0
- data/lib/cocoapods/external_sources.rb +57 -0
- data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods/external_sources/path_source.rb +55 -0
- data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods/gem_version.rb +5 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods/generator/app_target_helper.rb +244 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/constant.rb +19 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
- data/lib/cocoapods/generator/dummy_source.rb +31 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
- data/lib/cocoapods/generator/header.rb +103 -0
- data/lib/cocoapods/generator/info_plist_file.rb +116 -0
- data/lib/cocoapods/generator/module_map.rb +99 -0
- data/lib/cocoapods/generator/prefix_header.rb +60 -0
- data/lib/cocoapods/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods/hooks_manager.rb +132 -0
- data/lib/cocoapods/installer.rb +703 -0
- data/lib/cocoapods/installer/analyzer.rb +972 -0
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
- data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
- data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
- data/lib/cocoapods/installer/installation_options.rb +158 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
- data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods/installer/podfile_validator.rb +139 -0
- data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
- data/lib/cocoapods/installer/xcode.rb +8 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
- data/lib/cocoapods/open-uri.rb +33 -0
- data/lib/cocoapods/project.rb +414 -0
- data/lib/cocoapods/resolver.rb +585 -0
- data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
- data/lib/cocoapods/sandbox.rb +404 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
- data/lib/cocoapods/sandbox/headers_store.rb +146 -0
- data/lib/cocoapods/sandbox/path_list.rb +220 -0
- data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
- data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods/sources_manager.rb +157 -0
- data/lib/cocoapods/target.rb +261 -0
- data/lib/cocoapods/target/aggregate_target.rb +338 -0
- data/lib/cocoapods/target/build_settings.rb +1075 -0
- data/lib/cocoapods/target/pod_target.rb +559 -0
- data/lib/cocoapods/user_interface.rb +459 -0
- data/lib/cocoapods/user_interface/error_report.rb +187 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/validator.rb +981 -0
- 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
|