cocoapods 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +329 -0
- data/lib/cocoapods/command/init.rb +6 -6
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -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/ipc.rb +18 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +111 -0
- data/lib/cocoapods/command/lib.rb +3 -207
- data/lib/cocoapods/command/repo/push.rb +44 -20
- data/lib/cocoapods/command/setup.rb +2 -1
- data/lib/cocoapods/command/spec/lint.rb +4 -0
- data/lib/cocoapods/command.rb +2 -1
- data/lib/cocoapods/config.rb +4 -1
- data/lib/cocoapods/downloader/cache.rb +1 -0
- data/lib/cocoapods/downloader.rb +20 -0
- data/lib/cocoapods/executable.rb +1 -1
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/acknowledgements/plist.rb +4 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +4 -10
- data/lib/cocoapods/generator/header.rb +2 -1
- data/lib/cocoapods/generator/prefix_header.rb +0 -12
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +38 -5
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +5 -4
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +5 -1
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +24 -1
- data/lib/cocoapods/installer/analyzer.rb +161 -1
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +29 -9
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +204 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +314 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +401 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +214 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +265 -0
- data/lib/cocoapods/installer/xcode.rb +7 -0
- data/lib/cocoapods/installer.rb +50 -214
- data/lib/cocoapods/resolver.rb +15 -9
- data/lib/cocoapods/sandbox/headers_store.rb +4 -10
- data/lib/cocoapods/sandbox/path_list.rb +20 -9
- data/lib/cocoapods/sources_manager.rb +7 -10
- data/lib/cocoapods/target/aggregate_target.rb +20 -0
- data/lib/cocoapods/target/pod_target.rb +37 -7
- data/lib/cocoapods/user_interface/error_report.rb +7 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/user_interface.rb +7 -5
- data/lib/cocoapods/validator.rb +59 -11
- metadata +112 -83
- data/lib/cocoapods/command/inter_process_communication.rb +0 -177
- data/lib/cocoapods/installer/file_references_installer.rb +0 -310
- data/lib/cocoapods/installer/migrator.rb +0 -86
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +0 -191
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +0 -368
- data/lib/cocoapods/installer/target_installer.rb +0 -210
data/lib/cocoapods/resolver.rb
CHANGED
@@ -73,9 +73,10 @@ module Pod
|
|
73
73
|
def specs_by_target
|
74
74
|
@specs_by_target ||= {}.tap do |specs_by_target|
|
75
75
|
podfile.target_definition_list.each do |target|
|
76
|
+
dependencies = {}
|
76
77
|
specs = target.dependencies.map(&:name).flat_map do |name|
|
77
78
|
node = @activated.vertex_named(name)
|
78
|
-
valid_dependencies_for_target_from_node(target, node) << node
|
79
|
+
valid_dependencies_for_target_from_node(target, dependencies, node) << node
|
79
80
|
end
|
80
81
|
|
81
82
|
specs_by_target[target] = specs.
|
@@ -389,7 +390,6 @@ module Pod
|
|
389
390
|
error.conflicts.each do |name, conflict|
|
390
391
|
local_pod_parent = conflict.requirement_trees.flatten.reverse.find(&:local?)
|
391
392
|
lockfile_reqs = conflict.requirements[name_for_locking_dependency_source]
|
392
|
-
|
393
393
|
if lockfile_reqs && lockfile_reqs.last && lockfile_reqs.last.prerelease? && !conflict.existing
|
394
394
|
message = 'Due to the previous naïve CocoaPods resolver, ' \
|
395
395
|
"you were using a pre-release version of `#{name}`, " \
|
@@ -398,7 +398,7 @@ module Pod
|
|
398
398
|
'version requirement to your Podfile ' \
|
399
399
|
"(e.g. `pod '#{name}', '#{lockfile_reqs.map(&:requirement).join("', '")}'`) " \
|
400
400
|
"or revert to a stable version by running `pod update #{name}`."
|
401
|
-
elsif local_pod_parent && !specifications_for_dependency(conflict.requirement).empty?
|
401
|
+
elsif local_pod_parent && !specifications_for_dependency(conflict.requirement).empty? && !conflict.possibility
|
402
402
|
# Conflict was caused by a requirement from a local dependency.
|
403
403
|
# Tell user to use `pod update`.
|
404
404
|
message << "\n\nIt seems like you've changed the constraints of dependency `#{name}` " \
|
@@ -472,13 +472,19 @@ module Pod
|
|
472
472
|
# An array of target-appropriate nodes whose `payload`s are
|
473
473
|
# dependencies for `target`.
|
474
474
|
#
|
475
|
-
def valid_dependencies_for_target_from_node(target, node)
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
475
|
+
def valid_dependencies_for_target_from_node(target, dependencies, node)
|
476
|
+
dependencies[node.name] ||= begin
|
477
|
+
validate_platform(node.payload, target)
|
478
|
+
dependency_nodes = node.outgoing_edges.select do |edge|
|
479
|
+
edge_is_valid_for_target?(edge, target)
|
480
|
+
end.map(&:destination)
|
481
|
+
|
482
|
+
dependency_nodes + dependency_nodes.flat_map do |item|
|
483
|
+
node_result = valid_dependencies_for_target_from_node(target, dependencies, item)
|
480
484
|
|
481
|
-
|
485
|
+
node_result
|
486
|
+
end
|
487
|
+
end
|
482
488
|
end
|
483
489
|
|
484
490
|
# Whether the given `edge` should be followed to find dependencies for the
|
@@ -72,11 +72,11 @@ module Pod
|
|
72
72
|
#
|
73
73
|
def add_files(namespace, relative_header_paths)
|
74
74
|
relative_header_paths.map do |relative_header_path|
|
75
|
-
add_file(namespace, relative_header_path
|
75
|
+
add_file(namespace, relative_header_path)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
# Adds a header to the directory
|
79
|
+
# Adds a header to the directory.
|
80
80
|
#
|
81
81
|
# @param [Pathname] namespace
|
82
82
|
# the path where the header file should be stored relative to the
|
@@ -86,23 +86,17 @@ module Pod
|
|
86
86
|
# the path of the header file relative to the Pods project
|
87
87
|
# (`PODS_ROOT` variable of the xcconfigs).
|
88
88
|
#
|
89
|
-
# @param [String] final_name
|
90
|
-
# the name under which the file should be available in the
|
91
|
-
# headers directory.
|
92
|
-
#
|
93
89
|
# @note This method does _not_ add the file to the search paths.
|
94
90
|
#
|
95
91
|
# @return [Pathname]
|
96
92
|
#
|
97
|
-
def add_file(namespace, relative_header_path
|
93
|
+
def add_file(namespace, relative_header_path)
|
98
94
|
namespaced_path = root + namespace
|
99
95
|
namespaced_path.mkpath unless File.exist?(namespaced_path)
|
100
96
|
|
101
97
|
absolute_source = (sandbox.root + relative_header_path)
|
102
98
|
source = absolute_source.relative_path_from(namespaced_path)
|
103
|
-
|
104
|
-
FileUtils.ln_sf(source, final_name)
|
105
|
-
end
|
99
|
+
FileUtils.ln_sf(source, namespaced_path)
|
106
100
|
namespaced_path + relative_header_path.basename
|
107
101
|
end
|
108
102
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/multibyte/unicode'
|
2
|
+
|
1
3
|
module Pod
|
2
4
|
class Sandbox
|
3
5
|
# The PathList class is designed to perform multiple glob matches against
|
@@ -20,7 +22,8 @@ module Pod
|
|
20
22
|
# @param [Pathname] root The root of the PathList.
|
21
23
|
#
|
22
24
|
def initialize(root)
|
23
|
-
|
25
|
+
root_dir = ActiveSupport::Multibyte::Unicode.normalize(root.to_s)
|
26
|
+
@root = Pathname.new(root_dir)
|
24
27
|
@glob_cache = {}
|
25
28
|
end
|
26
29
|
|
@@ -47,15 +50,23 @@ module Pod
|
|
47
50
|
unless root.exist?
|
48
51
|
raise Informative, "Attempt to read non existent folder `#{root}`."
|
49
52
|
end
|
50
|
-
root_length = root.to_s.length + 1
|
51
53
|
escaped_root = escape_path_for_glob(root)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
|
55
|
+
absolute_paths = Pathname.glob(escaped_root + '**/*', File::FNM_DOTMATCH).lazy
|
56
|
+
dirs_and_files = absolute_paths.reject { |path| path.basename.to_s =~ /^\.\.?$/ }
|
57
|
+
dirs, files = dirs_and_files.partition { |path| File.directory?(path) }
|
58
|
+
|
59
|
+
root_length = root.cleanpath.to_s.length + File::SEPARATOR.length
|
60
|
+
sorted_relative_paths_from_full_paths = lambda do |paths|
|
61
|
+
relative_paths = paths.lazy.map do |path|
|
62
|
+
path_string = path.to_s
|
63
|
+
path_string.slice(root_length, path_string.length - root_length)
|
64
|
+
end
|
65
|
+
relative_paths.sort_by(&:upcase)
|
66
|
+
end
|
67
|
+
|
68
|
+
@dirs = sorted_relative_paths_from_full_paths.call(dirs)
|
69
|
+
@files = sorted_relative_paths_from_full_paths.call(files)
|
59
70
|
@glob_cache = {}
|
60
71
|
end
|
61
72
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cocoapods-core/source'
|
2
|
+
require 'set'
|
2
3
|
|
3
4
|
module Pod
|
4
5
|
class Source
|
@@ -102,24 +103,22 @@ module Pod
|
|
102
103
|
end
|
103
104
|
|
104
105
|
def update_git_repo(show_output = false)
|
105
|
-
ensure_in_repo!
|
106
106
|
Config.instance.with_changes(:verbose => show_output) do
|
107
|
-
git!(
|
107
|
+
git!(['-C', repo, 'pull', '--ff-only'])
|
108
108
|
end
|
109
109
|
rescue
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
raise Informative, 'CocoaPods was not able to update the ' \
|
111
|
+
"`#{name}` repo. If this is an unexpected issue " \
|
112
|
+
'and persists you can inspect it running ' \
|
113
|
+
'`pod repo update --verbose`'
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
117
|
class MasterSource
|
118
118
|
def update_git_repo(show_output = false)
|
119
|
-
ensure_in_repo!
|
120
119
|
if repo.join('.git', 'shallow').file?
|
121
120
|
UI.info "Performing a deep fetch of the `#{name}` specs repo to improve future performance" do
|
122
|
-
git!(
|
121
|
+
git!(['-C', repo, 'fetch', '--unshallow'])
|
123
122
|
end
|
124
123
|
end
|
125
124
|
super
|
@@ -141,8 +140,6 @@ module Pod
|
|
141
140
|
"CocoaPods #{latest_cocoapods_version} is available.".green,
|
142
141
|
"To update use: `#{install_message}`".green,
|
143
142
|
("[!] This is a test version we'd love you to try.".yellow if rc),
|
144
|
-
("Until we reach version 1.0 the features of CocoaPods can and will change.\n" \
|
145
|
-
'We strongly recommend that you use the latest version at all times.'.yellow unless rc),
|
146
143
|
'',
|
147
144
|
'For more information, see https://blog.cocoapods.org ' \
|
148
145
|
'and the CHANGELOG for this version at ' \
|
@@ -7,6 +7,10 @@ module Pod
|
|
7
7
|
# generated this target.
|
8
8
|
attr_reader :target_definition
|
9
9
|
|
10
|
+
# Product types where the product's frameworks must be embedded in a host target
|
11
|
+
#
|
12
|
+
EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES = [:app_extension, :framework, :messages_extension, :watch_extension, :xpc_service].freeze
|
13
|
+
|
10
14
|
# Initialize a new instance
|
11
15
|
#
|
12
16
|
# @param [TargetDefinition] target_definition @see target_definition
|
@@ -23,6 +27,22 @@ module Pod
|
|
23
27
|
@xcconfigs = {}
|
24
28
|
end
|
25
29
|
|
30
|
+
# @return [Boolean] True if the user_target's pods are
|
31
|
+
# for an extension and must be embedded in a host,
|
32
|
+
# target, otherwise false.
|
33
|
+
#
|
34
|
+
def requires_host_target?
|
35
|
+
# If we don't have a user_project, then we can't
|
36
|
+
# glean any info about how this target is going to
|
37
|
+
# be integrated, so return false since we can't know
|
38
|
+
# for sure that this target refers to an extension
|
39
|
+
# target that would require a host target
|
40
|
+
return false if user_project.nil?
|
41
|
+
symbol_types = user_targets.map(&:symbol_type).uniq
|
42
|
+
raise ArgumentError, "Expected single kind of user_target for #{name}. Found #{symbol_types.join(', ')}." unless symbol_types.count == 1
|
43
|
+
EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include?(symbol_types[0])
|
44
|
+
end
|
45
|
+
|
26
46
|
# @return [String] the label for the target.
|
27
47
|
#
|
28
48
|
def label
|
@@ -47,6 +47,7 @@ module Pod
|
|
47
47
|
@file_accessors = []
|
48
48
|
@resource_bundle_targets = []
|
49
49
|
@dependent_targets = []
|
50
|
+
@build_config_cache = {}
|
50
51
|
end
|
51
52
|
|
52
53
|
# @param [Hash{Array => PodTarget}] cache
|
@@ -65,6 +66,7 @@ module Pod
|
|
65
66
|
target.native_target = native_target
|
66
67
|
target.archs = archs
|
67
68
|
target.dependent_targets = dependent_targets.flat_map { |pt| pt.scoped(cache) }.select { |pt| pt.target_definitions == [target_definition] }
|
69
|
+
target.host_requires_frameworks = host_requires_frameworks
|
68
70
|
cache[cache_key] = target
|
69
71
|
end
|
70
72
|
end
|
@@ -80,6 +82,12 @@ module Pod
|
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
85
|
+
# @return [String] the Swift version for the target.
|
86
|
+
#
|
87
|
+
def swift_version
|
88
|
+
target_definitions.map(&:swift_version).compact.uniq.first
|
89
|
+
end
|
90
|
+
|
83
91
|
# @note The deployment target for the pod target is the maximum of all
|
84
92
|
# the deployment targets for the current platform of the target
|
85
93
|
# (or the minimum required to support the current installation
|
@@ -134,9 +142,12 @@ module Pod
|
|
134
142
|
# A target should not be build if it has no source files.
|
135
143
|
#
|
136
144
|
def should_build?
|
137
|
-
|
138
|
-
|
139
|
-
|
145
|
+
return @should_build if defined? @should_build
|
146
|
+
@should_build = begin
|
147
|
+
source_files = file_accessors.flat_map(&:source_files)
|
148
|
+
source_files -= file_accessors.flat_map(&:headers)
|
149
|
+
!source_files.empty?
|
150
|
+
end
|
140
151
|
end
|
141
152
|
|
142
153
|
# @return [Array<Specification::Consumer>] the specification consumers for
|
@@ -149,8 +160,11 @@ module Pod
|
|
149
160
|
# @return [Boolean] Whether the target uses Swift code
|
150
161
|
#
|
151
162
|
def uses_swift?
|
152
|
-
|
153
|
-
|
163
|
+
return @uses_swift if defined? @uses_swift
|
164
|
+
@uses_swift = begin
|
165
|
+
file_accessors.any? do |file_accessor|
|
166
|
+
file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
|
167
|
+
end
|
154
168
|
end
|
155
169
|
end
|
156
170
|
|
@@ -188,8 +202,14 @@ module Pod
|
|
188
202
|
# dependency upon.
|
189
203
|
#
|
190
204
|
def recursive_dependent_targets
|
191
|
-
targets = dependent_targets
|
192
|
-
|
205
|
+
targets = dependent_targets.clone
|
206
|
+
|
207
|
+
targets.each do |target|
|
208
|
+
target.dependent_targets.each do |t|
|
209
|
+
targets.push(t) unless t == self || targets.include?(t)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
193
213
|
targets
|
194
214
|
end
|
195
215
|
|
@@ -203,13 +223,20 @@ module Pod
|
|
203
223
|
# The name of the build configuration.
|
204
224
|
#
|
205
225
|
def include_in_build_config?(target_definition, configuration_name)
|
226
|
+
key = [target_definition.label, configuration_name]
|
227
|
+
if @build_config_cache.key?(key)
|
228
|
+
return @build_config_cache[key]
|
229
|
+
end
|
230
|
+
|
206
231
|
whitelists = target_definition_dependencies(target_definition).map do |dependency|
|
207
232
|
target_definition.pod_whitelisted_for_configuration?(dependency.name, configuration_name)
|
208
233
|
end.uniq
|
209
234
|
|
210
235
|
if whitelists.empty?
|
236
|
+
@build_config_cache[key] = true
|
211
237
|
return true
|
212
238
|
elsif whitelists.count == 1
|
239
|
+
@build_config_cache[key] = whitelists.first
|
213
240
|
whitelists.first
|
214
241
|
else
|
215
242
|
raise Informative, "The subspecs of `#{pod_name}` are linked to " \
|
@@ -224,13 +251,16 @@ module Pod
|
|
224
251
|
# @return [Bool]
|
225
252
|
#
|
226
253
|
def inhibit_warnings?
|
254
|
+
return @inhibit_warnings if defined? @inhibit_warnings
|
227
255
|
whitelists = target_definitions.map do |target_definition|
|
228
256
|
target_definition.inhibits_warnings_for_pod?(root_spec.name)
|
229
257
|
end.uniq
|
230
258
|
|
231
259
|
if whitelists.empty?
|
260
|
+
@inhibit_warnings = false
|
232
261
|
return false
|
233
262
|
elsif whitelists.count == 1
|
263
|
+
@inhibit_warnings = whitelists.first
|
234
264
|
whitelists.first
|
235
265
|
else
|
236
266
|
UI.warn "The pod `#{pod_name}` is linked to different targets " \
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rbconfig'
|
4
4
|
require 'cgi'
|
5
|
+
require 'gh_inspector'
|
5
6
|
|
6
7
|
module Pod
|
7
8
|
module UserInterface
|
@@ -112,6 +113,12 @@ EOS
|
|
112
113
|
EOS
|
113
114
|
end
|
114
115
|
|
116
|
+
def search_for_exceptions(exception)
|
117
|
+
inspector = GhInspector::Inspector.new 'cocoapods', 'cocoapods'
|
118
|
+
message_delegate = UserInterface::InspectorReporter.new
|
119
|
+
inspector.search_exception exception, message_delegate
|
120
|
+
end
|
121
|
+
|
115
122
|
private
|
116
123
|
|
117
124
|
def `(other)
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module UserInterface
|
5
|
+
# Redirects GH-issues delegate callbacks to CocoaPods UI methods.
|
6
|
+
#
|
7
|
+
class InspectorReporter
|
8
|
+
# Called just as the investigation has begun.
|
9
|
+
# Lets the user know that it's looking for an issue.
|
10
|
+
#
|
11
|
+
# @param [query] String unused
|
12
|
+
#
|
13
|
+
# @param [GhInspector::Inspector] inspector
|
14
|
+
# The current inspector
|
15
|
+
#
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
def inspector_started_query(_, inspector)
|
19
|
+
UI.puts "Looking for related issues on #{inspector.repo_owner}/#{inspector.repo_name}..."
|
20
|
+
end
|
21
|
+
|
22
|
+
# Called once the inspector has recieved a report with more than one issue,
|
23
|
+
# showing the top 3 issues, and offering a link to see more.
|
24
|
+
#
|
25
|
+
# @param [GhInspector::InspectionReport] report
|
26
|
+
# Report a list of the issues
|
27
|
+
#
|
28
|
+
# @param [GhInspector::Inspector] inspector
|
29
|
+
# The current inspector
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
#
|
33
|
+
def inspector_successfully_recieved_report(report, _)
|
34
|
+
report.issues[0..2].each { |issue| print_issue_full(issue) }
|
35
|
+
|
36
|
+
if report.issues.count > 3
|
37
|
+
UI.puts "and #{report.total_results - 3} more at:"
|
38
|
+
UI.puts report.url
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Called once the report has been recieved, but when there are no issues found.
|
43
|
+
#
|
44
|
+
# @param [GhInspector::InspectionReport] report
|
45
|
+
# An empty report
|
46
|
+
#
|
47
|
+
# @param [GhInspector::Inspector] inspector
|
48
|
+
# The current inspector
|
49
|
+
#
|
50
|
+
# @return [void]
|
51
|
+
#
|
52
|
+
def inspector_recieved_empty_report(_, inspector)
|
53
|
+
UI.puts 'Found no similar issues. To create a new issue, please visit:'
|
54
|
+
UI.puts "https://github.com/#{inspector.repo_owner}/#{inspector.repo_name}/issues/new"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Called when there have been networking issues in creating the report.
|
58
|
+
#
|
59
|
+
# @param [Error] error
|
60
|
+
# The error returned during networking
|
61
|
+
#
|
62
|
+
# @param [String] query
|
63
|
+
# The original search query
|
64
|
+
#
|
65
|
+
# @param [GhInspector::Inspector] inspector
|
66
|
+
# The current inspector
|
67
|
+
#
|
68
|
+
# @return [void]
|
69
|
+
#
|
70
|
+
def inspector_could_not_create_report(error, query, inspector)
|
71
|
+
safe_query = URI.escape query
|
72
|
+
UI.puts 'Could not access the GitHub API, you may have better luck via the website.'
|
73
|
+
UI.puts "https://github.com/#{inspector.repo_owner}/#{inspector.repo_name}/search?q=#{safe_query}&type=Issues&utf8=✓"
|
74
|
+
UI.puts "Error: #{error.name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def print_issue_full(issue)
|
80
|
+
safe_url = URI.escape issue.html_url
|
81
|
+
UI.puts " - #{issue.title}"
|
82
|
+
UI.puts " #{safe_url} [#{issue.state}] [#{issue.comments} comment#{issue.comments == 1 ? '' : 's'}]"
|
83
|
+
UI.puts " #{pretty_date(issue.updated_at)}"
|
84
|
+
UI.puts ''
|
85
|
+
end
|
86
|
+
|
87
|
+
# Taken from http://stackoverflow.com/questions/195740/how-do-you-do-relative-time-in-rails
|
88
|
+
def pretty_date(date_string)
|
89
|
+
date = Time.parse(date_string)
|
90
|
+
a = (Time.now - date).to_i
|
91
|
+
|
92
|
+
case a
|
93
|
+
when 0 then 'just now'
|
94
|
+
when 1 then 'a second ago'
|
95
|
+
when 2..59 then a.to_s + ' seconds ago'
|
96
|
+
when 60..119 then 'a minute ago' # 120 = 2 minutes
|
97
|
+
when 120..3540 then (a / 60).to_i.to_s + ' minutes ago'
|
98
|
+
when 3541..7100 then 'an hour ago' # 3600 = 1 hour
|
99
|
+
when 7101..82_800 then ((a + 99) / 3600).to_i.to_s + ' hours ago'
|
100
|
+
when 82_801..172_000 then 'a day ago' # 86400 = 1 day
|
101
|
+
when 172_001..518_400 then ((a + 800) / (60 * 60 * 24)).to_i.to_s + ' days ago'
|
102
|
+
when 518_400..1_036_800 then 'a week ago'
|
103
|
+
when 1_036_801..4_147_204 then ((a + 180_000) / (60 * 60 * 24 * 7)).to_i.to_s + ' weeks ago'
|
104
|
+
else date.strftime('%d %b %Y')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cocoapods/user_interface/error_report'
|
2
|
+
require 'cocoapods/user_interface/inspector_reporter'
|
2
3
|
|
3
4
|
module Pod
|
4
5
|
# Provides support for UI output. It provides support for nested sections of
|
@@ -7,7 +8,7 @@ module Pod
|
|
7
8
|
module UserInterface
|
8
9
|
require 'colored'
|
9
10
|
|
10
|
-
@title_colors = %w( yellow green
|
11
|
+
@title_colors = %w( yellow green )
|
11
12
|
@title_level = 0
|
12
13
|
@indentation_level = 2
|
13
14
|
@treat_titles_as_messages = false
|
@@ -117,9 +118,6 @@ module Pod
|
|
117
118
|
self.title_level -= 1
|
118
119
|
end
|
119
120
|
|
120
|
-
# def title(title, verbose_prefix = '', relative_indentation = 2)
|
121
|
-
# end
|
122
|
-
|
123
121
|
# Prints a verbose message taking an optional verbose prefix and
|
124
122
|
# a relative indentation valid for the UI action in the passed
|
125
123
|
# block.
|
@@ -187,7 +185,11 @@ module Pod
|
|
187
185
|
if pathname
|
188
186
|
from_path = config.podfile_path.dirname if config.podfile_path
|
189
187
|
from_path ||= Pathname.pwd
|
190
|
-
path =
|
188
|
+
path = begin
|
189
|
+
Pathname(pathname).relative_path_from(from_path)
|
190
|
+
rescue
|
191
|
+
pathname
|
192
|
+
end
|
191
193
|
"`#{path}`"
|
192
194
|
else
|
193
195
|
''
|
data/lib/cocoapods/validator.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/array'
|
2
2
|
require 'active_support/core_ext/string/inflections'
|
3
3
|
|
4
|
-
autoload :Fourflusher, 'fourflusher'
|
5
|
-
|
6
4
|
module Pod
|
7
5
|
# Validates a Specification.
|
8
6
|
#
|
@@ -144,7 +142,15 @@ module Pod
|
|
144
142
|
reasons << 'all results apply only to public specs, but you can use ' \
|
145
143
|
'`--private` to ignore them if linting the specification for a private pod'
|
146
144
|
end
|
147
|
-
|
145
|
+
if dot_swift_version.nil?
|
146
|
+
reasons.to_sentence + ".\n[!] The validator for Swift projects uses " \
|
147
|
+
'Swift 3.0 by default, if you are using a different version of ' \
|
148
|
+
'swift you can use a `.swift-version` file to set the version for ' \
|
149
|
+
"your Pod. For example to use Swift 2.3, run: \n" \
|
150
|
+
' `echo "2.3" > .swift-version`'
|
151
|
+
else
|
152
|
+
reasons.to_sentence
|
153
|
+
end
|
148
154
|
end
|
149
155
|
|
150
156
|
#-------------------------------------------------------------------------#
|
@@ -239,6 +245,30 @@ module Pod
|
|
239
245
|
Pathname(Dir.tmpdir) + 'CocoaPods/Lint'
|
240
246
|
end
|
241
247
|
|
248
|
+
# @return [String] the SWIFT_VERSION to use for validation.
|
249
|
+
#
|
250
|
+
def swift_version
|
251
|
+
@swift_version ||= dot_swift_version || '3.0'
|
252
|
+
end
|
253
|
+
|
254
|
+
# Set the SWIFT_VERSION that should be used to validate the pod.
|
255
|
+
#
|
256
|
+
attr_writer :swift_version
|
257
|
+
|
258
|
+
# @return [String] the SWIFT_VERSION in the .swift-version file or nil.
|
259
|
+
#
|
260
|
+
def dot_swift_version
|
261
|
+
swift_version_path = file.dirname + '.swift-version'
|
262
|
+
swift_version_path.read if swift_version_path.exist?
|
263
|
+
end
|
264
|
+
|
265
|
+
# @return [String] A string representing the Swift version used during linting
|
266
|
+
# or nil, if Swift was not used.
|
267
|
+
#
|
268
|
+
def used_swift_version
|
269
|
+
swift_version if @installer.pod_targets.any?(&:uses_swift?)
|
270
|
+
end
|
271
|
+
|
242
272
|
#-------------------------------------------------------------------------#
|
243
273
|
|
244
274
|
private
|
@@ -388,10 +418,26 @@ module Pod
|
|
388
418
|
|
389
419
|
source_file = write_app_import_source_file(pod_target)
|
390
420
|
source_file_ref = app_project.new_group('App', 'App').new_file(source_file)
|
391
|
-
app_project.targets.first
|
421
|
+
app_target = app_project.targets.first
|
422
|
+
app_target.add_file_references([source_file_ref])
|
423
|
+
add_swift_version(app_target)
|
424
|
+
add_xctest(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
|
392
425
|
app_project.save
|
393
426
|
end
|
394
427
|
|
428
|
+
def add_swift_version(app_target)
|
429
|
+
app_target.build_configurations.each do |configuration|
|
430
|
+
configuration.build_settings['SWIFT_VERSION'] = swift_version
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def add_xctest(app_target)
|
435
|
+
app_target.build_configurations.each do |configuration|
|
436
|
+
search_paths = configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= '$(inherited)'
|
437
|
+
search_paths << ' "$(PLATFORM_DIR)/Developer/Library/Frameworks"'
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
395
441
|
def write_app_import_source_file(pod_target)
|
396
442
|
language = pod_target.uses_swift? ? :swift : :objc
|
397
443
|
|
@@ -427,7 +473,7 @@ module Pod
|
|
427
473
|
# for all available platforms with xcodebuild.
|
428
474
|
#
|
429
475
|
def install_pod
|
430
|
-
%i(
|
476
|
+
%i(verify_no_duplicate_framework_and_library_names
|
431
477
|
verify_no_static_framework_transitive_dependencies
|
432
478
|
verify_framework_usage generate_pods_project integrate_user_project
|
433
479
|
perform_post_install_actions).each { |m| @installer.send(m) }
|
@@ -438,6 +484,7 @@ module Pod
|
|
438
484
|
next unless native_target = pod_target.native_target
|
439
485
|
native_target.build_configuration_list.build_configurations.each do |build_configuration|
|
440
486
|
(build_configuration.build_settings['OTHER_CFLAGS'] ||= '$(inherited)') << ' -Wincomplete-umbrella'
|
487
|
+
build_configuration.build_settings['SWIFT_VERSION'] = swift_version if pod_target.uses_swift?
|
441
488
|
end
|
442
489
|
end
|
443
490
|
if target.pod_targets.any?(&:uses_swift?) && consumer.platform_name == :ios &&
|
@@ -575,7 +622,7 @@ module Pod
|
|
575
622
|
end
|
576
623
|
non_source_files = header_files - file_accessor.source_files
|
577
624
|
unless non_source_files.empty?
|
578
|
-
error(attr_name, 'The pattern includes header files that are not listed' \
|
625
|
+
error(attr_name, 'The pattern includes header files that are not listed ' \
|
579
626
|
"in source_files (#{non_source_files.join(', ')}).")
|
580
627
|
end
|
581
628
|
end
|
@@ -710,20 +757,21 @@ module Pod
|
|
710
757
|
# returns its output (both STDOUT and STDERR).
|
711
758
|
#
|
712
759
|
def xcodebuild
|
713
|
-
|
760
|
+
require 'fourflusher'
|
761
|
+
command = ['clean', 'build', '-workspace', File.join(validation_dir, 'App.xcworkspace'), '-scheme', 'App', '-configuration', 'Release']
|
714
762
|
case consumer.platform_name
|
715
763
|
when :ios
|
716
764
|
command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator)
|
717
|
-
command += Fourflusher::SimControl.new.destination(
|
765
|
+
command += Fourflusher::SimControl.new.destination(:oldest, 'iOS', deployment_target)
|
718
766
|
when :watchos
|
719
767
|
command += %w(CODE_SIGN_IDENTITY=- -sdk watchsimulator)
|
720
|
-
command += Fourflusher::SimControl.new.destination(
|
768
|
+
command += Fourflusher::SimControl.new.destination(:oldest, 'watchOS', deployment_target)
|
721
769
|
when :tvos
|
722
770
|
command += %w(CODE_SIGN_IDENTITY=- -sdk appletvsimulator)
|
723
|
-
command += Fourflusher::SimControl.new.destination(
|
771
|
+
command += Fourflusher::SimControl.new.destination(:oldest, 'tvOS', deployment_target)
|
724
772
|
end
|
725
773
|
|
726
|
-
output, status =
|
774
|
+
output, status = _xcodebuild(command)
|
727
775
|
|
728
776
|
unless status.success?
|
729
777
|
message = 'Returned an unsuccessful exit code.'
|