xccache 0.0.1 → 1.0.0.rc15341775774

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/xccache/cache/cachemap.rb +28 -11
  3. data/lib/xccache/command/base.rb +1 -4
  4. data/lib/xccache/command/build.rb +1 -14
  5. data/lib/xccache/command/off.rb +26 -0
  6. data/lib/xccache/command.rb +10 -1
  7. data/lib/xccache/core/config.rb +10 -4
  8. data/lib/xccache/core/hash.rb +9 -6
  9. data/lib/xccache/core/lockfile.rb +62 -7
  10. data/lib/xccache/core/log.rb +5 -0
  11. data/lib/xccache/core/sh.rb +3 -17
  12. data/lib/xccache/core/syntax/hash.rb +4 -0
  13. data/lib/xccache/core/system.rb +2 -1
  14. data/lib/xccache/installer/build.rb +3 -1
  15. data/lib/xccache/installer/integration/build.rb +28 -0
  16. data/lib/xccache/installer/integration/descs.rb +27 -0
  17. data/lib/xccache/installer/integration/supporting_files.rb +29 -0
  18. data/lib/xccache/installer/integration/viz.rb +38 -0
  19. data/lib/xccache/installer/integration.rb +12 -0
  20. data/lib/xccache/installer/use.rb +1 -1
  21. data/lib/xccache/installer.rb +47 -14
  22. data/lib/xccache/spm/build.rb +1 -1
  23. data/lib/xccache/spm/desc/base.rb +1 -4
  24. data/lib/xccache/spm/desc/desc.rb +2 -30
  25. data/lib/xccache/spm/mixin.rb +5 -4
  26. data/lib/xccache/spm/pkg/base.rb +40 -34
  27. data/lib/xccache/spm/pkg/proxy.rb +60 -0
  28. data/lib/xccache/spm/pkg/proxy_executable.rb +51 -0
  29. data/lib/xccache/utils/template.rb +1 -1
  30. data/lib/xccache/xcodeproj/pkg.rb +2 -4
  31. data/lib/xccache/xcodeproj/pkg_product_dependency.rb +16 -3
  32. data/lib/xccache/xcodeproj/project.rb +9 -15
  33. data/lib/xccache/xcodeproj/target.rb +4 -14
  34. data/lib/xccache.rb +5 -0
  35. metadata +12 -12
  36. data/lib/xccache/assets/templates/umbrella.Package.swift.template +0 -182
  37. data/lib/xccache/spm/pkg/umbrella/build.rb +0 -30
  38. data/lib/xccache/spm/pkg/umbrella/cachemap.rb +0 -110
  39. data/lib/xccache/spm/pkg/umbrella/descs.rb +0 -35
  40. data/lib/xccache/spm/pkg/umbrella/manifest.rb +0 -83
  41. data/lib/xccache/spm/pkg/umbrella/viz.rb +0 -40
  42. data/lib/xccache/spm/pkg/umbrella/xcconfigs.rb +0 -31
  43. data/lib/xccache/spm/pkg/umbrella.rb +0 -91
@@ -1,9 +1,11 @@
1
1
  require "xccache/spm"
2
+ require "xccache/installer/integration"
2
3
  Dir["#{__dir__}/#{File.basename(__FILE__, '.rb')}/*.rb"].sort.each { |f| require f }
3
4
 
4
5
  module XCCache
5
6
  class Installer
6
7
  include PkgMixin
8
+ include IntegrationMixin
7
9
 
8
10
  def initialize(options = {})
9
11
  ctx = options[:ctx]
@@ -14,29 +16,33 @@ module XCCache
14
16
  end
15
17
 
16
18
  def perform_install
19
+ verify_projects!
20
+ projects.each { |project| migrate_umbrella_to_proxy(project) }
17
21
  UI.message("Using cache dir: #{config.spm_cache_dir}")
18
22
  config.in_installation = true
19
- if @umbrella_pkg.nil?
20
- sync_lockfile
21
- umbrella_pkg.prepare(**@install_options)
22
- end
23
+ sync_lockfile
24
+ proxy_pkg.prepare(@install_options)
25
+
26
+ yield if block_given?
23
27
 
24
- yield
25
- umbrella_pkg.write_manifest
26
- umbrella_pkg.gen_xcconfigs
28
+ gen_supporting_files
27
29
  projects.each do |project|
