ローカルでGASの開発を可能にするCLIツールclaspを使ってみた

## はじめに
Google Apps Script（以後、GAS）で開発をするときに困ることがいくつかあります。GASのIDE上で開発を行うため、手に馴染んだエディタを使えなかったり、バージョン管理がしにくかったりします。

このような問題を解決するのがclaspというCLIツールです。今回はそのclaspについて、使い方や使うときの注意点などをまとめたいと思います。

## claspとは
claspとは、ローカルでGASを開発を可能にするCLIツールです。**C**ommand **L**ine **A**pps **S**cript **P**rojectsの各単語の頭文字をとって名付けられました。

今回はこちらのリポジトリにあるREADMEに従ってclaspを使っていこうと思います。

https://github.com/google/clasp

## 使い方
### 使い始める前に
:::note warn
claspを利用する場合、Node.jsのバージョンは12.20.0以上である必要があります（2022年10月1日現在）
:::

必要に応じてバージョンをチェックしておきましょう！

今回は以下のバージョンで実行しています。
```zsh
$ node -v
v18.10.0

$ clasp -v
2.4.2
```

また諸々のコマンドはこちらのディレクトリで実行していきます
```zsh
$ pwd
path/to/clasp_test
```

### インストール
まずはclaspをインストールします。以下のnpmコマンドを実行してインストールします。


```bash
npm install -g @google/clasp
```

インストールが完了したら、以下のURLにアクセスしGoogle Apps Script APIをオンにしましょう。

https://script.google.com/home/usersettings

### ログイン
ローカルでGASを開発するにあたって、GASのプロジェクトを作成するGoogleアカウントにログインする必要があります。ログインは以下のコマンドで行えます。

```
clasp login
```

上記のコマンドを実行すると、ブラウザが立ち上がります。アカウントを選択するとclaspの使用許可が求められるので、許可してください。ログインが完了します。

またログインが完了すると、ホームディレクトリにトークンが入った`~/.clasprc.json`が作成されます。

### プロジェクトの作成
GASで開発を行うために、まずはプロジェクトを作成する必要があります。プロジェクトを作成するには`create`コマンドを使用します。`create`コマンドには複数のオプションがあり、プロジェクト名を指定したり、プロジェクトを作成するディレクトリを指定したり、プロジェクトに紐づくGoogleアプリケーション（Google DocsやGoogle Sheetsなど）を一緒に作成したりすることが可能です。

今回は以下のコマンドを実行してプロジェクトを作成します。

```bash
clasp create --title "clasp_test" --type standalone --rootDir path/to/clasp_test
```

プロジェクトを作成すると、カレントディレクトリもしくはオプションで指定したディレクトリに以下の2つのファイルが作成されます。

- `.clasp.json`
    - スクリプトIDやプッシュされるディレクトリが記載されています
- `appsscript.json`
    - プロジェクトのマニュフェストファイルです


プロジェクトを作成した段階のファイルの中身は以下のような感じです。

```json:.clasp.json
{"scriptId":"<scriptId>","rootDir":"path/to/clasp_test"}
```

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

### ファイルを作成する
プロジェクトの作成が完了したら、次はGASを書いていきましょう！今回は試しに以下のようなファイルを作成してみました。

```js:hello.js
function hello() {
    Logger.log("Hello clasp!")
}
```

### プロジェクトにファイルをアップロードする
プロジェクトにファイルをアップロードするには、以下のコマンドを実行します。
```
clasp push
```

どのファイルがプロジェクトにアップロードされるかは`clasp status`を実行するとわかります。コマンドを実行した場合、以下のような結果が返ってきます。

```zsh
$ clasp status
Not ignored files:
└─ path/to/clasp_test/appsscript.json
└─ path/to/clasp_test/hello.js

Ignored files:
└─ path/to/clasp_test/.clasp.json
```
`.`から始まるファイルはデフォルトでアップロードされないようになっているため、`.clasp.json`は`Ignored files`に入っています。

