xccache 0.0.1a2 → 0.0.1a4

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/lib/xccache/assets/templates/cachemap.html.template +1 -0
  3. data/lib/xccache/assets/templates/cachemap.js.template +35 -34
  4. data/lib/xccache/assets/templates/cachemap.style.css.template +3 -1
  5. data/lib/xccache/assets/templates/framework.modulemap.template +1 -1
  6. data/lib/xccache/assets/templates/resource_bundle_accessor.m.template +3 -3
  7. data/lib/xccache/assets/templates/umbrella.Package.swift.template +43 -7
  8. data/lib/xccache/cache/cachemap.rb +11 -15
  9. data/lib/xccache/command/base.rb +29 -0
  10. data/lib/xccache/command/build.rb +12 -6
  11. data/lib/xccache/command/pkg/build.rb +2 -6
  12. data/lib/xccache/command/pkg.rb +1 -0
  13. data/lib/xccache/command/remote/pull.rb +15 -0
  14. data/lib/xccache/command/remote/push.rb +15 -0
  15. data/lib/xccache/command/remote.rb +39 -0
  16. data/lib/xccache/command/rollback.rb +2 -1
  17. data/lib/xccache/command/use.rb +3 -2
  18. data/lib/xccache/command.rb +18 -2
  19. data/lib/xccache/core/config.rb +30 -2
  20. data/lib/xccache/core/git.rb +15 -3
  21. data/lib/xccache/core/log.rb +11 -1
  22. data/lib/xccache/core/parallel.rb +10 -0
  23. data/lib/xccache/core/sh.rb +4 -3
  24. data/lib/xccache/core/syntax/plist.rb +17 -0
  25. data/lib/xccache/core/system.rb +8 -0
  26. data/lib/xccache/installer/build.rb +2 -6
  27. data/lib/xccache/installer/rollback.rb +1 -0
  28. data/lib/xccache/installer/use.rb +3 -2
  29. data/lib/xccache/installer.rb +50 -4
  30. data/lib/xccache/spm/build.rb +53 -0
  31. data/lib/xccache/spm/desc/base.rb +10 -3
  32. data/lib/xccache/spm/desc/desc.rb +31 -15
  33. data/lib/xccache/spm/desc/target/binary.rb +8 -0
  34. data/lib/xccache/spm/desc/target/macro.rb +8 -0
  35. data/lib/xccache/spm/desc/target.rb +28 -2
  36. data/lib/xccache/spm/macro.rb +44 -0
  37. data/lib/xccache/spm/mixin.rb +4 -1
  38. data/lib/xccache/spm/pkg/base.rb +48 -44
  39. data/lib/xccache/spm/pkg/umbrella/build.rb +2 -2
  40. data/lib/xccache/spm/pkg/umbrella/cachemap.rb +44 -27
  41. data/lib/xccache/spm/pkg/umbrella/descs.rb +2 -13
  42. data/lib/xccache/spm/pkg/umbrella/manifest.rb +1 -1
  43. data/lib/xccache/spm/pkg/umbrella/viz.rb +3 -3
  44. data/lib/xccache/spm/pkg/umbrella/xcconfigs.rb +31 -0
  45. data/lib/xccache/spm/pkg/umbrella.rb +20 -10
  46. data/lib/xccache/spm/xcframework/metadata.rb +41 -0
  47. data/lib/xccache/{framework → spm/xcframework}/slice.rb +50 -53
  48. data/lib/xccache/spm/xcframework/xcframework.rb +56 -0
  49. data/lib/xccache/spm/xcframework.rb +2 -0
  50. data/lib/xccache/storage/base.rb +26 -0
  51. data/lib/xccache/storage/git.rb +48 -0
  52. data/lib/xccache/storage/s3.rb +53 -0
  53. data/lib/xccache/storage.rb +1 -0
  54. data/lib/xccache/swift/sdk.rb +21 -2
  55. data/lib/xccache/xcodeproj/build_configuration.rb +20 -0
  56. data/lib/xccache/xcodeproj/config.rb +9 -0
  57. data/lib/xccache/xcodeproj/file_system_synchronized_root_group.rb +17 -0
  58. data/lib/xccache/xcodeproj/group.rb +26 -0
  59. data/lib/xccache/xcodeproj/pkg.rb +5 -1
  60. data/lib/xccache/xcodeproj/project.rb +21 -1
  61. data/lib/xccache/xcodeproj/target.rb +5 -3
  62. metadata +40 -5
  63. data/lib/xccache/framework/xcframework.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8478aeb0498b7eaa2e6c231f65cf65421d247958a30b2cfca0750e0d8b0603e9