28
30
  add_xccache_refs_to_project(project)
29
31
  inject_xcconfig_to_project(project)
30
32
  end
31
- umbrella_pkg.gen_cachemap_viz
33
+ gen_cachemap_viz
32
34
  end
33
35
 
34
36
  def sync_lockfile
35
37
  UI.info("Syncing lockfile")
38
+ known_dependencies = lockfile.known_product_dependencies
36
39
  update_projects do |project|
37
- lockfile.deep_merge!(project.display_name => lockfile_hash_for_project(project))
40
+ lockfile.deep_merge!(
41
+ project.display_name => lockfile_hash_for_project(project, known_dependencies)
42
+ )
38
43
  end
39
44
  lockfile.save
45
+ lockfile.verify!
40
46
  end
41
47
 
42
48
  def lockfile
@@ -53,7 +59,6 @@ module XCCache
53
59
  end
54
60
 
55
61
  def update_projects
56
- verify_projects!
57
62
  projects.each do |project|
58
63
  yield project if block_given?
59
64
  project.save
@@ -62,17 +67,29 @@ module XCCache
62
67
 
63
68
  private
64
69
 
65
- def lockfile_hash_for_project(project)
70
+ def lockfile_hash_for_project(project, known_dependencies)
66
71
  deps_by_targets = project.targets.to_h do |target|
67
- deps = target.non_xccache_pkg_product_dependencies.select(&:pkg).map { |d| "#{d.pkg.slug}/#{d.product_name}" }
68
- [target.name, deps]
72
+ deps = target.non_xccache_pkg_product_dependencies.map do |dep|
73
+ next dep.full_name unless dep.pkg.nil?
74
+ known = known_dependencies.find { |x| File.basename(x) == dep.product_name }
75
+ UI.warn("-> Assuming #{known} for #{dep.full_name}".dark) if known
76
+ known || dep.full_name
77
+ end
78
+ [target.name, deps.sort]
69
79
  end
70
80
  {
71
81
  "packages" => project.non_xccache_pkgs.map(&:to_h),
72
82
  "dependencies" => deps_by_targets,
83
+ "platforms" => platforms_for_project(project),
73
84
  }
74
85
  end
75
86
 
87
+ def platforms_for_project(project)
88
+ project
89
+ .targets.map { |t| [t.platform_name.to_s, t.deployment_target] }
90
+ .sort.reverse.to_h # sort descendingly -> min value is picked for the hash
91
+ end
92
+
76
93
  def verify_projects!
77
94
  raise "No projects detected. Are you running on the correct project directory?" if projects.empty?
78
95
  end
@@ -80,7 +97,7 @@ module XCCache
80
97
  def add_xccache_refs_to_project(project)
81
98
  group = project.xccache_config_group
82
99
  add_file = proc { |p| group[p.basename.to_s] || group.new_file(p) }
83
- add_file.call(config.spm_umbrella_sandbox / "Package.swift")
100
+ add_file.call(config.spm_proxy_sandbox / "Package.swift")
84
101
  add_file.call(config.lockfile.path)
85
102
  add_file.call(config.path) if config.path.exist?
86
103
  group.ensure_synced_group(name: "local-packages", path: config.spm_local_pkgs_dir)
@@ -110,5 +127,21 @@ module XCCache
110
127
  end
111
128
  end
112
129
  end
130
+
131
+ def migrate_umbrella_to_proxy(project)
132
+ return unless project.xccache_pkg&.slug == "umbrella"
133
+
134
+ UI.info <<~DESC
135
+ Migrating from umbrella to proxy for project #{project.display_name}
136
+ You should notice changes in project files from xccache/package/umbrella -> xccache/package/proxy.
137
+ Don't worry, this is expected.
138
+ DESC
139
+ .yellow
140
+
141
+ project.xccache_pkg.relative_path = "xccache/packages/proxy"
142
+ if (group = project.xccache_config_group) && (ref = group["Package.swift"])
143
+ ref.path = "xccache/packages/proxy/Package.swift"
144
+ end
145
+ end
113
146
  end
114
147
  end
@@ -35,7 +35,7 @@ module XCCache
35
35
  cmd << "-Xswiftc" << "-emit-module-interface"