ちなみにアップロードしたくないファイルがある場合は`.claspignore`を作成することで解決することができます。Gitでいう`.gitignore`と同じ役割を持つファイルです。今回は実際にpushされないようになるか、`.claspignore`と`test_claspignore.js`を作成して試してみたいと思います。

```js:test_claspignore.js
function test_claspignore() {
    Logger.log("Test .claspignore")
}
```

```.claspignore
test_claspignore.js
```

上記のファイルを作成したら`clasp status`を実行します。実行結果は以下のようになりました。

```zsh
$ clasp status
Not ignored files:
└─ path/to/clasp_test/appsscript.json
└─ path/to/clasp_test/hello.js

Ignored files:
└─ path/to/clasp_test/.clasp.json
└─ path/to/clasp_test/.claspignore
└─ path/to/clasp_test/test_claspignore.js
```

たしかに`test_claspignore.js`をアップロードされないようにすることができました。
実際にpushもしていると`Not ignored files`とされているファイルのみをpushすることができました。

```zsh
$ clasp push
└─ path/to/clasp_test/appsscript.json
└─ path/to/clasp_test/hello.js
Pushed 2 files.
```

実際にプロジェクトにアップロードされているか確認したい場合は`clasp open`というコマンドを実行します。実行するとブラウザが立ち上がりプロジェクトを確認することができます。

![スクリーンショット 2022-09-30 18.57.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/e1b885ea-f678-88eb-f54c-d93c0564cacb.png)

たしかにアップロードされていることがわかります。


### プロジェクトからファイルをダウンロードする
今度はプロジェクトにあがっているファイルをダウンロードしてみます。ダウンロードする前に、ダウンロードする用のファイルを作成してみました。

![スクリーンショット 2022-09-30 19.00.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/d0526931-f5bc-1be1-7f6d-4fa49000b5f0.png)

ダウンロードするためには`clasp pull`というコマンドを実行します。実行した結果は以下です。

```zsh
$ clasp pull
Warning: files in subfolder are not accounted for unless you set a 'path/to/clasp_test/.claspignore' file.
Cloned 3 files.
└─ path/to/clasp_test/test_pull.js
└─ path/to/clasp_test/hello.js
└─ path/to/clasp_test/appsscript.json
```

### すでにあるプロジェクトをローカルで開発する
今回はローカルで新たにプロジェクトを作成して開発を行う方法を紹介してきました。しかし、すでに作成されたプロジェクトをローカルで開発したい場合もあると思います。その場合は`clasp clone`というコマンド実行することで解決できます。

ローカルで開発したいプロジェクトは、プロジェクトのURLもしくはスクリプトIDで指定することが可能です。
```zsh
$ mkdir clasp_clone_test && cd clasp_clone_test

$ clasp clone https://script.google.com/home/projects/<scriptId>/edit
Warning: files in subfolder are not accounted for unless you set a 'path/to/clasp_clone_test/.claspignore' file.
Cloned 1 file.
└─ path/to/clasp_clone_test/appsscript.json
Not ignored files:
└─ path/to/clasp_clone_test/appsscript.json

Ignored files:
└─ path/to/clasp_clone_test/.clasp.json
```

### 余談
#### GitHubでの管理
claspを使ってみて、特定のファイルを選択してpushできないのは困るなあと思いました。claspのコマンドでファイルを管理するのもいいと思いましたが、素直にGitHub等で管理するのが個人的には楽だと思いました。

#### TypeScriptでの開発
claspはバージョンが1.5.0以降TypeScriptでの開発が可能になりました。
こちらに詳しい説明は記載されていて、簡単に始めることができます。

https://github.com/google/clasp/blob/master/docs/typescript.md

## さいごに
今回はローカルでGASを開発を可能にするCLIツールclaspの使い方などをまとめました！
ローカルで開発ができるようになり、さらにGASの開発の幅が広がったと思います。興味のある方は是非使ってみてください！