swift-package: unable to add json to the package manifest - swift

I just can't believe how unintuitive this process is and how complicated and convoluted #apple has made this normally simple process.
I've been spending the past 2 hours trying to add a test suite json file for some offline tests on my new package. I tried looking at the official apple way and another source on the internet but nothing works.
I'm just trying to add the following:
.target(
name: "testJSON",
resources: [
.copy("test.json")
]
)
In the package manifest, which is below:
let package = Package(
name: "SwiftHorizons",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "SwiftHorizons",
targets: ["SwiftHorizons"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "SwiftHorizons",
dependencies: []),
.testTarget(
name: "SwiftHorizonsTests",
dependencies: ["SwiftHorizons"]),
]
)
The file is in the sources folder at the moment. I tried putting it in the test folder, just the file itself, everywhere. None work, either give me an error message or none but when running the test suite, 0 tests are run.
This is the most stupid non work morning I have ever experienced with an apple product.

Related

How to create an SPM package based on ObjC code?

I'd like to create a SwiftPackageManager library based on Objective-C code but I can't seem to grasp what I'm missing.
My latest change to just vanilla ObjC interface .h file inside the include folder was to add an extra C header that includes de ObjC but still had no success. What am I missing?
The Package.swift file is the default generated one and from what I read it should automatically generate the module map from the include folder.
My swift-tools-version is 5.5
Figured it out.
I added a modulemap that specifies my ObjC header and it worked
Not sure if it is the correct way to do it since the include folder should already do this automatically.
So just had the same issue. (my 5 cent)
This is may Package.swift:
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "AlgorithmSDK",
platforms: [
.iOS(.v13)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages. , "AlgorithmSDKObjc"
.library(
name: "AlgorithmSDK",
targets: ["AlgorithmSDK","AlgorithmSDKObjc" ]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "AlgorithmSDK",
dependencies: []),
.testTarget(
name: "AlgorithmSDKTests",
dependencies: ["AlgorithmSDK"]),
.target(
name: "AlgorithmSDKObjc",
dependencies: [],
publicHeadersPath:"include"),//<----- This path is relative to the target! (and can be ignored)
]
)
With the structure:
The publicHeadersPath should be publicHeadersPath:"include" OR ignored according to docs (it seems that it takes it relative to target and not the root). I don't think we should touch module.modulemap for such a simple structure

Conditional dependency for target in SwiftPM