36
36
  cmd << "-Xswiftc" << "-no-verify-emitted-module-interface"
37
37
  end
38
- Sh.run(cmd, suppress_err: /(dependency '.*' is not used by any target|unable to create symbolic link)/)
38
+ Sh.run(cmd)
39
39
  end
40
40
 
41
41
  def swift_build_args
@@ -57,10 +57,7 @@ module XCCache
57
57
  end
58
58
 
59
59
  def src_dir
60
- @src_dir ||= begin
61
- path = root.raw.fetch("packageKind", {}).fetch("root", [])[0]
62
- Pathname.new(path) unless path.nil?
63
- end
60
+ @src_dir ||= Pathname(root.raw["path"]).parent
64
61
  end
65
62
  end
66
63
  end
@@ -5,33 +5,9 @@ module XCCache
5
5
  class Package
6
6
  class Description < BaseObject
7
7
  include Cacheable
8
- cacheable :resolve_recursive_dependencies
9
8
 
10
- def self.descs_in_metadata_dir
11
- descs = Config.instance.spm_metadata_dir.glob("*.json").map { |p| Description.new(p) }
12
- [descs, combine_descs(descs)]
13
- end
14
-
15
- def self.in_dir(dir, save_to_dir: nil)
16
- path = save_to_dir / "#{dir.basename}.json" unless save_to_dir.nil?
17
- begin
18
- raw = JSON.parse(Sh.capture_output("swift package dump-package --package-path #{dir}"))
19
- Description.new(path, raw: raw)
20
- rescue StandardError => e
21
- UI.error("Failed to dump package in #{dir}. Error: #{e}")
22
- end
23
- end
24
-
25
- def self.descs_in_dir(root_dir, save_to_dir: nil)
26
- dirs = [root_dir] + root_dir.glob(".build/checkouts/*").reject { |p| p.glob("Package*.swift").empty? }
27
- descs = dirs.parallel_map do |dir|
28
- desc = Description.in_dir(dir, save_to_dir: save_to_dir)
29
- unless save_to_dir.nil?
30
- desc.save
31
- desc.save(to: desc.path.parent / "#{desc.name}.json") if desc.name != dir.basename.to_s
32
- end
33
- desc
34
- end
9
+ def self.descs_in_metadata_dir(dir)
10
+ descs = dir.glob("*.json").map { |p| Description.new(p) }
35
11
  [descs, combine_descs(descs)]
36
12
  end
37
13
 
@@ -77,10 +53,6 @@ module XCCache
77
53
  .flat_map { |p| targets.select { |t| p.target_names.include?(t.name) } }
78
54
  end
79
55
 
80
- def resolve_recursive_dependencies(platform: nil)
81
- products.to_h { |p| [p, p.recursive_targets(platform: platform)] }
82
- end
83
-
84
56
  def local?
85
57
  # Workaround: If the pkg dir is under the build checkouts dir -> remote
86
58
  !src_dir.to_s.start_with?((config.spm_build_dir / "checkouts").to_s)
@@ -3,10 +3,11 @@ module XCCache
3
3
  include Config::Mixin
4
4
 
5
5
  def umbrella_pkg
6
- @umbrella_pkg ||= SPM::Package::Umbrella.new(
7
- root_dir: config.spm_umbrella_sandbox,
8
- warn_if_not_direct_target: false,
9
- )
6
+ proxy_pkg.umbrella
7
+ end
8
+
9
+ def proxy_pkg
10
+ @proxy_pkg ||= SPM::Package::Proxy.new(root_dir: config.spm_proxy_sandbox)
10
11
  end
11
12
  end
12
13
  end
@@ -2,11 +2,15 @@ require "json"
2
2
  require "xccache/spm/xcframework/slice"
3
3
  require "xccache/spm/xcframework/xcframework"
4
4
  require "xccache/spm/xcframework/metadata"
5
+ require "xccache/spm/pkg/proxy"
5
6
  require "xccache/swift/sdk"
6
7
 
7
8
  module XCCache
8
9
  module SPM
9
10
  class Package
11
+ include Config::Mixin
12
+ include Proxy::Mixin
13
+
10
14
  include Cacheable
11
15
  cacheable :pkg_desc_of_target
