I have a question and I hope you can help me. I am working on a piece of code with the goal of programmatically changing SPM dependencies. Specifically, I want to force a certain version of an SPM package in a project.
For example, app A is using dependency B, and I want to force a particular version of B because I am the maintainer of B. I want to test if the new version of B breaks app A.
Can you give me some pointers on how to do this properly? Should I add a requirement to the XCRemoteSwiftPackageReference object?
In the code snippet below, I am trying to modify the pbxproj file as expected.
I would be glad to contribute code to your project once it is working properly.
Thanks,
func transformPbxproj(_ package: String, _ url: URL, _ version: PackageVersion) async throws {
do {
var folderXcodeProjectFile = url.deletingLastPathComponent()
let proj = try XCProjectFile(xcodeprojURL: folderXcodeProjectFile)
var output = proj
for obj in proj.allObjects.objects.values {
if let dep = obj as? XCRemoteSwiftPackageReference {
if let repo = dep.repositoryURL, repo.path.contains(package) == false { continue }
switch version {
// How to properly represent requirement ?
/*
3758DBD6234CB17D0046933B /* XCRemoteSwiftPackageReference "RxSwift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ReactiveX/RxSwift.git";
requirement = {
kind = exactVersion;
version = 6.6.0;
};
};
*/
case let .tag(value):
let fields = Fields(dictionaryLiteral: ("kind", "exactVersion"), ("version", value))
let pkgRef = try XCRemoteSwiftPackageReference(id: dep.id, fields: fields, allObjects: dep.allObjects)
output.allObjects.objects[dep.id] = pkgRef
case let .branch(value):
let fields = Fields(dictionaryLiteral: ("kind", "branch"), ("branch", value))
let pkgRef = try XCRemoteSwiftPackageReference(id: dep.id, fields: fields, allObjects: dep.allObjects)
output.allObjects.objects[dep.id] = pkgRef
case let .commit(value):
let fields = Fields(dictionaryLiteral: ("kind", "revision"), ("revision", value))
let pkgRef = try XCRemoteSwiftPackageReference(id: dep.id, fields: fields, allObjects: dep.allObjects)
output.allObjects.objects[dep.id] = pkgRef
case let .path(value, name):
let fields = Fields(dictionaryLiteral: ("relativePath", value))
let pkgRef = try XCLocalSwiftPackageReference(id: dep.id, fields: fields, allObjects: dep.allObjects)
output.allObjects.objects[dep.id] = pkgRef
}
}
}
// Write out a new pbxproj file
try output.write(to: folderXcodeProjectFile, format: PropertyListSerialization.PropertyListFormat.openStep)
} catch {
print("Error with file to open \(url)")
}
}
Hi @tomlokhorst, thanks for working on XcodeEdit.
I have a question and I hope you can help me. I am working on a piece of code with the goal of programmatically changing SPM dependencies. Specifically, I want to force a certain version of an SPM package in a project.
For example, app A is using dependency B, and I want to force a particular version of B because I am the maintainer of B. I want to test if the new version of B breaks app A.
Can you give me some pointers on how to do this properly? Should I add a
requirement
to theXCRemoteSwiftPackageReference
object?In the code snippet below, I am trying to modify the pbxproj file as expected.
I would be glad to contribute code to your project once it is working properly.
Thanks,