xccache 0.0.1a2 → 0.0.1a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/xccache/assets/templates/cachemap.html.template +1 -0
- data/lib/xccache/assets/templates/cachemap.js.template +35 -34
- data/lib/xccache/assets/templates/cachemap.style.css.template +3 -1
- data/lib/xccache/assets/templates/framework.modulemap.template +1 -1
- data/lib/xccache/assets/templates/resource_bundle_accessor.m.template +3 -3
- data/lib/xccache/assets/templates/umbrella.Package.swift.template +43 -7
- data/lib/xccache/cache/cachemap.rb +11 -15
- data/lib/xccache/command/base.rb +29 -0
- data/lib/xccache/command/build.rb +12 -6
- data/lib/xccache/command/pkg/build.rb +2 -6
- data/lib/xccache/command/pkg.rb +1 -0
- data/lib/xccache/command/remote/pull.rb +15 -0
- data/lib/xccache/command/remote/push.rb +15 -0
- data/lib/xccache/command/remote.rb +39 -0
- data/lib/xccache/command/rollback.rb +2 -1
- data/lib/xccache/command/use.rb +3 -2
- data/lib/xccache/command.rb +18 -2
- data/lib/xccache/core/config.rb +30 -2
- data/lib/xccache/core/git.rb +11 -3
- data/lib/xccache/core/log.rb +11 -1
- data/lib/xccache/core/parallel.rb +10 -0
- data/lib/xccache/core/sh.rb +4 -3
- data/lib/xccache/core/syntax/plist.rb +17 -0
- data/lib/xccache/core/system.rb +8 -0
- data/lib/xccache/installer/build.rb +2 -6
- data/lib/xccache/installer/rollback.rb +1 -0
- data/lib/xccache/installer/use.rb +3 -2
- data/lib/xccache/installer.rb +50 -4
- data/lib/xccache/spm/build.rb +53 -0
- data/lib/xccache/spm/desc/base.rb +10 -3
- data/lib/xccache/spm/desc/desc.rb +31 -15
- data/lib/xccache/spm/desc/target/binary.rb +8 -0
- data/lib/xccache/spm/desc/target/macro.rb +8 -0
- data/lib/xccache/spm/desc/target.rb +28 -2
- data/lib/xccache/spm/macro.rb +44 -0
- data/lib/xccache/spm/mixin.rb +4 -1
- data/lib/xccache/spm/pkg/base.rb +48 -44
- data/lib/xccache/spm/pkg/umbrella/build.rb +2 -2
- data/lib/xccache/spm/pkg/umbrella/cachemap.rb +44 -27
- data/lib/xccache/spm/pkg/umbrella/descs.rb +2 -13
- data/lib/xccache/spm/pkg/umbrella/manifest.rb +1 -1
- data/lib/xccache/spm/pkg/umbrella/viz.rb +3 -3
- data/lib/xccache/spm/pkg/umbrella/xcconfigs.rb +31 -0
- data/lib/xccache/spm/pkg/umbrella.rb +20 -10
- data/lib/xccache/spm/xcframework/metadata.rb +41 -0
- data/lib/xccache/{framework → spm/xcframework}/slice.rb +50 -53
- data/lib/xccache/spm/xcframework/xcframework.rb +56 -0
- data/lib/xccache/spm/xcframework.rb +2 -0
- data/lib/xccache/storage/base.rb +26 -0
- data/lib/xccache/storage/git.rb +46 -0
- data/lib/xccache/storage/s3.rb +53 -0
- data/lib/xccache/storage.rb +1 -0
- data/lib/xccache/swift/sdk.rb +21 -2
- data/lib/xccache/xcodeproj/build_configuration.rb +20 -0
- data/lib/xccache/xcodeproj/config.rb +9 -0
- data/lib/xccache/xcodeproj/file_system_synchronized_root_group.rb +17 -0
- data/lib/xccache/xcodeproj/group.rb +26 -0
- data/lib/xccache/xcodeproj/pkg.rb +5 -1
- data/lib/xccache/xcodeproj/project.rb +21 -1
- data/lib/xccache/xcodeproj/target.rb +5 -3
- metadata +40 -5
- data/lib/xccache/framework/xcframework.rb +0 -51
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            require "xccache/spm/build"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module XCCache
         | 