4
- data.tar.gz: 4f5266ef2925ce5ca1b06596da4b6aa879c53926eaf2a460638b912187f9316b
3
+ metadata.gz: 8f25ddb49ae65e34b141a696ca54f50bd3dcb3e65d7883609263b6e6904c8f78
4
+ data.tar.gz: 8f73671a9e7dbdfc17026a3c38176d01fa2db96d7a85436d1da52dcd63656a6f
5
5
  SHA512:
6
- metadata.gz: 78daeec82245936d646cfe0f8f5d8ea1e82d2d851333aa8523a010e8a78c257d7fadbbb3fed8a1a88bdd59a57070843c87330ad79e5bab5f3dc6e9774623b420
7
- data.tar.gz: d9f4e5ba9057726fd4a6679ba7014b8c444cd195c7481f36c2f66f59bedefd5d409d473420016869bf327951b4ccfc3e42799bfc8a4709b5244476d10ef306ba
6
+ metadata.gz: 2c939fbafc217ac9784278e37e2946ba4c289aee5ca67f239f0ec358d869551674720f1077cfdd4daba2da70c895f8b3918b4b2453a86c6c4233a398cd3e533d
7
+ data.tar.gz: a49f327f9e5551e2b095581ae650b5904bc09003c5b1399774ffacc635b16ac43856cc49ca02275692eda4c1f4d01430f8e3202f0dcd796ce4e69e1b934483ed
@@ -39,6 +39,7 @@
39
39
  <div class="info">Target: <span class="value target">TBU</span></div>
40
40
  <div class="info">Checksum: <span class="value checksum">TBU</span></div>
41
41
  <div class="info">Binary: <a class="value binary" href="">TBU</a></div>
42
+ <div class="info"><p class="others">TBU</p></div>
42
43
  </div>
43
44
  </section>
44
45
  </div>
