[Pre-pitch] SwiftPM Manifest based on Result Builders

To me, investing time in meeting this decision when there're tons of bugs and existing radars, with a poorly tool integration, it is literally a waste of time and resources to be honest.

2 Likes

+1 for the main approach. Results builder sounds good too. I do think that if folks want to declare all configurations in a config file (json/yaml) then hopefully they can still do this adhoc.

I’m not sure that’s completely fair. Over at the Compile Time Constants pitch, this work could be a step towards improving the performance of SwiftPM:

So maybe with less sandboxes, we might get some of that two-three minutes our Macs spend stuttering playing music, switching Slack channels or browsing web pages while trying resolving 30 or so package dependencies after a changing a branch :grimacing::crossed_fingers:t2:

Bugs > Performance

Doesn't matter that you have the fastest tool if it is unusable because of blocking bugs.
Just my opinion

I'm curious to know what issues you are referring to, and if they're more on SwiftPM itself or its integration with Xcode.

In my experience, all my issues with SwiftPM are in its integration with Xcode, so the unfortunate reality is that even if those get fixed within 24 hours of being reported... they're effectively not fixed for months at a time while we wait for the next version of Xcode to be released.

And in some cases, we have to wait entirely for the new major version of Xcode, leaving bugs existing for an entire year - and then some, as you have to then make sure you're able to build with the new version of Xcode.

1 Like

bundle_resource_accessor, which I believe is generated by Xcode is wrongly generated for example. Boy bear in mind that 95% of SwiftPM relies on Xcode Integration, where is mostly used into, so one problem links to another.

Only two-three minutes? You must have fast internet.

Why does it download the same dependencies time after time even though they haven't changed in months, whenever I change branches.

Why do I have to force quit Xcode if I try to close a project while it's Resolving package graphs?

1 Like

This is off-topic really but I have terrible internet and SwiftPM's caching is helping me tremendously:

❯ rm -rf .build/
❯ swift build
Fetching https://github.com/crossroadlabs/Regex.git from cache
Fetching https://github.com/mxcl/PromiseKit from cache
Fetching https://github.com/kylef/Commander.git from cache
Fetched https://github.com/crossroadlabs/Regex.git (1.13s)
Fetching https://github.com/kylef/Spectre.git from cache
Fetched https://github.com/kylef/Commander.git (1.14s)
...

I'd like to hug everyone who's helped ship this :)

To make this somewhat on-topic: I don't think arguing this change is without merit because other things are imperfect is fair to the proposal, and I doubt it's helpful to the authors. It's not like this pre-pitch or its eventual implementation would fundamentally prevent those other issues from being addressed.

5 Likes

It seems that Xcode use a private SwiftPM framework, not build upon on the open source swift-package-manager. Their function is the same and share almost the same name but they are different thing. See [Optimus] Simplify resource_bundle_accessor.swift by Kyle-Ye · Pull Request #3824 · apple/swift-package-manager · GitHub and [SR-15550] Loading a resource from a bundle fails due to incorrect bundle path · Issue #4372 · apple/swift-package-manager · GitHub

That's why I insist on that making progress on spm as a standalone product without taking in mind that it is an apple tool and more importantly, a tool that is widely used in xcode because is our unique IDE is just a fairy tale.
More cross-team and collaboration with the xcode team (for example integrating SPM as a plug-in in Xcode would've been great). But the effort is pushing because it is what it sells more.

3 Likes

Have just caught up on this discussion, and I realise that the last post was a while ago, so I'm not sure what the current status is. Apologies if I'm reviving a zombie...

My tuppence-worth:

:+1: to the result builder turtles-all-the-way-down approach:

import PackageManifest

Package {
  ...
}

:+1: to moving the swift-tools-version out of a comment. I'm neutral on changing its name, but I can see the point. So perhaps, in fact:

import PackageManifest

Package(schema: .v6) {
  ...
}

[/quote]

As a minor point of syntax, rather than

Executable("MyProgram", public: true)

I'd prefer something like

Executable("MyProgram")
  .exported()
4 Likes

Interesting. I agree that Package should also be a builder, rather than using SwiftUI-style modifiers for each structural group.

Also, since you can only declare one package per manifest, would we be able to have a hidden global (within the PackageManifest module) which is assigned to in buildFinalResult?

// Within PackageManifest module

public var package: Package?

@resultBuilder
struct Package {

  @discardableResult
  static func buildFinalResult(_ p: Package) -> Package {
    package = p
  }
}

// in Package.swift

import PackageManifest

Package {
  ...
}

I experiment with that idea for another project. To make a top level Package definition like @Karl proposed, you also need to add this initializer:

    @discardableResult
    public init(@Package _ builder: () -> Package) {
        self = builder()
    }

Just wanted to share this with other in case someone tries to implement this type of top level builder.

Hello folks,

I went ahead and built something like this for my codebases. Maybe you'll find it helpful to you or the future of Swift development.

2 Likes

nice @leogdion! thanks for sharing

incidentally @NeoNacho has been also working on this recently in SwiftPM codebase maybe the two of you can collaborate to get this proposal over the finish line

4 Likes

You're welcome

I'll reach out to @NeoNacho and see how I can help with the proposal. I would love to help in any way.

3 Likes