Disambiguating SwiftPM Naming Conflicts
- Proposal: TBD
- Author(s): Erica Sadun
- Status: TBD
- Review manager: TBD
This proposal creates a way to resolve SwiftPM module conflicts. It introduces namespacing to handle the rare case of name overlaps without requiring a central package registry.
This proposal was discussed on the Swift-Dev and Swift-Build-Dev lists in the "Right List?" thread.
Swift offers a built in mechanism for distinguishing symbol conflicts. When working with
Swift.print outputs text to the console or stream.
Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like
SwiftCollections because simple clear naming is a hallmark of Swift design. At the same time, this style introduces the possibility of package name conflicts.
import SwiftString // mine import SwiftString // someone else's. oops.
SwiftString packages cannot be used simultaneously without some form of namespace resolution. Moving back to Cocoa-style namespacing, for example
ESSwiftString, feels ugly and antithetical to Swift. Swift should encourage recognizable, easy-to-understand module names. This proposal addresses this rare but possible conflict.
Under the current system, same-named modules:
import PackageDescription let package = Package ( name: "myutility", dependencies: [ .Package(url: "https://github.com/erica/SwiftString.git", majorVersion: 1), .Package(url: "https://github.com/nudas/SwiftString.git", majorVersion: 1), ] )
produce the following errors:
% swift build Cloning Packages/SwiftString Using version 1.0.5 of package SwiftString Cloning Packages/SwiftString /usr/bin/git clone --recursive --depth 10 https://github.com/nudas/SwiftString.git /home/erica/Work/test/Packages/SwiftString fatal: destination path '/home/erica/Work/test/Packages/SwiftString' already exists and is not an empty directory. swift-build: Failed to clone https://github.com/nudas/SwiftString.git to /home/erica/Work/test/Packages/SwiftString Makefile:3: recipe for target 'all' failed make: *** [all] Error 1
Under this proposal, the Swift Package manager uses reverse domain naming to differentiate otherwise identically-named items. The two conflicting packages in the following example:
import PackageDescription let package = Package ( name: "MyUtility", dependencies: [ .Package(url: "https://github.com/erica/SwiftString.git", majorVersion: 1), .Package(url: "https://github.com/bob/SwiftString.git", majorVersion: 1), ] )
Packages/com.github.bob.SwiftString rather than
These can then be imported using the full RDN notation:
import com.github.erica.SwiftString import com.github.bob.SwiftString
Reverse domain names
- are rarely used outside the import statement and only to distinguish overlapping implementations
- are relatively short
- are already well established for Apple app distribution
- are tied to the hosting repo
However concise, using reverse domain names bring verbiage to name conflicts. Upon adopting this proposal, I intend following through with language specific proposals that allow either
import as or right-to-left namespacing.
import as statement would allow a developer to rename a module on import:
import com.github.erica.SwiftString as EricaString
A right-to-left alternative would require only as much of the reverse domain name prefix as needed to distinguish one implementation from another, for example:
although presumably the fully specified RDN prefix could be used as well: