cocoapods-spm 0.0.1 → 0.0.2
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/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 +24 -8
- 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: 4a5eda6a0153888c9f65ee3e325c3dfc4c09aa2de0d8021556da54b3f1ea0d43
|
4
|
+
data.tar.gz: 3d37731a7d09ddc7cfb4064d47a0fa82ad7bc83fd30b7175a66485a8f7f35db0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cfb06f8423f4bfe9ff580aebb49a0417d7d2bd0cc3146114f4b3f40c11c8ed2ced93469d7482a6442f0acd396083256018ca6a8b8b9c0cbb8ffa657e01ad586
|
7
|
+
data.tar.gz: 0111ab82c0ce14ff7a17831450d1710bbd583738a73f037ed09c9b822160a521c1d7f4d05a1587ffe3550836d165595f4c5bbe6372aa1c80ce6eda8e759aa245
|
@@ -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
|
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
|
@@ -84,8 +100,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
100
|
- !ruby/object:Gem::Version
|
85
101
|
version: '0'
|
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