[swift-build-dev] Namespacing SPM modules (was Re: [swift-dev] Right list?)

Erica Sadun erica at ericasadun.com
Mon Feb 29 13:39:57 CST 2016


It is my intent that wherever a module name is established, this allows an override of that name at the consuming end and no more. All other behavior would exist as-is, and any dependency trees would adopt the default name or an override name at the time the dependency is declared.

-- Erica

> On Feb 29, 2016, at 12:33 PM, Jason Dusek <jason.dusek at gmail.com> wrote:
> 
> Consider the case where Erica has packages SwiftString, HTMLString, PGString, IBMString… These modules all have somewhat different dependencies — so you would not necessarily want to download and build all of them — but they do form a coherent whole under EricaString. Would this proposal allow for names like EricaString.Swift, EricaString.HTML and EricaString.IBM?
> 
> 
> On Mon, 29 Feb 2016 at 10:43 Erica Sadun via swift-build-dev <swift-build-dev at swift.org <mailto:swift-build-dev at swift.org>> wrote:
> 
>> On Feb 29, 2016, at 9:59 AM, Daniel Dunbar <daniel_dunbar at apple.com <mailto:daniel_dunbar at apple.com>> wrote:
>> 
>> Yup!
>> 
>>  - Daniel
>> 
>>> On Feb 29, 2016, at 8:53 AM, Erica Sadun <erica at ericasadun.com <mailto:erica at ericasadun.com>> wrote:
>>> 
>>> I'll try writing up a proposal. Does everything work the same for swift-build-dev as -evolution?
>>> 
>>> -- E
> 
> 
> First draft: https://gist.github.com/erica/c6553a5f6f35e7462074 <https://gist.github.com/erica/c6553a5f6f35e7462074>
> 
> Looking forward to feedback, questions, and corrections. -- E
> 
> 
> Disambiguating SPM 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
> 
> I propose to modify Swift's SPM PackageDescription to allow developers to assign local module names to avoid module conflicts. Namespacing supports a decentralized packaging ecosystem that handles 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, I take care to differentiate Swift.print, which outputs text to the console or stream from NSView's  print, which 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. 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.
> My SwiftString or StringUtility package can't be used alongside someone else's SwiftString or StringUtilitypackage. Moving back to Cocoa-style ESSwiftString namespacing feels ugly and antithetical to Swift design. Swift should encourage recognizable, easy-to-understand module names.
> 
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#original-design>Original Design
> 
> I first considered namespacing using reverse domain naming in Package declarations. This offers a traditional approach to identify a module's source:
> 
> import PackageDescription
> 
> let package = Package(
>     name:   "SwiftString"
>     origin: "org.sadun"
> )
> Reverse domain names
> 
> are relatively short
> are already well established for Apple app distribution
> do not rely on a web address that may change should the repo move
> are less likely to conflict with user names across repo hosts 
> However concise, using reverse domain names bring unnecessary verbiage to name conflicts. Consider the following example.
> 
> import org.sadun.SwiftString
> import com.other.SwiftString
> 
> ...
> 
> // Use my implementation of countSyllables
> let count = org.sadun.SwiftString.countSyllables(myString)
> In this example, org.sadun.SwiftString.countSyllables places a burden both on writing and reading code. Surely there has to be a better solution.
> 
> Adapting import statements resolves symbols but has negative side effects:
> 
> import org.sadun.SwiftString as SadunString
> import com.other.SwiftString as OtherString
> 
> ...
> 
> // Use my implementation of countSyllables
> let count = SadunString.countSyllables(myString)
> This approach requires Swift language modification
> Import redeclarations may be required across multiple files
> Joe Groff suggested a simpler approach: allow package manifests to take responsibility for mapping dependencies to source-level module names.
> 
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#revised-design>Revised Design
> 
> Under the revised solution, renaming occurs when declaring dependencies. This is what package descriptions looks like under the current system:
> 
> 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),
>     ]
> )
> Under this proposal, the Package dependency gains an optional localName parameter. When localName is omitted, a package imports as the name declared in Package.name.
> 
> import PackageDescription
> let package = Package (
>     name: "myutility",
>     dependencies: [
>     .Package(url: "https://github.com/erica/SwiftString.git <https://github.com/erica/SwiftString.git>",
>                  majorVersion: 1, localName: "SadunString"), // import SadunString
>     .Package(url: "https://github.com/bob/SwiftString.git <https://github.com/bob/SwiftString.git>",
>                  majorVersion: 1, localName: "BobString"), // import BobString
>     .Package(url: https://github.com/erica/SwiftCollections.git <https://github.com/erica/SwiftCollections.git>",
>                  majorVersion: 1), // import SwiftCollections
>     ]
> )
>  <https://gist.github.com/erica/c6553a5f6f35e7462074#alternatives-considered>Alternatives Considered
> 
> Swift names should be as simple and elegant as possible without overlapping with built-in keywords. Other suggestions brought up in-discussion included:
> 
> Using GitHub or Bitbucket usernames as namespacing prefixes, e.g. erica.SwiftString. This would not be resilient across cross-repo username conflicts.
> Using repo URLs to resolve namespacing conflicts. This would be fragile if repos moved and does not address local module name resolution.
> Introducing a registration index for packages.
> 
> _______________________________________________
> swift-build-dev mailing list
> swift-build-dev at swift.org <mailto:swift-build-dev at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-build-dev <https://lists.swift.org/mailman/listinfo/swift-build-dev>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20160229/6f57542f/attachment.html>


More information about the swift-build-dev mailing list