Hi Ankit, thanks for your reply.

> Am 21.07.2017 um 07:33 schrieb Ankit Aggarwal via swift-users 
> <swift-users@swift.org>:
> 
> 
> 
> On Thu, Jul 20, 2017 at 10:34 PM, Geordie J via swift-users 
> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
> Hi all,
> 
> My team and I are trying to use SwiftPM to develop a relatively complex app 
> with multiple dependencies, all of which are being developed locally and in 
> parallel. The reason for this is compatibility with an existing module/import 
> structure used by our iOS app. Maybe I’m doing something very wrong but my 
> experience so far (2 months in) is that this is extremely difficult with 
> SwiftPM.
> 
> What I’d love to be able to do is to just run `git add submodule 
> http://blah.com/mysubmodule.git` <http://blah.com/mysubmodule.git%60> in the 
> Packages subdirectory and SwiftPM would just let me manage dependencies from 
> there myself.
> 
> I was excited to see that SwiftPM 4 has a "Top of Tree" development option 
> for this purpose. So far my experience with this has not been good. Firstly 
> because SwiftPM still unnecessarily tries to clone my repos itself (some of 
> which are huge), and secondly because this creates an absolute path 
> dependency in `.build/dependencies-state.json`, meaning this setup isn’t 
> sharable within our dev team.
> 
> Attempting this with "local" git urls adds an almost absurd level of 
> complexity, having to tag each commit for SwiftPM to build. The fact that 
> we'd need to make a commit to test whether the project even builds is insane 
> enough as is, let alone the tagging and trying to tell the base project to 
> use a newer minor version etc etc.
> 
> Adding multiple subtargets is also not an option because the dependencies (as 
> dynamic libraries) really are shared between multiple 
> targets/sub-dependencies, which SwiftPM seems to deal with quite well.
> 
> tldr; *Please* let us manage dependencies ourselves. It’d be so easy if 
> Package.swift had an option along the lines of .Package.local(named: "XYZ") 
> that it then looked for in ./Packages/XYZ. Again, maybe I’m overlooking 
> something but this seems like an obvious and vital option to have. It’d also 
> simplify the introductory SwiftPM docs significantly.
> 
> Is anyone else having this issue? Would this change really be as simple and 
> painless as it sounds? I would be prepared to make a pull request along these 
> lines.
> 
> I think you're not really using the Top of Tree feature. You need to add each 
> dependency using its canonical URL, hosted at some server like github. After 
> adding the dependencies, you can use edit feature to put a dependency in Top 
> of Tree mode. To do so, run:
> 
> $ swift package edit <PackageName> --path 
> ../path/to/self/managed/checkout/of/the/package

Yes, this is what I tried this week. I’m pretty sure this is not a case of 
misunderstanding the feature or the docs.

> 
> The package manager will then stop using the cloned repository and use the 
> checkout present at that path (regardless of the state it is in).

Yes, but then I have – per dependency – two checkouts of a potentially huge 
repository. Why force everyone on the dev team to clone a huge repo twice, only 
to *never* use one of the clones. Also, SwiftPM breaks when —path points at 
Packages/PackageName, which is exactly where I’d expect the package to be, not 
in some arbitrary external path (+ some kind of internal checkout cache that 
will never be used) as well.

I haven’t tried to test this recently because it’s a slow process but I have 
the impression the deps could be even be cloned more than twice, depending on 
how cleverly SwiftPM realises that multiple Packages have the same dependency.

Also, this makes managing interdependent state of development amongst 
dependencies more difficult than needed. How do we guarantee that devs are on 
the same commit when using top of tree development? Tagging and managing 
version numbers etc for day-to-day development is emphatically not an option 
for us. Since SwiftPM packages only work from a git context anyway, why not 
allow use of git’s established pattern of dealing with this, namely submodules?

> Sharing this setup is not automatic, but simple. Each user just needs to run 
> the above command once per dependency.

We have about 10 dependencies, all of which will always be in this state. This 
seems like a lot of overhead and room for user error, plus it’s a huge 
workaround for something that could be very simple.

> Also, you only need to do this if you're actively working on a dependency.

The point is that we will always be working on the dependencies. This is the 
core of what we’re doing, not a short aside. This is what makes me think we are 
either doing something wrong, or there is a big feature gap (as it appears from 
here).

> The new manifest also supports using branch instead of version range, which 
> is very helpful during the development period.

This has much the same result as top-of-tree development, but it is how we were 
able to "hack" SwiftPM 3 into leaving us alone.

> Let me know if something is unclear or if you have more questions!

Maybe an overview of our structure would be helpful to make our use case 
clearer:

Main Project (git repo, not a Swift Package, contains no swift code directly)
–– Dependencies (external)
–– Subproject (internal git submodule, is a Swift Package, has multiple Swift 
Targets)
–––– Dependency A (internal, git submodule)
–––––––– Huge external C-language dependencies (managed via git submodules)
–––– Dependency B (internal, git submodule)
–––––––– Depends on internal dependency D
–––– Dependency C (internal, git submodule)
–––––––– Depends on internal dependency A
–––––––– Depends on internal dependency B
–––––––– etc.
–––– Dependency D (internal, git submodule)

I think the friction is coming from the fact that we’d like to use SwiftPM just 
to build, rather than to manage our dependencies.

Again, this could be solved with a simple API addition in the manifest:

Package(
  …
  dependencies: [
    .package.local(named: "Dependency A")
    .package.local(named: "Dependency B")
    ...
  ]
)


At the end of the day it seems we can work around this by cloning the 
submodules at Project/Submodule instead of Project/Package/Submodule and then 
running swift package edit Submodule —path ./Submodule, just that this process 
would have to be manual for each new dev cloning the repo. And then we’d still 
have two checkouts of the same thing. Yes, this works, it just seems very 
inefficient and still hacky. And it’s very possible it'll break again with 
future SwiftPM versions.

I’m just surprised the idea of a "local dependency" is not seen as a first 
class citizen in SwiftPM, still trying to understand the logic behind that. 
Maybe you can give me an idea of the reasoning behind this?

Best Regards,
Geordie

>  
> Best Regards,
> Geordie
> 
> 
> PS. In SwiftPM 3 we had been using a hack that worked great: by filling in 
> the dependencies' "basedOn" key in `workspace-state.json`, SwiftPM just left 
> us alone.. We were able to commit `workspace-state.json` into our base 
> project’s git repo and the rest Just Worked™. Now with the absolute paths 
> being checked for this doesn’t seem to be an option.
> 
> 
> Please do not rely on internals of the package manager as they're not stable 
> and will change without notice.

This was not our preferred way of going about it of course. But it was 
(unfortunately) the best solution to the problem.

> 
>  
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org <mailto:swift-users@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users 
> <https://lists.swift.org/mailman/listinfo/swift-users>
> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to