SwiftPM support for Swift scripts

This is kinda unrelated to the thread, but this is done by tools which can show UI. Checkout swift-progress as an example (it's the CREATE_INFOPLIST_SECTION_IN_BINARY Xcode setting).

Actually it would be quite cool to support this (i.e. write scripts which can show AppKit UI). Or does this just work? No idea :slight_smile:

2 Likes

With SwiftUI making it so easy and compact to create a UI, it's actually quite feasible to make a small GUI for your tool. It can be really useful for prototyping UI components.

You don't need an Info.plist section for UI, though - here's the script template I use for SwiftUI. You do need it for other things like entitlements (it would be really nice if we added support for those... at all!).

3 Likes

I think I would much rather have my build tools be liberal with respect this method of declaring dependencies. Having the option of turning on a linting rule to catch instances of this seems like a better way of policing than imposing this limitation on every project only because it might not be ideal for the average case.

1 Like

I'm really excited about this proposal! I love Swift "scripting" but honestly I always endup just making CLI binaries because they have a way better experience. This makes me wonder how all of you work since I'm seeing a lot of discussion about short vs. long lived scripts. Seems like the tooling should make an effort to support both cases and, most importantly, the transition from one to the other, like creating a distributable binary from a script. For me the most important thing is that Xcode supports the scripts directly. (and things like the difference between and Xcode CLI app and a SPM executable are weird)

I also don't think we should be changing the syntax from the one in SPM. If I don't care about the version I can just specify branch master. Is not a big deal IMO. But if we endup maknig a different syntax I would like to see same changes accepted on the SPM Package. I feel like both system should follow the same rules for easy of adoption. (Unless we go with a totally new and custom import)
Another thing I'm not sure I want to see is to favourite GitHub in any way, I feel like that's something that can be done in a third party solution but it would feel weird from Swift itself.

1 Like

1+ on this

I know Xcode is out of the scope of Swift Evolution but I would just like to put it out there that it would be convenient if you could execute scripts with given params directly from the Xcode UI similarly to how you can run individual tests today. This would be very helpful for development tasks such as seeding a database, running database migrations etc.

1 Like

+1 for the general idea.

my humble opinion: I can't decide what is the best between an attribute on import, or a separate statement. But if we go for the attribute, we should be able to import several module at once to avoid declaring the package twice.

For example:

@package(url: /* … */)
import TSCBasic, TSCUtility

instead of

It doesn't seem right to have one attribute applying to 2 imports

3 Likes

Huge +1 on doing something in this area! My experience has been similar to @Alejandro_Martinez in that I end up making Xcode projects just for the better tooling, even though 99% of what I do ends up in one file.

Keeping the same syntax as SPM and allowing this in regular swift modules seems like it would allow simple scripts to grow into full projects really easily.

Hi @Rahul_Malik since a lot of people have positive feedback on this idea should this move to the next phase ?

1 Like

Why exclude the REPL? I could see Playgrounds benefiting greatly from being able to also pull in dependencies. Especially in teaching Swift, being able to pull in an IntArray so you don't have to explain generics too early or the like would be very useful.

7 Likes

I am really sorry I have not had a chance to properly engage on this thread (most recently because of circumstances created by COVID-19) but I wanted to say that I'm inspired by both this proposal and work that various people are doing in the community to explore this problem space. Having a first class story for scripting that ties into the package manager is really important for Swift.

I hesitate to even make these remarks right now, given that I haven't had chance to set aside proper time to engage with this immediate discussion, but a few high-level thoughts come to mind:

  • If we had a package index, how would that impact this proposed idea? Obviously that depends on how a possible package index would work.

  • The proposal excludes the REPL. Is that a tactical concern to keep the implementation scope limited at first, or a fundamental design decision? In other words, there can be a broader arc of where such an enhancement fits in, but the feature itself is supported in an increasing number of contexts over time.

I agree that the REPL and other interactive environments could benefit from having something like this.

7 Likes

I don't think dotfiles or library are an either/or decision. If you look at what comes with macOS X, you can see that Apple left most standard Unix tools with their default settings. E.g. Apache, which isn't owned by Apple Most stuff is in /etc and the like, but most of the user-serviceable configurable paths like the web page directory were redirected to Apple-style directories like ~/Sites and /Library/WebServer/Documents.

So there is no reason why Swift scripts could not use different directories on other platforms to be a good citizen, like Apache does.

Regarding .CFUserTextEncoding, my guess is that's not a user default because UserDefaults probably needed that to do its work. And .DS_Store doesn't really fit the discussion, as it is used to store Finder view settings, like folder background images, on a per-folder basis, so is really just a per-folder override of Finder's default settings. It's the easiest to deal with if kept with its folder (also, Finder doesn't have to clean it up then).

And no, .DS_Store is not just for compatibility with other platforms and filesystems. Even HFS+ disk images use it to store their background picture.

1 Like

I’m really eager to see this feature in Swift I use scripting everyday. Do you think it might be in Swift 5.3 ? @Rahul_Malik
That would help making 5.3 a big release for SPM(since it already have a few other great features plan’ed for 5.3).

5 Likes

It would be amazing to have this feature in Swift! I wanted to push Swift usage at work, but we do a lot of scripting and unfortunately the lack of an easy way to import packages is hampering such objective. This needs to be built-in, thanks for your proposal!

2 Likes

Up until this point I have been relying on swift-sh to provide SPM support in swift scripts. But since swift 5.2 it has been broken due to Package.swift changes. I have rolled my own version of swift-sh to get around some of the issues but that isn't a permanent solution.

To have swift SPM support in scripts being treated as a first class citizen would be great. Relying on a tool that doesn't get updated lockstep with the rest of swift is not ideal.

3 Likes

This don’t seem to move. @Aciid what could we do as a community to make this go foward ?

8 Likes

I think this would be a great feature for Swift 6...But it seems to stuck for some time. What can we do to push it further except for discussing it here? @Rahul_Malik

2 Likes

I don’t think the original version authors have time or will to make this go forward so it will be up to us to make this move.

What could be the next step ?

I love this proposal, hoping it gets implemented.

If anything, I'd like to suggest the addition of a command to convert a Swift script into an executable package. Maybe something like this:

swift package init --from myscript.swift

The reasoning is that scripting is great for tinkering, prototyping, and creating quick tools. However, once these scripts grow both in complexity and over time, becoming long-lived scripts, it would be great to have an easy way to refactor them into a Package without having to do the manual work.

This addition might also help easing any discussions between short and long-lived scripts.

4 Likes

I love this proposal so far, one thing I'd add that's been mentioned before is updating packages with implied verisons, a build flag --update could be used that checks each package for an update against it's source.

Then the @package could still be used normally to imply the latest version, and the swift build --update could be used every once in a while to check for new versions.

Looks great! Here’s my suggestion on syntax:

# Update on every run
# Unrecommended because updating and rebuilding takes time
swift script.swift --update 

# Update and rebuild immediately
# I propose to add a `swift-script` tool which is similar to `swift-package`
swift script update script.swift
1 Like