Add Swift Package (SPM) from CLI with fastlane, ruby and Xcodeproj

210 Views Asked by At

There seems to be a lot of questions and answers on how to refresh Swift Package Manager from CLI, but none on how to add or remove a dependency from CLI.

I need this as I have a lot of combinations of external dependencies that need to be handled from on single target. So I need to be able to set/remove dependencies from my fastlane lane and then resolve.

The closest I've found is the xcodeproj tools to manipulate my "project.pbxproj" file. The closest to a solution is this snippet from https://github.com/CocoaPods/Xcodeproj/issues/408#issuecomment-465942072 :

# Replace these with your values
project_location = '/path/to/MyApp.xcodeproj'
target_name = 'MyApp'
framework_root = '/framework/parent/directory'
framework_name = 'MyFramework.framework'

# Get useful variables
project = Xcodeproj::Project.open(project_location)
frameworks_group = project.groups.find { |group| group.display_name == 'Frameworks' }
target = project.targets.find { |target| target.to_s == target_name }
frameworks_build_phase = target.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }

# Add new "Embed Frameworks" build phase to target
embed_frameworks_build_phase = project.new(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
embed_frameworks_build_phase.name = 'Embed Frameworks'
embed_frameworks_build_phase.symbol_dst_subfolder_spec = :frameworks
target.build_phases << embed_frameworks_build_phase

# Add framework search path to target
['Debug', 'Release'].each do |config|
  paths = ['$(inherited)', framework_root]
  target.build_settings(config)['FRAMEWORK_SEARCH_PATHS'] = paths
end

# Add framework to target as "Embedded Frameworks"
framework_ref = frameworks_group.new_file("#{framework_root}/#{framework_name}")
build_file = embed_frameworks_build_phase.add_file_reference(framework_ref)
frameworks_build_phase.add_file_reference(framework_ref)
build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }

# Save Xcode project
project.save

But it's not exactly what I'm looking for.

This seems to be relevant: https://www.rubydoc.info/gems/xcodeproj/Xcodeproj/Project/Object/XCRemoteSwiftPackageReference

There seem to be a lot of places a SPM is referenced in the pbxproj-file. Adding a SPM-package to a target and reviewing the change in Git reveals these four locations:

1. Under

/* Begin PBXFrameworksBuildPhase section */

enter image description here

2. Under

/* Begin PBXFrameworksBuildPhase section */
        1B13EC1422A7971500543B8E /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (

enter image description here

3. and under:

/* Begin PBXNativeTarget section */
    /* ... */
    1BB8572F2A44716000A81663 /* BuildTarget_AK */ = {
        isa = PBXNativeTarget;
        /* ... */
        name = BuildTarget_AK;
        packageProductDependencies = (

enter image description here

4. Under

/* Begin XCSwiftPackageProductDependency section */

enter image description here

Any leads for me here? I assume I need four different ways of setting these entries.

Update: This seems to be some code in the right direction: https://github.com/igor-makarov/xcoed/blob/564c4ae5dec1a3edb8154d33c146f776dec406bd/lib/xcoed.rb#L98

0

There are 0 best solutions below