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

Erica Sadun erica at ericasadun.com
Thu Mar 3 11:43:50 CST 2016


> On Mar 3, 2016, at 1:30 AM, Daniel Dunbar <daniel_dunbar at apple.com> wrote:
> 
> Thanks for writing this up!

No worries. Let's get this fixed.  I warn you the following rambles a bit, but there's a point to it by the end.

State of the art:
So I have two git repos: https://github.com/erica/SwiftString.git <https://github.com/erica/SwiftString.git> and https://github.com/nudas/SwiftString.git <https://github.com/nudas/SwiftString.git>

My package looks like this:

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),
        ]

)

and of course, make fails:

% make
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

This is my starting point, where I am attempting to import two standalone modules, let alone import a package that contains further
dependencies. 

* There are packages. There are modules. Both have names. Neither is distinguished in dependencies or declaration.
* Packages may be composed of modules or packages, and keeping track of modules can be problematic.

Tossing ideas out there:

Change 1: Let modules be declared differently. Instead of 

import PackageDescription

let package = Package(
    name:   "SwiftString",
)


allow:

import ModuleDescription

let module = Module(
    name:   "SwiftString",
    origin: "org.sadun.SwiftString"
)

Let's say there's also github/erica/StringUtilities, a package with 2 modules. It could consume the existing Packages and export them as named modules

on github/erica/StringsUtilities
import PackageDescription
let package = Package (
    origin: "com.sadun.StringsUtilities"
    name: "myutility",
    dependencies: [
       // I'm importing everything as a package and assuming something knows eventually
       // these are actually modules
       .Package(url: "https://github.com/erica/SwiftString.git",
	        majorVersion: 1),
       .Package(url: "https://github.com/nudas/SwiftString.git",
	        majorVersion: 1),
       .Package(url: "http://github.com/erica/SomeStringOtherPackage.git <http://github.com/erica/SomeStringOtherPackage.git>",
                majorVersion: 1), // just throwing some package in there
    ],
)

From the consuming side, you attempt to build with:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
        .Package(url: "https://github.com/erica/StringsUtilities <https://github.com/erica/StringsUtilities>.git",
	         majorVersion: 1),
   ],
)

the build tool places the modules into separate org.sadun.SwiftString and com.foo.SwiftString build paths but still spits out an error:

org.sadun.SwiftString module name ("SwiftString") conflicts with com.foo.SwiftString ("SwiftString"). 
Cannot build without adding import name overrides.

So you hop back in and edit:

import PackageDescription
let package = Package (
    name: "myutility",
    dependencies: [
        .Package(url: "https://github.com/erica/StringsUtilities <https://github.com/erica/StringsUtilities>.git",
	         majorVersion: 1),
    ]
    importMappings: [
       .Map(origin: "org.sadun.SwiftString", toName: "SwiftString"),
       .Map(origin: "com.foo.SwiftString", toName: "SwiftString2"),
    ],
)

And fixed?

-- Erica

> 
> One problem with this proposal as it stands is that it conflates the package name with the module name. The package can contain multiple modules, so "importAs" on the package is ambiguous except for single module packages (and even then, it is weird, because it is naming a module, but in the context where the package is being named).
> 
> We eventually need a way for packages to specify what modules they actually export, at which point it would probably be possible to specify this as a rename of the exported module names.
> 
> To make this a concrete proposal, I think it would also need to clarify exactly how we would implement the feature. The most straightforward way that I can see would require either SwiftPM specific hacks (which I wouldn't want to see go in), or some level of compiler support. We already need more compiler support for module specification stuff (e.g., to enforce dependencies), so it is possible it could tack on to what we need there, but none of that work has been designed yet.
> 
> These two issues bring up a related problem:
>  - We have packages, and we have modules, and both have names.
>  - Substantial packages may be composed of a significant number of modules, only some of which are exported. For example, "LLVM" could be a package which exported an "LLVM" module (the client API), but internally had things like "Support".
>  - The collision likelihood for package-internal module names is quite a bit higher than for packages (because there are likely to be more of them, and because they are implementation details).
> 
> One possible direction to take this is that we should gain explicit Swift language support for the concept of package namespaces. It could take the same form as imports, where the package component of the namespace is only required when there are ambiguities.
> 
> If we had such a feature, then a package-level rename would probably make complete sense (retaining your current proposal), and we would probably be able to implement it in the package manager (for the most part; I still see problems if a package tree had multiple sources which referred by name to the package being renamed).
> 
>  - Daniel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20160303/354fa073/attachment.html>


More information about the swift-build-dev mailing list