<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 26, 2016, at 11:40 AM, Joe Groff <<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 26, 2016, at 10:30 AM, Max Howell <<a href="mailto:max.howell@apple.com" class="">max.howell@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class=""><em class="">I first brought this topic up on swift-dev, and was pointed to swift-build-dev.</em></p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">Having spent considerable time messing up my Swift packages by giving them ridiculously obvious names like <code class="">SwiftString</code> and <code class="">SwiftCollections</code>, I realized that namespacing would be a solution for disambiguating conflicts. <code class="">import SwiftString</code> is insufficient when several packages are named <code class="">SwiftString</code>. </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">When you have two identically named packages, the module imports need to distinguish both the sources as well as references defined per package. Although SwiftPM finds packages using git URLs and module names, I do not believe that origin is addressable or usable. Plus, throughout the lifetime of a package, that origin could potentially move from, for example, GitHub to Bitbucket. </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">I suggest using some kind of origin key for differentiation. The simplest solutions for these include reverse domain names (basically a company/source identifier), git URLs (the current location of the repo), Github/Bitbucket user names (which are similar to a company/source identifier but more subject to updates over time). </p><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">Of these, I’d recommend reverse domain for the following reasons: </p><ul style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; font-size: 16px;" class=""><li style="font-size: 18px;" class="">They are relatively short</li><li style="font-size: 18px;" class="">They are already well established for Apple app distribution</li><li style="font-size: 18px;" class="">They do not rely on a web address that may change should the repo move</li><li style="font-size: 18px;" class="">They are less likely to conflict with user names across repo hosts</li></ul><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">I’d imagine a package declaration that looks something like this:</p><pre style="color: rgb(17, 17, 17); font-size: 16px;" class=""><code class=" coffeescript hljs" style="display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); background-position: initial initial; background-repeat: initial initial;"><span class="hljs-reserved">import</span> PackageDescription
<span class="hljs-reserved">let</span> package = Package(
<span class="hljs-attribute" style="color: rgb(0, 128, 128);">name</span>: <span class="hljs-string" style="color: rgb(221, 17, 68);">"SwiftString"</span>
<span class="hljs-attribute" style="color: rgb(0, 128, 128);">origin</span>: <span class="hljs-string" style="color: rgb(221, 17, 68);">"org.sadun"</span>
)</code></pre><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">In the case of name conflicts instead of importing <code class="">SwiftString</code>, you’d prefix an origin:</p><pre style="color: rgb(17, 17, 17); font-size: 16px;" class=""><code class=" actionscript hljs" style="display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); background-position: initial initial; background-repeat: initial initial;"><span class="hljs-preprocessor" style="color: rgb(153, 153, 153); font-weight: bold;"><span class="hljs-keyword" style="color: rgb(51, 51, 51);">import</span> org.sadun.SwiftString
<span class="hljs-keyword" style="color: rgb(51, 51, 51);">import</span> com.foobar.SwiftString</span></code></pre><p style="color: rgb(17, 17, 17); font-family: 'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; font-size: 1.1429em; line-height: 1.3125em; margin: 1.3125em 0px;" class="">Ideally, you could further alias these to shorten symbol disambiguation:</p><pre style="color: rgb(17, 17, 17); font-size: 16px;" class=""><code class=" vim hljs" style="display: block; padding: 0.5em; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); background-position: initial initial; background-repeat: initial initial;">import org.sadun.SwiftString <span class="hljs-keyword" style="font-weight: bold;">as</span> SadunStrings
import <span class="hljs-keyword" style="font-weight: bold;">com</span>.foobar.SwiftString <span class="hljs-keyword" style="font-weight: bold;">as</span> FoobarStrings
// Unique <span class="hljs-keyword" style="font-weight: bold;">to</span> <span class="hljs-keyword" style="font-weight: bold;">only</span> one package, <span class="hljs-keyword" style="font-weight: bold;">no</span> name conflict
uniqueMethod(<span class="hljs-string" style="color: rgb(221, 17, 68);">"Hello World"</span>)
// name collision disambiguation
SadunStrings.sharedMethod(<span class="hljs-string" style="color: rgb(221, 17, 68);">"Hello World"</span>)</code></pre><div class="">I'm interested in hearing any feedback and thoughts about whether this is possible and what I could do to help further this idea.</div></div></div></div></blockquote><br class=""></div><div class="">I think you have the right approach for sure. We need to talk with Swift-core as this will require work in that arena and they will need to chime in.</div><div class=""><br class=""></div><div class="">Certainly I would like to encourage namespacing with GitHub usernames because:</div><div class=""><br class=""></div><div class="">1) The majority of iOS open source happens there nowadays</div><div class="">2) People think of eg. mxcl’s PromiseKit, and thus both `import mxcl.PromiseKit` is very clear and communicates that these projects have origins/owners/maintainers.</div><div class=""><br class=""></div><div class="">However certainly I wouldn’t advocate for a GitHub only namespacing system, I just like that it have some extra sugar. SwiftPM was deliberately designed to be distributed.</div><div class=""><br class=""></div><div class="">I’ve cc’d Joe Groff since he probably can say something, then I can have some meetings, or we can try to do it all on the lists and then get this proposal written up.</div></div></div></blockquote><br class=""></div><div class="">Usernames strike me as too short to serve as a universal discriminator by themselves, and as you noted, tie the system to a specific service. Reverse-domain is certainly more precedented. I'm jumping into this conversation in the middle, so pardon me if this has already been discussed, but could the package manifest take responsibility for mapping global package identifiers to their source-level module names? That would let you say:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">let dependencies = [</div><div class=""> "SadunString": "org.sadun.SwiftString",</div><div class=""> "FoobarStrings": "com.foobar.SwiftString"</div><div class="">]</div></blockquote><br class=""><div class="">and would give users some leeway to change their module references, should their dependencies end up forked or vendored.</div></div></div></blockquote><br class=""></div><div>Original post here: <a href="http://ericasadun.com/2016/02/08/naming-your-swift-packages/" class="">http://ericasadun.com/2016/02/08/naming-your-swift-packages/</a> and you really haven't missed much.</div><div><br class=""></div><div>If you want to do it from the consumer end, then it becomes a lot simpler, without adding any specific <font face="Menlo" class="">origin</font> information or adapting the package declaration. This is what it looks like now:</div><div><pre style="box-sizing: border-box; border-style: solid; border-color: rgb(5, 0, 0); border-width: 2px 0px; padding: 15px 0px; word-wrap: break-word; width: 646.59375px; margin-top: 30px; margin-bottom: 30px; margin-left: 40px;" class=""><font color="#050000" face="andale mono, lucida console, monospace" class=""><span style="font-size: 0.75em; white-space: pre-wrap;" class="">import PackageDescription
let package = Package (
name: "myutility",
dependencies: [
</span><span style="font-size: 11px; white-space: pre-wrap;" class="">        .Package(url: "<a href="https://github.com/erica/SwiftString.git" class="">https://github.com/erica/SwiftString.git</a>",
majorVersion: 1),
        .Package(url: "<a href="https://github.com/bob/SwiftString.git" class="">https://github.com/bob/SwiftString.git</a>",
majorVersion: 1),
</span><span style="font-size: 0.75em; white-space: pre-wrap;" class=""> ]
)</span></font></pre><div class="">I'd imagine that you'd want to change it to look like this:</div><div class=""><pre style="box-sizing: border-box; border-style: solid; border-color: rgb(5, 0, 0); border-width: 2px 0px; padding: 15px 0px; word-wrap: break-word; width: 646.59375px; margin-top: 30px; margin-bottom: 30px; margin-left: 40px;" class=""><font color="#050000" face="andale mono, lucida console, monospace" class=""><span style="font-size: 0.75em; white-space: pre-wrap;" class="">import PackageDescription
let package = Package (
name: "myutility",
dependencies: [
</span><span style="font-size: 11px; white-space: pre-wrap;" class="">        .Package(url: "<a href="https://github.com/erica/SwiftString.git" class="">https://github.com/erica/SwiftString.git</a>",
majorVersion: 1, localName: "SadunString"),
        .Package(url: "<a href="https://github.com/bob/SwiftString.git" class="">https://github.com/bob/SwiftString.git</a>",
majorVersion: 1, localName: "BobString"),
</span><span style="font-size: 0.75em; white-space: pre-wrap;" class=""> ]
)</span></font></pre><div class="">If you leave off <font face="Menlo" class="">localName</font> (or whatever it is called), it imports as the name declared in Package.name.</div><div class=""><br class=""></div><div class="">-- E</div></div><div class=""><br class=""></div></div></body></html>