| 4 | 
            +
              module SPM
         | 
| 5 | 
            +
                class XCFramework < Buildable
         | 
| 6 | 
            +
                  attr_reader :slices
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def initialize(options = {})
         | 
| 9 | 
            +
                    super
         | 
| 10 | 
            +
                    @slices ||= @sdks.map do |sdk|
         | 
| 11 | 
            +
                      FrameworkSlice.new(
         | 
| 12 | 
            +
                        **options,
         | 
| 13 | 
            +
                        sdks: [sdk],
         | 
| 14 | 
            +
                        path: Dir.prepare(tmpdir / sdk.triple / "#{module_name}.framework"),
         | 
| 15 | 
            +
                      )
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def build(merge_slices: false, **_options)
         | 
| 20 | 
            +
                    tmp_new_path = tmpdir / "new.xcframework"
         | 
| 21 | 
            +
                    tmp_existing_path = tmpdir / "existing.framework"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    slices.each(&:build)
         | 
| 24 | 
            +
                    UI.section("Creating #{name}.xcframework from slices") do
         | 
| 25 | 
            +
                      create_xcframework(from: slices.map(&:path), to: tmp_new_path)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    path.copy(to: tmp_existing_path) if path.exist? && merge_slices
         | 
| 29 | 
            +
                    path.rmtree if path.exist?
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    if merge_slices && tmp_existing_path.exist?
         | 
| 32 | 
            +
                      UI.section("Merging #{name}.xcframework with existing slices") do
         | 
| 33 | 
            +
                        framework_paths =
         | 
| 34 | 
            +
                          [tmp_new_path, tmp_existing_path]
         | 
| 35 | 
            +
                          .flat_map { |p| p.glob("*/*.framework") }
         | 
| 36 | 
            +
                          .uniq { |p| p.parent.basename.to_s } # uniq by id (ex. ios-arm64), preferred new ones
         | 
| 37 | 
            +
                        create_xcframework(from: framework_paths, to: path)
         | 
| 38 | 
            +
                      end
         | 
| 39 | 
            +
                    else
         | 
| 40 | 
            +
                      path.parent.mkpath
         | 
| 41 | 
            +
                      tmp_new_path.copy(to: path)
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    UI.info("-> XCFramework: #{path.to_s.dark}")
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def create_xcframework(options = {})
         | 
| 47 | 
            +
                    cmd = ["xcodebuild", "-create-xcframework"]
         | 
| 48 | 
            +
                    cmd << "-allow-internal-distribution" unless library_evolution?
         | 
| 49 | 
            +
                    cmd << "-output" << options[:to]
         | 
| 50 | 
            +
                    options[:from].each { |p| cmd << "-framework" << p }
         | 
| 51 | 
            +
                    cmd << "> /dev/null" # Only care about errors
         | 
| 52 | 
            +
                    Sh.run(cmd)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module XCCache
         | 
| 2 | 
            +
              class Storage
         | 
| 3 | 
            +
                include Config::Mixin
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(options = {}); end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def pull
         | 
| 8 | 
            +
                  print_warnings
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def push
         | 
| 12 | 
            +
                  print_warnings
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                private
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def print_warnings
         | 
| 18 | 
            +
                  UI.warn <<~DESC
         | 
| 19 | 
            +
                    Do nothing as remote cache is not set up yet.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    To set it up, specify `remote` in `xccache.yml`.
         | 
| 22 | 
            +
                    See: https://github.com/trinhngocthuyen/xccache/blob/main/docs/configuration.md#remote
         | 
| 23 | 
            +
                  DESC
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            require_relative "base"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module XCCache
         | 
| 4 | 
            +
              class GitStorage < Storage
         | 
| 5 | 
            +
                attr_reader :branch
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(options = {})
         | 
| 8 | 
            +
                  super
         | 
| 9 | 
            +
                  if (@remote = options[:remote])
         | 
| 10 | 
            +
                    @remote = File.expand_path(@remote) unless ["http", "https", "git"].include?(URI.parse(@remote).scheme)
         | 
| 11 | 
            +
                    ensure_remote
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  @branch = options[:branch]
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def pull
         | 
