cocoapods-spm 0.0.1 → 0.0.2.rc7194768598

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88926a40ad19c2ccc3b9ceccefe301a6f939ec7460c719b914a13eba5c1d3739
4
- data.tar.gz: 190363f1092af74595af470f7bdc617e8ffaca00314894b136298a9c31e9d979
3
+ metadata.gz: 023cb57cc496da534db60773efea73bdcdc40a869a7edeee06e52c16344dbe98
4
+ data.tar.gz: 5cc2ca8ee116d74324e187a1a3150386f74e01a9994f5d4a05278fc55820986f
5
5
  SHA512:
6
- metadata.gz: '06209d7e15bdbccf151db058e53dc27dfb9179d75ed76c6341518f5f56f02d62629ae2f0a369cdace8e719725a040aee2a24d626b709f280c15b18277f2ca636'
7
- data.tar.gz: c40d20e4560c12625ac7a4a52c6bbcee54407582039ac59f829f75978c29581379f24514e489fa6f393ef8872a131ce7608969b193927cabca7dfc2f06a0db35
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
@@ -1,15 +1,65 @@
1
1
  module Pod
2
2
  module SPM
3
3
  class Config
4
- attr_accessor :dsl_config
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,15 @@
1
+ require "cocoapods-spm/def/spm_package"
2
+
3
+ module Pod
4
+ class Podfile
5
+ class TargetDefinition
6
+ def store_spm_pkg(name, options)
7
+ spm_pkgs << SPM::Package.new(name, options)
8
+ end
9
+
10
+ def spm_pkgs
11
+ @spm_pkgs ||= []
12
+ end
13
+ end
14
+ end
15
+ 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
@@ -1,78 +1,5 @@
1
- require "cocoapods-spm/config"
2
- require "cocoapods-spm/dsl"
3
- require "cocoapods-spm/specification"
4
-
5
- module Pod
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
@@ -1,5 +1 @@
1
1
  require "cocoapods-spm/main"
2
-
3
- Pod::HooksManager.register("cocoapods-spm", :post_install) do |context|
4
- Pod::SPM::Hook.new(context).run
5
- 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.0.1
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-28 00:00:00.000000000 Z
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/dsl.rb
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/specification.rb
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: '0'
101
+ version: 1.3.1
86
102
  requirements: []
87
- rubygems_version: 3.2.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: []
@@ -1,11 +0,0 @@
1
- require "cocoapods-spm/config"
2
-
3
- module Pod
4
- class Podfile
5
- module DSL
6
- def config_xcconfig_hooks(options)
7
- Pod::SPM::Config.instance.dsl_config = options
8
- end
9
- end
10
- end
11
- end
@@ -1,10 +0,0 @@
1
- module Pod
2
- class Specification
3
- attr_reader :spm_dependencies
4
-
5
- def spm_dependency(options)
6
- @spm_dependencies ||= []
7
- @spm_dependencies << options
8
- end
9
- end
10
- end