Marathon : Swift スクリプト作成・管理ツール

この記事では [Marathon](https://github.com/johnsundell/marathon) の紹介をします。

Marathon は、Swift でスクリプトを作成したり管理したりするツールです。

# Swift でスクリプト？

Swift でスクリプトというと、最初に思いつくのが、以下のような使い方です。

`helloworld.swift` という名前で以下のようなファイルを作ります。

```swift
#!/usr/bin/swift

print("Hello world")
```

このファイルに `chmod` で実行属性をつけておけば `./helloworld.swift` で実行できます。この使い方は、一般的な意味でのスクリプトと呼んで良いと思います。

・・・ただ、これが普段使うスクリプトとして便利かというと微妙です。

素の Swift の機能や Foundation の機能くらいでは、ファイル操作するとか外部コマンド実行するとかのちょっとしたことでも結構面倒です。実際にスクリプトとして活用する気持ちには、あんまりなれません。

# Marathon でスクリプト

そこで Marathon です。

Marathon でスクリプト、と言いましたが、上記のような意味でのスクリプトを指しているわけではありません。

実際のところは、Swift Package Manager ベースのプロジェクトを作成し、それをビルドして実行します。しかし、Marathon が専用の場所にプロジェクトを自動生成して管理してくれるので、単一の Swift ファイルだけを意識すれば良く、スクリプトのように扱える、という仕組みです。また、外部ライブラリの活用も簡単に行えるような仕組みになっています。

# インストール

Marathon のインストールは [README](https://github.com/JohnSundell/Marathon/blob/master/README.md) を参照してください。Homebrew を使うか、Mint を使うか、リポジトリを clone してビルドするかになります。

（この記事を書いている時点では、Homebrew でインストールできるバイナリは Xcode 9.x との組み合わせで問題があるようなので、リポジトリを clone してビルドするのが良さそうです）

# 使ってみる

まずはスクリプトを新規作成します。

```
$ marathon create helloworld
```

これを行うと、カレントディレクトリに `helloworld.swift` というファイルが生成され、さらには `~/.marathon` フォルダ内にプロジェクトが自動生成されて、Xcode が起動します。（`--verbose` オプションをつけると何をやっているかを出力してくれます）

Xcode プロジェクト内の `main.swift` を編集・保存して Xcode を閉じます。編集内容は `helloworld.swift` に反映されます。

```swift
print("Hello world")
```

次のようにしてスクリプトを実行します。

```
$ marathon run helloworld
```

これを行うと、`~/.marathon` フォルダ内のプロジェクトで `swift build` が行われ、ビルドされたバイナリファイルが実行されます。（そのため少し時間がかかります）（ここでも `--verbose` オプションをつけると何をやっているかを出力してくれます）

スクリプトを Xcode で編集したい場合、次のコマンドで Xcode プロジェクトを開くことができます。

```
$ marathon edit helloworld
```

Xcode を使わずに `helloworld.swift` をテキストエディタで編集しても良いです。

# 外部ライブラリ活用 : Files

では、外部ライブラリを活用してみます。

ファイル操作が簡単にできる [Files](https://github.com/JohnSundell/Files) ライブラリを使ってみます。次のようなスクリプトを作成します。

```swift
import Files // marathon:https://github.com/JohnSundell/Files.git

for file in Folder.current.files {
    print(file.name)
}
```

ここで `import` の後のコメントは Marathon 向けの専用コメントです。

このスクリプトを実行します。

```
$ marathon run <スクリプト名>
```

これを行うと、指定したリポジトリからライブラリを自動的に取得してからビルドしてくれます。内部的には Swift Package Manager を利用して管理しています。

なお、ライブラリの指定方法は、上記の `import` コメントの方法のほかに、`Marathonfile` という別ファイルを作ってそちらに記述する方法もあります。

# 外部ライブラリ活用 : ShellOut

次に、外部コマンドを実行する [ShellOut](https://github.com/JohnSundell/ShellOut) ライブラリを使ってみます。

```swift
import ShellOut // marathon:https://github.com/JohnSundell/ShellOut.git

let output = try shellOut(to: "echo", arguments: ["Hello world"])
print(output)
```

このような感じで、外部コマンドである `echo` を呼び出せます。

また、ShellOut には Git などいくつかのコマンドがあらかじめ定義されており、それらを簡単に呼び出すことも可能です。

# 作ったスクリプトをビルドしてインストールする

`marathon run` は、いちいちスクリプトをビルドしてから実行するため、遅いです。そのため、できたスクリプトをあらかじめビルドしてインストールしておくと便利です。

そのためには次を実行します。

```
$ marathon install <スクリプト名>
```

これを行うと、ビルドしてできたバイナリを `/usr/local/bin` にインストールします。なお、インストールパスを指定することも可能です。

# 他の人が作成したスクリプトをインストールする

`marathon install` は、GitHub などで公開されているスクリプトのインストールも可能です。

例えば、次のようにして公開されているスクリプトをインストールできます。

```
$ marathon install https://raw.githubusercontent.com/JohnSundell/Marathon-Examples/master/AddSuffix/addSuffix.swift
```

あるいは、次のように GitHub で公開されているツールをインストールできます。

```
$ marathon install johnsundell/testdrive
```

# まとめ

Marathon を使うと、日常のスクリプトも Swift で書けるようになります。便利ですね。