12
16
 
@@ -14,7 +18,6 @@ module XCCache
14
18
 
15
19
  def initialize(options = {})
16
20
  @root_dir = Pathname(options[:root_dir] || ".").expand_path
17
- @warn_if_not_direct_target = options.fetch(:warn_if_not_direct_target, true)
18
21
  end
19
22
 
20
23
  def build(options = {})
@@ -33,7 +36,10 @@ module XCCache
33
36
  end
34
37
 
35
38
  def build_target(target: nil, sdks: nil, config: nil, out_dir: nil, **options)
36
- target_pkg_desc = pkg_desc_of_target(target, skip_resolving_dependencies: options[:skip_resolving_dependencies])
39
+ target_pkg_desc = pkg_desc_of_target(
40
+ target,
41
+ ensure_exist: true,
42
+ )
37
43
  if target_pkg_desc.binary_targets.any? { |t| t.name == target }
38
44
  return UI.warn("Target #{target} is a binary target -> no need to build")
39
45
  end
@@ -42,33 +48,44 @@ module XCCache
42
48
 
43
49
  out_dir = Pathname(out_dir || ".")
44
50
  out_dir /= target.name if options[:checksum]
51
+ ext = target.macro? ? ".macro" : ".xcframework"
45
52
  basename = options[:checksum] ? "#{target.name}-#{target.checksum}" : target.name
46
- basename += target.macro? ? ".macro" : ".xcframework"
53
+ binary_path = out_dir / "#{basename}#{ext}"
47
54
 
48
- Dir.create_tmpdir do |_tmpdir|
55
+ Dir.create_tmpdir do |tmpdir|
49
56
  cls = target.macro? ? Macro : XCFramework
50
57
  cls.new(
51
58
  name: target.name,
52
59
  pkg_dir: root_dir,
53
60
  config: config,
54
61
  sdks: sdks,
55
- path: out_dir / basename,
56
- tmpdir: Dir.create_tmpdir,
62
+ path: binary_path,
63
+ tmpdir: tmpdir,
57
64
  pkg_desc: target_pkg_desc,
58
65
  library_evolution: options[:library_evolution],
59
66
  ).build(**options)
60
67
  end
68
+ return if (symlinks_dir = options[:symlinks_dir]).nil?
69
+ binary_path.symlink_to(symlinks_dir / target.name / "#{target.name}#{ext}")
61
70
  end
62
71
 
63
- def resolve(force: false)
64
- return if @resolved && !force
65
-
66
- UI.section("Resolving package dependencies (package: #{root_dir.basename})", timing: true) do
67
- Sh.run("swift package resolve --package-path #{root_dir} 2>&1")
68
- end
72
+ def resolve
73
+ return if @resolved
74
+ xccache_proxy.run("resolve --pkg #{root_dir} --metadata #{metadata_dir}")
69
75
  @resolved = true
70
76
  end
71
77
 
78
+ def pkg_desc_of_target(name, **options)
79
+ resolve
80
+ desc = descs.find { |d| d.has_target?(name) }
81
+ raise GeneralError, "Cannot find package with the given target #{name}" if options[:ensure_exist] && desc.nil?
82
+ desc
83
+ end
84
+
85
+ def get_target(name)
86
+ pkg_desc_of_target(name)&.get_target(name)
87
+ end
88
+
72
89
  private
73
90
 
74
91
  def validate!
@@ -76,31 +93,20 @@ module XCCache
76
93
  raise GeneralError, "No Package.swift in #{root_dir}. Are you sure you're running on a package dir?"
77
94
  end
78
95
 
79
- def pkg_desc_of_target(name, skip_resolving_dependencies: false)
80
- # The current package contains the given target
81
- return pkg_desc if pkg_desc.has_target?(name)
96
+ def metadata_dir
97
+ config.in_installation? ? config.spm_metadata_dir : root_dir / ".build/metadata"
98
+ end
82
99
 
