claspの導入でGoogle Apps Scriptのローカル開発＆git管理を実現する

# claspはいいぞ
久しぶりに[GAS（Google Apps Script）](https://developers.google.com/apps-script)を使ったミニマルなツールを作ったのですが、[clasp](https://github.com/google/clasp)導入のやり方を忘れていたので手順をメモしておきます。

GASはWeb上のスクリプトエディタでサクッと書けるメリットがある一方、エディタの使い勝手が微妙で、スクリプトの機能拡充や複数人開発などをやり始めると早々にしんどい事態に陥ります。
![スクリーンショット 2020-02-16 21.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/94c856db-a352-2da9-21d7-53a7662f4956.png)

特に変更履歴で差分の判別ができないのは絶望的…

そんなGASのソースコードをローカル環境に落とし、自由度の高い開発スタイルを実現してくれるCLIツールがclaspです。
![42856573-a5d96d7c-89fa-11e8-9d69-8d2c66f00d8d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/a8e968c8-6f94-edbd-c48f-4220a9de5f7d.gif)
[google/clasp: 🔗 Command Line Apps Script Projects](https://github.com/google/clasp)

Google製だよ:wink:

# claspの導入
というわけで、さっそく導入してみましょう。
## npmコマンドでclaspをインストール
まずはclaspを`npm`コマンドでインストール。

```terminal
$ npm i @google/clasp -g
/usr/local/bin/clasp -> /usr/local/lib/node_modules/@google/clasp/src/index.js
npm WARN inquirer-autocomplete-prompt@1.0.1 requires a peer of inquirer@^5.0.0 || ^6.0.0 but none is installed. You must install peer dependencies yourself.

+ @google/clasp@2.3.0
```

`npm`未導入の場合は、Homebrew経由でインストールするのがよろしいかと思います。

- [MacにHomebrewをインストールする手順とWarningの解決方法 - Qiita](https://qiita.com/unsoluble_sugar/items/6ac1848ba1933ac05c76)
- [Node.js / npm をインストール (Mac環境) - Qiita](https://qiita.com/PolarBear/items/62c0416492810b7ecf7c)


## Googleアカウント連携
続いてGoogleアカウントと連携します。

```terminal
$ clasp login
Warning: You seem to already be logged in *globally*. You have a ~/.clasprc.json
Logging in globally...
🔑 Authorize clasp by visiting this url:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=xxxxxxxxxx
```

`clasp login`コマンドを叩くとブラウザで認証画面が開くので
![スクリーンショット 2020-02-16 21.23.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/9a5c6c13-7f48-eebd-d3d9-f18508ac793f.png)

Googleアカウントへのアクセスを許可しましょう。

```terminal
Authorization successful.
```


## Google Apps Script APIを有効化する

これを忘れると後述の`clasp push`などでエラーが起きます。

```terminal
? Give a description:  
User has not enabled the Apps Script API. Enable it by visiting https://script.google.com/home/usersettings then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
```

Google Apps Scriptの「設定」画面へアクセスして
https://script.google.com/home/usersettings

オフになっている「Google Apps Script API」項目をクリック。
<img width="274" alt="スクリーンショット 2020-02-12 11.03.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/da84f53a-aac7-59b8-1cfa-de27ced98450.png">
設定を「オン」にします。
<img width="487" alt="スクリーンショット 2020-02-12 11.03.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/370c4c14-b910-4f9e-7761-556425f74848.png">

以上でclaspの導入は完了です。
簡単ですね。


# よく使うコマンド

実際にGASプロジェクトをローカル環境に落とすなど、比較的よく使うコマンドを紹介しておきます。

## Clone
すでに存在しているGASプロジェクトがある場合は、`clasp clone`でクローンできます。引数に対象のスクリプトIDを指定しましょう。

```terminal
$ clasp clone <SCRIPT_ID>
```

これでGASプロジェクトのソースコードがローカル環境でいじれるようになりました。

```terminal
Warning: files in subfolder are not accounted for unless you set a '.claspignore' file.
Cloned 8 files.
└─ character.js
└─ main.js
└─ menu.js
└─ pr.js
└─ random.js
└─ appsscript.json
└─ channel.js
└─ reviewer.js

Ignored files:
└─ .clasp.json
```

使い勝手の微妙なスクリプトエディタとはおさらば。お好みのエディタで快適に開発できます。
![スクリーンショット 2020-02-16 21.28.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/b376064a-de0e-f2e2-0a98-1b12e9214443.png)

もちろんgit管理なども自由自在。
[新しいMacでGitHubのSSH接続をするまでの環境構築手順 - Qiita](https://qiita.com/unsoluble_sugar/items/14bea376d8e6fce82eb3)

やったぜ。



## Push
ローカルに落としてきたファイルは`.js`ファイルになっていますが、`clasp push`すると`.gs`ファイルとして、Web上のApp Scriptプロジェクトにアップロードされます。

```terminal
$ clasp push
```

`push`対象のファイルは`clasp status`で確認できます。

```
$ clasp status
Not ignored files:
└─ appsscript.json
└─ channel.js
└─ character.js
└─ main.js
└─ menu.js
└─ pr.js
└─ random.js
└─ reviewer.js

Ignored files:
└─ .DS_Store
└─ .clasp.json
```

`git add`のように変更ファイルだけをインデックス（ステージング）領域に上げる機能は無さそうです。`push`するとカレントディレクトリ内のファイル構成で、一括アップロード&上書きされるので注意してください。


## Pull

`clasp pull`でApp Scriptプロジェクト上のソースコードをダウンロードできます。

```terminal
$ clasp pull
```

ローカルにある同一名ファイルは上書きされてしまうので、git管理しておくと良いでしょう。

## Create

`clasp create`でローカルからGASプロジェクトの新規作成もできます。

```terminal
$ clasp create sample_app
? Create which script? (Use arrow keys)
❯ standalone 
  docs 
  sheets 
  slides 
  forms 
  webapp 
  api 

```

clasp 1.7.0から、`standalone`だけでなく、Spreadsheetに紐付いたスクリプトや`webapp`、`api`など、作成するプロジェクトのタイプが選べるようになったようです。

```terminal
Created new standalone script: https://script.google.com/d/xxxxxxxxxx/edit
Warning: files in subfolder are not accounted for unless you set a '.claspignore' file.
Cloned 1 file.
└─ appsscript.json

```

`clasp create`で生成される`appsscript.json` は、Apps Scriptプロジェクトのマニフェストファイルです。
[Manifests  |  Apps Script  |  Google Developers](https://developers.google.com/apps-script/concepts/manifests)

タイムゾーンやライブラリの設定などのプロパティがありますので、必要に応じて設定しましょう。

```appsscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

[Manifest structure  |  Apps Script  |  Google Developers](https://developers.google.com/apps-script/manifest/)


## Open

`clasp open`でスクリプトエディタにアクセスできます。コマンドを打つことでブラウザが開きます。

```terminal
$ clasp open
```
スクリプトプロパティやトリガーをいじる際に使う。

## Version
GASのバージョン管理もclaspでできます。

### バージョン作成

`clasp version`コマンドでバージョン作成が可能。引数でdescriptionをつけられます。

```terminal
$ clasp version "Update sugoi kinou"
Created version 2.
```

![スクリーンショット 2020-02-17 00.45.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/d032949a-0e9a-5f57-2ce2-815b1d154180.png)

手元で作業中はgit管理ベースでブランチ切ったりコミットしたりして、デプロイする際に`clasp version`でバージョンインクリメントするような運用などが良さ気です。

### バージョン履歴確認

`clasp versions`コマンドではバージョン履歴が確認できます。

```terminal
$ clasp versions
~ 3 Versions ~
3 - Update sugoku sugoi kinou
2 - Update sugoi kinou
1 - Update
```

# claspで広がるGoogle Apps Scriptの世界

他にも様々なコマンドや機能があるので、公式リポジトリやドキュメントもご参照ください。
[google/clasp: 🔗 Command Line Apps Script Projects](https://github.com/google/clasp)
[Command Line Interface using clasp - Apps Script  |  Google Developers](https://developers.google.com/apps-script/guides/clasp)

最近だとTypescriptで開発する人も多いみたいですね。
[clasp が Typescript をサポートした！ - Qiita](https://qiita.com/HeRo/items/f2ce057c6b1456e896ad)

自分はSpreadsheetと組み合わせてSlack bot作ったり、軽めのAPI作ったり程度しか経験ありませんが、極めればもっと色々なことができそうです:smile: