[swift-build-dev] Revisiting package conflicts

Erica Sadun erica at ericasadun.com
Thu Mar 31 13:24:34 CDT 2016

I'm trying to clean up a few things while my kids are on Spring Break and decided to rewrite my package
conflict proposal, which follows.

This updated version does not require any language change (although one could be adopted later), does not
require any package change, and only affects the target directories and module names.

I'd appreciate any feedback you could give.

Thanks, -- Erica

Disambiguating SwiftPM Naming Conflicts

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica>
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? <http://article.gmane.org/gmane.comp.lang.swift.devel/1149>" thread.


Swift offers a built in mechanism for distinguishing symbol conflicts. When working with NSView, using Swift.printoutputs text to the console or stream. NSView's  print creates a print job. Swift does not yet offer a solution for conflicting module names.

Like many other Swift developers, I have spent considerable time building utility packages. Mine use obvious names like SwiftString and 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.
Two 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 error:

% 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
 <https://gist.github.com/erica/c6553a5f6f35e7462074#detail-design>Detail Design

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),
unpack to Packages/com.github.erica.SwiftString and Packages/com.github.bob.SwiftString rather than Packages/SwiftString.

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
 <https://gist.github.com/erica/c6553a5f6f35e7462074#future-directions>Future Directions

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.

A Swift 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:


Thanks to Joe Groff <https://github.com/jckarter>, Ankit Aggarwal <https://github.com/aciidb0mb3r>, Max Howell, Daniel Dunbar, Kostiantyn Koval
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20160331/253010c8/attachment.html>

More information about the swift-build-dev mailing list