83
- if @warn_if_not_direct_target
84
- UI.message(
85
- "#{name.yellow.dark} is not a direct target of package #{root_dir.basename.to_s.dark} " \
86
- "-> trigger from dependencies"
87
- )
88
- end
89
- # Otherwise, it's inside one of the dependencies. Need to resolve then find it
90
- resolve unless skip_resolving_dependencies
91
-
92
- @descs ||= if Config.instance.in_installation?
93
- then Description.descs_in_metadata_dir[0]
94
- else
95
- Description.descs_in_dir(Pathname(".").expand_path)[0]
96
- end
97
- desc = @descs.find { |d| d.has_target?(name) }
98
- return desc unless desc.nil?
99
- raise GeneralError, "Cannot find package with the given target #{name}"
100
+ def descs
101
+ @descs ||= load_descs[0]
102
+ end
103
+
104
+ def descs_by_name
105
+ @descs_by_name ||= load_descs[1]
100
106
  end
101
107
 
102
- def pkg_desc
103
- @pkg_desc ||= Description.in_dir(root_dir)
108
+ def load_descs
109
+ @descs, @descs_by_name = Description.descs_in_metadata_dir(metadata_dir)
104
110
  end
105
111
  end
106
112
  end
@@ -0,0 +1,60 @@
1
+ Dir["#{__dir__}/#{File.basename(__FILE__, '.rb')}/*.rb"].sort.each { |f| require f }
2
+ require_relative "proxy_executable"
3
+
4
+ module XCCache
5
+ module SPM
6
+ class Package
7
+ class Proxy < Package
8
+ module Mixin
9
+ def xccache_proxy
10
+ @xccache_proxy ||= Executable.new
11
+ end
12
+ end
13
+
14
+ include Mixin
15
+
16
+ def umbrella
17
+ @umbrella ||= Package.new(root_dir: config.spm_umbrella_sandbox)
18
+ end
19
+
20
+ def prepare(options = {})
21
+ xccache_proxy.run("gen-umbrella")
22
+ umbrella.resolve
23
+ invalidate_cache(sdks: options[:sdks])
24
+ gen_proxy
25
+ end
26
+
27
+ def gen_proxy
28
+ xccache_proxy.run("gen-proxy")
29
+ config.cachemap.update_from_graph(graph.reload)
30
+ end
31
+
32
+ def invalidate_cache(sdks: [])
33
+ UI.message("Invalidating cache (sdks: #{sdks.map(&:name)})")
34
+
35
+ config.spm_cache_dir.glob("*/*.{xcframework,macro}").each do |p|
36
+ cmps = p.basename(".*").to_s.split("-")
37
+ name, checksum = cmps[...-1].join("-"), cmps[-1]
38
+ p_without_checksum = config.spm_binaries_dir / name / "#{name}#{p.extname}"
39
+ accept_cache = proc { p.symlink_to(p_without_checksum) }
40
+ reject_cache = proc { p_without_checksum.rmtree if p_without_checksum.exist? }
41
+ next reject_cache.call if (target = umbrella.get_target(name)).nil?
42
+ next reject_cache.call if target.checksum != checksum
43
+ # For macro, we just need the tool binary to exist
44
+ next accept_cache.call if target.macro?
45
+
46
+ # For regular targets, the xcframework must satisfy the sdk constraints (ie. containing all the slices)
47
+ metadata = XCFramework::Metadata.new(p / "Info.plist")
48
+ expected_triples = sdks.map { |sdk| sdk.triple(without_vendor: true) }
49
+ missing_triples = expected_triples - metadata.triples
50
+ missing_triples.empty? ? accept_cache.call : reject_cache.call
51
+ end
52
+ end
53
+
54
+ def graph
55
+ @graph ||= JSONRepresentable.new(root_dir / "graph.json")
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ module XCCache
2
+ module SPM
3
+ class Package
4
+ class Proxy < Package
5
+ class Executable
6
+ VERSION = "0.0.1rc3".freeze
7
+
8
+ def run(cmd)
9
+ env = { "FORCE_OUTPUT" => "console", "FORCE_COLOR" => "1" } if Config.instance.ansi?
10
+ cmd = cmd.is_a?(Array) ? [bin_path.to_s] + cmd : [bin_path.to_s, cmd]
11
+ Sh.run(cmd, env: env)
12
+ end
13
+
14
+ def bin_path
15
+ @bin_path ||= lookup
16
+ end
17
+
18
+ private
19
+
20
+ def lookup
21
+ [
22
+ local_bin_path,
23
+ default_bin_path,
24
+ ].find(&:exist?) || download
25
+ end
26
+
27
+ def download
28
+ UI.section("Downloading xccache-proxy binary from remote...".magenta) do
29
+ Dir.create_tmpdir do |dir|
30
+ url = "https://github.com/trinhngocthuyen/xccache-proxy/releases/download/#{VERSION}/xccache-proxy.zip"
31
+ default_bin_path.parent.mkpath
32
+ tmp_path = dir / File.basename(url)
33
+ Sh.run("curl -fSL -o #{tmp_path} #{url} && unzip -d #{default_bin_path.parent} #{tmp_path}")
34
+ FileUtils.chmod("+x", default_bin_path)
35
+ end
36
+ end
37
+ default_bin_path
38
+ end
39
+
40
+ def default_bin_path
41
+ @default_bin_path ||= LIBEXEC / ".download" / "xccache-proxy-#{VERSION}" / "xccache-proxy"
42
+ end
43
+
44
+ def local_bin_path
45
+ @local_bin_path ||= LIBEXEC / ".local" / "xccache-proxy"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -7,7 +7,7 @@ module XCCache
7
7
 
