cocoapods-spm2 0.1.10
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 +7 -0
- data/lib/cocoapods-spm/command/clean.rb +31 -0
- data/lib/cocoapods-spm/command/macro/deprecated.rb +35 -0
- data/lib/cocoapods-spm/command/macro/fetch.rb +33 -0
- data/lib/cocoapods-spm/command/macro/prebuild.rb +37 -0
- data/lib/cocoapods-spm/command/macro.rb +14 -0
- data/lib/cocoapods-spm/command/spm.rb +17 -0
- data/lib/cocoapods-spm/compatibility/all.rb +1 -0
- data/lib/cocoapods-spm/compatibility/rb26.rb +14 -0
- data/lib/cocoapods-spm/config/pod.rb +11 -0
- data/lib/cocoapods-spm/config/project.rb +32 -0
- data/lib/cocoapods-spm/config/spm.rb +111 -0
- data/lib/cocoapods-spm/config.rb +15 -0
- data/lib/cocoapods-spm/def/installer.rb +7 -0
- data/lib/cocoapods-spm/def/podfile.rb +80 -0
- data/lib/cocoapods-spm/def/spec.rb +26 -0
- data/lib/cocoapods-spm/def/spm_dependency.rb +24 -0
- data/lib/cocoapods-spm/def/spm_package.rb +106 -0
- data/lib/cocoapods-spm/def/target_definition.rb +15 -0
- data/lib/cocoapods-spm/def/xcodeproj.rb +38 -0
- data/lib/cocoapods-spm/executables.rb +9 -0
- data/lib/cocoapods-spm/helpers/io.rb +14 -0
- data/lib/cocoapods-spm/helpers/patch.rb +14 -0
- data/lib/cocoapods-spm/hooks/base.rb +99 -0
- data/lib/cocoapods-spm/hooks/helpers/update_script.rb +61 -0
- data/lib/cocoapods-spm/hooks/post_integrate/1.add_spm_pkgs.rb +31 -0
- data/lib/cocoapods-spm/hooks/post_integrate/5.update_settings.rb +88 -0
- data/lib/cocoapods-spm/hooks/post_integrate/6.update_embed_frameworks_script.rb +32 -0
- data/lib/cocoapods-spm/hooks/post_integrate/7.update_copy_resources_script.rb +33 -0
- data/lib/cocoapods-spm/macro/config.rb +27 -0
- data/lib/cocoapods-spm/macro/fetcher.rb +86 -0
- data/lib/cocoapods-spm/macro/metadata.rb +17 -0
- data/lib/cocoapods-spm/macro/pod_installer.rb +35 -0
- data/lib/cocoapods-spm/macro/prebuilder.rb +50 -0
- data/lib/cocoapods-spm/main.rb +13 -0
- data/lib/cocoapods-spm/patch/aggregate_target.rb +25 -0
- data/lib/cocoapods-spm/patch/installer.rb +75 -0
- data/lib/cocoapods-spm/resolver/recursive_target_resolver.rb +39 -0
- data/lib/cocoapods-spm/resolver/result.rb +73 -0
- data/lib/cocoapods-spm/resolver/target_dep_resolver.rb +64 -0
- data/lib/cocoapods-spm/resolver/umbrella_package.rb +72 -0
- data/lib/cocoapods-spm/resolver/validator.rb +32 -0
- data/lib/cocoapods-spm/resolver.rb +43 -0
- data/lib/cocoapods-spm/swift/package/base.rb +54 -0
- data/lib/cocoapods-spm/swift/package/dependency.rb +27 -0
- data/lib/cocoapods-spm/swift/package/description.rb +76 -0
- data/lib/cocoapods-spm/swift/package/product.rb +17 -0
- data/lib/cocoapods-spm/swift/package/project_packages.rb +59 -0
- data/lib/cocoapods-spm/swift/package/resources.rb +17 -0
- data/lib/cocoapods-spm/swift/package/target.rb +171 -0
- data/lib/cocoapods-spm.rb +1 -0
- data/lib/cocoapods_plugin.rb +1 -0
- metadata +108 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require "cocoapods-spm/helpers/patch"
|
2
|
+
require "cocoapods-spm/resolver"
|
3
|
+
require "cocoapods-spm/macro/pod_installer"
|
4
|
+
require "cocoapods-spm/hooks/base"
|
5
|
+
|
6
|
+
module Pod
|
7
|
+
class Installer
|
8
|
+
include Mixin::PatchingBehavior
|
9
|
+
include SPM::Config::Mixin
|
10
|
+
|
11
|
+
patch_method :resolve_dependencies do
|
12
|
+
origin_resolve_dependencies
|
13
|
+
resolve_spm_dependencies
|
14
|
+
end
|
15
|
+
|
16
|
+
patch_method :create_pod_installer do |pod_name|
|
17
|
+
if macro_pods.include?(pod_name)
|
18
|
+
macro_pod_installer = MacroPodInstaller.new(
|
19
|
+
sandbox,
|
20
|
+
podfile,
|
21
|
+
specs_for_pod(pod_name),
|
22
|
+
can_cache: installation_options.clean?
|
23
|
+
)
|
24
|
+
pod_installers << macro_pod_installer
|
25
|
+
macro_pod_installer
|
26
|
+
else
|
27
|
+
origin_create_pod_installer(pod_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
patch_method :integrate do
|
32
|
+
run_spm_pre_integrate_hooks
|
33
|
+
origin_integrate
|
34
|
+
run_spm_post_integrate_hooks
|
35
|
+
end
|
36
|
+
|
37
|
+
patch_method :sandbox_state do
|
38
|
+
state = origin_sandbox_state
|
39
|
+
# NOTE: For macro pods, we force-trigger their source installers even in incremental installations.
|
40
|
+
# This is done by altering the `sandbox_state` & marking them as `added`
|
41
|
+
spm_config.all_macros.each do |name|
|
42
|
+
%i[unchanged changed deleted].each { |key| state.send(key).delete(name) }
|
43
|
+
state.added << (name)
|
44
|
+
end
|
45
|
+
state
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def hook_options
|
51
|
+
{
|
52
|
+
:spm_resolver => @spm_resolver,
|
53
|
+
:analysis_result => @analysis_result,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def run_spm_pre_integrate_hooks
|
58
|
+
context = PreIntegrateHooksContext.generate(sandbox, pods_project, pod_target_subprojects, aggregate_targets)
|
59
|
+
SPM::Hook.run_hooks(:pre_integrate, context, hook_options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def run_spm_post_integrate_hooks
|
63
|
+
context = PostIntegrateHooksContext.generate(sandbox, pods_project, pod_target_subprojects, aggregate_targets)
|
64
|
+
SPM::Hook.run_hooks(:post_integrate, context, hook_options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def resolve_spm_dependencies
|
68
|
+
UI.section "Resolving SPM dependencies" do
|
69
|
+
@spm_resolver ||= SPM::Resolver.new(podfile, aggregate_targets)
|
70
|
+
@spm_resolver.resolve
|
71
|
+
podfile.spm_resolver = @spm_resolver
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class RecursiveTargetResolver
|
5
|
+
require "cocoapods-spm/swift/package/project_packages"
|
6
|
+
|
7
|
+
include Config::Mixin
|
8
|
+
|
9
|
+
def initialize(podfile, result)
|
10
|
+
@podfile = podfile
|
11
|
+
@result = result
|
12
|
+
end
|
13
|
+
|
14
|
+
def resolve
|
15
|
+
resolve_recursive_targets
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def project_pkgs
|
21
|
+
@result.project_pkgs ||= Swift::ProjectPackages.new(
|
22
|
+
src_dir: spm_config.pkg_checkouts_dir,
|
23
|
+
write_json_to_dir: spm_config.pkg_metadata_dir
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def resolve_recursive_targets
|
28
|
+
@result.spm_dependencies_by_target.values.flatten.uniq(&:product).each do |dep|
|
29
|
+
next if dep.pkg.try(:use_default_xcode_linking?)
|
30
|
+
|
31
|
+
@podfile.platforms.each do |platform|
|
32
|
+
project_pkgs.resolve_recursive_targets_of(dep.pkg.name, dep.product, platform: platform)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class Result
|
5
|
+
include Config::Mixin
|
6
|
+
|
7
|
+
ATTRS = {
|
8
|
+
:spm_pkgs => [],
|
9
|
+
:spm_dependencies_by_target => {},
|
10
|
+
:project_pkgs => nil,
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
class WritableResult < Result
|
14
|
+
ATTRS.each_key { |x| attr_accessor x }
|
15
|
+
|
16
|
+
def to_read_only
|
17
|
+
Result.new(ATTRS.to_h { |x| [x, instance_variable_get("@#{x}")] })
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ATTRS.each_key { |x| attr_reader x }
|
22
|
+
|
23
|
+
def initialize(options = {})
|
24
|
+
ATTRS.each do |k, v|
|
25
|
+
instance_variable_set("@#{k}", options[k] || v)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def spm_pkgs_for(target)
|
30
|
+
spm_dependencies_for(target).map(&:pkg).uniq(&:name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def spm_dependencies_for(target)
|
34
|
+
filtered_dependencies = @spm_dependencies_by_target[spec_name_of(target)]&.reject do |dep|
|
35
|
+
dep.pkg&.should_exclude_from_target?(target.name)
|
36
|
+
end
|
37
|
+
filtered_dependencies.to_a
|
38
|
+
end
|
39
|
+
|
40
|
+
def spm_targets_for(target, exclude_default_xcode_linking: true)
|
41
|
+
targets = spm_dependencies_for(target).flat_map do |d|
|
42
|
+
project_pkgs.resolve_recursive_targets_of(d.pkg.name, d.product, platform: target.platform.name)
|
43
|
+
end.uniq(&:name)
|
44
|
+
return targets.reject(&:use_default_xcode_linking?) if exclude_default_xcode_linking
|
45
|
+
|
46
|
+
targets
|
47
|
+
end
|
48
|
+
|
49
|
+
def linker_flags_for(target)
|
50
|
+
(
|
51
|
+
spm_targets_for(target).flat_map(&:linker_flags) +
|
52
|
+
spm_pkgs_for(target).flat_map(&:linker_flags)
|
53
|
+
).uniq
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def spec_name_of(target)
|
59
|
+
# In case of multi-platforms, the target name might contains the platform (ex. Logger-iOS, Logger-macOS)
|
60
|
+
# We need to strip the platform suffix out
|
61
|
+
return target.name if @spm_dependencies_by_target.key?(target.name)
|
62
|
+
return target.root_spec.name if target.is_a?(Pod::PodTarget)
|
63
|
+
return target.name if target.is_a?(Pod::AggregateTarget)
|
64
|
+
|
65
|
+
cmps = target.name.split("-")
|
66
|
+
return cmps[...-1].join("-") if ["iOS", "macOS", "watchOS", "tvOS"].include?(cmps[-1])
|
67
|
+
|
68
|
+
target.name
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class TargetDependencyResolver
|
5
|
+
def initialize(podfile, aggregate_targets, result)
|
6
|
+
@podfile = podfile
|
7
|
+
@aggregate_targets = aggregate_targets
|
8
|
+
@result = result
|
9
|
+
end
|
10
|
+
|
11
|
+
def resolve
|
12
|
+
resolve_spm_pkgs
|
13
|
+
resolve_spm_dependencies_by_target
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def resolve_spm_pkgs
|
19
|
+
@result.spm_pkgs = @podfile.target_definition_list.flat_map(&:spm_pkgs).uniq(&:name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def resolve_spm_dependencies_by_target
|
23
|
+
resolve_dependencies_for_targets
|
24
|
+
resolve_dependencies_for_aggregate_targets
|
25
|
+
@result.spm_dependencies_by_target.values.flatten.each { |d| d.pkg = spm_pkg_for(d.name) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def resolve_dependencies_for_targets
|
29
|
+
specs = @aggregate_targets.flat_map(&:specs).uniq
|
30
|
+
specs.each do |spec|
|
31
|
+
@result.spm_dependencies_by_target[spec.name] = spec.spm_dependencies
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def resolve_dependencies_for_aggregate_targets
|
36
|
+
@aggregate_targets.each do |target|
|
37
|
+
spm_dependencies = target.specs.flat_map(&:spm_dependencies)
|
38
|
+
@result.spm_dependencies_by_target[target.to_s] = merge_spm_dependencies(spm_dependencies)
|
39
|
+
end
|
40
|
+
|
41
|
+
@podfile.spm_pkgs_by_aggregate_target.each do |target, pkgs|
|
42
|
+
existing = @result.spm_dependencies_by_target[target].to_a
|
43
|
+
spm_dependencies = pkgs.flat_map(&:to_dependencies)
|
44
|
+
@result.spm_dependencies_by_target[target] = merge_spm_dependencies(existing + spm_dependencies)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def merge_spm_dependencies(deps)
|
49
|
+
deps_by_name = Hash.new { |h, k| h[k] = [] }
|
50
|
+
deps.each { |d| deps_by_name[d.name] << d }
|
51
|
+
deps_by_name.each do |name, ds|
|
52
|
+
deps_by_name[name] = ds.uniq { |d| [d.name, d.product] }
|
53
|
+
end
|
54
|
+
deps_by_name.values.flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
def spm_pkg_for(name)
|
58
|
+
@_spm_pkgs_by_name ||= @result.spm_pkgs.to_h { |pkg| [pkg.name, pkg] }
|
59
|
+
@_spm_pkgs_by_name[name]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class UmbrellaPackage
|
4
|
+
include Config::Mixin
|
5
|
+
|
6
|
+
def initialize(podfile)
|
7
|
+
@podfile = podfile
|
8
|
+
@spm_pkgs = @podfile.target_definition_list.flat_map(&:spm_pkgs).uniq(&:name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare
|
12
|
+
generate_pkg_swift
|
13
|
+
swift_pkg_resolve
|
14
|
+
create_symlinks_to_local_pkgs
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_pkg_swift
|
21
|
+
swift_tools_version = "5.7"
|
22
|
+
dependencies = @spm_pkgs.map do |pkg|
|
23
|
+
# https://developer.apple.com/documentation/packagedescription/package/dependency
|
24
|
+
next ".package(path: \"#{pkg.absolute_path}\")" if pkg.local?
|
25
|
+
|
26
|
+
tail = case pkg.requirement[:kind]
|
27
|
+
when "exactVersion"
|
28
|
+
"exact: \"#{pkg.requirement[:version]}\""
|
29
|
+
when "branch"
|
30
|
+
"branch: \"#{pkg.requirement[:branch]}\""
|
31
|
+
when "revision"
|
32
|
+
"revision: \"#{pkg.requirement[:revision]}\""
|
33
|
+
else
|
34
|
+
# TODO: Handle this
|
35
|
+
"todo: \"handle this\""
|
36
|
+
end
|
37
|
+
".package(url: \"#{pkg.url}\", #{tail})"
|
38
|
+
end
|
39
|
+
|
40
|
+
package_content = <<~HEREDOC
|
41
|
+
// swift-tools-version:#{swift_tools_version}
|
42
|
+
import PackageDescription
|
43
|
+
|
44
|
+
let package = Package(
|
45
|
+
name: "_umbrella_",
|
46
|
+
dependencies: [
|
47
|
+
#{dependencies.join(",\n ")}
|
48
|
+
]
|
49
|
+
)
|
50
|
+
HEREDOC
|
51
|
+
(spm_config.pkg_umbrella_dir / "Package.swift").write(package_content)
|
52
|
+
end
|
53
|
+
|
54
|
+
def swift_pkg_resolve
|
55
|
+
Dir.chdir(spm_config.pkg_umbrella_dir) { `swift package resolve` }
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_symlinks_to_local_pkgs
|
59
|
+
local_spm_pkgs = @spm_pkgs.select(&:local?)
|
60
|
+
symlinks = local_spm_pkgs.to_h { |p| [p.slug, p.absolute_path] }
|
61
|
+
local_spm_pkgs.each do |pkg|
|
62
|
+
pkg_desc = Swift::PackageDescription.from_dir(pkg.absolute_path)
|
63
|
+
pkg_desc.dependencies.select(&:local?).each { |d| symlinks[d.slug] = d.path }
|
64
|
+
end
|
65
|
+
|
66
|
+
symlinks.each do |slug, src_dir|
|
67
|
+
IOUtils.symlink(src_dir, spm_config.pkg_checkouts_dir / slug)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Validator
|
4
|
+
def initialize(aggregate_targets, result)
|
5
|
+
@aggregate_targets = aggregate_targets
|
6
|
+
@spm_pkgs = result.spm_pkgs
|
7
|
+
@spm_dependencies_by_target = result.spm_dependencies_by_target
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate!
|
11
|
+
verify_no_missing_pkgs
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def dependents_of_pkg(name)
|
17
|
+
@specs ||= @aggregate_targets.flat_map(&:specs).uniq
|
18
|
+
@specs.select { |s| s.spm_dependencies.any? { |d| d.name == name } }.map(&:name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def verify_no_missing_pkgs
|
22
|
+
missing_pkgs = @spm_dependencies_by_target.values.flatten.select { |d| d.pkg.nil? }.map(&:name).uniq
|
23
|
+
return if missing_pkgs.empty?
|
24
|
+
|
25
|
+
messages = ["The following packages were not declared in Podfile:"]
|
26
|
+
messages += missing_pkgs.map { |pkg| " • #{pkg}: used by #{dependents_of_pkg(pkg).join(', ')}" }
|
27
|
+
messages << "Use the `spm_pkg` method to declare those packages in Podfile."
|
28
|
+
raise Informative, messages.join("\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "cocoapods-spm/resolver/validator"
|
2
|
+
require "cocoapods-spm/resolver/umbrella_package"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
module SPM
|
6
|
+
class Resolver
|
7
|
+
require "cocoapods-spm/resolver/result"
|
8
|
+
require "cocoapods-spm/resolver/target_dep_resolver"
|
9
|
+
require "cocoapods-spm/resolver/recursive_target_resolver"
|
10
|
+
|
11
|
+
def initialize(podfile, aggregate_targets)
|
12
|
+
@_result = Result::WritableResult.new
|
13
|
+
@podfile = podfile
|
14
|
+
@aggregate_targets = aggregate_targets
|
15
|
+
@umbrella_pkg = nil
|
16
|
+
@resolvers = [
|
17
|
+
TargetDependencyResolver.new(podfile, aggregate_targets, @_result),
|
18
|
+
RecursiveTargetResolver.new(podfile, @_result),
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
def resolve
|
23
|
+
generate_umbrella_pkg
|
24
|
+
@resolvers.each(&:resolve)
|
25
|
+
validate!
|
26
|
+
end
|
27
|
+
|
28
|
+
def result
|
29
|
+
@result ||= @_result.to_read_only
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def generate_umbrella_pkg
|
35
|
+
@umbrella_pkg = Pod::SPM::UmbrellaPackage.new(@podfile).prepare
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate!
|
39
|
+
Validator.new(@aggregate_targets, result).validate!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class PackageDescriptionBaseObject
|
6
|
+
attr_reader :raw, :parent
|
7
|
+
|
8
|
+
def initialize(raw, parent: nil)
|
9
|
+
@raw = raw
|
10
|
+
@parent = parent
|
11
|
+
end
|
12
|
+
|
13
|
+
def root
|
14
|
+
@root ||= begin
|
15
|
+
node = self
|
16
|
+
node = node.parent until node.parent.nil?
|
17
|
+
node
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def pkg_name
|
22
|
+
root.name
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_s(str)
|
26
|
+
new(JSON.parse(str))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.from_file(path)
|
30
|
+
from_s(File.read(path))
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
"#<#{self.class} #{name}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
alias to_s inspect
|
38
|
+
|
39
|
+
def [](key)
|
40
|
+
raw[key]
|
41
|
+
end
|
42
|
+
|
43
|
+
def name
|
44
|
+
raw["name"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def dup_with_attrs(options = {})
|
48
|
+
copy = dup
|
49
|
+
options.each { |key, value| copy.instance_variable_set("@#{key}", value) }
|
50
|
+
copy
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "cocoapods-spm/swift/package/base"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class PackageDescription
|
6
|
+
class Dependency < PackageDescriptionBaseObject
|
7
|
+
def local?
|
8
|
+
raw.key?("fileSystem")
|
9
|
+
end
|
10
|
+
|
11
|
+
def slug
|
12
|
+
hash["identity"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def path
|
16
|
+
hash["path"]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def hash
|
22
|
+
raw.values.flatten[0] || {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "cocoapods-spm/swift/package/base"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class PackageDescription < PackageDescriptionBaseObject
|
6
|
+
include SPM::Config::Mixin
|
7
|
+
autoload :Dependency, "cocoapods-spm/swift/package/dependency"
|
8
|
+
autoload :Target, "cocoapods-spm/swift/package/target"
|
9
|
+
autoload :Product, "cocoapods-spm/swift/package/product"
|
10
|
+
|
11
|
+
def self.from_dir(dir)
|
12
|
+
raw = `swift package dump-package --package-path #{dir.shellescape}`
|
13
|
+
from_s(raw)
|
14
|
+
end
|
15
|
+
|
16
|
+
def src_dir
|
17
|
+
@src_dir ||= begin
|
18
|
+
path = raw.fetch("packageKind", {}).fetch("root", [])[0]
|
19
|
+
Pathname.new(path) unless path.nil?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def checkouts_dir
|
24
|
+
src_dir.parent
|
25
|
+
end
|
26
|
+
|
27
|
+
def artifacts_dir
|
28
|
+
spm_config.pkg_artifacts_dir / slug
|
29
|
+
end
|
30
|
+
|
31
|
+
def slug
|
32
|
+
src_dir.nil? ? name : src_dir.basename.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def dependencies
|
36
|
+
@dependencies ||= convert_field("dependencies", Dependency)
|
37
|
+
end
|
38
|
+
|
39
|
+
def targets
|
40
|
+
@targets ||= convert_field("targets", Target)
|
41
|
+
end
|
42
|
+
|
43
|
+
def products
|
44
|
+
@products ||= convert_field("products", Product)
|
45
|
+
end
|
46
|
+
|
47
|
+
def targets_of_product(name)
|
48
|
+
matched_products = products.select { |p| p.name == name }
|
49
|
+
dynamic = matched_products.any?(&:dynamic?)
|
50
|
+
matched_products
|
51
|
+
.flat_map do |p|
|
52
|
+
targets.select { |t| p.target_names.include?(t.name) }.map do |t|
|
53
|
+
t.dup_with_attrs(dynamic: dynamic, product_name: name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def macro_impl_name
|
59
|
+
targets.find(&:macro?)&.name
|
60
|
+
end
|
61
|
+
|
62
|
+
def use_default_xcode_linking?
|
63
|
+
return @use_default_xcode_linking unless @use_default_xcode_linking.nil?
|
64
|
+
|
65
|
+
pkg = pod_config.podfile.spm_pkgs.find { |t| t.name == name }
|
66
|
+
@use_default_xcode_linking = pkg&.use_default_xcode_linking?
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def convert_field(name, type)
|
72
|
+
raw.fetch(name, []).flat_map { |h| type.new(h, parent: self) }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "cocoapods-spm/swift/package/base"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class PackageDescription
|
6
|
+
class Product < PackageDescriptionBaseObject
|
7
|
+
def dynamic?
|
8
|
+
@dynamic ||= raw.fetch("type", {}).fetch("library", []).include?("dynamic")
|
9
|
+
end
|
10
|
+
|
11
|
+
def target_names
|
12
|
+
raw["targets"]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "cocoapods-spm/swift/package/description"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class ProjectPackages
|
6
|
+
def initialize(options = {})
|
7
|
+
@src_dir = options[:src_dir]
|
8
|
+
raise Informative, "src_dir must not be nil" if @src_dir.nil?
|
9
|
+
|
10
|
+
@json_dir = options[:write_json_to_dir]
|
11
|
+
@pkg_desc_cache = {}
|
12
|
+
load
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve_recursive_targets_of(pkg_name, product_name, platform: nil)
|
16
|
+
@recursive_targets_cache ||= {}
|
17
|
+
@recursive_targets_cache[platform] ||= {}
|
18
|
+
return @recursive_targets_cache[platform][product_name] if @recursive_targets_cache[platform].key(product_name)
|
19
|
+
|
20
|
+
res = []
|
21
|
+
to_visit = pkg_desc_of(pkg_name).targets_of_product(product_name)
|
22
|
+
until to_visit.empty?
|
23
|
+
target = to_visit.pop
|
24
|
+
res << target
|
25
|
+
# Exclude macros as they wont be linked to the project's binary
|
26
|
+
# https://github.com/trinhngocthuyen/cocoapods-spm/issues/107
|
27
|
+
to_visit += target.resolve_dependencies(@pkg_desc_cache, platform: platform).reject(&:macro?)
|
28
|
+
end
|
29
|
+
@recursive_targets_cache[platform][product_name] = res.uniq(&:name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def pkg_desc_of(name)
|
33
|
+
return @pkg_desc_cache[name] if @pkg_desc_cache.key?(name)
|
34
|
+
|
35
|
+
raise Informative, "Package description of `#{name}` does not exist!"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def load
|
41
|
+
@src_dir.glob("*").each do |dir|
|
42
|
+
next if dir.glob("Package*.swift").empty?
|
43
|
+
|
44
|
+
pkg_desc = PackageDescription.from_dir(dir)
|
45
|
+
name = pkg_desc.name
|
46
|
+
slug = dir.basename.to_s
|
47
|
+
@pkg_desc_cache[name] = pkg_desc
|
48
|
+
@pkg_desc_cache[slug] = pkg_desc
|
49
|
+
next if @json_dir.nil?
|
50
|
+
|
51
|
+
json_path = @json_dir / "#{name}.json"
|
52
|
+
slug_json_path = @json_dir / "#{slug}.json"
|
53
|
+
json_path.write(pkg_desc.raw.to_json)
|
54
|
+
IOUtils.symlink(json_path, slug_json_path) unless name == slug
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "cocoapods-spm/swift/package/base"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Swift
|
5
|
+
class PackageDescription
|
6
|
+
class Resources < PackageDescriptionBaseObject
|
7
|
+
def name
|
8
|
+
"#{pkg_name}_#{parent.name}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def built_resource_path
|
12
|
+
"${PODS_CONFIGURATION_BUILD_DIR}/#{name}.bundle"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|