SALE ENDS TODAY: Save 50% on all Swift books and bundles! >>

Write your scripts in Swift with Beak

It’s a smart and simple way to run code by function.

Paul Hudson       @twostraws

If you’re visiting here it’s because you’re already sold on Swift as a great language for apps, but have you ever considered using it for scripting? If not, a new GitHub project from Yonas Kolb is here to convince you otherwise: it’s called Beak and it lets your run Swift code straight from the command line.

To get started, run these three commands from your Mac’s terminal:

git clone https://github.com/yonaskolb/Beak.git
cd Beak
swift run beak run install

That builds and installs Beak, which means it’s ready to run any Swift scripts you need.

Let’s try it out now. Create a new Swift file on your desktop called factors.swift and give it this content:

import Foundation

public func calculate() {
    let number = 100
    let factors = (1...number).filter { number % $0 == 0 }
    print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}

That creates a single function called calculate(), which creates an array of numbers that divide equally into 100, then prints them out as a single string.

To run that using Beak you need to write a command that does the following:

  • Specifies factors.swift as its input filename.
  • Tells it to run a single function from the file.
  • Provides the function name to run.

Run this command now:

beak --path factors.swift run calculate

You specify the function name you want to run, so a single Swift script can contain as many related functions as you want.

As well as run you can also use list to show the list of available functions:

beak --path factors.swift list

That will show you there’s only function available, which is our calculate() function.

Tip: Beak can only see functions that are marked as public. If you want a function for internal use only – i.e., not exposed by the list command – just don’t declare it as public.

Right now our function uses a hard-coded input value, but Beak can process arguments from the command-line and convert them into function arguments.

Try changing the function to this:

public func calculate(number: Int) {
    let factors = (1...number).filter { number % $0 == 0 }
    print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}

When using the calculate() method now, you need to run it like this:

beak --path factors.swift run calculate --number 1000

Now that we have a command that takes input, you might want to try using the “function” option for Beak, which provides more details on a specific function. For example:

beak --path factors.swift function calculate

That will say calculate() takes one argument called number, which is an Int. However, if you want more useful output you should add some Markdown comments to your code, like this:

/// Calculates the factors for a given number
/// - Parameters:
///   - number: the input number to use
public func calculate(number: Int) {
    let factors = (1...number).filter { number % $0 == 0 }
    print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}

These comments are exactly the same format used by Xcode and other Swift tools, so you should already be familiar with them – if not, now would be a good time to investigate my Pro Swift book! If you run Beak’s “function” command now you’ll get much more useful help.

At this point I hope you’re certainly curious to try Swift scripting yourself, but before we’re done I want to demonstrate one last, important feature: cleaning up the commands.

So far we’ve been using commands like this one:

beak --path factors.swift run calculate --number 1000

While it’s certainly nice and clear, it’s also supremely clumsy. Fortunately Beak supports shebang lines, which means you can add a special line to the start of your Swift scripts that allows you to make your scripts into standalone commands.

Modify factors.swift to this:

#!/usr/bin/env beak run --path
import Foundation

/// Calculates the factors for a given number
/// - Parameters:
///   - number: the input number to use
public func calculate(number: Int) {
    let factors = (1...number).filter { number % $0 == 0 }
    print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}

That first line is the shebang line: it tells Unix systems that the rest of this file should be passed to Beak as its input.

Now run this command from your terminal:

chmod a+x factors.swift

That marks factors.swift as being executable (X) for all (A) users. You can now run this instead:

./factors.swift calculate --number 100 

That’s slightly better, but now try running this command:

mv factors.swift /usr/local/bin/factors

That moves factors.swift to the directory containing your local commands, while also renaming it just to “factors”.

Now your command becomes this:

factors calculate --number 100

To make it even shorter (because why not?), you can mark the parameter as unnamed like this:

public func calculate(_ number: Int) {

(Note: make sure you edit /usr/local/bin/factors!)

Because the parameter is unnamed, you no longer need to specify --number on the command line. So, your command becomes just this:

factors calculate 100

I think you’ll agree that’s much easier to remember!

So, go and give Beak a try. Swift is slowly evolving into a full-stack language (Server-Side Swift, anyone?), and Beak is just one more great step in that direction.

Link: Beak

SPONSORED Instabug helps you identify and resolve severe crashes quickly. You can retrace in-app events and know exactly which line of code caused the crash along with environment details, network logs, repro steps, and the session profiler. Ask more questions or keep users up-to-date with in-app replies straight from your dashboard. Instabug takes data privacy seriously, so no one sees your data but you! See more detailed features comparison and try Instabug's crash reporting SDK for free.

Save 50% on all books and bundles

The biggest ever Hacking with Swift sale is now on, letting you save 50% on all books and bundles. Learn something new with Swift and enjoy great savings while the sale lasts!

Click here to save 50% in our Black Friday sale!

BUY OUR BOOKS
Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

About the author

Paul Hudson is the creator of Hacking with Swift, the most comprehensive series of Swift books in the world. He's also the editor of Swift Developer News, the maintainer of the Swift Knowledge Base, and a speaker at Swift events around the world. If you're curious you can learn more here.

Was this page useful? Let us know!

Average rating: 5.0/5