8
8
  def initialize(name)
9
9
  @name = name
10
- @path = Gem.find_files("xccache/assets/templates/#{name}.template").first
10
+ @path = ROOT / "lib/xccache/assets/templates/#{name}.template"
11
11
  end
12
12
 
13
13
  def render(hash = {}, save_to: nil)
@@ -17,7 +17,7 @@ module Xcodeproj
17
17
  end
18
18
 
19
19
  def xccache_pkg?
20
- local? && id == "xccache/packages/umbrella"
20
+ local? && ["xccache/packages/umbrella", "xccache/packages/proxy"].include?(id)
21
21
  end
22
22
 
23
23
  def non_xccache_pkg?
@@ -50,9 +50,7 @@ module Xcodeproj
50
50
 
51
51
  def to_h
52
52
  {
53
- "relative_path" => relative_path,
54
- "path" => path,
55
- "path_from_root" => absolute_path.relative_path_from(Pathname(".").expand_path).to_s,
53
+ "path_from_root" => absolute_path.relative_path_from(Pathname.pwd).to_s,
56
54
  }
57
55
  end
58
56
 
@@ -5,13 +5,26 @@ module Xcodeproj
5
5
  module Object
6
6
  class XCSwiftPackageProductDependency
7
7
  def full_name
8
- "#{pkg.slug}/#{product_name}"
8
+ @full_name ||= "#{pkg&.slug || '__unknown__'}/#{product_name}"
9
9
  end
10
10
 
11
11
  def pkg
12
- return package unless package.nil?
12
+ return package if package
13
+ return if @warned_missing_pkg
14
+ @warned_missing_pkg = true
15
+ Log.warn("Missing pkg of product dependency #{uuid}: #{to_hash}")
16
+ end
13
17
 
14
- Log.warn("Missing pkg for #{inspect}")
18
+ def remove_alongside_related
19
+ target = referrers.find { |x| x.is_a?(PBXNativeTarget) }
20
+ Log.info(
21
+ "(-) Remove #{product_name.red} from product dependencies of target #{target.display_name.bold}"
22
+ )
23
+ target.dependencies.each { |x| x.remove_from_project if x.product_ref == self }
24
+ target.build_phases.each do |phase|
25
+ phase.files.select { |f| f.remove_from_project if f.product_ref == self }
26
+ end
27
+ remove_from_project
15
28
  end
16
29
  end
17
30
  end
@@ -29,8 +29,8 @@ module Xcodeproj
29
29
  end
30
30
 
31
31
  def has_pkg?(hash)
32
- id = hash[pkg_key_in_hash(hash)]
33
- pkgs.any? { |p| p.id == id }
32
+ pkg_hash = XCCache::Lockfile::Pkg.from_h(hash)
33
+ pkgs.any? { |p| p.id == pkg_hash.id }
34
34
  end
35
35
 
36
36
  def has_xccache_pkg?
@@ -38,26 +38,26 @@ module Xcodeproj
38
38
  end
39
39
 
40
40
  def add_pkg(hash)