| 17 | 
            +
                  git.fetch("--depth 1 origin #{branch}")
         | 
| 18 | 
            +
                  git.switch("--detach FETCH_HEAD", capture: true)
         | 
| 19 | 
            +
                  git.clean("-dfx", capture: true)
         | 
| 20 | 
            +
                  # Re-create local branch so that it has the latest from remote
         | 
| 21 | 
            +
                  git.branch("-D #{branch} || true", capture: true)
         | 
| 22 | 
            +
                  git.checkout("-b #{branch}", capture: true)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def push
         | 
| 26 | 
            +
                  return UI.info("No changes to push, cache repo is clean".magenta) if git.clean?
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  git.add(".")
         | 
| 29 | 
            +
                  git.commit("-m \"Update cache at #{Time.new}\"")
         | 
| 30 | 
            +
                  git.push("origin #{branch}")
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                private
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def git
         | 
| 36 | 
            +
                  @git ||= Git.new(config.spm_repo_dir)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def ensure_remote
         | 
| 40 | 
            +
                  existing = git.remote("get-url origin || true", capture: true, log_cmd: false)[0].strip
         | 
| 41 | 
            +
                  return if @remote == existing
         | 
| 42 | 
            +
                  return git.remote("add origin #{@remote}") if existing.empty?
         | 
| 43 | 
            +
                  git.remote("set-url origin #{@remote}")
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            require_relative "base"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module XCCache
         | 
| 4 | 
            +
              class S3Storage < Storage
         | 
| 5 | 
            +
                def initialize(options = {})
         | 
| 6 | 
            +
                  super
         | 
| 7 | 
            +
                  @uri = options[:uri]
         | 
| 8 | 
            +
                  @creds_path = Pathname(options[:creds_path] || "~/.xccache/s3.creds.json").expand_path
         | 
| 9 | 
            +
                  creds = JSONRepresentable.new(@creds_path)
         | 
| 10 | 
            +
                  @access_key_id = creds["access_key_id"]
         | 
| 11 | 
            +
                  @secret_access_key = creds["secret_access_key"]
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def pull
         | 
| 15 | 
            +
                  s3_sync(src: @uri, dst: config.spm_repo_dir)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def push
         | 
| 19 | 
            +
                  s3_sync(src: config.spm_repo_dir, dst: @uri)
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                private
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def s3_sync(src: nil, dst: nil)
         | 
| 25 | 
            +
                  validate!
         | 
| 26 | 
            +
                  UI.info("Syncing cache from #{src.to_s.bold} to #{dst.to_s.bold}...")
         | 
| 27 | 
            +
                  env = {
         | 
| 28 | 
            +
                    "AWS_ACCESS_KEY_ID" => @access_key_id,
         | 
| 29 | 
            +
                    "AWS_SECRET_ACCESS_KEY" => @secret_access_key,
         | 
| 30 | 
            +
                  }
         | 
| 31 | 
            +
                  cmd = ["aws", "s3", "sync"]
         | 
| 32 | 
            +
                  cmd << "--exact-timestamps" << "--delete"
         | 
| 33 | 
            +
                  cmd << "--include" << "*.xcframework"
         | 
| 34 | 
            +
                  cmd << "--include" << "*.macro"
         | 
| 35 | 
            +
                  cmd << src << dst
         | 
| 36 | 
            +
                  Sh.run(cmd, env: env)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def validate!
         | 
| 40 | 
            +
                  if File.which("awsss").nil?
         | 
| 41 | 
            +
                    raise GeneralError, "awscli is not installed. Please install it via brew: `brew install awscli`"
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                  return unless @access_key_id.nil? || @secret_access_key.nil?
         | 
| 44 | 
            +
                  raise GeneralError, <<~DESC
         | 
| 45 | 
            +
                    Please ensure the credentials json at #{@creds_path}. Example:
         | 
| 46 | 
            +
                    {
         | 
| 47 | 
            +
                      "access_key_id": <ACCESS_KEY_ID>,
         | 
| 48 | 
            +
                      "secret_access_key": <SECRET_ACCESS_KEY>
         | 
| 49 | 
            +
                    }
         | 
