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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b10dd2ba3e0a83b400776d8dde8116be6632a9806714ee85526f3788f6364cab
4
- data.tar.gz: 789518eadb39c223a5044788122897e7b38c62d0e487733736602b22cb17ff8b
3
+ metadata.gz: 9f7b0d46b9a50e667904aedb052da8fa0605932bcd56c518bb308b9802622d74
4
+ data.tar.gz: 3b98c6610a1f5db2223f93747533a5b8c27f35a163b0e2b6d480a264b7a9ffd0
5
5
  SHA512:
6
- metadata.gz: 349bbbf1f5101dfc4e4555ff8e9546fa870660ad2f600ea57b28fdbb7a8f7d6007d9fd7aab37937c61659f181fc85d19358c7bc00b3408118d0f4a8e8e6c989e
7
- data.tar.gz: f77646c655bdfbcb413a5112f1935545dc2b6c042f92122c0181b9f4b9761874dcc75cad783d645cad5f332eeb49f71181aa9766b84d9f498486ccd7e50e6a3d
6
+ metadata.gz: 00d1a9e5103c69e770c96b78012ae25ee9dbfd6dbacfee4d2d5b2962d52a116663dfae34e3b7263ead13928470883c555cf11e1d0b17d8c332939d1d8938a1b1
7
+ data.tar.gz: efb6d6d67964fe7edd78a08985682101c691d38837f92a322c5e85a395808a88e248db6cce3c01aadc4b9dc8b2f97a4d6340be129c61ef0bd2a8cfe7558b8171
@@ -11,14 +11,6 @@ module XCCache
11
11
  raw["cache"] ||= {}
12
12
  end
13
13
 
14
- def manifest_data
15
- raw["manifest"] ||= {
16
- "targets" => {},
17
- "deps" => {},
18
- "macros" => {},
19
- }
20
- end
21
-
22
14
  def missed?(name)
23
15
  missed.include?(name)
24
16
  end
@@ -36,20 +28,45 @@ module XCCache
36
28
  end
37
29
 
38
30
  def print_stats
39
- hit, missed, ignored = %i[hit missed ignore].map { |type| get_cache_data(type) }
31
+ hit, missed, ignored = %i[hit missed ignored].map { |type| get_cache_data(type) }
40
32
  total_count = cache_data.count
41
33
  UI.message <<~DESC
42
34
  -------------------------------------------------------------------
43
35
  Cache stats