41
- key = pkg_key_in_hash(hash)
42
- is_local = ["relative_path", "path"].include?(key)
41
+ pkg_hash = XCCache::Lockfile::Pkg.from_h(hash)
42
+ pkg_hash["relative_path"] = pkg_hash.relative_path_from_dir(dir).to_s if pkg_hash.key == "path_from_root"
43
43
 
44
- Log.message("Add package #{hash[key].bold} to project #{display_name.bold}")
45
- cls = is_local ? XCLocalSwiftPackageReference : XCRemoteSwiftPackageReference
44
+ Log.info("Add package #{pkg_hash.id.bold} to project #{display_name.bold}")
45
+ cls = pkg_hash.local? ? XCLocalSwiftPackageReference : XCRemoteSwiftPackageReference
46
46
  ref = new(cls)
47
47
  custom_keys = ["path_from_root"]
48
- hash.each { |k, v| ref.send("#{k}=", v) unless custom_keys.include?(k) }
48
+ pkg_hash.each { |k, v| ref.send("#{k}=", v) unless custom_keys.include?(k) }
49
49
  root_object.package_references << ref
50
50
  ref
51
51
  end
52
52
 
53
53
  def add_xccache_pkg
54
- sandbox_path = XCCache::Config.instance.spm_umbrella_sandbox
54
+ sandbox_path = XCCache::Config.instance.spm_proxy_sandbox
55
55
  add_pkg("relative_path" => sandbox_path.relative_path_from(path.parent).to_s)
56
56
  end
57
57
 
58
58
  def remove_pkgs(&block)
59
59
  pkgs.select(&block).each do |pkg|
60
- XCCache::UI.info("(-) Remove #{pkg.display_name.red} from package refs of project #{display_name.bold}")
60
+ Log.info("(-) Remove #{pkg.display_name.red} from package refs of project #{display_name.bold}")
61
61
  pkg.remove_from_project
62
62
  end
63
63
  end
@@ -73,11 +73,5 @@ module Xcodeproj
73
73
  def xccache_config_group
74
74
  self["xccache.config"] || new_group("xccache.config")
75
75
  end
76
-
77
- private
78
-
79
- def pkg_key_in_hash(hash)
80
- ["repositoryURL", "relative_path", "path"].find { |k| hash.key?(k) }
81
- end
82
76
  end
83
77
  end
@@ -19,32 +19,22 @@ module Xcodeproj
19
19
  end
20
20
 
21
21
  def add_pkg_product_dependency(name)
22
- Log.message("(+) Add dependency #{name.blue} to target #{display_name.bold}")
22
+ Log.info("(+) Add dependency #{name.blue} to target #{display_name.bold}")
23
23
  pkg_name, product_name = name.split("/")
24
24
  pkg = project.get_pkg(pkg_name)
25
25
  pkg_product_dependencies << pkg.create_target_dependency_ref(product_name).product_ref
26
26
  end
27
27
 
28
28
  def add_xccache_product_dependency
29
- add_pkg_product_dependency("umbrella/#{name}.xccache")
29
+ add_pkg_product_dependency("proxy/#{name}.xccache")
30
30
  end
31
31
 
32
32
  def remove_xccache_product_dependencies
33
- remove_pkg_product_dependencies { |d| d.pkg.xccache_pkg? }
33
+ remove_pkg_product_dependencies { |d| d.pkg&.xccache_pkg? }
34
34
  end
35
35
 
36
36
  def remove_pkg_product_dependencies(&block)
37
- package_product_dependencies.select(&block).each do |d|
38
- XCCache::UI.info(
39
- "(-) Remove #{d.product_name.red} from product dependencies of target #{display_name.bold}"
40
- )
41
- build_phases.each do |phase|
42
- phase.files.select { |f| f.remove_from_project if f.product_ref == d }
43
- end
44
- # Remove it from target dependencies
45
- dependencies.each { |x| x.remove_from_project if x.product_ref == d }
46
- d.remove_from_project
47
- end
37
+ package_product_dependencies.select(&block).each(&:remove_alongside_related)
48
38
  end
49
39
  end
50
40
  end
data/lib/xccache.rb CHANGED
@@ -1 +1,6 @@
1
1
  require "xccache/main"
2
+
3
+ module XCCache
4
+ ROOT = Pathname(__dir__).parent
5
+ LIBEXEC = ROOT / "libexec"
6
+ end