| 50 | 
            +
                  DESC
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            Dir["#{__dir__}/#{File.basename(__FILE__, '.rb')}/*.rb"].sort.each { |f| require f }
         | 
    
        data/lib/xccache/swift/sdk.rb
    CHANGED
    
    | @@ -8,6 +8,7 @@ module XCCache | |
| 8 8 | 
             
                  NAME_TO_TRIPLE = {
         | 
| 9 9 | 
             
                    :iphonesimulator => "arm64-apple-ios-simulator",
         | 
| 10 10 | 
             
                    :iphoneos => "arm64-apple-ios",
         | 
| 11 | 
            +
                    :macosx => "arm64-apple-macosx",
         | 
| 11 12 | 
             
                  }.freeze
         | 
| 12 13 |  | 
| 13 14 | 
             
                  def initialize(name)
         | 
| @@ -18,13 +19,31 @@ module XCCache | |
| 18 19 | 
             
                    name
         | 
| 19 20 | 
             
                  end
         | 
| 20 21 |  | 
| 21 | 
            -
                  def triple
         | 
| 22 | 
            -
                    NAME_TO_TRIPLE[name.to_sym]
         | 
| 22 | 
            +
                  def triple(without_vendor: false)
         | 
| 23 | 
            +
                    res = NAME_TO_TRIPLE[name.to_sym]
         | 
| 24 | 
            +
                    res = res.sub("-apple", "") if without_vendor
         | 
| 25 | 
            +
                    res
         | 
| 23 26 | 
             
                  end
         | 
| 24 27 |  | 
| 25 28 | 
             
                  def sdk_path
         | 
| 29 | 
            +
                    # rubocop:disable Layout/LineLength
         | 
| 30 | 
            +
                    # /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
         | 
| 31 | 
            +
                    # rubocop:enable Layout/LineLength
         | 
| 26 32 | 
             
                    @sdk_path ||= Pathname(Sh.capture_output("xcrun --sdk #{name} --show-sdk-path")).realpath
         | 
| 27 33 | 
             
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def sdk_platform_developer_path
         | 
| 36 | 
            +
                    @sdk_platform_developer_path ||= sdk_path.parent.parent # iPhoneSimulator.platform/Developer
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def swiftc_args
         | 
| 40 | 
            +
                    developer_library_frameworks_path = sdk_platform_developer_path / "Library" / "Frameworks"
         | 
| 41 | 
            +
                    developer_usr_lib_path = sdk_platform_developer_path / "usr" / "lib"
         | 
| 42 | 
            +
                    [
         | 
| 43 | 
            +
                      "-F#{developer_library_frameworks_path}",
         | 
| 44 | 
            +
                      "-I#{developer_usr_lib_path}",
         | 
| 45 | 
            +
                    ]
         | 
| 46 | 
            +
                  end
         | 
| 28 47 | 
             
                end
         | 
| 29 48 | 
             
              end
         | 
| 30 49 | 
             
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require "xcodeproj"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Xcodeproj
         | 
| 4 | 
            +
              class Project
         | 
| 5 | 
            +
                module Object
         | 
| 6 | 
            +
                  class XCBuildConfiguration
         | 
| 7 | 
            +
                    def base_configuration_xcconfig
         | 
| 8 | 
            +
                      path = base_configuration_xcconfig_path
         | 
| 9 | 
            +
                      Config.new(path) if path
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    def base_configuration_xcconfig_path
         | 
| 13 | 
            +
                      return base_configuration_reference.real_path if base_configuration_reference
         | 
| 14 | 
            +
                      return unless base_configuration_reference_anchor && base_configuration_reference_relative_path
         | 
| 15 | 
            +
                      project.dir / base_configuration_reference_anchor.path / base_configuration_reference_relative_path
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require "xcodeproj"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Xcodeproj
         | 
| 4 | 
            +
              class Project
         | 
| 5 | 
            +
                module Object
         | 
| 6 | 
            +
                  class PBXFileSystemSynchronizedRootGroup
         | 
| 7 | 
            +
                    attribute :name, String
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def display_name
         | 
| 10 | 
            +
                      return name if name
         | 
| 11 | 
            +
                      return File.basename(path) if path
         | 
