[swift-build-dev] Revisiting package conflicts

Daniel Dunbar daniel_dunbar at apple.com
Mon Apr 4 01:43:43 CDT 2016


I think my high level opinion on this problem is that it is still a questionable thing to support in this particular form.

I agree that using clear names, like SwiftString, is useful. However, I also think it would be very unfortunate if a product ended up using a SwiftString module from multiple authors within a single build graph. That would be confusing to work on, and especially doing it without involvement from Swift the language would be problematic (e.g., there might be mangling collisions, how would the user understand which types they were seeing in places outside of a specific module with an explicit import).

I think having more namespacing options at the language level is the right place to push on this, after which SwiftPM can adopt them (if indeed any work is required).

For example, one situation where I think this is reasonable to support is when a large package has a complicated internal module structure, most of which clients cannot see. Such a package might want to have a "Util" module, as might many other such packages, and they shouldn't collide. However, for this case to work the package needs to be written in such a way that it is clear which imports have visibility into which namespaces, it isn't just a renaming operation at the SwiftPM level.

 - Daniel

> On Mar 31, 2016, at 11:24 AM, Erica Sadun <erica at ericasadun.com> wrote:
> 
> 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
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#introduction>Introduction
> 
> 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.
> 
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#motivation>Motivation
> 
> 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 <https://github.com/erica/SwiftString.git>",
>                  majorVersion: 1),
>         .Package(url: "https://github.com/nudas/SwiftString.git <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 <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 <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 <https://github.com/erica/SwiftString.git>",
>                  majorVersion: 1),
>     .Package(url: "https://github.com/bob/SwiftString.git <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:
> 
> erica.SwiftString.print(x)
> bob.SwiftString.print(x)
> although presumably the fully specified RDN prefix could be used as well:
> 
> com.github.erica.SwiftString.print(x)
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#acknowledgements>Acknowledgements
> 
> 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/20160403/aa91f660/attachment.html>


More information about the swift-build-dev mailing list