Use async code inside Swift command line tool

I am trying to learn how to write a command line tool in Swift. I am writing a tool to search through a directory tree of files and search from some text as a first step. I am using the following code to read the text in files and it is async.

for try await line in handle.bytes.lines { /* insert code here */ }

I have tried lots of things from just adding a Task to using a TaskGroup and adding a task for each file that I find. I always seem to end up getting “‘async’ call in a function that does not support concurrency” or the tool exits before it finishes processing the files. A potential fix is to make the run() function async, but then it just prints the help then returns and doesn’t run my code.

How can you write a Swift command line tool and then use async code somewhere in the implementation? I have yet to see any solutions for calling async code and then waiting for it to finish from synchronous code. Since making run() async doesn’t appear to work, does that mean that you can’t use Swift concurrency in a command line tool?

Assuming you’re using swift-argument-parser, you need to conform your type to AsyncParsableCommand and then make your run function async.

2 Likes

It now compiles and runs. It basically does what I expect. It now just needs a little code clean up to finish it. Thanks!!!

I need to find a better way to search the Swift documentation and Swift Package Manager stuff.