| 12 | 
            +
                      super
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require "xcodeproj"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Xcodeproj
         | 
| 4 | 
            +
              class Project
         | 
| 5 | 
            +
                module Object
         | 
| 6 | 
            +
                  class PBXGroup
         | 
| 7 | 
            +
                    def synced_groups
         | 
| 8 | 
            +
                      children.grep(PBXFileSystemSynchronizedRootGroup)
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    def ensure_synced_group(name: nil, path: nil)
         | 
| 12 | 
            +
                      synced_groups.find { |g| g.name == name } || new_synced_group(name: name, path: path)
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def new_synced_group(name: nil, path: nil)
         | 
| 16 | 
            +
                      path = path.relative_path_from(project.dir) unless path.relative?
         | 
| 17 | 
            +
                      synced_group = project.new(PBXFileSystemSynchronizedRootGroup)
         | 
| 18 | 
            +
                      synced_group.path = path.to_s
         | 
| 19 | 
            +
                      synced_group.name = name || path.basename.to_s
         | 
| 20 | 
            +
                      self << synced_group
         | 
| 21 | 
            +
                      synced_group
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -20,6 +20,10 @@ module Xcodeproj | |
| 20 20 | 
             
                      local? && id == "xccache/packages/umbrella"
         | 
| 21 21 | 
             
                    end
         | 
| 22 22 |  | 
| 23 | 
            +
                    def non_xccache_pkg?
         | 
| 24 | 
            +
                      !xccache_pkg?
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
             | 
| 23 27 | 
             
                    def create_pkg_product_dependency_ref(product)
         | 
| 24 28 | 
             
                      ref = project.new(XCSwiftPackageProductDependency)
         | 
| 25 29 | 
             
                      ref.package = self
         | 
| @@ -53,7 +57,7 @@ module Xcodeproj | |
| 53 57 | 
             
                    end
         | 
| 54 58 |  | 
| 55 59 | 
             
                    def absolute_path
         | 
| 56 | 
            -
                      path.nil? ? project. | 
| 60 | 
            +
                      path.nil? ? project.dir / relative_path : path
         | 
| 57 61 | 
             
                    end
         | 
| 58 62 | 
             
                  end
         | 
| 59 63 |  | 
| @@ -12,10 +12,18 @@ module Xcodeproj | |
| 12 12 | 
             
                  @relative_path ||= path.relative_path_from(Pathname(".").expand_path)
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 | 
            +
                def dir
         | 
| 16 | 
            +
                  path.parent
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 15 19 | 
             
                def pkgs
         | 
| 16 20 | 
             
                  root_object.package_references
         | 
| 17 21 | 
             
                end
         | 
| 18 22 |  | 
| 23 | 
            +
                def xccache_pkg
         | 
| 24 | 
            +
                  pkgs.find(&:xccache_pkg?)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 19 27 | 
             
                def non_xccache_pkgs
         | 
| 20 28 | 
             
                  pkgs.reject(&:xccache_pkg?)
         | 
| 21 29 | 
             
                end
         | 
| @@ -36,7 +44,8 @@ module Xcodeproj | |
| 36 44 | 
             
                  Log.message("Add package #{hash[key].bold} to project #{display_name.bold}")
         | 
| 37 45 | 
             
                  cls = is_local ? XCLocalSwiftPackageReference : XCRemoteSwiftPackageReference
         | 
| 38 46 | 
             
                  ref = new(cls)
         | 
| 39 | 
            -
                   | 
| 47 | 
            +
                  custom_keys = ["path_from_root"]
         | 
| 48 | 
            +
                  hash.each { |k, v| ref.send("#{k}=", v) unless custom_keys.include?(k) }
         | 
| 40 49 | 
             
                  root_object.package_references << ref
         | 
| 41 50 | 
             
                  ref
         | 
| 42 51 | 
             
                end
         | 
| @@ -46,6 +55,13 @@ module Xcodeproj | |
| 46 55 | 
             
                  add_pkg("relative_path" => sandbox_path.relative_path_from(path.parent).to_s)
         | 
| 47 56 | 
             
                end
         | 
| 48 57 |  | 
| 58 | 
            +
                def remove_pkgs(&block)
         | 