@@ -1,10 +1,15 @@
1
- // MARK: GENERATED
2
- // ------------------------------------------------
3
- graph = JSON.parse(`
1
+ const graph = JSON.parse(`
4
2
  <%= json %>
5
3
  `);
4
+
6
5
  // ------------------------------------------------
7
6
 
7
+ const COLORS = {
8
+ 'hit': '#339966',
9
+ 'missed': '#ff6f00',
10
+ 'ignored': '#888',
11
+ 'NA': '#888',
12
+ }
8
13
  const cy = cytoscape({
9
14
  container: $('#cy'),
10
15
  elements: ([...graph.nodes, ...graph.edges]).map(x => ({data: x})),
@@ -18,7 +23,8 @@ const cy = cytoscape({
18
23
  'text-halign': 'center',
19
24
  'font-size': '14px',
20
25
  'shape': 'roundrectangle',
21
- 'width': (e) => Math.max(50, e.id().split("/")[1].length * 8),
26
+ 'width': (e) => Math.max(50, e.id().split('/')[1].length * 8),
27
+ 'background-color': (e) => COLORS[e.data('cache') || 'NA'],
22
28
  }
23
29
  },
24
30
  {
@@ -29,26 +35,12 @@ const cy = cytoscape({
29
35
  'border-color': '#333',
30
36
  }
31
37
  },
32
- {
33
- selector: 'node[cache="hit"]',
34
- style: {'background-color': '#339966'}
35
- },
36
- {
37
- selector: 'node[cache="missed"]',
38
- style: {'background-color': '#ff6f00'}
39
- },
40
38
  {
41
39
  selector: 'node[type="agg"]',
42
40
  style: {
43
41
  'background-color': '#333',
44
42
  }
45
43
  },
46
- {
47
- selector: 'node[cache="ignored"]',
48
- style: {
49
- 'background-color': '#888',
50
- }
51
- },
52
44
  {
53
45
  selector: 'edge',
54
46
  style: {
@@ -56,14 +48,13 @@ const cy = cytoscape({
56
48
  'target-arrow-shape': 'triangle',
57
49
  'curve-style': 'bezier',
58
50
  'line-color': '#ccc',
59
- // 'line-color': e => e.target().style('background-color') || '#999',
60
- 'target-arrow-color': e => e.style('line-color'),
51
+ 'target-arrow-color': '#ccc',
61
52
  }
62
53
  },
63
54
  ],
64
55
  layout: {
65
56
  name: 'fcose',
66
- animationDuration: 300,
57
+ animationDuration: 200,
67
58
  nodeRepulsion: 10000,
68
59
  idealEdgeLength: 120,
69
60
  gravity: 0.25,
@@ -71,24 +62,34 @@ const cy = cytoscape({
71
62
  });
72
63
 
73
64
  cy.on('select', 'node', function(event) {
74
- $('.node-info').css('display', 'block');
75
65
  const node = event.target;
76
- const info = $('.node-info .info');
77
- info.find('.target').html(node.id());
78
- info.find('.checksum').html(node.data('checksum') || 'NA');
79
- info.find('.binary')
80
- .html((node.data('binary') || 'NA').split('/').slice(-1))
81
- .attr({'href': node.data('binary') || ''});
82
-
83
- // Mark neighbor as focused, dim others
84
- const focused = node.neighborhood().add(node);
85
- focused.animate({style: {'opacity': 1}, duration: 200});
86
- cy.elements().not(focused).animate({style: {'opacity': 0.15}, duration: 200});
66
+ node.displayDetails();
67
+ node.neighborhood().add(node).focus();
87
68
  });
88
69
 
89
70
  cy.on('tap', function(event) {
90
71
  if (event.target == cy) {
91
72
  $('.node-info').css('display', 'none');
92
- cy.elements().animate({style: {'opacity': 1}});
73
+ cy.elements().animateStyle({'opacity': 1, 'line-color': '#ccc', 'target-arrow-color': '#ccc'});
93
74
  }
94
75
  });
76
+
77
+ // -----------------------------------------------------------------
78
+
79
+ cytoscape('collection', 'animateStyle', function(style) {
80
+ this.animate({style: style, duration: 200, easing: 'ease-out'})
81
+ });
82
+ cytoscape('collection', 'focus', function() {
83
+ this.animateStyle({'opacity': 1, 'line-color': '#666', 'target-arrow-color': '#666'});
84
+ cy.elements().not(this).animateStyle({'opacity': 0.15, 'line-color': '#ccc', 'target-arrow-color': '#ccc'});
85
+ });
86
+ cytoscape('collection', 'displayDetails', function() {
87
+ $('.node-info').css('display', 'block');
88
+ const info = $('.node-info .info');
89
+ info.find('.target').html(this.id());
90
+ info.find('.checksum').html(this.data('checksum') || 'NA');
91
+ info.find('.binary')
92
+ .html((this.data('binary') || 'NA').split('/').slice(-1))
93
+ .attr({'href': this.data('binary') || ''});
94
+ info.find('.others').html(`Node degree: ${this.degree()} (${this.indegree()} in, ${this.outdegree()} out)`);
95
+ });
@@ -67,9 +67,11 @@ a:hover { color: #339966; }
67
67
  .node-info {
68
68
  display: none;
69
69
  }
70
+ .metadata .info {
71
+ font-size: 10px;
72
+ }
70
73
  .info {
71
74
  color: #888;
72
- font-size: 10px;
73
75
  }
74
76
  .info .value {
75
77
  color: #666;
@@ -1,5 +1,5 @@
1
1
  framework module <%= module_name %> {
2
- umbrella header "<%= module_name %>-umbrella.h"
2
+ umbrella header "<%= target %>-umbrella.h"
3
3
 
4
4
  export *
5
5
  module * { export * }
@@ -1,16 +1,16 @@
1
1
  #import <Foundation/Foundation.h>
2
2
 
3
- @interface BundleFinder : NSObject
3
+ @interface BundleFinder_<%= module_name %> : NSObject
4
4
  @end
5
5
 
6
- @implementation BundleFinder
6
+ @implementation BundleFinder_<%= module_name %>
7
7
  @end
8
8
 
9
9
  NSBundle* <%= module_name %>_SWIFTPM_MODULE_BUNDLE() {
10
10
  NSString *bundleName = @"<%= pkg %>_<%= target %>";
11
11
  NSArray<NSURL *> *candidates = @[
12
12
  NSBundle.mainBundle.resourceURL,
13
- [NSBundle bundleForClass:[BundleFinder class]].resourceURL,
13
+ [NSBundle bundleForClass:[BundleFinder_<%= module_name %> class]].resourceURL,
14
14
  NSBundle.mainBundle.bundleURL,
15
15
  [NSBundle.mainBundle.bundleURL URLByAppendingPathComponent:@"Frameworks/<%= target %>.framework"]
16
16
  ];
@@ -40,6 +40,7 @@ enum XCCache {
40
40
  @MainActor
41
41
  struct Config {
42
42
  static let pkgDir = URL(filePath: #filePath).deletingLastPathComponent()
43
+ static let repoDir = URL.homeDirectory.appending(path: ".xccache/default")
43
44
  // NOTE: Do NOT change `binariesDir` to `static let`
44
45
  // Somehow, incremental resolution doesnt work causing the `binaryExist` wrongly cached
45
46
  static var binariesDir: URL { pkgDir.appending(path: "binaries") }
@@ -55,7 +56,7 @@ enum XCCache {
55
56
 
56
57
  var spm: PackageDescription.Package {
57
58
  let regularTargets = targets.map(\.spm)
58
- let binaryTargets = targets.flatMap(\.flattenDeps).unique(by: \.name).compactMap(\.spmBinaryTarget)
59
+ let binaryTargets = targets.flatMap(\.flattenRegularDeps).unique(by: \.name).compactMap(\.spmBinaryTarget)
59
60
  return .init(
60
61
  name: "xccache",
61
62
  platforms: PLATFORMS,
@@ -80,29 +81,54 @@ enum XCCache {
80
81
  .library(name: name, targets: [name])
81
82
  }
82
83
  var spm: PackageDescription.Target {
83
- .target(name: name, dependencies: flattenDeps.map(\.spm), path: ".Sources/\(name)")
84
+ .target(
85
+ name: name,
86
+ dependencies: flattenRegularDeps.map(\.spm),
87
+ path: ".Sources/\(name)",
88
+ swiftSettings: [
89
+ .unsafeFlags(macroFlags),
90
+ ]
91
+ )
84
92
  }
85
93
  var flattenDeps: [Dependency] { deps.flatMap(\.toBinariesIfOk).unique(by: \.name) }
94
+ var flattenRegularDeps: [Dependency] { flattenDeps.filter(\.regular) }
95
+ var macroFlags: [String] { flattenDeps.filter(\.macroBinary).flatMap(\.macroFlags) }
86
96
  }
87
97
 
88
98
  // MARK: Dependency
89
99
  @MainActor
90
100
  class Dependency {
91
101
  let name: String
102
+ let bareName: String
103
+ let binaryURL: URL
92
104
  let binary: Bool
93
- private let bareName: String
105
+ let macro: Bool
106
+ var regular: Bool { !macro }
107
+ var regularBinary: Bool { binary && regular }
108
+ var macroBinary: Bool { binary && macro }
94
109
 
95
110
  init(_ name: String) {
96
111
  self.name = name
97
- self.bareName = name.basename.withoutExtenstion
98
- self.binary = name.hasSuffix(".binary") && Config.binariesDir.appending(path: "\(bareName)/\(bareName).xcframework").exist
112
+ self.bareName = String(name.basename.split(separator: ".")[0])
113
+ self.macro = name.contains(".macro")
114
+ self.binaryURL = if macro {
115
+ Config.binariesDir.appending(path: "\(bareName)/\(bareName).macro").readlink()
116
+ } else {
117
+ Config.binariesDir.appending(path: "\(bareName)/\(bareName).xcframework").readlink()
118
+ }
119
+ self.binary = name.hasSuffix(".binary") && binaryURL.exist
120
+ }
121
+
122
+ var macroFlags: [String] {
123
+ ["-load-plugin-executable", "\(binaryURL.path())#\(bareName)"]
99
124
  }
125
+
100
126
  var spm: PackageDescription.Target.Dependency {
101
127
  if binary { return .byName(name: name) }
102
128
  return .product(name: bareName, package: name.slug)
103
129
  }
104
130
  var spmBinaryTarget: PackageDescription.Target? {
105
- binary ? .binaryTarget(name: name, path: "binaries/\(bareName)/\(bareName).xcframework") : nil
131
+ regularBinary ? .binaryTarget(name: name, path: "binaries/\(bareName)/\(bareName).xcframework") : nil
106
132
  }
107
133
  }
108
134
 
@@ -129,7 +155,17 @@ func parseJSON<T>(_ content: String) throws -> T {
129
155
  }
130
156
 
131
157
  extension URL {
132
- var exist: Bool { FileManager.default.fileExists(atPath: path()) }
158
+ var basename: String { lastPathComponent }
159
+ var exist: Bool { FileManager.default.fileExists(atPath: readlink().path()) }
160
+ /// Resolve symlinks recursively, equivalent to `readlink -f` in bash
161
+ func readlink() -> URL {
162
+ var prev = self, cur = resolvingSymlinksInPath()
163
+ while prev != cur {
164
+ prev = cur
165
+ cur = cur.resolvingSymlinksInPath()
166
+ }
167
+ return cur
168
+ }
133
169
  }
134
170
 
135
171
  extension String {
@@ -12,7 +12,11 @@ module XCCache
12
12
  end
13
13
 
14
14
  def manifest_data
15
- raw["manifest"] ||= { "targets" => {}, "deps" => {} }
15
+ raw["manifest"] ||= {
16
+ "targets" => {},
17
+ "deps" => {},
18
+ "macros" => {},
19
+ }
16
20
  end
17
21
 
18
22
  def missed?(name)
@@ -24,23 +28,15 @@ module XCCache
24
28
  end
25
29
 
26
30
  def stats
27
- describe = proc do |type|
28
- count = get_cache_data(type).count
29
- total_count = [cache_data.count, 1].max
30
- percent = (count * 100 / total_count).to_i
31
- "#{percent}% (#{count}/#{total_count})"
31
+ %i[hit missed ignored].to_h do |type|
32
+ count, total_count = get_cache_data(type).count, cache_data.count
33
+ percent = total_count.positive? ? (count.to_f * 100 / total_count).round : 0
34
+ [type, "#{percent}% (#{count}/#{total_count})"]
32
35
  end
33
- {
34
- :hit => describe.call(:hit),
35
- :missed => describe.call(:missed),
36
- :ignored => describe.call(:ignored),
37
- }
38
36
  end
39
37
 
40
38
  def print_stats
41
- hit = get_cache_data(:hit)
42
- missed = get_cache_data(:missed)
43
- ignored = get_cache_data(:ignored)
39
+ hit, missed, ignored = %i[hit missed ignore].map { |type| get_cache_data(type) }
44
40
  total_count = cache_data.count
45
41
  UI.message <<~DESC
46
42
  -------------------------------------------------------------------
@@ -53,7 +49,7 @@ module XCCache
53
49
  end
54
50
 
55
51
  def get_cache_data(type)
56
- cache_data.select { |k, v| !k.end_with?(".xccache") && v == type }.keys
52
+ cache_data.select { |_, v| v == type }.keys
57
53
  end
58
54
  end
59
55
  end
@@ -0,0 +1,29 @@
1
+ require "xccache/installer"
2
+
3
+ module XCCache
4
+ class Command
5
+ class Options
6
+ SDK = ["--sdk=foo,bar", "SDKs (iphonesimulator, iphoneos, etc.)"].freeze
7
+ CONFIG = ["--config=foo", "Configuration (debug, release)"].freeze
8
+ SKIP_RESOLVING_DEPENDENCIES = [
9
+ "--skip-resolving-dependencies", "Skip resolving package dependencies",
10
+ ].freeze
11
+ MERGE_SLICES = [
12
+ "--merge-slices/--no-merge-slices",
13
+ "Whether to merge with existing slices/sdks in the xcframework (default: true)",
14
+ ].freeze
15
+ LIBRARY_EVOLUTION = [
16
+ "--library-evolution/--no-library-evolution",
17
+ "Whether to enable library evolution (build for distribution) (default: false)",
18
+ ].freeze
19
+
20
+ def self.install_options
21
+ [SDK, SKIP_RESOLVING_DEPENDENCIES]
22
+ end
23
+
24
+ def self.build_options
25
+ install_options + [CONFIG, MERGE_SLICES, LIBRARY_EVOLUTION]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,4 +1,5 @@
1
1
  require "xccache/installer"
2
+ require_relative "base"
2
3
 
3
4
  module XCCache
4
5
  class Command
@@ -6,10 +7,9 @@ module XCCache
6
7
  self.summary = "Build packages to xcframeworks"
7
8
  def self.options
8
9
  [
9
- ["--sdk=iphonesimulator", "SDKs to build (comma separated)"],
10
+ *Options.build_options,
10
11
  ["--integrate/no-integrate", "Whether to integrate after building target (default: true)"],
11
12
  ["--recursive", "Whether to build their recursive targets if cache-missed (default: false)"],
12
- ["--skip-resolving-dependencies", "Skip resolving package dependencies"],
13
13
  ].concat(super)
14
14
  end
15
15
  self.arguments = [
@@ -19,16 +19,22 @@ module XCCache
19
19
  def initialize(argv)
20
20
  super
21
21
  @targets = argv.arguments!
22
- @sdk = argv.option("sdk")
23
22
  @should_integrate = argv.flag?("integrate", true)
24
- @recursive = argv.flag?("recursive", false)
25
23
  end
26
24
 
27
25
  def run
28
- installer = Installer::Build.new(targets: @targets, sdk: @sdk, recursive: @recursive, **@install_options)
26
+ installer = Installer::Build.new(
27
+ ctx: self,
28
+ targets: @targets,
29
+ )
29
30
  installer.install!
31
+
30
32
  # Reuse umbrella_pkg from previous installers
31
- Installer::Use.new(umbrella_pkg: installer.umbrella_pkg, **@install_options).install! if @should_integrate
33
+ return unless @should_integrate
34
+ Installer::Use.new(
35
+ ctx: self,
36
+ umbrella_pkg: installer.umbrella_pkg,
37
+ ).install!
32
38
  end
33
39
  end
34
40
  end
@@ -7,8 +7,7 @@ module XCCache
7
7
  self.summary = "Build a Swift package into an xcframework"
8
8
  def self.options
9
9
  [
10
- ["--sdk=foo,bar", "Sdk (iphonesimulator, iphoneos, etc.)"],
11
- ["--config=foo", "Configuration (debug, release)"],
10
+ *Options.build_options,
12
11
  ["--out=foo", "Output directory for the xcframework"],
13
12
  ["--checksum/no-checksum", "Whether to include checksum to the binary name"],
14
13
  ].concat(super)
@@ -20,8 +19,6 @@ module XCCache
20
19
  def initialize(argv)
21
20
  super
22
21
  @targets = argv.arguments!
23
- @sdk = argv.option("sdk")
24
- @config = argv.option("config")
25
22
  @out_dir = argv.option("out")
26
23
  @include_checksum = argv.flag?("checksum")
27
24
  end
@@ -30,11 +27,10 @@ module XCCache
30
27
  pkg = SPM::Package.new
31
28
  pkg.build(
32
29
  targets: @targets,
33
- sdk: @sdk,
34
30
  config: @config,
35
31
  out_dir: @out_dir,
36
32
  checksum: @include_checksum,
37
- skip_resolve: @skip_resolving_dependencies,
33
+ **@build_options,
38
34
  )
39
35
  end
40
36
  end
@@ -1,3 +1,4 @@
1
+ require_relative "base"
1
2
  require "xccache/command/pkg/build"
2
3
 
3
4
  module XCCache
@@ -0,0 +1,15 @@
1
+ require "xccache/spm"
2
+
3
+ module XCCache
4
+ class Command
5
+ class Remote < Command
6
+ class Pull < Remote
7
+ self.summary = "Pulling cache to local"
8
+
9
+ def run
10
+ storage.pull
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require "xccache/spm"
2
+
3
+ module XCCache
4
+ class Command
5
+ class Remote < Command
6
+ class Push < Remote
7
+ self.summary = "Pushing cache to remote"
8
+
9
+ def run
10
+ storage.push
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "base"
2
+ require "xccache/storage"
3
+ require "xccache/command/remote/pull"
4
+ require "xccache/command/remote/push"
5
+
6
+ module XCCache
7
+ class Command
8
+ class Remote < Command
9
+ self.abstract_command = true
10
+ self.summary = "Working with remote cache"
11
+ def self.options
12
+ [
13
+ ["--branch=foo", "Cache branch (if using git) (default: main)"],
14
+ ].concat(super)
15
+ end
16
+
17
+ def initialize(argv)
18
+ super
19
+ @branch = argv.option("branch", "main")
20
+ end
21
+
22
+ def storage
23
+ @storage ||= create_storage
24
+ end
25
+
26
+ private
27
+
28
+ def create_storage
29
+ remote_config = config.remote_config
30
+ if (remote = remote_config["git"])
31
+ return GitStorage.new(branch: @branch, remote: remote)
32
+ elsif (s3_config = remote_config["s3"])
33
+ return S3Storage.new(uri: s3_config["uri"], creds_path: s3_config["creds"])
34
+ end
35
+ Storage.new
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
1
  require "xccache/installer"
2
+ require_relative "base"
2
3
 
3
4
  module XCCache
4
5
  class Command
@@ -6,7 +7,7 @@ module XCCache
6
7
  self.summary = "Roll back prebuilt cache for packages"
7
8
 
8
9
  def run
9
- Installer::Rollback.new.install!
10
+ Installer::Rollback.new(ctx: self).install!
10
11
  end
11
12
  end
12
13
  end
@@ -1,4 +1,5 @@
1
1
  require "xccache/installer"
2
+ require_relative "base"
2
3
 
3
4
  module XCCache
4
5
  class Command
@@ -6,12 +7,12 @@ module XCCache
6
7
  self.summary = "Use prebuilt cache for packages"
7
8
  def self.options
8
9
  [
9
- ["--skip-resolving-dependencies", "Skip resolving package dependencies"],
10
+ *Options.install_options,
10
11
  ].concat(super)
11
12
  end
12
13
 
13
14
  def run
14
- Installer::Use.new(**@install_options).install!
15
+ Installer::Use.new(ctx: self).install!
15
16
  end
16
17
  end
17
18
  end
@@ -1,5 +1,6 @@
1
1
  require "claide"
2
2
  require "xccache/core/config"
3
+ require "xccache/swift/sdk"
3
4
 
4
5
  module XCCache
5
6
  class Command < CLAide::Command
@@ -10,11 +11,26 @@ module XCCache
10
11
  self.default_subcommand = "use"
11
12
  self.summary = "xccache - a build caching tool"
12
13
 
14
+ attr_reader :install_options, :build_options
15
+
13
16
  def initialize(argv)
14
17
  super
15
18
  config.verbose = verbose unless verbose.nil?
16
- @skip_resolving_dependencies = argv.flag?("skip-resolving-dependencies")
17
- @install_options = { :skip_resolving_dependencies => @skip_resolving_dependencies }
19
+ @install_options = {
20
+ :sdks => str_to_sdks(argv.option("sdk")),
21
+ :skip_resolving_dependencies => argv.flag?("skip-resolving-dependencies"),
22
+ }
23
+ @build_options = {
24
+ **@install_options,
25
+ :config => argv.option("config"),
26
+ :recursive => argv.flag?("recursive"),
27
+ :merge_slices => argv.flag?("merge-slices", true),
28
+ :library_evolution => argv.flag?("library-evolution"),
29
+ }
30
+ end
31
+
32
+ def str_to_sdks(str)
33
+ (str || config.default_sdk).split(",").map { |s| Swift::Sdk.new(s) }
18
34
  end
19
35
  end
20
36
  end
@@ -16,6 +16,10 @@ module XCCache
16
16
  attr_accessor :verbose
17
17
  alias verbose? verbose
18
18
 
19
+ # To distinguish if it's within an installation, or standalone like `xccache pkg build`
20
+ attr_accessor :in_installation
21
+ alias in_installation? in_installation
22
+
19
23
  def sandbox
20
24
  @sandbox = Dir.prepare("xccache").expand_path
21
25
  end
@@ -24,8 +28,20 @@ module XCCache
24
28
  @spm_sandbox ||= Dir.prepare(sandbox / "packages").expand_path
25
29
  end
26
30
 
27
- def spm_binaries_frameworks_dir
28
- @spm_binaries_frameworks_dir ||= Dir.prepare(spm_umbrella_sandbox / "binaries")
31
+ def spm_local_pkgs_dir
32
+ @spm_local_pkgs_dir ||= Dir.prepare(spm_sandbox / "local")
33
+ end
34
+
35
+ def spm_xcconfig_dir
36
+ @spm_xcconfig_dir ||= Dir.prepare(spm_sandbox / "xcconfigs")
37
+ end
38
+
39
+ def spm_repo_dir
40
+ @spm_repo_dir ||= Dir.prepare(Pathname("~/.xccache/default").expand_path)
41
+ end
42
+
43
+ def spm_binaries_dir
44
+ @spm_binaries_dir ||= Dir.prepare(spm_umbrella_sandbox / "binaries")
29
45
  end
30
46
 
31
47
  def spm_build_dir
@@ -62,6 +78,10 @@ module XCCache
62
78
  projects.flat_map(&:targets)
63
79
  end
64
80
 
81
+ def remote_config
82
+ raw["remote"] || {}
83
+ end
84
+
65
85
  def ignore_list
66
86
  raw["ignore"] || []
67
87
  end
@@ -78,5 +98,13 @@ module XCCache
78
98
  def ignore_build_errors?
79
99
  raw["ignore_build_errors"]
80
100
  end
101
+
102
+ def keep_pkgs_in_project?
103
+ raw["keep_pkgs_in_project"]
104
+ end
105
+
106
+ def default_sdk
107
+ raw["default_sdk"] || "iphonesimulator"
108
+ end
81
109
  end
82
110
  end