cocoapods-spm 0.0.1 → 0.0.2.rc7194768598
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cocoapods-spm/command/fetch.rb +31 -0
- data/lib/cocoapods-spm/command/prebuild.rb +35 -0
- data/lib/cocoapods-spm/command/spm.rb +17 -0
- data/lib/cocoapods-spm/config.rb +52 -2
- data/lib/cocoapods-spm/def/podfile.rb +55 -0
- data/lib/cocoapods-spm/def/spec.rb +26 -0
- data/lib/cocoapods-spm/def/spm_dependency.rb +22 -0
- data/lib/cocoapods-spm/def/spm_package.rb +65 -0
- data/lib/cocoapods-spm/def/target_definition.rb +15 -0
- data/lib/cocoapods-spm/def/xcodeproj.rb +31 -0
- data/lib/cocoapods-spm/hooks/base.rb +83 -0
- data/lib/cocoapods-spm/hooks/post_integrate/add_spm_pkgs.rb +50 -0
- data/lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb +71 -0
- data/lib/cocoapods-spm/installer/analyzer.rb +66 -0
- data/lib/cocoapods-spm/macro/fetcher.rb +51 -0
- data/lib/cocoapods-spm/macro/pod_installer.rb +35 -0
- data/lib/cocoapods-spm/macro/prebuilder.rb +64 -0
- data/lib/cocoapods-spm/main.rb +5 -78
- data/lib/cocoapods-spm/metadata.rb +33 -0
- data/lib/cocoapods-spm/patch/installer.rb +63 -0
- data/lib/cocoapods_plugin.rb +0 -4
- metadata +26 -10
- data/lib/cocoapods-spm/dsl.rb +0 -11
- data/lib/cocoapods-spm/specification.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 023cb57cc496da534db60773efea73bdcdc40a869a7edeee06e52c16344dbe98
|
4
|
+
data.tar.gz: 5cc2ca8ee116d74324e187a1a3150386f74e01a9994f5d4a05278fc55820986f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3ee693e680264039630ac55ea94d477bab5a5e8e264b3af1f9d696b40d2d232a4e006495746d1b2722b633acabee97b937be065d1e4eb465554b41cdff33d90
|
7
|
+
data.tar.gz: 87e655ba9232d80f6277bfef1cf234876fd8a164dcac3e2a2be1298f313b2528ed267ff5697cc40c21039c5672df2659f19b914b448cc47947486f9179006aa8
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "cocoapods-spm/macro/fetcher"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Command
|
5
|
+
class Spm < Command
|
6
|
+
class Fetch < Spm
|
7
|
+
self.summary = "Fetch macros"
|
8
|
+
def self.options
|
9
|
+
[
|
10
|
+
["--all", "Prebuild all macros"],
|
11
|
+
["--macros=foo", "Macros to prebuild, separated by comma (,)"],
|
12
|
+
].concat(super)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(argv)
|
16
|
+
super
|
17
|
+
update_cli_config(
|
18
|
+
all: argv.flag?("all"),
|
19
|
+
macros: argv.option("macros", "").split(",")
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def run
|
24
|
+
spm_config.macros.each do |name|
|
25
|
+
SPM::MacroFetcher.new(name: name, can_cache: true).run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "cocoapods-spm/macro/prebuilder"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Command
|
5
|
+
class Spm < Command
|
6
|
+
class Prebuild < Spm
|
7
|
+
self.summary = "Prebuild macros"
|
8
|
+
def self.options
|
9
|
+
[
|
10
|
+
["--all", "Prebuild all macros"],
|
11
|
+
["--macros=foo", "Macros to prebuild, separated by comma (,)"],
|
12
|
+
["--config=foo", "Config (debug/release) to prebuild macros"],
|
13
|
+
].concat(super)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(argv)
|
17
|
+
super
|
18
|
+
update_cli_config(
|
19
|
+
all: argv.flag?("all"),
|
20
|
+
macros: argv.option("macros", "").split(","),
|
21
|
+
config: argv.option("config"),
|
22
|
+
dont_prebuild_macros: false,
|
23
|
+
dont_prebuild_macros_if_exist: false
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
spm_config.macros.each do |name|
|
29
|
+
SPM::MacroPrebuilder.new(name: name).run
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "cocoapods-spm/command/prebuild"
|
2
|
+
require "cocoapods-spm/command/fetch"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Command
|
6
|
+
class Spm < Command
|
7
|
+
include SPM::Config::Mixin
|
8
|
+
|
9
|
+
self.summary = "Working with SPM"
|
10
|
+
self.abstract_command = true
|
11
|
+
|
12
|
+
def update_cli_config(options)
|
13
|
+
spm_config.cli_config.merge!(options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/cocoapods-spm/config.rb
CHANGED
@@ -1,15 +1,65 @@
|
|
1
1
|
module Pod
|
2
2
|
module SPM
|
3
3
|
class Config
|
4
|
-
|
4
|
+
module Mixin
|
5
|
+
def spm_config
|
6
|
+
Config.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
def macro_pods
|
10
|
+
Pod::Config.instance.podfile.macro_pods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :dsl_config, :cli_config
|
5
15
|
|
6
16
|
def initialize
|
7
|
-
@dsl_config = {
|
17
|
+
@dsl_config = {
|
18
|
+
:dont_prebuild_macros => false,
|
19
|
+
:dont_prebuild_macros_if_exist => true
|
20
|
+
}
|
21
|
+
@cli_config = {}
|
8
22
|
end
|
9
23
|
|
10
24
|
def self.instance
|
11
25
|
@instance ||= Config.new
|
12
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)
|
62
|
+
end
|
13
63
|
end
|
14
64
|
end
|
15
65
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "cocoapods-spm/config"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Podfile
|
5
|
+
module DSL
|
6
|
+
alias origin_pod pod
|
7
|
+
def config_cocoapods_spm(options)
|
8
|
+
SPM::Config.instance.dsl_config = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def macro_pods
|
12
|
+
@macro_pods ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def pod(name = nil, *requirements)
|
16
|
+
macro = requirements[0].delete(:macro) if requirements.first.is_a?(Hash)
|
17
|
+
macro ||= {}
|
18
|
+
unless macro.empty?
|
19
|
+
requirements[0][:path] = prepare_macro_pod_dir(name, macro)
|
20
|
+
macro_pods[name] = macro
|
21
|
+
end
|
22
|
+
origin_pod(name, *requirements)
|
23
|
+
end
|
24
|
+
|
25
|
+
def spm_pkg(name, options)
|
26
|
+
current_target_definition.store_spm_pkg(name, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def prepare_macro_pod_dir(name, requirement)
|
32
|
+
link = requirement[:git]
|
33
|
+
podspec_content = <<~HEREDOC
|
34
|
+
Pod::Spec.new do |s|
|
35
|
+
s.name = "#{name}"
|
36
|
+
s.version = "0.0.1"
|
37
|
+
s.summary = "#{name}"
|
38
|
+
s.description = "#{name}"
|
39
|
+
s.homepage = "#{link}"
|
40
|
+
s.license = "MIT"
|
41
|
+
s.authors = "dummy@gmail.com"
|
42
|
+
s.source = #{requirement}
|
43
|
+
s.source_files = "Sources/**/*"
|
44
|
+
end
|
45
|
+
HEREDOC
|
46
|
+
|
47
|
+
path = Pathname(".spm.pods/#{name}")
|
48
|
+
(path / ".prebuilt").mkpath
|
49
|
+
(path / "Sources").mkpath
|
50
|
+
(path / "#{name}.podspec").write(podspec_content)
|
51
|
+
path
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "cocoapods-spm/config"
|
2
|
+
require "cocoapods-spm/def/spm_dependency"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Specification
|
6
|
+
def spm_dependencies
|
7
|
+
@spm_dependencies ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def spm_dependency(name, options = {})
|
11
|
+
spm_dependencies << SPM::Dependency.new(name, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def with
|
15
|
+
spec = Pod::Spec.new(
|
16
|
+
parent,
|
17
|
+
name,
|
18
|
+
test_specification,
|
19
|
+
app_specification: app_specification
|
20
|
+
)
|
21
|
+
spec.attributes_hash = attributes_hash.dup
|
22
|
+
yield spec if block_given?
|
23
|
+
spec
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class Dependency
|
4
|
+
attr_reader :name, :product
|
5
|
+
attr_accessor :pkg
|
6
|
+
|
7
|
+
def initialize(name, options = {}, product: nil, pkg: nil)
|
8
|
+
cmps = name.split("/")
|
9
|
+
raise "Invalid dependency `#{name}`" if cmps.count > 2
|
10
|
+
|
11
|
+
@name = cmps.first
|
12
|
+
@product = product || cmps.last
|
13
|
+
@options = options
|
14
|
+
@pkg = pkg
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"#<#{self.class} name=#{name} product=#{product} pkg=#{pkg}>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "cocoapods-spm/def/xcodeproj"
|
2
|
+
require "cocoapods-spm/def/spm_dependency"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
module SPM
|
6
|
+
class Package
|
7
|
+
attr_reader :name, :requirement, :url, :relative_path
|
8
|
+
|
9
|
+
def initialize(name, options = {})
|
10
|
+
@name = name
|
11
|
+
@options = options
|
12
|
+
@requirement = requirement_from(options)
|
13
|
+
@url = options[:url]
|
14
|
+
@relative_path = options[:relative_path]
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"#<#{self.class} name=#{name}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def local?
|
22
|
+
@relative_path != nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_dependencies
|
26
|
+
if (products = @options[:products])
|
27
|
+
products.map { |product| Dependency.new(@name, product: product, pkg: self) }
|
28
|
+
else
|
29
|
+
[Dependency.new(@name, pkg: self)]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_pkg_ref(project)
|
34
|
+
cls = local? ? Object::XCLocalSwiftPackageReference : Object::XCRemoteSwiftPackageReference
|
35
|
+
ref = project.new(cls)
|
36
|
+
ref.name = name
|
37
|
+
if local?
|
38
|
+
ref.relative_path = relative_path
|
39
|
+
else
|
40
|
+
ref.repositoryURL = url
|
41
|
+
ref.requirement = requirement
|
42
|
+
end
|
43
|
+
ref
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def requirement_from(options)
|
49
|
+
if options[:requirement]
|
50
|
+
options[:requirement]
|
51
|
+
elsif (version = options.delete(:version))
|
52
|
+
{ :kind => "exactVersion", :version => version }
|
53
|
+
elsif (branch = options.delete(:branch))
|
54
|
+
{ :kind => "branch", :branch => branch }
|
55
|
+
elsif (revision = options.delete(:commit))
|
56
|
+
{ :kind => "revision", :revision => revision }
|
57
|
+
elsif options[:relative_path]
|
58
|
+
nil
|
59
|
+
else
|
60
|
+
raise "Missing requirement for SPM package: #{name}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "xcodeproj"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module SPM
|
5
|
+
module Object
|
6
|
+
module PackageReferenceMixin
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
def create_pkg_product_dependency_ref(product)
|
10
|
+
ref = project.new(BaseObject::XCSwiftPackageProductDependency)
|
11
|
+
ref.package = self
|
12
|
+
ref.product_name = product
|
13
|
+
ref
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
BaseObject = Xcodeproj::Project::Object
|
18
|
+
|
19
|
+
class XCRemoteSwiftPackageReference < BaseObject::XCRemoteSwiftPackageReference
|
20
|
+
include PackageReferenceMixin
|
21
|
+
end
|
22
|
+
|
23
|
+
class XCLocalSwiftPackageReference < BaseObject::XCLocalSwiftPackageReference
|
24
|
+
include PackageReferenceMixin
|
25
|
+
end
|
26
|
+
|
27
|
+
class XCSwiftPackageProductDependency < BaseObject::XCSwiftPackageProductDependency
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "cocoapods-spm/config"
|
2
|
+
require "cocoapods-spm/def/podfile"
|
3
|
+
require "cocoapods-spm/def/spec"
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
module SPM
|
7
|
+
class Hook
|
8
|
+
include Config::Mixin
|
9
|
+
|
10
|
+
def initialize(context, options = {})
|
11
|
+
@context = context
|
12
|
+
@options = options
|
13
|
+
@spm_analyzer = options[:spm_analyzer]
|
14
|
+
@analysis_result = options[:analysis_result]
|
15
|
+
end
|
16
|
+
|
17
|
+
def sandbox
|
18
|
+
@context.sandbox
|
19
|
+
end
|
20
|
+
|
21
|
+
def pods_project
|
22
|
+
@context.pods_project
|
23
|
+
end
|
24
|
+
|
25
|
+
def pod_targets
|
26
|
+
@analysis_result.pod_targets
|
27
|
+
end
|
28
|
+
|
29
|
+
def aggregate_targets
|
30
|
+
@analysis_result.targets
|
31
|
+
end
|
32
|
+
|
33
|
+
def user_build_configurations
|
34
|
+
@user_build_configurations ||= (pod_targets + aggregate_targets)[0].user_build_configurations
|
35
|
+
end
|
36
|
+
|
37
|
+
def config
|
38
|
+
Config.instance
|
39
|
+
end
|
40
|
+
|
41
|
+
def run; end
|
42
|
+
|
43
|
+
def self.run_hooks(phase, context, options)
|
44
|
+
Dir["#{__dir__}/#{phase}/*.rb"].sort.each do |f|
|
45
|
+
require f
|
46
|
+
id = File.basename(f, ".*")
|
47
|
+
cls_name = "Pod::SPM::Hook::#{id.camelize}"
|
48
|
+
UI.message "Running hook: #{cls_name}"
|
49
|
+
cls_name.constantize.new(context, options).run
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def perform_settings_update(
|
54
|
+
update_targets: nil,
|
55
|
+
update_pod_targets: nil,
|
56
|
+
update_aggregate_targets: nil
|
57
|
+
)
|
58
|
+
proc = lambda do |update, target, setting, config|
|
59
|
+
return if update.nil?
|
60
|
+
|
61
|
+
hash = update.call(target, setting, config)
|
62
|
+
setting.xcconfig.merge!(hash)
|
63
|
+
setting.generate.merge!(hash)
|
64
|
+
end
|
65
|
+
|
66
|
+
pod_targets.each do |target|
|
67
|
+
target.build_settings.each do |config, setting|
|
68
|
+
proc.call(update_targets, target, setting, config)
|
69
|
+
proc.call(update_pod_targets, target, setting, config)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
aggregate_targets.each do |target|
|
74
|
+
target.user_build_configurations.each_key do |config|
|
75
|
+
setting = target.build_settings(config)
|
76
|
+
proc.call(update_targets, target, setting, config)
|
77
|
+
proc.call(update_aggregate_targets, target, setting, config)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "cocoapods-spm/hooks/base"
|
2
|
+
require "cocoapods-spm/installer/analyzer"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
module SPM
|
6
|
+
class Hook
|
7
|
+
class AddSpmPkgs < Hook
|
8
|
+
def run
|
9
|
+
return unless @spm_analyzer.spm_pkgs
|
10
|
+
|
11
|
+
add_spm_pkg_refs_to_project
|
12
|
+
add_spm_products_to_targets
|
13
|
+
pods_project.save
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def spm_pkg_refs
|
19
|
+
@spm_pkg_refs ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_spm_pkg_refs_to_project
|
23
|
+
@spm_pkg_refs = @spm_analyzer.spm_pkgs.to_h do |pkg|
|
24
|
+
pkg_ref = pkg.create_pkg_ref(pods_project)
|
25
|
+
pods_project.root_object.package_references << pkg_ref
|
26
|
+
[pkg.name, pkg_ref]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def spm_pkgs_by_target
|
31
|
+
@spm_pkgs_by_target ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_spm_products_to_targets
|
35
|
+
pods_project.targets.each do |target|
|
36
|
+
@spm_analyzer.spm_dependencies_by_target[target.name].to_a.each do |dep|
|
37
|
+
pkg_ref = spm_pkg_refs[dep.pkg.name]
|
38
|
+
product_ref = pkg_ref.create_pkg_product_dependency_ref(dep.product)
|
39
|
+
target.package_product_dependencies << product_ref
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def podfile
|
45
|
+
Pod::Config.instance.podfile
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "cocoapods-spm/hooks/base"
|
2
|
+
require "cocoapods-spm/metadata"
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
module SPM
|
6
|
+
class Hook
|
7
|
+
class UpdateSettings < Hook
|
8
|
+
def run
|
9
|
+
update_other_swift_flags
|
10
|
+
update_swift_include_paths
|
11
|
+
update_linker_flags
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def other_swift_flags_by_config
|
17
|
+
@other_swift_flags_by_config ||= begin
|
18
|
+
hash = user_build_configurations.keys.to_h do |config|
|
19
|
+
flags = macro_pods.keys.map do |name|
|
20
|
+
metadata = Metadata.for_pod(name)
|
21
|
+
impl_module_name = metadata.macro_impl_name
|
22
|
+
plugin_executable_path =
|
23
|
+
"${PODS_ROOT}/../.spm.pods/#{name}/.prebuilt/#{config.to_s.downcase}/" \
|
24
|
+
"#{impl_module_name}##{impl_module_name}"
|
25
|
+
"-load-plugin-executable \"#{plugin_executable_path}\""
|
26
|
+
end.join(" ")
|
27
|
+
[config, flags]
|
28
|
+
end
|
29
|
+
user_build_configurations.each { |config, symbol| hash[symbol] = hash[config] }
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_other_swift_flags
|
35
|
+
return unless spm_config.macros
|
36
|
+
|
37
|
+
# For prebuilt macros
|
38
|
+
perform_settings_update(
|
39
|
+
update_targets: lambda do |_, _, config|
|
40
|
+
{ "OTHER_SWIFT_FLAGS" => other_swift_flags_by_config[config] }
|
41
|
+
end
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_linker_flags
|
46
|
+
return unless @spm_analyzer.spm_pkgs
|
47
|
+
|
48
|
+
# For packages to work in the main target
|
49
|
+
perform_settings_update(
|
50
|
+
update_aggregate_targets: lambda do |target, _, _|
|
51
|
+
spm_deps = @spm_analyzer.spm_dependencies_by_target[target.to_s].to_a
|
52
|
+
flags = spm_deps.map { |d| "-l\"#{d.product}.o\"" }
|
53
|
+
{ "OTHER_LDFLAGS" => flags }
|
54
|
+
end
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_swift_include_paths
|
59
|
+
return unless @spm_analyzer.spm_pkgs
|
60
|
+
|
61
|
+
# For macro packages
|
62
|
+
perform_settings_update(
|
63
|
+
update_targets: lambda do |_, _, _|
|
64
|
+
{ "SWIFT_INCLUDE_PATHS" => "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}" }
|
65
|
+
end
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class SPMAnalyzer
|
4
|
+
attr_reader :spm_pkgs, :spm_dependencies_by_target
|
5
|
+
|
6
|
+
def initialize(podfile, umbrella_targets)
|
7
|
+
@podfile = podfile
|
8
|
+
@umbrella_targets = umbrella_targets
|
9
|
+
@spm_pkgs = []
|
10
|
+
@spm_dependencies_by_target = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def analyze
|
14
|
+
analyze_spm_pkgs
|
15
|
+
analyze_spm_dependencies_by_target
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def analyze_spm_pkgs
|
21
|
+
@spm_pkgs = @podfile.target_definition_list.flat_map(&:spm_pkgs).uniq
|
22
|
+
end
|
23
|
+
|
24
|
+
def analyze_spm_dependencies_by_target
|
25
|
+
analyze_dependencies_for_targets
|
26
|
+
analyze_dependencies_for_umbrella_targets
|
27
|
+
@spm_dependencies_by_target.values.flatten.each { |d| d.pkg = spm_pkg_for(d.name) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def analyze_dependencies_for_targets
|
31
|
+
specs = @umbrella_targets.flat_map(&:specs).uniq
|
32
|
+
specs.each do |spec|
|
33
|
+
@spm_dependencies_by_target[spec.name] = spec.spm_dependencies
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def analyze_dependencies_for_umbrella_targets
|
38
|
+
@umbrella_targets.each do |target|
|
39
|
+
spm_dependencies = target.specs.flat_map(&:spm_dependencies)
|
40
|
+
@spm_dependencies_by_target[target.to_s] = merge_spm_dependencies(spm_dependencies)
|
41
|
+
end
|
42
|
+
|
43
|
+
common_spm_pkgs = @podfile.root_target_definitions.flat_map(&:spm_pkgs)
|
44
|
+
@podfile.target_definition_list.reject(&:abstract?).each do |target|
|
45
|
+
existing = @spm_dependencies_by_target[target.label].to_a
|
46
|
+
spm_dependencies = (common_spm_pkgs + target.spm_pkgs).flat_map(&:to_dependencies)
|
47
|
+
@spm_dependencies_by_target[target.label] = merge_spm_dependencies(existing + spm_dependencies)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def merge_spm_dependencies(deps)
|
52
|
+
deps_by_name = Hash.new { |h, k| h[k] = [] }
|
53
|
+
deps.each { |d| deps_by_name[d.name] << d }
|
54
|
+
deps_by_name.each do |name, ds|
|
55
|
+
deps_by_name[name] = ds.uniq { |d| [d.name, d.product] }
|
56
|
+
end
|
57
|
+
deps_by_name.values.flatten
|
58
|
+
end
|
59
|
+
|
60
|
+
def spm_pkg_for(name)
|
61
|
+
@_spm_pkgs_by_name ||= @spm_pkgs.to_h { |pkg| [pkg.name, pkg] }
|
62
|
+
@_spm_pkgs_by_name[name]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Pod
|
2
|
+
module SPM
|
3
|
+
class MacroFetcher
|
4
|
+
include Config::Mixin
|
5
|
+
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@name = options[:name]
|
10
|
+
@specs_by_platform = options[:specs_by_platform]
|
11
|
+
@can_cache = options[:can_cache]
|
12
|
+
@podfile = Pod::Config.instance.podfile
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
download_macro_source
|
17
|
+
macro_dir = spm_config.macro_root_dir / name
|
18
|
+
macro_downloaded_dir = spm_config.macro_downloaded_root_dir / name
|
19
|
+
FileUtils.copy_entry(
|
20
|
+
macro_downloaded_dir / "Sources" / name,
|
21
|
+
macro_dir / "Sources" / name
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def download_macro_source
|
26
|
+
@specs_by_platform ||= @podfile.root_target_definitions.to_h do |definition|
|
27
|
+
spec = Pod::Spec.from_file(spm_config.macro_root_dir / name / "#{name}.podspec")
|
28
|
+
[definition.platform, [spec]]
|
29
|
+
end
|
30
|
+
|
31
|
+
# When `can_cache` is true, PodSourceDownloader only keeps the contents
|
32
|
+
# according to its `source_files` declared in the podspec.
|
33
|
+
# However, we wish to keep all contents (including Package.swift...).
|
34
|
+
# --> We alter the spec when downloading the source.
|
35
|
+
altered_specs_by_platform = @specs_by_platform.to_h do |platform, specs|
|
36
|
+
altered_specs = specs.map do |spec|
|
37
|
+
spec.with { |s| s.source_files = "**/*" }
|
38
|
+
end
|
39
|
+
[platform, altered_specs]
|
40
|
+
end
|
41
|
+
downloader = Pod::Installer::PodSourceDownloader.new(
|
42
|
+
spm_config.macro_downloaded_sandbox,
|
43
|
+
@podfile,
|
44
|
+
altered_specs_by_platform,
|
45
|
+
can_cache: @can_cache
|
46
|
+
)
|
47
|
+
downloader.download!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "cocoapods-spm/def/spec"
|
2
|
+
require "cocoapods-spm/macro/fetcher"
|
3
|
+
require "cocoapods-spm/macro/prebuilder"
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
class MacroPodInstaller < PodSourceInstaller
|
8
|
+
include SPM::Config::Mixin
|
9
|
+
|
10
|
+
def install!
|
11
|
+
install_macro_pod!
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def fetcher
|
18
|
+
@fetcher ||= SPM::MacroFetcher.new(
|
19
|
+
name: name,
|
20
|
+
specs_by_platform: specs_by_platform,
|
21
|
+
can_cache: can_cache?
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def prebuilder
|
26
|
+
@prebuilder ||= SPM::MacroPrebuilder.new(name: name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def install_macro_pod!
|
30
|
+
fetcher.run
|
31
|
+
prebuilder.run
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "cocoapods-spm/metadata"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module SPM
|
5
|
+
class MacroPrebuilder
|
6
|
+
include Config::Mixin
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@name = options[:name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
generate_metadata
|
16
|
+
prebuild_macro_impl
|
17
|
+
end
|
18
|
+
|
19
|
+
def macro_downloaded_dir
|
20
|
+
spm_config.macro_downloaded_root_dir / name
|
21
|
+
end
|
22
|
+
|
23
|
+
def macro_dir
|
24
|
+
@macro_dir ||= spm_config.macro_root_dir / name
|
25
|
+
end
|
26
|
+
|
27
|
+
def macro_prebuilt_dir
|
28
|
+
macro_dir / ".prebuilt"
|
29
|
+
end
|
30
|
+
|
31
|
+
def metadata_path
|
32
|
+
macro_dir / "metadata.json"
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_metadata
|
36
|
+
raise "Package.swift not exist in #{macro_downloaded_dir}" \
|
37
|
+
unless (macro_downloaded_dir / "Package.swift").exist?
|
38
|
+
|
39
|
+
cmd =
|
40
|
+
"cd #{macro_downloaded_dir} " \
|
41
|
+
"&& swift package dump-package " \
|
42
|
+
"> #{metadata_path.relative_path_from(macro_downloaded_dir)}"
|
43
|
+
`#{cmd}`
|
44
|
+
@metadata = Metadata.from_file(metadata_path)
|
45
|
+
end
|
46
|
+
|
47
|
+
def prebuild_macro_impl
|
48
|
+
return if spm_config.dont_prebuild_macros?
|
49
|
+
|
50
|
+
config = spm_config.macro_config
|
51
|
+
impl_module_name = @metadata.macro_impl_name
|
52
|
+
return if spm_config.dont_prebuild_macros_if_exist? && (macro_prebuilt_dir / config / impl_module_name).exist?
|
53
|
+
|
54
|
+
UI.puts "Building macro implementation: #{impl_module_name} (#{config})...".green
|
55
|
+
`cd #{macro_downloaded_dir} && swift build -c #{config}`
|
56
|
+
(macro_prebuilt_dir / config).mkpath
|
57
|
+
FileUtils.copy_entry(
|
58
|
+
macro_downloaded_dir / ".build" / config / impl_module_name,
|
59
|
+
macro_prebuilt_dir / config / impl_module_name
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/cocoapods-spm/main.rb
CHANGED
@@ -1,78 +1,5 @@
|
|
1
|
-
require "cocoapods-spm/
|
2
|
-
require "cocoapods-spm/
|
3
|
-
require "cocoapods-spm/
|
4
|
-
|
5
|
-
|
6
|
-
module SPM
|
7
|
-
class Hook
|
8
|
-
def initialize(context)
|
9
|
-
@context = context
|
10
|
-
end
|
11
|
-
|
12
|
-
def sandbox
|
13
|
-
@context.sandbox
|
14
|
-
end
|
15
|
-
|
16
|
-
def pods_project
|
17
|
-
@context.pods_project
|
18
|
-
end
|
19
|
-
|
20
|
-
def config
|
21
|
-
Config.instance
|
22
|
-
end
|
23
|
-
|
24
|
-
def all_specs
|
25
|
-
@all_specs ||= @context.umbrella_targets.flat_map(&:specs).uniq
|
26
|
-
end
|
27
|
-
|
28
|
-
def run
|
29
|
-
all_specs.each do |spec|
|
30
|
-
if spec.spm_dependencies
|
31
|
-
target = pods_project.targets.find { |t| t.name == spec.name }
|
32
|
-
add_spm_dependencies(target, spec.spm_dependencies)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
update_import_paths
|
36
|
-
pods_project.save
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def add_spm_dependencies(target, dependencies)
|
42
|
-
dependencies.each do |data|
|
43
|
-
pkg = pkg_from_data(data)
|
44
|
-
data[:products].each do |product|
|
45
|
-
ref = pods_project.new(Xcodeproj::Project::Object::XCSwiftPackageProductDependency)
|
46
|
-
ref.package = pkg
|
47
|
-
ref.product_name = product
|
48
|
-
target.package_product_dependencies << ref
|
49
|
-
end
|
50
|
-
pods_project.root_object.package_references << pkg
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def update_import_paths
|
55
|
-
# Workaround: Currently, update the swift import paths of the base/Pods project
|
56
|
-
# to make it effective across all pod targets
|
57
|
-
pods_project.build_configurations.each do |config|
|
58
|
-
to_add = '${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}'
|
59
|
-
import_paths = config.build_settings['SWIFT_INCLUDE_PATHS'] || ['$(inherited)']
|
60
|
-
import_paths << to_add unless import_paths.include?(to_add)
|
61
|
-
config.build_settings['SWIFT_INCLUDE_PATHS'] = import_paths
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def pkg_from_data(data)
|
66
|
-
if data[:requirement]
|
67
|
-
pkg = pods_project.new(Xcodeproj::Project::Object::XCRemoteSwiftPackageReference)
|
68
|
-
pkg.repositoryURL = data[:url]
|
69
|
-
pkg.requirement = data[:requirement]
|
70
|
-
else
|
71
|
-
pkg = pods_project.new(Xcodeproj::Project::Object::XCLocalSwiftPackageReference)
|
72
|
-
pkg.relative_path = data[:relative_path]
|
73
|
-
end
|
74
|
-
pkg
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
require "cocoapods-spm/def/target_definition"
|
2
|
+
require "cocoapods-spm/def/podfile"
|
3
|
+
require "cocoapods-spm/def/spec"
|
4
|
+
require "cocoapods-spm/patch/installer"
|
5
|
+
require "cocoapods-spm/command/spm"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module SPM
|
5
|
+
class Metadata
|
6
|
+
attr_reader :raw
|
7
|
+
|
8
|
+
def initialize(raw)
|
9
|
+
@raw = raw
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_file(path)
|
13
|
+
new(JSON.parse(File.read(path)))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.for_pod(name)
|
17
|
+
from_file(Config.instance.macro_root_dir / name / "metadata.json")
|
18
|
+
end
|
19
|
+
|
20
|
+
def targets
|
21
|
+
raw["targets"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def targets_of_type(type)
|
25
|
+
targets.select { |t| t["type"] == type }
|
26
|
+
end
|
27
|
+
|
28
|
+
def macro_impl_name
|
29
|
+
targets_of_type("macro").first&.fetch("name")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "cocoapods-spm/installer/analyzer"
|
2
|
+
require "cocoapods-spm/macro/pod_installer"
|
3
|
+
require "cocoapods-spm/hooks/base"
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
include SPM::Config::Mixin
|
8
|
+
|
9
|
+
alias origin_resolve_dependencies resolve_dependencies
|
10
|
+
def resolve_dependencies
|
11
|
+
origin_resolve_dependencies
|
12
|
+
resolve_spm_dependencies
|
13
|
+
end
|
14
|
+
|
15
|
+
alias origin_create_pod_installer create_pod_installer
|
16
|
+
def create_pod_installer(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
|
+
alias origin_integrate integrate
|
32
|
+
def integrate
|
33
|
+
run_spm_pre_integrate_hooks
|
34
|
+
origin_integrate
|
35
|
+
run_spm_post_integrate_hooks
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def hook_options
|
41
|
+
{
|
42
|
+
:spm_analyzer => @spm_analyzer,
|
43
|
+
:analysis_result => @analysis_result
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def run_spm_pre_integrate_hooks
|
48
|
+
context = PreIntegrateHooksContext.generate(sandbox, pods_project, pod_target_subprojects, aggregate_targets)
|
49
|
+
SPM::Hook.run_hooks(:pre_integrate, context, hook_options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_spm_post_integrate_hooks
|
53
|
+
context = PostIntegrateHooksContext.generate(sandbox, pods_project, pod_target_subprojects, aggregate_targets)
|
54
|
+
SPM::Hook.run_hooks(:post_integrate, context, hook_options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def resolve_spm_dependencies
|
58
|
+
# TODO: convert aggregate_targets to umbrella_targets?
|
59
|
+
@spm_analyzer ||= Pod::Installer::SPMAnalyzer.new(podfile, aggregate_targets)
|
60
|
+
@spm_analyzer.analyze
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/cocoapods_plugin.rb
CHANGED
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.0.
|
4
|
+
version: 0.0.2.rc7194768598
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thuyen Trinh
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -60,16 +60,32 @@ extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
62
|
- lib/cocoapods-spm.rb
|
63
|
+
- lib/cocoapods-spm/command/fetch.rb
|
64
|
+
- lib/cocoapods-spm/command/prebuild.rb
|
65
|
+
- lib/cocoapods-spm/command/spm.rb
|
63
66
|
- lib/cocoapods-spm/config.rb
|
64
|
-
- lib/cocoapods-spm/
|
67
|
+
- lib/cocoapods-spm/def/podfile.rb
|
68
|
+
- lib/cocoapods-spm/def/spec.rb
|
69
|
+
- lib/cocoapods-spm/def/spm_dependency.rb
|
70
|
+
- lib/cocoapods-spm/def/spm_package.rb
|
71
|
+
- lib/cocoapods-spm/def/target_definition.rb
|
72
|
+
- lib/cocoapods-spm/def/xcodeproj.rb
|
73
|
+
- lib/cocoapods-spm/hooks/base.rb
|
74
|
+
- lib/cocoapods-spm/hooks/post_integrate/add_spm_pkgs.rb
|
75
|
+
- lib/cocoapods-spm/hooks/pre_integrate/update_settings.rb
|
76
|
+
- lib/cocoapods-spm/installer/analyzer.rb
|
77
|
+
- lib/cocoapods-spm/macro/fetcher.rb
|
78
|
+
- lib/cocoapods-spm/macro/pod_installer.rb
|
79
|
+
- lib/cocoapods-spm/macro/prebuilder.rb
|
65
80
|
- lib/cocoapods-spm/main.rb
|
66
|
-
- lib/cocoapods-spm/
|
81
|
+
- lib/cocoapods-spm/metadata.rb
|
82
|
+
- lib/cocoapods-spm/patch/installer.rb
|
67
83
|
- lib/cocoapods_plugin.rb
|
68
84
|
homepage: https://github.com/trinhngocthuyen/cocoapods-spm
|
69
85
|
licenses:
|
70
86
|
- MIT
|
71
87
|
metadata: {}
|
72
|
-
post_install_message:
|
88
|
+
post_install_message:
|
73
89
|
rdoc_options: []
|
74
90
|
require_paths:
|
75
91
|
- lib
|
@@ -80,12 +96,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
96
|
version: '0'
|
81
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
98
|
requirements:
|
83
|
-
- - "
|
99
|
+
- - ">"
|
84
100
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
101
|
+
version: 1.3.1
|
86
102
|
requirements: []
|
87
|
-
rubygems_version: 3.
|
88
|
-
signing_key:
|
103
|
+
rubygems_version: 3.1.6
|
104
|
+
signing_key:
|
89
105
|
specification_version: 4
|
90
106
|
summary: CocoaPods plugin to add SPM dependencies to CocoaPods targets
|
91
107
|
test_files: []
|
data/lib/cocoapods-spm/dsl.rb
DELETED