It would be great to avoid heavy crypto package or even a simple stream if we only need file.git, but if they're available somewhere in the graph we would get extra APIs from the file.git:
By default it shouldn't. It should be used as dependency only if it's available somewhere in the graph (if it's being used as non-optional dependency somewhere)
The answer to all of this: nothing happens. It doesn't add any constrain. We only use the dependency if we can satisfy the requirements using the main graph.
Well, actually we could treat them as non-optional in this case because it's a dev-only story I think.
I'm trying to conditionally add code into a SPM target (A) only when that's a dependency of another target (B) that imports another dependency (C).
in target A
#if canImport(C)
...
target B imports A and C.
I thought canImport would work for this but it doesn't seem to behave as I expect, at least from Xcode. Sometimes the code is compiled when compiling the schema for A, even tho C is not imported at all. Other times compiling B doesn't work, even tho it imports both other targets.
I don't think canImport works for this, since it is based on whether or not there happens to be a module C in the search path. If you don't explicitly depend on it, that will not be deterministic as C can be build in parallel or even after A. It can also be present from previous builds if you are building incrementally.
That’s what it looked like ^^ thanks for confirming it!
I guess there is no way to get something like this then?
Basically I wish I could do the same Apple does where you need to import SwiftUI and MapKit to get access to map view, that but with my own (or 3rd party) packages.
This is because otherwise you always need to make an extra package that brings both together. This is fine for 1 but when you modularise your app things like this arise a bunch.
Oh that seems to be what I was looking for. In my mind the can import technique makes more sense so you don’t have to make more packages but maybe it can’t work. Anyway I will look into that other thread.
cheers
There’s a few issues here that I feel are worth discussing, as the status quo runs straight into them.
A package should be able to take advantage of an optional package if it already exists. Despite being optional, it would need to have version restrictions to avoid unpredictably breaking. In the event of a version that doesn’t match the optional dependency, it would be best for the optional functionality to be disabled rather than failing outright.
A package may want a dependency purely to use optional functionality in another package (that is, without directly using anything in the optional dependency). It may make sense, therefore, to instead specify that the optional functionality is required. This could be accomplished by assigning optional dependencies to a “flag” that can be passed when depending on a product. Using a separate product would be ideal, but prevents internal declarations from being used.
A package may need at least one of a set of “optional” dependencies. Swift Package Manager could implement this deterministically by choosing the first compatible dependency in the list if none of them already exist (most notably when it is the root package).
A package may have mutually-exclusive optional dependencies that produce the same interface: for instance, the same protocol implementation may be provided using different packages, such that having multiple would cause compilation to fail. This could be resolved deterministically by choosing the first present dependency in the list, similar to #3.