cocoapods-spm 0.1.1 → 0.1.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.
- checksums.yaml +4 -4
- 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 +92 -0
- data/lib/cocoapods-spm/config.rb +7 -57
- data/lib/cocoapods-spm/def/podfile.rb +8 -4
- data/lib/cocoapods-spm/def/spm_dependency.rb +0 -9
- data/lib/cocoapods-spm/def/spm_package.rb +19 -2
- data/lib/cocoapods-spm/hooks/base.rb +6 -2
- data/lib/cocoapods-spm/hooks/post_integrate/{add_spm_pkgs.rb → 1.add_spm_pkgs.rb} +5 -8
- data/lib/cocoapods-spm/hooks/post_integrate/{update_settings.rb → 5.update_settings.rb} +32 -13
- data/lib/cocoapods-spm/hooks/post_integrate/{update_embed_frameworks_script.rb → 6.update_embed_frameworks_script.rb} +2 -6
- data/lib/cocoapods-spm/macro/prebuilder.rb +3 -7
- data/lib/cocoapods-spm/metadata.rb +13 -0
- data/lib/cocoapods-spm/patch/aggregate_target.rb +1 -1
- data/lib/cocoapods-spm/patch/installer.rb +6 -6
- data/lib/cocoapods-spm/resolver/product.rb +31 -0
- data/lib/cocoapods-spm/resolver/product_dep_resolver.rb +134 -0
- data/lib/cocoapods-spm/resolver/result.rb +51 -0
- data/lib/cocoapods-spm/resolver/target_dep_resolver.rb +64 -0
- data/lib/cocoapods-spm/resolver/umbrella_package.rb +67 -0
- data/lib/cocoapods-spm/{installer → resolver}/validator.rb +5 -5
- data/lib/cocoapods-spm/resolver.rb +45 -0
- metadata +15 -7
- data/lib/cocoapods-spm/installer/analyzer.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e61ad227d509165fab0c8f3e832aa06d05524fa7c2cbfd4d7cc8f393252fc60f
|
4
|
+
data.tar.gz: 66f6bf9e254c7a99edc55f304fcf34ea60867fbbb9f138a6473eb200b6fa9f32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e48c19f9a2ed81601a69cca75ceda44b9353bf76f996458dc3398dad8e7b0ed2fa6fff8ce03cad91122cdcf6f7603a5cc1070b9944dfab98a0d1ff5081f82740
|
7
|
+
data.tar.gz: d26d1674591412b761b92e51154142b5e76f7515464b0e462d5b26a06caeadd3162df96308d2ff34b1cb3d27c554eb33715d2248b7e66e2e58e1d56ceb4b1214
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Config
|
4
|
+
module ProjectConfigMixin
|
5
|
+
def project_config
|
6
|
+
ProjectConfig.instance
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ProjectConfig
|
11
|
+
def self.instance
|
12
|
+
@instance ||= ProjectConfig.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def workspace
|
16
|
+
@workspace ||= Pod::Config.instance.podfile.defined_in_file.parent.glob("*.xcworkspace").first
|
17
|
+
end
|
18
|
+
|
19
|
+
def scheme
|
20
|
+
workspace.parent.glob("*.xcodeproj/**/*.xcscheme").first.basename(".xcscheme")
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_derived_data_path
|
24
|
+
@default_derived_data_path ||= begin
|
25
|
+
raw = `xcodebuild -showBuildSettings -workspace #{workspace.shellescape} -scheme #{scheme.shellescape}`
|
26
|
+
Pathname(raw[/BUILD_DIR = (.*)/, 1]).parent.parent
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Config
|
4
|
+
module SPMConfigMixin
|
5
|
+
def spm_config
|
6
|
+
Config.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
def macro_pods
|
10
|
+
pod_config.podfile.macro_pods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :dsl_config, :cli_config
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@dsl_config = {
|
18
|
+
:dont_prebuild_macros => false,
|
19
|
+
:dont_prebuild_macros_if_exist => true
|
20
|
+
}
|
21
|
+
@cli_config = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.instance
|
25
|
+
@instance ||= Config.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def merged_config
|
29
|
+
@dsl_config.merge(@cli_config)
|
30
|
+
end
|
31
|
+
|
32
|
+
def dont_prebuild_macros?
|
33
|
+
merged_config[:dont_prebuild_macros]
|
34
|
+
end
|
35
|
+
|
36
|
+
def dont_prebuild_macros_if_exist?
|
37
|
+
merged_config[:dont_prebuild_macros_if_exist]
|
38
|
+
end
|
39
|
+
|
40
|
+
def macro_config
|
41
|
+
merged_config[:config] || merged_config[:default_macro_config] || "debug"
|
42
|
+
end
|
43
|
+
|
44
|
+
def all_macros
|
45
|
+
@all_macros ||= Pod::Config.instance.podfile.macro_pods.keys
|
46
|
+
end
|
47
|
+
|
48
|
+
def macros
|
49
|
+
merged_config[:all] ? all_macros : (merged_config[:macros] || [])
|
50
|
+
end
|
51
|
+
|
52
|
+
def root_dir
|
53
|
+
@root_dir ||= Pathname(".spm.pods")
|
54
|
+
end
|
55
|
+
|
56
|
+
def pkg_root_dir
|
57
|
+
@pkg_root_dir ||= prepare_dir(root_dir / "packages")
|
58
|
+
end
|
59
|
+
|
60
|
+
def macro_root_dir
|
61
|
+
root_dir # To be updated: rootdir / "macros"
|
62
|
+
end
|
63
|
+
|
64
|
+
def macro_downloaded_root_dir
|
65
|
+
macro_root_dir / ".downloaded"
|
66
|
+
end
|
67
|
+
|
68
|
+
def macro_downloaded_sandbox
|
69
|
+
@macro_downloaded_sandbox ||= Sandbox.new(macro_downloaded_root_dir)
|
70
|
+
end
|
71
|
+
|
72
|
+
def pkg_umbrella_dir
|
73
|
+
@pkg_umbrella_dir ||= prepare_dir(root_dir / ".umbrella")
|
74
|
+
end
|
75
|
+
|
76
|
+
def pkg_checkouts_dir
|
77
|
+
pkg_umbrella_dir / ".build" / "checkouts"
|
78
|
+
end
|
79
|
+
|
80
|
+
def pkg_metadata_dir
|
81
|
+
@pkg_metadata_dir ||= prepare_dir(pkg_root_dir / "metadata")
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def prepare_dir(dir)
|
87
|
+
dir.mkpath
|
88
|
+
dir
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/cocoapods-spm/config.rb
CHANGED
@@ -1,64 +1,14 @@
|
|
1
|
+
require "cocoapods-spm/config/spm"
|
2
|
+
require "cocoapods-spm/config/pod"
|
3
|
+
require "cocoapods-spm/config/project"
|
4
|
+
|
1
5
|
module Pod
|
2
6
|
module SPM
|
3
7
|
class Config
|
4
8
|
module Mixin
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def macro_pods
|
10
|
-
Pod::Config.instance.podfile.macro_pods
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_accessor :dsl_config, :cli_config
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@dsl_config = {
|
18
|
-
:dont_prebuild_macros => false,
|
19
|
-
:dont_prebuild_macros_if_exist => true
|
20
|
-
}
|
21
|
-
@cli_config = {}
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.instance
|
25
|
-
@instance ||= Config.new
|
26
|
-
end
|
27
|
-
|
28
|
-
def merged_config
|
29
|
-
@dsl_config.merge(@cli_config)
|
30
|
-
end
|
31
|
-
|
32
|
-
def dont_prebuild_macros?
|
33
|
-
merged_config[:dont_prebuild_macros]
|
34
|
-
end
|
35
|
-
|
36
|
-
def dont_prebuild_macros_if_exist?
|
37
|
-
merged_config[:dont_prebuild_macros_if_exist]
|
38
|
-
end
|
39
|
-
|
40
|
-
def macro_config
|
41
|
-
merged_config[:config] || merged_config[:default_macro_config] || "debug"
|
42
|
-
end
|
43
|
-
|
44
|
-
def all_macros
|
45
|
-
@all_macros ||= Pod::Config.instance.podfile.macro_pods.keys
|
46
|
-
end
|
47
|
-
|
48
|
-
def macros
|
49
|
-
merged_config[:all] ? all_macros : (merged_config[:macros] || [])
|
50
|
-
end
|
51
|
-
|
52
|
-
def macro_root_dir
|
53
|
-
@macro_root_dir ||= Pathname(".spm.pods")
|
54
|
-
end
|
55
|
-
|
56
|
-
def macro_downloaded_root_dir
|
57
|
-
macro_root_dir / ".downloaded"
|
58
|
-
end
|
59
|
-
|
60
|
-
def macro_downloaded_sandbox
|
61
|
-
@macro_downloaded_sandbox ||= Sandbox.new(macro_downloaded_root_dir)
|
9
|
+
include ProjectConfigMixin
|
10
|
+
include PodConfigMixin
|
11
|
+
include SPMConfigMixin
|
62
12
|
end
|
63
13
|
end
|
64
14
|
end
|
@@ -2,7 +2,7 @@ require "cocoapods-spm/config"
|
|
2
2
|
|
3
3
|
module Pod
|
4
4
|
class Podfile
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :spm_resolver
|
6
6
|
|
7
7
|
alias origin_pod pod
|
8
8
|
def config_cocoapods_spm(options)
|
@@ -33,10 +33,14 @@ module Pod
|
|
33
33
|
|
34
34
|
def spm_pkgs_by_aggregate_target
|
35
35
|
@spm_pkgs_by_aggregate_target ||= begin
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
dict = {}
|
37
|
+
to_visit = root_target_definitions.map { |t| [t, []] }
|
38
|
+
until to_visit.empty?
|
39
|
+
target, acc = to_visit.pop
|
40
|
+
dict[target.to_s] = (target.spm_pkgs + acc).uniq
|
41
|
+
to_visit += target.children.map { |t| [t, dict[target.to_s]] }
|
39
42
|
end
|
43
|
+
dict
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
@@ -14,15 +14,6 @@ module Pod
|
|
14
14
|
@pkg = pkg
|
15
15
|
end
|
16
16
|
|
17
|
-
def linkage
|
18
|
-
# TODO: How to detect the linkage of an SPM library?
|
19
|
-
@pkg.linkage.is_a?(Hash) ? @pkg.linkage[@product] : @pkg.linkage
|
20
|
-
end
|
21
|
-
|
22
|
-
def dynamic?
|
23
|
-
linkage == :dynamic
|
24
|
-
end
|
25
|
-
|
26
17
|
def inspect
|
27
18
|
"#<#{self.class} name=#{name} product=#{product} pkg=#{pkg}>"
|
28
19
|
end
|
@@ -4,7 +4,7 @@ require "cocoapods-spm/def/spm_dependency"
|
|
4
4
|
module Pod
|
5
5
|
module SPM
|
6
6
|
class Package
|
7
|
-
attr_reader :name, :requirement, :url, :relative_path, :
|
7
|
+
attr_reader :name, :requirement, :url, :relative_path, :linking_opts
|
8
8
|
|
9
9
|
def initialize(name, options = {})
|
10
10
|
@name = name
|
@@ -13,14 +13,23 @@ module Pod
|
|
13
13
|
@linkage = nil
|
14
14
|
@url = nil
|
15
15
|
@requirement = nil
|
16
|
+
@linking_opts = {}
|
16
17
|
parse_options(options)
|
17
18
|
end
|
18
19
|
|
19
20
|
def parse_options(options)
|
20
21
|
@url = options[:url] || options[:git]
|
21
|
-
@linkage = options[:linkage]
|
22
22
|
@relative_path = relative_path_from(options)
|
23
23
|
@requirement = requirement_from(options)
|
24
|
+
@linking_opts = options[:linking] || {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def slug
|
28
|
+
@slug ||= File.basename(@url || @relative_path, ".*")
|
29
|
+
end
|
30
|
+
|
31
|
+
def absolute_path
|
32
|
+
(Pathname("Pods") / relative_path).realpath.to_s
|
24
33
|
end
|
25
34
|
|
26
35
|
def relative_path_from(options)
|
@@ -40,6 +49,14 @@ module Pod
|
|
40
49
|
@relative_path != nil
|
41
50
|
end
|
42
51
|
|
52
|
+
def use_default_xcode_linking?
|
53
|
+
@linking_opts.fetch(:use_default_xcode_linking, false)
|
54
|
+
end
|
55
|
+
|
56
|
+
def linker_flags
|
57
|
+
@linking_opts[:linker_flags] || []
|
58
|
+
end
|
59
|
+
|
43
60
|
def to_dependencies
|
44
61
|
if (products = @_options[:products])
|
45
62
|
products.map { |product| Dependency.new(@name, product: product, pkg: self) }
|
@@ -10,7 +10,7 @@ module Pod
|
|
10
10
|
def initialize(context, options = {})
|
11
11
|
@context = context
|
12
12
|
@options = options
|
13
|
-
@
|
13
|
+
@spm_resolver = options[:spm_resolver]
|
14
14
|
@analysis_result = options[:analysis_result]
|
15
15
|
end
|
16
16
|
|
@@ -38,12 +38,16 @@ module Pod
|
|
38
38
|
Config.instance
|
39
39
|
end
|
40
40
|
|
41
|
+
def podfile
|
42
|
+
pod_config.podfile
|
43
|
+
end
|
44
|
+
|
41
45
|
def run; end
|
42
46
|
|
43
47
|
def self.run_hooks(phase, context, options)
|
44
48
|
Dir["#{__dir__}/#{phase}/*.rb"].sort.each do |f|
|
45
49
|
require f
|
46
|
-
id = File.basename(f, ".*")
|
50
|
+
id = File.basename(f, ".*").split(".").last
|
47
51
|
cls_name = "Pod::SPM::Hook::#{id.camelize}"
|
48
52
|
UI.message "- Running hook: #{cls_name}" do
|
49
53
|
cls_name.constantize.new(context, options).run
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require "cocoapods-spm/hooks/base"
|
2
|
-
require "cocoapods-spm/
|
2
|
+
require "cocoapods-spm/resolver"
|
3
3
|
|
4
4
|
module Pod
|
5
5
|
module SPM
|
6
6
|
class Hook
|
7
7
|
class AddSpmPkgs < Hook
|
8
8
|
def run
|
9
|
-
return
|
9
|
+
return if @spm_resolver.result.spm_pkgs.empty?
|
10
10
|
|
11
11
|
add_spm_pkg_refs_to_project
|
12
12
|
add_spm_products_to_targets
|
@@ -20,7 +20,7 @@ module Pod
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def add_spm_pkg_refs_to_project
|
23
|
-
@spm_pkg_refs = @
|
23
|
+
@spm_pkg_refs = @spm_resolver.result.spm_pkgs.to_h do |pkg|
|
24
24
|
pkg_ref = pkg.create_pkg_ref(pods_project)
|
25
25
|
pods_project.root_object.package_references << pkg_ref
|
26
26
|
[pkg.name, pkg_ref]
|
@@ -33,17 +33,14 @@ module Pod
|
|
33
33
|
|
34
34
|
def add_spm_products_to_targets
|
35
35
|
pods_project.targets.each do |target|
|
36
|
-
@
|
36
|
+
@spm_resolver.result.spm_dependencies_by_target[target.name].to_a.each do |dep|
|
37
37
|
pkg_ref = spm_pkg_refs[dep.pkg.name]
|
38
38
|
target_dep_ref = pkg_ref.create_target_dependency_ref(dep.product)
|
39
39
|
target.dependencies << target_dep_ref
|
40
|
+
target.package_product_dependencies << target_dep_ref.product_ref if dep.pkg.use_default_xcode_linking?
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
43
|
-
|
44
|
-
def podfile
|
45
|
-
Pod::Config.instance.podfile
|
46
|
-
end
|
47
44
|
end
|
48
45
|
end
|
49
46
|
end
|
@@ -6,15 +6,16 @@ module Pod
|
|
6
6
|
class Hook
|
7
7
|
class UpdateSettings < Hook
|
8
8
|
def run
|
9
|
-
|
9
|
+
update_macro_plugin_flags
|
10
|
+
update_modulemap_flags
|
10
11
|
update_swift_include_paths
|
11
12
|
update_linker_flags
|
12
13
|
end
|
13
14
|
|
14
15
|
private
|
15
16
|
|
16
|
-
def
|
17
|
-
@
|
17
|
+
def macro_plugin_flag_by_config
|
18
|
+
@macro_plugin_flag_by_config ||= begin
|
18
19
|
hash = user_build_configurations.keys.to_h do |config|
|
19
20
|
flags = macro_pods.keys.map do |name|
|
20
21
|
metadata = Metadata.for_pod(name)
|
@@ -31,19 +32,29 @@ module Pod
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
+
def update_macro_plugin_flags
|
35
36
|
return if spm_config.all_macros.empty?
|
36
37
|
|
37
|
-
# For prebuilt macros
|
38
38
|
perform_settings_update(
|
39
39
|
update_targets: lambda do |_, _, config|
|
40
|
-
{ "OTHER_SWIFT_FLAGS" =>
|
40
|
+
{ "OTHER_SWIFT_FLAGS" => macro_plugin_flag_by_config[config] }
|
41
|
+
end
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_modulemap_flags
|
46
|
+
perform_settings_update(
|
47
|
+
update_targets: lambda do |target, _, _|
|
48
|
+
{
|
49
|
+
"OTHER_SWIFT_FLAGS" => modulemap_args_for_target(target, prefix: "-Xcc"),
|
50
|
+
"OTHER_CFLAGS" => modulemap_args_for_target(target)
|
51
|
+
}
|
41
52
|
end
|
42
53
|
)
|
43
54
|
end
|
44
55
|
|
45
56
|
def update_linker_flags
|
46
|
-
return if @
|
57
|
+
return if @spm_resolver.result.spm_pkgs.empty?
|
47
58
|
|
48
59
|
# For packages to work in the main target
|
49
60
|
perform_settings_update(
|
@@ -58,22 +69,30 @@ module Pod
|
|
58
69
|
end
|
59
70
|
|
60
71
|
def linker_flags_for(target)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
framework_flags + library_flags
|
72
|
+
return [] if !target.is_a?(Pod::AggregateTarget) && target.build_as_static?
|
73
|
+
|
74
|
+
@spm_resolver.result.linker_flags_for(target)
|
65
75
|
end
|
66
76
|
|
67
77
|
def update_swift_include_paths
|
68
|
-
return if @
|
78
|
+
return if @spm_resolver.result.spm_pkgs.empty? && spm_config.all_macros.empty?
|
69
79
|
|
70
|
-
# For macro packages
|
71
80
|
perform_settings_update(
|
72
81
|
update_targets: lambda do |_, _, _|
|
73
82
|
{ "SWIFT_INCLUDE_PATHS" => "$(PODS_CONFIGURATION_BUILD_DIR)" }
|
74
83
|
end
|
75
84
|
)
|
76
85
|
end
|
86
|
+
|
87
|
+
def modulemap_args_for_target(target, prefix: nil)
|
88
|
+
@spm_resolver
|
89
|
+
.result
|
90
|
+
.spm_products_for(target)
|
91
|
+
.reject { |p| p.headers_path.nil? }
|
92
|
+
.map { |p| "-fmodule-map-file=\"${GENERATED_MODULEMAP_DIR}/#{p.name}.modulemap\"" }
|
93
|
+
.map { |v| prefix.nil? ? v : "#{prefix} #{v}" }
|
94
|
+
.join(" ")
|
95
|
+
end
|
77
96
|
end
|
78
97
|
end
|
79
98
|
end
|
@@ -18,12 +18,8 @@ module Pod
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def framework_paths_for(target)
|
21
|
-
@
|
22
|
-
|
23
|
-
.spm_dependencies_by_target
|
24
|
-
.transform_values { |deps| deps.select(&:dynamic?) }
|
25
|
-
@dynamic_deps_by_target[target.to_s].map do |d|
|
26
|
-
"${BUILT_PRODUCTS_DIR}/PackageFrameworks/#{d.product}.framework"
|
21
|
+
@spm_resolver.result.spm_products_for(target).select(&:dynamic?).map do |p|
|
22
|
+
"${BUILT_PRODUCTS_DIR}/PackageFrameworks/#{p.name}.framework"
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
@@ -37,13 +37,9 @@ module Pod
|
|
37
37
|
raise "Package.swift not exist in #{macro_downloaded_dir}" \
|
38
38
|
unless (macro_downloaded_dir / "Package.swift").exist?
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
metadata_path.write(raw)
|
45
|
-
@metadata = Metadata.from_s(raw)
|
46
|
-
end
|
40
|
+
raw = Dir.chdir(macro_downloaded_dir) { `swift package dump-package` }
|
41
|
+
metadata_path.write(raw)
|
42
|
+
@metadata = Metadata.from_s(raw)
|
47
43
|
end
|
48
44
|
|
49
45
|
def prebuild_macro_impl
|
@@ -21,10 +21,23 @@ module Pod
|
|
21
21
|
from_file(Config.instance.macro_root_dir / name / "metadata.json")
|
22
22
|
end
|
23
23
|
|
24
|
+
def [](key)
|
25
|
+
raw[key]
|
26
|
+
end
|
27
|
+
|
24
28
|
def targets
|
25
29
|
raw["targets"]
|
26
30
|
end
|
27
31
|
|
32
|
+
def products
|
33
|
+
raw["products"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def product_names_of_target(name)
|
37
|
+
names = products.select { |h| h["targets"].include?(name) }.map { |h| h["name"] }
|
38
|
+
names.empty? ? [name] : names
|
39
|
+
end
|
40
|
+
|
28
41
|
def targets_of_type(type)
|
29
42
|
targets.select { |t| t["type"] == type }
|
30
43
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "cocoapods-spm/
|
1
|
+
require "cocoapods-spm/resolver"
|
2
2
|
require "cocoapods-spm/macro/pod_installer"
|
3
3
|
require "cocoapods-spm/hooks/base"
|
4
4
|
|
@@ -39,7 +39,7 @@ module Pod
|
|
39
39
|
|
40
40
|
def hook_options
|
41
41
|
{
|
42
|
-
:
|
42
|
+
:spm_resolver => @spm_resolver,
|
43
43
|
:analysis_result => @analysis_result
|
44
44
|
}
|
45
45
|
end
|
@@ -55,10 +55,10 @@ module Pod
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def resolve_spm_dependencies
|
58
|
-
UI.section "
|
59
|
-
@
|
60
|
-
@
|
61
|
-
podfile.
|
58
|
+
UI.section "Resolving SPM dependencies" do
|
59
|
+
@spm_resolver ||= SPM::Resolver.new(podfile, aggregate_targets)
|
60
|
+
@spm_resolver.resolve
|
61
|
+
podfile.spm_resolver = @spm_resolver
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class Product
|
5
|
+
attr_reader :pkg, :name, :linkage, :headers_path, :binary
|
6
|
+
|
7
|
+
alias binary? binary
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@pkg = options[:pkg]
|
11
|
+
@name = options[:name]
|
12
|
+
@linkage = options.fetch(:linkage, :static)
|
13
|
+
@headers_path = options[:headers_path]
|
14
|
+
@binary = options[:binary]
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"#<#{self.class} #{pkg}/#{name}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def dynamic?
|
22
|
+
@linkage == :dynamic
|
23
|
+
end
|
24
|
+
|
25
|
+
def linked_as_framework?
|
26
|
+
dynamic? || binary?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class ProductDependencyResolver
|
5
|
+
require "cocoapods-spm/resolver/product"
|
6
|
+
|
7
|
+
include Config::Mixin
|
8
|
+
|
9
|
+
def initialize(podfile, result)
|
10
|
+
@podfile = podfile
|
11
|
+
@result = result
|
12
|
+
end
|
13
|
+
|
14
|
+
def resolve
|
15
|
+
generate_metadata
|
16
|
+
resolve_dynamic_products
|
17
|
+
resolve_binary_targets
|
18
|
+
resolve_headers_path_by_target
|
19
|
+
resolve_product_deps
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def generate_metadata
|
25
|
+
spm_config.pkg_checkouts_dir.glob("*").each do |dir|
|
26
|
+
next if dir.glob("Package*.swift").empty?
|
27
|
+
|
28
|
+
raw = Dir.chdir(dir) { `swift package dump-package` }
|
29
|
+
metadata = Metadata.from_s(raw)
|
30
|
+
write_metadata = lambda do |name|
|
31
|
+
(spm_config.pkg_metadata_dir / "#{name}.json").write(raw)
|
32
|
+
@result.metadata_cache[name] = metadata
|
33
|
+
end
|
34
|
+
|
35
|
+
pkg_name = metadata["name"]
|
36
|
+
pkg_slug = dir.basename.to_s
|
37
|
+
write_metadata.call(pkg_name)
|
38
|
+
write_metadata.call(pkg_slug) unless pkg_name == pkg_slug
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def resolve_dynamic_products
|
43
|
+
@dynamic_products ||= Set.new
|
44
|
+
@result.metadata_cache.each_value do |metadata|
|
45
|
+
metadata.products.each do |h|
|
46
|
+
library_types = h.fetch("type", {}).fetch("library", [])
|
47
|
+
@dynamic_products << h["name"] if library_types.include?("dynamic")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve_binary_targets
|
53
|
+
@binary_targets ||= Set.new
|
54
|
+
@result.metadata_cache.each_value do |metadata|
|
55
|
+
metadata.targets.each do |h|
|
56
|
+
@binary_targets << h["name"] if h["type"] == "binary"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def resolve_headers_path_by_target
|
62
|
+
@headers_path_by_product ||= {}
|
63
|
+
@result.metadata_cache.each_value do |metadata|
|
64
|
+
metadata.targets.each do |h|
|
65
|
+
next unless h.key?("publicHeadersPath")
|
66
|
+
|
67
|
+
metadata.product_names_of_target(h["name"]).each do |name|
|
68
|
+
@headers_path_by_product[name] = h["publicHeadersPath"]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def resolve_product_deps
|
75
|
+
@result.spm_dependencies_by_target.values.flatten.uniq(&:product).each do |dep|
|
76
|
+
next if dep.pkg.use_default_xcode_linking?
|
77
|
+
|
78
|
+
verify_product_exists_in_pkg(dep.pkg.name, dep.product)
|
79
|
+
product = create_product(dep.pkg.name, dep.product)
|
80
|
+
recursive_products_of(product)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def verify_product_exists_in_pkg(pkg, name)
|
85
|
+
return unless @result.metadata_of(pkg).products.find { |h| h["name"] == name }.nil?
|
86
|
+
|
87
|
+
raise Informative, "Package `#{pkg}` does not contain product named `#{name}`"
|
88
|
+
end
|
89
|
+
|
90
|
+
def recursive_products_of(product)
|
91
|
+
products = [product] + direct_products_of(product).flat_map do |child|
|
92
|
+
[child] + recursive_products_of(child)
|
93
|
+
end.uniq(&:name)
|
94
|
+
@result.spm_products[product.name] = products
|
95
|
+
products
|
96
|
+
end
|
97
|
+
|
98
|
+
def direct_products_of(product)
|
99
|
+
metadata = @result.metadata_of(product.pkg)
|
100
|
+
metadata
|
101
|
+
.products
|
102
|
+
.find { |h| h["name"] == product.name }
|
103
|
+
.to_h
|
104
|
+
.fetch("targets", [product.name])
|
105
|
+
.flat_map do |t|
|
106
|
+
metadata
|
107
|
+
.targets
|
108
|
+
.find { |h| h["name"] == t }
|
109
|
+
.fetch("dependencies", [])
|
110
|
+
.map { |h| product_from_hash(h, metadata) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def product_from_hash(hash, metadata)
|
115
|
+
type = ["byName", "target", "product"].find { |k| hash.key?(k) }
|
116
|
+
name = hash[type][0] unless type.nil?
|
117
|
+
pkg = metadata["name"]
|
118
|
+
pkg = hash["product"][1] if hash.key?("product")
|
119
|
+
create_product(pkg, name)
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_product(pkg, name)
|
123
|
+
Product.new(
|
124
|
+
pkg: pkg,
|
125
|
+
name: name,
|
126
|
+
linkage: @dynamic_products.include?(name) ? :dynamic : :static,
|
127
|
+
headers_path: @headers_path_by_product[name],
|
128
|
+
binary: @binary_targets.include?(name)
|
129
|
+
)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Resolver
|
4
|
+
class Result
|
5
|
+
class WritableResult < Result
|
6
|
+
attr_accessor :spm_pkgs, :spm_dependencies_by_target, :spm_products, :metadata_cache
|
7
|
+
|
8
|
+
def to_read_only
|
9
|
+
Result.new(
|
10
|
+
spm_pkgs: spm_pkgs,
|
11
|
+
spm_dependencies_by_target: spm_dependencies_by_target,
|
12
|
+
spm_products: spm_products,
|
13
|
+
metadata_cache: metadata_cache
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :spm_pkgs, :spm_dependencies_by_target, :spm_products, :metadata_cache
|
19
|
+
|
20
|
+
def initialize(options = {})
|
21
|
+
@spm_pkgs = options[:spm_pkgs] || []
|
22
|
+
@spm_dependencies_by_target = options[:spm_dependencies_by_target] || {}
|
23
|
+
@spm_products = options[:spm_products] || {}
|
24
|
+
@metadata_cache = options[:metadata_cache] || {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def metadata_of(name)
|
28
|
+
return @metadata_cache[name] if @metadata_cache.key?(name)
|
29
|
+
|
30
|
+
raise Informative, "Metadata of `#{name}` does not exist"
|
31
|
+
end
|
32
|
+
|
33
|
+
def spm_dependencies_for(target)
|
34
|
+
@spm_dependencies_by_target[target.to_s].to_a
|
35
|
+
end
|
36
|
+
|
37
|
+
def spm_products_for(target)
|
38
|
+
spm_dependencies_for(target).flat_map { |d| @spm_products[d.product].to_a }.uniq(&:name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def linker_flags_for(target)
|
42
|
+
flags = spm_dependencies_for(target).flat_map { |d| d.pkg.linker_flags }
|
43
|
+
flags += spm_products_for(target).map do |p|
|
44
|
+
p.linked_as_framework? ? "-framework \"#{p.name}\"" : "-l\"#{p.name}.o\""
|
45
|
+
end
|
46
|
+
flags.uniq
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
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
|
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,67 @@
|
|
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
|
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
|
+
@spm_pkgs.select(&:local?).each do |pkg|
|
60
|
+
dst_dir = spm_config.pkg_checkouts_dir / pkg.slug
|
61
|
+
dst_dir.delete if dst_dir.exist?
|
62
|
+
File.symlink(pkg.absolute_path, dst_dir)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Pod
|
2
|
-
|
3
|
-
class
|
4
|
-
def initialize(aggregate_targets,
|
2
|
+
module SPM
|
3
|
+
class Validator
|
4
|
+
def initialize(aggregate_targets, result)
|
5
5
|
@aggregate_targets = aggregate_targets
|
6
|
-
@spm_pkgs = spm_pkgs
|
7
|
-
@spm_dependencies_by_target = spm_dependencies_by_target
|
6
|
+
@spm_pkgs = result.spm_pkgs
|
7
|
+
@spm_dependencies_by_target = result.spm_dependencies_by_target
|
8
8
|
end
|
9
9
|
|
10
10
|
def validate!
|
@@ -0,0 +1,45 @@
|
|
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/product_dep_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
|
+
@target_dep_resolver = TargetDependencyResolver.new(podfile, aggregate_targets, @_result)
|
17
|
+
@product_dep_resolver = ProductDependencyResolver.new(podfile, @_result)
|
18
|
+
end
|
19
|
+
|
20
|
+
def resolve
|
21
|
+
generate_umbrella_pkg
|
22
|
+
resolvers.each(&:resolve)
|
23
|
+
validate!
|
24
|
+
end
|
25
|
+
|
26
|
+
def result
|
27
|
+
@result ||= @_result.to_read_only
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def resolvers
|
33
|
+
[@target_dep_resolver, @product_dep_resolver]
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_umbrella_pkg
|
37
|
+
@umbrella_pkg = Pod::SPM::UmbrellaPackage.new(@podfile).prepare
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate!
|
41
|
+
Validator.new(@aggregate_targets, result).validate!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-spm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thuyen Trinh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xcodeproj
|
@@ -36,6 +36,9 @@ files:
|
|
36
36
|
- lib/cocoapods-spm/command/prebuild.rb
|
37
37
|
- lib/cocoapods-spm/command/spm.rb
|
38
38
|
- lib/cocoapods-spm/config.rb
|
39
|
+
- lib/cocoapods-spm/config/pod.rb
|
40
|
+
- lib/cocoapods-spm/config/project.rb
|
41
|
+
- lib/cocoapods-spm/config/spm.rb
|
39
42
|
- lib/cocoapods-spm/def/podfile.rb
|
40
43
|
- lib/cocoapods-spm/def/spec.rb
|
41
44
|
- lib/cocoapods-spm/def/spm_dependency.rb
|
@@ -44,11 +47,9 @@ files:
|
|
44
47
|
- lib/cocoapods-spm/def/xcodeproj.rb
|
45
48
|
- lib/cocoapods-spm/executables.rb
|
46
49
|
- lib/cocoapods-spm/hooks/base.rb
|
47
|
-
- lib/cocoapods-spm/hooks/post_integrate/add_spm_pkgs.rb
|
48
|
-
- lib/cocoapods-spm/hooks/post_integrate/
|
49
|
-
- lib/cocoapods-spm/hooks/post_integrate/
|
50
|
-
- lib/cocoapods-spm/installer/analyzer.rb
|
51
|
-
- lib/cocoapods-spm/installer/validator.rb
|
50
|
+
- lib/cocoapods-spm/hooks/post_integrate/1.add_spm_pkgs.rb
|
51
|
+
- lib/cocoapods-spm/hooks/post_integrate/5.update_settings.rb
|
52
|
+
- lib/cocoapods-spm/hooks/post_integrate/6.update_embed_frameworks_script.rb
|
52
53
|
- lib/cocoapods-spm/macro/fetcher.rb
|
53
54
|
- lib/cocoapods-spm/macro/pod_installer.rb
|
54
55
|
- lib/cocoapods-spm/macro/prebuilder.rb
|
@@ -56,6 +57,13 @@ files:
|
|
56
57
|
- lib/cocoapods-spm/metadata.rb
|
57
58
|
- lib/cocoapods-spm/patch/aggregate_target.rb
|
58
59
|
- lib/cocoapods-spm/patch/installer.rb
|
60
|
+
- lib/cocoapods-spm/resolver.rb
|
61
|
+
- lib/cocoapods-spm/resolver/product.rb
|
62
|
+
- lib/cocoapods-spm/resolver/product_dep_resolver.rb
|
63
|
+
- lib/cocoapods-spm/resolver/result.rb
|
64
|
+
- lib/cocoapods-spm/resolver/target_dep_resolver.rb
|
65
|
+
- lib/cocoapods-spm/resolver/umbrella_package.rb
|
66
|
+
- lib/cocoapods-spm/resolver/validator.rb
|
59
67
|
- lib/cocoapods_plugin.rb
|
60
68
|
homepage: https://github.com/trinhngocthuyen/cocoapods-spm
|
61
69
|
licenses:
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require "cocoapods-spm/installer/validator"
|
2
|
-
|
3
|
-
module Pod
|
4
|
-
class Installer
|
5
|
-
class SPMAnalyzer
|
6
|
-
attr_reader :spm_pkgs, :spm_dependencies_by_target
|
7
|
-
|
8
|
-
def initialize(podfile, aggregate_targets)
|
9
|
-
@podfile = podfile
|
10
|
-
@aggregate_targets = aggregate_targets
|
11
|
-
@spm_pkgs = []
|
12
|
-
@spm_dependencies_by_target = {}
|
13
|
-
end
|
14
|
-
|
15
|
-
def analyze
|
16
|
-
analyze_spm_pkgs
|
17
|
-
analyze_spm_dependencies_by_target
|
18
|
-
validate!
|
19
|
-
end
|
20
|
-
|
21
|
-
def spm_dependencies_for(target)
|
22
|
-
@spm_dependencies_by_target[target.to_s]
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def analyze_spm_pkgs
|
28
|
-
@spm_pkgs = @podfile.target_definition_list.flat_map(&:spm_pkgs).uniq
|
29
|
-
end
|
30
|
-
|
31
|
-
def analyze_spm_dependencies_by_target
|
32
|
-
analyze_dependencies_for_targets
|
33
|
-
analyze_dependencies_for_aggregate_targets
|
34
|
-
@spm_dependencies_by_target.values.flatten.each { |d| d.pkg = spm_pkg_for(d.name) }
|
35
|
-
end
|
36
|
-
|
37
|
-
def analyze_dependencies_for_targets
|
38
|
-
specs = @aggregate_targets.flat_map(&:specs).uniq
|
39
|
-
specs.each do |spec|
|
40
|
-
@spm_dependencies_by_target[spec.name] = spec.spm_dependencies
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def analyze_dependencies_for_aggregate_targets
|
45
|
-
@aggregate_targets.each do |target|
|
46
|
-
spm_dependencies = target.specs.flat_map(&:spm_dependencies)
|
47
|
-
@spm_dependencies_by_target[target.to_s] = merge_spm_dependencies(spm_dependencies)
|
48
|
-
end
|
49
|
-
|
50
|
-
@podfile.spm_pkgs_by_aggregate_target.each do |target, pkgs|
|
51
|
-
existing = @spm_dependencies_by_target[target].to_a
|
52
|
-
spm_dependencies = pkgs.flat_map(&:to_dependencies)
|
53
|
-
@spm_dependencies_by_target[target] = merge_spm_dependencies(existing + spm_dependencies)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def merge_spm_dependencies(deps)
|
58
|
-
deps_by_name = Hash.new { |h, k| h[k] = [] }
|
59
|
-
deps.each { |d| deps_by_name[d.name] << d }
|
60
|
-
deps_by_name.each do |name, ds|
|
61
|
-
deps_by_name[name] = ds.uniq { |d| [d.name, d.product] }
|
62
|
-
end
|
63
|
-
deps_by_name.values.flatten
|
64
|
-
end
|
65
|
-
|
66
|
-
def spm_pkg_for(name)
|
67
|
-
@_spm_pkgs_by_name ||= @spm_pkgs.to_h { |pkg| [pkg.name, pkg] }
|
68
|
-
@_spm_pkgs_by_name[name]
|
69
|
-
end
|
70
|
-
|
71
|
-
def validate!
|
72
|
-
validator = SPMValidator.new(@aggregate_targets, @spm_pkgs, @spm_dependencies_by_target)
|
73
|
-
validator.validate!
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|