I have a custom swift package I am building that has as one of its dependencies a package (Bugfender) that is an xcframework and is iOS only (and Mac Catalyst). Understandably, when I try to compile this package in Xcode (12.5) I get an error that a mac library for that package cannot be found (all iOS specific code is wrapped in a #if os(iOS) block).
Based on this (https://github.com/apple/swift-evolution/blob/master/proposals/0273-swiftpm-conditional-target-dependencies.md) addition to the Swift package spec, I thought I could use a condition to exclude the dependency for mac, but when I try the following Swift.package file, I still get the same error when building for mac. Is this a bug or am I doing something wrong? It seems like it should work based on this post as well (Swift package manager: How best to indicate platform dependent code?)
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "GTSApplicationLogging",
platforms: [
.iOS(.v12), .macOS(.v10_13),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "GTSApplicationLogging",
targets: ["GTSApplicationLogging"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(name: "BugfenderPackage", url: "https://github.com/bugfender/BugfenderSDK-iOS", .exact("1.10.2")),
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver.git", .exact("1.9.5")),
.package(url: "https://github.com/marmelroy/Zip.git", .exact("2.1.1")),
.package(path: "../GTSPureAppleExtensions"),
.package(path: "../GTSApplicationError"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "GTSApplicationLogging",
dependencies: ["SwiftyBeaver", "GTSPureAppleExtensions", "GTSApplicationError", "Zip", .product(name: "BugfenderLibrary", package: "BugfenderPackage", condition: .when(platforms: [.iOS]))]),
.testTarget(
name: "GTSApplicationLoggingTests",
dependencies: ["GTSApplicationLogging", "GTSApplicationError"]),
])

Swift Package Compiler Issue

I have a Project has 4 Swift Package Dependencies. Package A, B, C, D. Each package uses the previous packages as dependencies.
I'm facing an issue where Package D is having issues compiling due to do errors inside Package B that don't actually exist. (Cannot find type 'CustomType' in scope) As Package B and the xcode project I'm using the packages in both work fine.
This is preventing me from working efficiently because the complier wont work inside Package D.
I've tried deleting derived data, cleaning the build folder, reseting package cache and none of this has worked. I'm assuming I'm doing something wrong, but I have no idea what it is.
let package = Package(
name: "PackageD",
defaultLocalization: "en",
platforms: [
.iOS(.v13),
.macOS(.v10_15)
],
products: [
.library(
name: "PackageD",
targets: ["PackageD"]),
],
dependencies: [
.package(url: "PackageA", "0.0.1"..<"1.0.0"),
.package(url: "PackageB", "0.0.1"..<"1.0.0"),
.package(url: "PackageC", "0.0.1"..<"1.0.0"),
],
targets: [
.target(
name: "PackageD",
dependencies: [
"PackageA",
"PackageB",
"PackageC"
],
resources: [.process("Resources")]
),
]
)
It looks like there were a few different structs that required the use of UIKit. Which mean that UIKit needed to be able to be imported. Which wasn't an issue in the xcode project, but was an issue in the package that was built upon other packages.
Adding #if canImport(UIKit) and #endif to all the files that required it solved the issue.

Sharing code across test targets when using the Swift Package Manager

I have some code that I need to share across test targets, while I'm using the Swift Package Manager. To do this, I have a .testTarget that I also name as a dependency in another .testTarget.
Here is a simple example:
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "ExampleLib",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "ExampleLib",
targets: ["ExampleLib"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "ExampleLib",
dependencies: []),
.testTarget(
name: "Common",
dependencies: ["ExampleLib"]),
.testTarget(
name: "ExampleLibTests",
dependencies: ["Common"]),
]
)
If I try to build this package in Xcode, I get the following error:
Unable to resolve build file: XCBCore.BuildFile (The workspace has a reference to a missing target with GUID 'PACKAGE-TARGET:Common')
However, if I build from the command line (swift build) or test from the command line (swift test), I get success.
I'm using Xcode 12 beta 6, but have also tried Xcode 11.5 (with a change to the Package.swift header) and get the same results.
Here is the complete Swift package example:
https://www.dropbox.com/s/h6ypvbfonnb2zyk/ExampleLib.zip?dl=0
I really would like to use this in Xcode to build for iOS. Thoughts?
I faced the same issue and solved it by defining a Target (not Test Target) instead for Common.
My Package.swift file:
// ...
.target(name: "Common", dependencies: ["App"], path: "Tests/Common"),
.testTarget(name: "AppTests", dependencies: ["App", "Common"]),
.testTarget(name: "IntegrationTests", dependencies: ["App", "Common"])
// ...

Swift Package Manager, how to handle fixtures?

I'm looking to integrate DVR into my tests for an HTTP request-heavy library I am writing. I'm using Swift Package Manager (on macOS 10.15 using the Xcode 11 Beta) to manage my dependencies and I'm unsure how to include my fixtures generated by DVR into my test target. How do I add my fixtures from DVR to my test target?
I've tried using the default Session configuration as well as attempting to store the fixtures in a Fixtures directory using Session(outputDirectory: "Fixtures", cassetteName: "example", testBundle: .main, backingSession: .shared)
My package file is as follows:
// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Example",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "Example",
targets: ["Example"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/venmo/DVR.git", from: "2.0.0")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Example",
dependencies: []
),
.testTarget(
name: "ExampleTests",
dependencies: ["Example", "DVR"]
)
]
)
When running my tests, I get the error [DVR] Persisted cassette at Fixtures/example.json. Please add this file to your test target
I'm unsure how to add this directory to my test target.
Looks like this may be impossible as of Swift 5.1. Swift ticket: SR-2866