44
36
  • Hit (#{hit.count}/#{total_count}): #{hit.to_s.green.dark}
45
37
  • Missed (#{missed.count}/#{total_count}): #{missed.to_s.yellow.dark}
46
- • Ignored (#{ignored.count}/#{total_count}): #{ignored.to_s.yellow.dark}
38
+ • Ignored (#{ignored.count}/#{total_count}): #{ignored.to_s.dark}
47
39
  -------------------------------------------------------------------
48
40
  DESC
49
41
  end
50
42
 
51
43
  def get_cache_data(type)
52
- cache_data.select { |_, v| v == type }.keys
44
+ cache_data.select { |k, v| v == type && !k.end_with?(".xccache") }.keys
45
+ end
46
+
47
+ def update_from_graph(graph)
48
+ cache_data = graph["cache"].to_h do |k, v|
49
+ next [k, :hit] if v
50
+ next [k, :ignored] if Config.instance.ignore?(k)
51
+ [k, :missed]
52
+ end
53
+
54
+ deps = graph["deps"]
55
+ edges = deps.flat_map { |k, xs| xs.map { |v| { :source => k, :target => v } } }
56
+ nodes = deps.keys.map do |k|
57
+ {
58
+ :id => k,
59
+ :cache => cache_data[k],
60
+ :type => ("agg" if k.end_with?(".xccache")),
61
+ :binary => graph["cache"][k],
62
+ }
63
+ end
64
+ self.raw = {
65
+ "cache" => cache_data,
66
+ "depgraph" => { "nodes" => nodes, "edges" => edges },
67
+ }
68
+ save
69
+ print_stats
53
70
  end
54
71
  end
55
72
  end
@@ -5,9 +5,6 @@ module XCCache
5
5
  class Options
6
6
  SDK = ["--sdk=foo,bar", "SDKs (iphonesimulator, iphoneos, etc.)"].freeze
7
7
  CONFIG = ["--config=foo", "Configuration (debug, release) (default: debug)"].freeze
8
- SKIP_RESOLVING_DEPENDENCIES = [
9
- "--skip-resolving-dependencies", "Skip resolving package dependencies",
10
- ].freeze
11
8
  MERGE_SLICES = [
12
9
  "--merge-slices/--no-merge-slices",
13
10
  "Whether to merge with existing slices/sdks in the xcframework (default: true)",
@@ -18,7 +15,7 @@ module XCCache
18
15
  ].freeze
19
16
 
20
17
  def self.install_options
21
- [SDK, CONFIG, SKIP_RESOLVING_DEPENDENCIES]
18
+ [SDK, CONFIG]
22
19
  end
23
20
 
24
21
  def self.build_options
@@ -8,7 +8,6 @@ module XCCache
8
8
  def self.options
9
9
  [
10
10
  *Options.build_options,
11
- ["--integrate/no-integrate", "Whether to integrate after building target (default: true)"],
12
11
  ["--recursive", "Whether to build their recursive targets if cache-missed (default: false)"],
13
12
  ].concat(super)
14
13
  end
@@ -19,22 +18,10 @@ module XCCache
19
18
  def initialize(argv)
20
19
  super
21
20
  @targets = argv.arguments!
22
- @should_integrate = argv.flag?("integrate", true)
23
21
  end
24
22
 
25
23
  def run
26
- installer = Installer::Build.new(
27
- ctx: self,
28
- targets: @targets,
29
- )
30
- installer.install!
31
-
32
- # Reuse umbrella_pkg from previous installers
33
- return unless @should_integrate
34
- Installer::Use.new(
35
- ctx: self,
36
- umbrella_pkg: installer.umbrella_pkg,
37
- ).install!
24
+ Installer::Build.new(ctx: self, targets: @targets).install!
38
25
  end
39
26
  end
40
27
  end
@@ -0,0 +1,26 @@
1
+ require "xccache/installer"
2
+ require_relative "base"
3
+
4
+ module XCCache
5
+ class Command
6
+ class Off < Command
7
+ self.summary = "Force-switch to source mode for specific targets"
8
+ self.arguments = [
9
+ CLAide::Argument.new("TARGET", false, true),
10
+ ]
11
+
12
+ def initialize(argv)
13
+ super
14
+ @targets = argv.arguments!
15
+ end
16
+
17
+ def run
18
+ return if @targets.empty?
19
+
20
+ UI.info("Will force-use source mode for targets: #{@targets}")
21
+ @targets.each { |t| config.ignore_list << "*/#{t}" }
22
+ Installer::Use.new(ctx: self).install!
23
+ end
24
+ end
25
+ end
26
+ end
@@ -15,12 +15,12 @@ module XCCache
15
15
 
16
16
  def initialize(argv)
17
17
  super
18
+ set_ansi_mode
18
19
  config.verbose = verbose unless verbose.nil?
19
20
  config.install_config = argv.option("config", "debug")
20
21
  @install_options = {
21
22
  :sdks => str_to_sdks(argv.option("sdk")),
22
23
  :config => config.install_config,
23
- :skip_resolving_dependencies => argv.flag?("skip-resolving-dependencies"),
24
24
  }
25
25
  @build_options = {
26
26
  **@install_options,
@@ -33,5 +33,14 @@ module XCCache
33
33
  def str_to_sdks(str)
34
34
  (str || config.default_sdk).split(",").map { |s| Swift::Sdk.new(s) }
35
35
  end
36
+
37
+ private
38
+
39
+ def set_ansi_mode
40
+ config.ansi = ansi_output?
41
+ return if ansi_output?
42
+ Colored2.disable!
43
+ String.send(:define_method, :colorize) { |s, _| s }
44
+ end
36
45
  end
37
46
  end
@@ -13,8 +13,9 @@ module XCCache
13
13
  @instance ||= new(Pathname("xccache.yml").expand_path)
14
14
  end
15
15
 
16
- attr_accessor :verbose
16
+ attr_accessor :verbose, :ansi
17
17
  alias verbose? verbose
18
+ alias ansi? ansi
18
19
 
19
20
  # To distinguish if it's within an installation, or standalone like `xccache pkg build`
20
21
  attr_accessor :in_installation
@@ -35,11 +36,11 @@ module XCCache
35
36
  end
36
37
 
37
38
  def spm_local_pkgs_dir
38
- @spm_local_pkgs_dir ||= Dir.prepare(spm_sandbox / "local")
39
+ @spm_local_pkgs_dir ||= Dir.prepare(spm_sandbox / "local", clean: true)
39
40
  end
40
41
 
41
42
  def spm_xcconfig_dir
42
- @spm_xcconfig_dir ||= Dir.prepare(spm_sandbox / "xcconfigs")
43
+ @spm_xcconfig_dir ||= Dir.prepare(spm_sandbox / "xcconfigs", clean: true)
43
44
  end
44
45
 
45
46
  def spm_cache_dir
@@ -47,7 +48,7 @@ module XCCache
47
48
  end
48
49
 
49
50
  def spm_binaries_dir
50
- @spm_binaries_dir ||= Dir.prepare(spm_umbrella_sandbox / "binaries")
51
+ @spm_binaries_dir ||= Dir.prepare(spm_sandbox / "binaries", clean: true)
51
52
  end
52
53
 
53
54
  def spm_build_dir
@@ -58,6 +59,10 @@ module XCCache
58
59
  @spm_artifacts_dir ||= spm_build_dir / "artifacts"
59
60
  end
60
61
 
62
+ def spm_proxy_sandbox
63
+ @spm_proxy_sandbox ||= Dir.prepare(spm_sandbox / "proxy")
64
+ end
65
+
61
66
  def spm_umbrella_sandbox
62
67
  @spm_umbrella_sandbox ||= Dir.prepare(spm_sandbox / "umbrella")
63
68
  end
@@ -71,6 +76,7 @@ module XCCache
71
76
  end
72
77
 
73
78
  def cachemap
79
+ require "xccache/cache/cachemap"
74
80
  @cachemap ||= Cache::Cachemap.new(sandbox / "cachemap.json")
75
81
  end
76
82
 
@@ -1,12 +1,12 @@
1
1
  class Hash
2
- def deep_merge(other, uniq_block: nil, &block)
3
- dup.deep_merge!(other, uniq_block: uniq_block, &block)
2
+ def deep_merge(other, uniq_block: nil, sort_block: nil, &block)
3
+ dup.deep_merge!(other, uniq_block: uniq_block, sort_block: sort_block, &block)
4
4
  end
5
5
 
6
- def deep_merge!(other, uniq_block: nil, &block)
6
+ def deep_merge!(other, uniq_block: nil, sort_block: nil, &block)
7
7
  merge!(other) do |key, this_val, other_val|
8
8
  result = if this_val.is_a?(Hash) && other_val.is_a?(Hash)
9
- this_val.deep_merge(other_val, uniq_block: uniq_block, &block)
9
+ this_val.deep_merge(other_val, uniq_block: uniq_block, sort_block: sort_block, &block)
10
10
  elsif this_val.is_a?(Array) && other_val.is_a?(Array)
11
11
  this_val + other_val
12
12
  elsif block_given?
@@ -14,8 +14,11 @@ class Hash
14
14
  else
15
15
  other_val
16
16
  end
17
- next result if uniq_block.nil? || !result.is_a?(Array)
18
- result.reverse.uniq(&uniq_block).reverse # prefer updates
17
+
18
+ # uniq by block, prefer updates
19
+ result = result.reverse.uniq(&uniq_block).reverse if uniq_block && result.is_a?(Array)
20
+ result = result.sort_by(&sort_block) if sort_block && result.is_a?(Array)
21
+ result
19
22
  end
20
23
  end
21
24
  end
@@ -2,6 +2,37 @@ require "xccache/core/syntax/json"
2
2
 
3
3
  module XCCache
4
4
  class Lockfile < JSONRepresentable
5
+ class Pkg < Hash
6
+ def self.from_h(h)
7
+ Pkg.new.merge(h)
8
+ end
9
+
10
+ def key
11
+ @key ||= ["repositoryURL", "path_from_root", "relative_path"].find { |x| key?(x) }
12
+ end
13
+
14
+ def id
15
+ self[key]
16
+ end
17
+
18
+ def local?
19
+ key != "repositoryURL"
20
+ end
21
+
22
+ def slug
23
+ @slug ||= File.basename(id, ".*")
24
+ end
25
+
26
+ def relative_path_from_dir(dir)
27
+ return id if key == "relative_path"
28
+ (Pathname.pwd / id).relative_path_from(dir) if key == "path_from_root"
29
+ end
30
+
31
+ def local_absolute_path
32
+ Pathname.pwd / self["path_from_root"] if local?
33
+ end
34
+ end
35
+
5
36
  def hash_for_project(project)
6
37
  raw[project.display_name] ||= {}
7
38
  end
@@ -11,22 +42,31 @@ module XCCache
11
42
  end
12
43
 
13
44
  def deep_merge!(hash)
14
- keys = ["repositoryURL", "path_from_root", "relative_path"]
15
- raw.deep_merge!(hash, uniq_block: proc do |h|
16
- h.is_a?(Hash) && (k = keys.find { |k| h.key?(k) }) ? h[k] : h
17
- end)
45
+ raw.deep_merge!(
46
+ hash,
47
+ uniq_block: proc { |h| h.is_a?(Hash) ? Pkg.from_h(h).id || h : h },
48
+ sort_block: proc { |x| x.to_s.downcase },
49
+ )
50
+ # After deep_merge, clear property cache
51
+ (instance_variables - %i[@path @raw]).each do |ivar|
52
+ remove_instance_variable(ivar)
53
+ end
18
54
  end
19
55
 
20
56
  def pkgs
21
- @pkgs ||= raw.values.flat_map { |h| h["packages"] || [] }
57
+ @pkgs ||= raw.values.flat_map { |h| h["packages"] || [] }.map { |h| Pkg.from_h(h) }
22
58
  end
23
59
 
24
60
  def local_pkgs
25
- @local_pkgs ||= pkgs.select { |h| h.key?("relative_path") || h.key?("path") }
61
+ @local_pkgs ||= pkgs.select(&:local?).uniq
26
62
  end
27
63
 
28
64
  def local_pkg_slugs
29
- @local_pkg_slugs ||= local_pkgs.map { |h| File.basename(h["relative_path"] || h["path"]) }.uniq
65
+ @local_pkg_slugs ||= local_pkgs.map(&:slug).uniq
66
+ end
67
+
68
+ def known_product_dependencies
69
+ raw.empty? ? [] : product_dependencies.reject { |d| File.dirname(d) == "__unknown__" }
30
70
  end
31
71
 
32
72
  def product_dependencies
@@ -36,5 +76,20 @@ module XCCache
36
76
  def targets_data
37
77
  @targets_data ||= product_dependencies_by_targets.transform_keys { |k| "#{k}.xccache" }
38
78
  end
79
+
80
+ def verify!
81
+ known_slugs = pkgs.map(&:slug)
82
+ unknown = product_dependencies.reject { |d| known_slugs.include?(File.dirname(d)) }
83
+ return if unknown.empty?
84
+
85
+ UI.error! <<~DESC
86
+ Unknown product dependencies at #{path}:
87
+
88
+ #{unknown.sort.map { |d| " • #{d}" }.join("\n")}
89
+
90
+ Refer to this doc for how to resolve this issue:
91
+ https://github.com/trinhngocthuyen/xccache/blob/main/docs/troubleshooting.md#unknown-product-dependencies
92
+ DESC
93
+ end
39
94
  end
40
95
  end
@@ -43,6 +43,11 @@ module XCCache
43
43
  UI.puts("[ERROR] #{message}".red)
44
44
  end
45
45
 
46
+ def error!(message)
47
+ error(message)
48
+ raise GeneralError, message
49
+ end
50
+
46
51
  def puts(message)
47
52
  $stdout.puts("#{' ' * self.indent}#{message}")
48
53
  end
@@ -18,27 +18,13 @@ module XCCache
18
18
  def run(*args, env: nil, **options)
19
19
  cmd = args.join(" ")
20
20
  UI.message("$ #{cmd}".cyan.dark) if config.verbose? && options[:log_cmd] != false
21
+ return system(cmd) || (raise GeneralError, "Command '#{cmd}' failed") unless options[:capture]
21
22
 
22
23
  out, err = [], []
23
- handle_out = proc do |line|
24
- if options[:capture]
25
- out << line
26
- else
27
- UI.puts line
28
- end
29
- end
30
- handle_err = proc do |line|
31
- if options[:capture]
32
- err << line
33
- else
34
- UI.puts line.strip.yellow unless options[:suppress_err]&.match(line)
35
- end
36
- end
37
-
38
24
  popen3_args = env ? [env, cmd] : [cmd]
39
25
  Open3.popen3(*popen3_args) do |_stdin, stdout, stderr, wait_thr|
40
- stdout_thread = Thread.new { stdout.each { |l| handle_out.call(l) } }
41
- stderr_thread = Thread.new { stderr.each { |l| handle_err.call(l) } }
26
+ stdout_thread = Thread.new { stdout.each { |l| out << l } }
27
+ stderr_thread = Thread.new { stderr.each { |l| err << l } }
42
28
  [stdout_thread, stderr_thread].each(&:join)
43
29
  result = wait_thr.value
44
30
  result.exitstatus
@@ -8,6 +8,10 @@ module XCCache
8
8
  @raw = raw || load || {}
9
9
  end
10
10
 
11
+ def reload
12
+ @raw = load || {}
13
+ end
14
+
11
15
  def load
12
16
  raise NotImplementedError
13
17
  end
@@ -14,8 +14,9 @@ class File
14
14
  end
15
15
 
16
16
  class Dir
17
- def self.prepare(dir)
17
+ def self.prepare(dir, clean: false)
18
18
  dir = Pathname(dir)
19
+ dir.rmtree if clean && dir.exist?
19
20
  dir.mkpath
20
21
  dir
21
22
  end
@@ -10,12 +10,14 @@ module XCCache
10
10
 
11
11
  def install!
12
12
  perform_install do
13
- umbrella_pkg.build(
13
+ build(
14
14
  targets: @targets,
15
15
  out_dir: config.spm_cache_dir,
16
+ symlinks_dir: config.spm_binaries_dir,
16
17
  checksum: true,
17
18
  **@build_options,
18
19
  )
20
+ proxy_pkg.gen_proxy # Regenerate proxy to apply new cache after build
19
21
  end
20
22
  end
21
23
  end
@@ -0,0 +1,28 @@
1
+ module XCCache
2
+ class Installer
3
+ module BuildIntegrationMixin
4
+ def build(options = {})
5
+ to_build = targets_to_build(options)
6
+ return UI.warn("Detected no targets to build among cache-missed targets") if to_build.empty?
7
+
8
+ UI.info("-> Targets to build: #{to_build.to_s.bold}")
9
+ umbrella_pkg.build(**options, targets: to_build)
10
+ end
11
+
12
+ def targets_to_build(options)
13
+ items = options[:targets] || []
14
+ items = config.cachemap.missed.map { |x| File.basename(x) } if items.empty?
15
+ targets = items.map { |x| umbrella_pkg.get_target(x) }
16
+
17
+ if options[:recursive]
18
+ UI.message("Will include cache-missed recursive targets")
19
+ targets += targets.flat_map do |t|
20
+ t.recursive_targets.select { |x| config.cachemap.missed?(x.full_name) }
21
+ end
22
+ end
23
+ # TODO: Sort by number of dependents
24
+ targets.map(&:full_name).uniq
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ module XCCache
2
+ class Installer
3
+ module DescsIntegrationMixin
4
+ def xccache_desc
5
+ @xccache_desc ||= desc_of("xccache")
6
+ end
7
+
8
+ def targets_of_products(products)
9
+ products = [products] if products.is_a?(String)
10
+ products.flat_map { |x| desc_of(x).targets_of_products(File.basename(x)) }
11
+ end
12
+
13
+ def dependency_targets_of_products(products)
14
+ products = [products] if products.is_a?(String)
15
+ products.flat_map { |p| @dependency_targets_by_products[p] || [p] }.uniq
16
+ end
17
+
18
+ def desc_of(d)
19
+ descs_by_name[d.split("/").first]
20
+ end
21
+
22
+ def binary_targets
23
+ descs_by_name.values.flatten.uniq.flat_map(&:binary_targets)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module XCCache
2
+ class Installer
3
+ module SupportingFilesIntegrationMixin
4
+ def gen_supporting_files
5
+ UI.section("Generating supporting files") do
6
+ gen_xcconfigs
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def gen_xcconfigs
13
+ macros_config_by_targets.each do |target, hash|
14
+ xcconfig_path = config.spm_xcconfig_dir / "#{target}.xcconfig"
15
+ UI.message("XCConfig of target #{target} at: #{xcconfig_path}")
16
+ Xcodeproj::Config.new(hash).save_as(xcconfig_path)
17
+ end
18
+ end
19
+
20
+ def macros_config_by_targets
21
+ proxy_pkg.graph["macros"].to_h do |target, paths|
22
+ swift_flags = paths.map { |p| "-load-plugin-executable #{p}##{File.basename(p, '.*')}" }
23
+ hash = { "OTHER_SWIFT_FLAGS" => "$(inherited) #{swift_flags.join(' ')}" }
24
+ [File.basename(target, ".*"), hash]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ module XCCache
2
+ class Installer
3
+ module VizIntegrationMixin
4
+ def gen_cachemap_viz
5
+ stats = config.cachemap.stats
6
+ html_path = config.sandbox / "cachemap.html"
7
+ js_path = Dir.prepare(config.sandbox / "assets") / "cachemap.js"
8
+ css_path = config.sandbox / "assets" / "style.css"
9
+
10
+ root_dir = Pathname(".").expand_path
11
+ to_relative = proc do |p|
12
+ p.to_s.start_with?(root_dir.to_s) ? p.relative_path_from(root_dir).to_s : p.to_s
13
+ end
14
+
15
+ UI.info("Cachemap visualization: #{html_path}")
16
+ Template.new("cachemap.html").render(
17
+ {
18
+ :root_dir => root_dir.to_s,
19
+ :root_dir_short => root_dir.basename.to_s,
20
+ :lockfile_path => config.lockfile.path.to_s,
21
+ :lockfile_path_short => to_relative.call(config.lockfile.path),
22
+ :binaries_dir => config.spm_binaries_dir.to_s,
23
+ :binaries_dir_short => to_relative.call(config.spm_binaries_dir),
24
+ :desc_hit => stats[:hit],
25
+ :desc_missed => stats[:missed],
26
+ :desc_ignored => stats[:ignored],
27
+ },
28
+ save_to: html_path
29
+ )
30
+ Template.new("cachemap.js").render(
31
+ { :json => JSON.pretty_generate(config.cachemap.depgraph_data) },
32
+ save_to: js_path
33
+ )
34
+ Template.new("cachemap.style.css").render(save_to: css_path)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ Dir["#{__dir__}/#{File.basename(__FILE__, '.rb')}/*.rb"].sort.each { |f| require f }
2
+
3
+ module XCCache
4
+ class Installer
5
+ module IntegrationMixin
6
+ include VizIntegrationMixin
7
+ include DescsIntegrationMixin
8
+ include BuildIntegrationMixin
9
+ include SupportingFilesIntegrationMixin
10
+ end
11
+ end
12
+ end
@@ -19,7 +19,7 @@ module XCCache
19
19
  project.add_xccache_pkg unless project.has_xccache_pkg?
20
20
  project.targets.each do |target|
21
21
  target.add_xccache_product_dependency unless target.has_xccache_product_dependency?
22
- target.remove_pkg_product_dependencies { |d| !d.pkg.xccache_pkg? }
22
+ target.remove_pkg_product_dependencies { |d| d.pkg.nil? || !d.pkg.xccache_pkg? }
23
23
  end
24
24
  project.remove_pkgs(&:non_xccache_pkg?) unless config.keep_pkgs_in_project?
25
25
  end