| 59 | 
            +
                  pkgs.select(&block).each do |pkg|
         | 
| 60 | 
            +
                    XCCache::UI.info("(-) Remove #{pkg.display_name.red} from package refs of project #{display_name.bold}")
         | 
| 61 | 
            +
                    pkg.remove_from_project
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 49 65 | 
             
                def get_target(name)
         | 
| 50 66 | 
             
                  targets.find { |t| t.name == name }
         | 
| 51 67 | 
             
                end
         | 
| @@ -54,6 +70,10 @@ module Xcodeproj | |
| 54 70 | 
             
                  pkgs.find { |p| p.slug == name }
         | 
| 55 71 | 
             
                end
         | 
| 56 72 |  | 
| 73 | 
            +
                def xccache_config_group
         | 
| 74 | 
            +
                  self["xccache.config"] || new_group("xccache.config")
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 57 77 | 
             
                private
         | 
| 58 78 |  | 
| 59 79 | 
             
                def pkg_key_in_hash(hash)
         | 
| @@ -7,15 +7,15 @@ module Xcodeproj | |
| 7 7 | 
             
                    alias pkg_product_dependencies package_product_dependencies
         | 
| 8 8 |  | 
| 9 9 | 
             
                    def non_xccache_pkg_product_dependencies
         | 
| 10 | 
            -
                      pkg_product_dependencies.reject { |d| d.pkg | 
| 10 | 
            +
                      pkg_product_dependencies.reject { |d| d.pkg&.xccache_pkg? }
         | 
| 11 11 | 
             
                    end
         | 
| 12 12 |  | 
| 13 13 | 
             
                    def has_xccache_product_dependency?
         | 
| 14 | 
            -
                      pkg_product_dependencies.any? { |d| d.pkg | 
| 14 | 
            +
                      pkg_product_dependencies.any? { |d| d.pkg&.xccache_pkg? }
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| 17 17 | 
             
                    def has_pkg_product_dependency?(name)
         | 
| 18 | 
            -
                      pkg_product_dependencies.any? { |d|  | 
| 18 | 
            +
                      pkg_product_dependencies.any? { |d| d.full_name == name }
         | 
| 19 19 | 
             
                    end
         | 
| 20 20 |  | 
| 21 21 | 
             
                    def add_pkg_product_dependency(name)
         | 
| @@ -41,6 +41,8 @@ module Xcodeproj | |
| 41 41 | 
             
                        build_phases.each do |phase|
         | 
| 42 42 | 
             
                          phase.files.select { |f| f.remove_from_project if f.product_ref == d }
         | 
| 43 43 | 
             
                        end
         | 
| 44 | 
            +
                        # Remove it from target dependencies
         | 
| 45 | 
            +
                        dependencies.each { |x| x.remove_from_project if x.product_ref == d }
         | 
| 44 46 | 
             
                        d.remove_from_project
         | 
| 45 47 | 
             
                      end
         | 
| 46 48 | 
             
                    end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: xccache
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.1a3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Thuyen Trinh
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2025- | 
| 11 | 
            +
            date: 2025-05-13 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: claide
         | 
| @@ -25,7 +25,7 @@ dependencies: | |
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            -
              name:  | 
| 28 | 
            +
              name: parallel
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - ">="
         | 
| @@ -38,6 +38,20 @@ dependencies: | |
| 38 38 | 
             
                - - ">="
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: xcodeproj
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - ">="
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: 1.26.0
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ">="
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: 1.26.0
         | 
| 41 55 | 
             
            description: A Ruby gem
         | 
| 42 56 | 
             
            email:
         | 
| 43 57 | 
             
            - trinhngocthuyen@gmail.com
         | 
| @@ -58,9 +72,13 @@ files: | |
| 58 72 | 
             
            - lib/xccache/assets/templates/umbrella.Package.swift.template
         | 
| 59 73 | 
             
            - lib/xccache/cache/cachemap.rb
         | 
| 60 74 | 
             
            - lib/xccache/command.rb
         | 
| 75 | 
            +
            - lib/xccache/command/base.rb
         | 
| 61 76 | 
             
            - lib/xccache/command/build.rb
         | 
| 62 77 | 
             
            - lib/xccache/command/pkg.rb
         | 
| 63 78 | 
             
            - lib/xccache/command/pkg/build.rb
         | 
| 79 | 
            +
            - lib/xccache/command/remote.rb
         | 
| 80 | 
            +
            - lib/xccache/command/remote/pull.rb
         | 
| 81 | 
            +
            - lib/xccache/command/remote/push.rb
         | 
| 64 82 | 
             
            - lib/xccache/command/rollback.rb
         | 
| 65 83 | 
             
            - lib/xccache/command/use.rb
         | 
| 66 84 | 
             
            - lib/xccache/core.rb
         | 
| @@ -71,26 +89,30 @@ files: | |
| 71 89 | 
             
            - lib/xccache/core/hash.rb
         | 
| 72 90 | 
             
            - lib/xccache/core/lockfile.rb
         | 
| 73 91 | 
             
            - lib/xccache/core/log.rb
         | 
| 92 | 
            +
            - lib/xccache/core/parallel.rb
         | 
| 74 93 | 
             
            - lib/xccache/core/sh.rb
         | 
| 75 94 | 
             
            - lib/xccache/core/syntax.rb
         | 
| 76 95 | 
             
            - lib/xccache/core/syntax/hash.rb
         | 
| 77 96 | 
             
            - lib/xccache/core/syntax/json.rb
         | 
| 97 | 
            +
            - lib/xccache/core/syntax/plist.rb
         | 
| 78 98 | 
             
            - lib/xccache/core/syntax/yml.rb
         | 
| 79 99 | 
             
            - lib/xccache/core/system.rb
         | 
| 80 | 
            -
            - lib/xccache/framework/slice.rb
         | 
| 81 | 
            -
            - lib/xccache/framework/xcframework.rb
         | 
| 82 100 | 
             
            - lib/xccache/installer.rb
         | 
| 83 101 | 
             
            - lib/xccache/installer/build.rb
         | 
| 84 102 | 
             
            - lib/xccache/installer/rollback.rb
         | 
| 85 103 | 
             
            - lib/xccache/installer/use.rb
         | 
| 86 104 | 
             
            - lib/xccache/main.rb
         | 
| 87 105 | 
             
            - lib/xccache/spm.rb
         | 
| 106 | 
            +
            - lib/xccache/spm/build.rb
         | 
| 88 107 | 
             
            - lib/xccache/spm/desc.rb
         | 
| 89 108 | 
             
            - lib/xccache/spm/desc/base.rb
         | 
| 90 109 | 
             
            - lib/xccache/spm/desc/dep.rb
         | 
| 91 110 | 
             
            - lib/xccache/spm/desc/desc.rb
         | 
| 92 111 | 
             
            - lib/xccache/spm/desc/product.rb
         | 
| 93 112 | 
             
            - lib/xccache/spm/desc/target.rb
         | 
| 113 | 
            +
            - lib/xccache/spm/desc/target/binary.rb
         | 
| 114 | 
            +
            - lib/xccache/spm/desc/target/macro.rb
         | 
| 115 | 
            +
            - lib/xccache/spm/macro.rb
         | 
| 94 116 | 
             
            - lib/xccache/spm/mixin.rb
         | 
| 95 117 | 
             
            - lib/xccache/spm/pkg.rb
         | 
| 96 118 | 
             
            - lib/xccache/spm/pkg/base.rb
         | 
| @@ -100,10 +122,23 @@ files: | |
| 100 122 | 
             
            - lib/xccache/spm/pkg/umbrella/descs.rb
         | 
| 101 123 | 
             
            - lib/xccache/spm/pkg/umbrella/manifest.rb
         | 
| 102 124 | 
             
            - lib/xccache/spm/pkg/umbrella/viz.rb
         | 
| 125 | 
            +
            - lib/xccache/spm/pkg/umbrella/xcconfigs.rb
         | 
| 126 | 
            +
            - lib/xccache/spm/xcframework.rb
         | 
| 127 | 
            +
            - lib/xccache/spm/xcframework/metadata.rb
         | 
| 128 | 
            +
            - lib/xccache/spm/xcframework/slice.rb
         | 
| 129 | 
            +
            - lib/xccache/spm/xcframework/xcframework.rb
         | 
| 130 | 
            +
            - lib/xccache/storage.rb
         | 
| 131 | 
            +
            - lib/xccache/storage/base.rb
         | 
| 132 | 
            +
            - lib/xccache/storage/git.rb
         | 
| 133 | 
            +
            - lib/xccache/storage/s3.rb
         | 
| 103 134 | 
             
            - lib/xccache/swift/sdk.rb
         | 
| 104 135 | 
             
            - lib/xccache/swift/swiftc.rb
         | 
| 105 136 | 
             
            - lib/xccache/utils/template.rb
         | 
| 106 137 | 
             
            - lib/xccache/xcodeproj.rb
         | 
| 138 | 
            +
            - lib/xccache/xcodeproj/build_configuration.rb
         | 
| 139 | 
            +
            - lib/xccache/xcodeproj/config.rb
         | 
| 140 | 
            +
            - lib/xccache/xcodeproj/file_system_synchronized_root_group.rb
         | 
| 141 | 
            +
            - lib/xccache/xcodeproj/group.rb
         | 
| 107 142 | 
             
            - lib/xccache/xcodeproj/pkg.rb
         | 
| 108 143 | 
             
            - lib/xccache/xcodeproj/pkg_product_dependency.rb
         | 
| 109 144 | 
             
            - lib/xccache/xcodeproj/project.rb
         | 
| @@ -1,51 +0,0 @@ | |
| 1 | 
            -
            module XCCache
         | 
| 2 | 
            -
              class Framework
         | 
| 3 | 
            -
                class XCFramework
         | 
| 4 | 
            -
                  attr_reader :name, :module_name, :pkg_dir, :pkg_desc, :config, :sdks, :path
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                  def initialize(options = {})
         | 
| 7 | 
            -
                    @name = options[:name]
         | 
| 8 | 
            -
                    @module_name = @name.c99extidentifier
         | 
| 9 | 
            -
                    @pkg_dir = options[:pkg_dir]
         | 
| 10 | 
            -
                    @pkg_desc = options[:pkg_desc]
         | 
| 11 | 
            -
                    @config = options[:config]
         | 
| 12 | 
            -
                    @sdks = options[:sdks]
         | 
| 13 | 
            -
                    @path = options[:path]
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  def create
         | 
| 17 | 
            -
                    slices.each(&:build)
         | 
| 18 | 
            -
                    UI.section("Creating #{name}.xcframework from slices") do
         | 
| 19 | 
            -
                      path.rmtree if path.exist?
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                      cmd = ["xcodebuild", "-create-xcframework"]
         | 
| 22 | 
            -
                      cmd << "-output" << path
         | 
| 23 | 
            -
                      slices.each { |slice| cmd << "-framework" << slice.path }
         | 
| 24 | 
            -
                      Sh.run(cmd)
         | 
| 25 | 
            -
                    end
         | 
| 26 | 
            -
                    tmpdir.rmtree
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    # TODO: Should we dispose tmpdir here as well?
         | 
| 29 | 
            -
                  end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                  def tmpdir
         | 
| 32 | 
            -
                    @tmpdir ||= Dir.create_tmpdir
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  def slices
         | 
| 36 | 
            -
                    @slices ||= sdks.map do |s|
         | 
| 37 | 
            -
                      sdk = Swift::Sdk.new(s)
         | 
| 38 | 
            -
                      Framework::Slice.new(
         | 
| 39 | 
            -
                        name: name,
         | 
| 40 | 
            -
                        pkg_dir: pkg_dir,
         | 
| 41 | 
            -
                        pkg_desc: pkg_desc,
         | 
| 42 | 
            -
                        sdk: sdk,
         | 
| 43 | 
            -
                        config: config,
         | 
| 44 | 
            -
                        path: Dir.prepare(tmpdir / sdk.triple / "#{module_name}.framework"),
         | 
| 45 | 
            -
                        tmpdir: tmpdir,
         | 
| 46 | 
            -
                      )
         | 
| 47 | 
            -
                    end
         | 
| 48 | 
            -
                  end
         | 
| 49 | 
            -
                end
         | 
| 50 | 
            -
              end
         | 
| 51 | 
            -
            end
         |