唐揚げ食べたい

六本木で働くwebエンジニアのブログです

usakoをローカルで開発できるようにしました

概要

前回疎結合化したGASアプリケーションのusakoを、ローカルで開発できるようにしました。
そのためにやったことを紹介します。
また、作業中に見たリンクは記事の最後につけておきます。

▼前回 kyanite.hatenablog.com

やったこと

claspを導入しローカルで開発できるようにする

ずっとブラウザから開発してたんですが、やっぱりやりにくいのでローカルで開発できるようにしました。
合わせて、ディレクトリもそれっぽい構成にできるように準備。

BEFORE AFTER
すべてのファイルを同改装に配置 ソースのファイルは src 以下に

すでにソースファイルがあるので、 create ではなく clone です。

各ライブラリをクラスにする

疎結合化するために各機能をライブラリに外出ししたのですが、ローカルで開発できるようになると逆にやりにくかったので、再度同じリポジトリ内にもってきました…。
前にやったこと無駄になったなと思いつつも、逆に別ライブラリに切り出せるほどになってるので移植自体はそんなに苦労しませんでした。前の作業無駄じゃない!はず!!! 合わせて、ディレクトリもそれっぽくして、内部の実装も軽くリファクタしました(変数の表現を揃えたり、無駄そうな処理をなくすなど…)
やっぱりこの作業が一番大変 & 楽しかった & 時間かかった。

BEFORE AFTER
ソース・ファイルはすべて src 以下 クラス定義は src/classes 。バッチは src/tasks に配置

lintツールを導入する

クラスにしたときに一部リファクタ失敗してしまってバッチがこけちゃったりしたので、ESLintを導入しました。
普段はphpなのでESLintの設定は初めてでしたが割とスッと出来てびっくり。
Sheet クラスなどのGAS独自のクラスがまあまあありますので、ESLintと合わせて eslint-plugin-googleappsscript も導入します。

npm install --save-dev eslint eslint-plugin-googleappsscript

導入後、各クラスでの宣言に no-unused-vars 等のエラーが出るようになったので、それぞれ無視する設定を個別に挿入しました。
まとめて設定出来たりもするかもしれないですが、意図しないところを無視されても困るので初めだけと割り切って粛々と進めました。
以下はバッチ用クラスの例です。例えば継承に利用している commandBase なんかがエラーだったのが、スキップされるようになります。

class NoticeTrashDay extends commandBase { // eslint-disable-line no-unused-vars, no-undef

  constructor() {
    super('ゴミの日通知バッチ');
  }

  main () {
    super.main();
  }

  /**
   * ゴミ捨て通知
   * 毎日 PM8〜9時
   */
  run() {
    Logger.log('called ' + this.constructor.name + ':run()');
    const dt = new Date();
    dt.setDate(dt.getDate() + 1);
    var comment = [];

    // 翌日が第何週目かを求める
    var isTheWhatWeekly = Math.floor((dt.getDate() - 1 ) / 7) + 1;
    switch(dt.getDay())
    {
      // 月曜日のごみ
      case 1:
        comment.push('可燃ごみ');
        break;

        // 中略

    // ごみの日じゃない場合は何もしない
    if (comment.length < 1) {
      return;
    }

    const line = new LineMessagingApi(); // eslint-disable-line no-undef
    line.pushAll('明日は ' + comment.join('、') + ' のゴミの日だよ!\n準備忘れずに!');
  }
}

function noticeTrashday () { // eslint-disable-line no-unused-vars
  const batch = new NoticeTrashDay();
  batch.main();
}

github Actionsを回す

lintができるようになったので、プルリクエストのマージ条件にlintの通過を追加しました。
自分ひとりでプルリク作成→マージでいつ事故るか怪しいので、こういうのができるのは助かります。
現行はこんな感じ。プルリクのマージ先である master ブランチは除外してもいいかもしれませんが。

name: CI

on:
  push

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-node@v1
      with:
        node-version: '12.16.2'
    - run: npm install
    - run: npm run lint # eslint src をタスクとして登録してあります

usako/main.yml at master · miyakona/usako · GitHub

余談: デプロイはできなかった

せっかくなので master ブランチにマージしたらデプロイしたいなーと思ったのですが、うまくいきませんでした。
.crasprc.json.clasp.json を配置しても、特定のプロジェクトに紐づくコマンドを発行すると以下のように権限のエラーが出てしまいます。

Run clasp versions1s
##[error]Process completed with exit code 1.
Run clasp versions
Could not read API credentials. Are you logged in globally?

##[error]Process completed with exit code 1.

https://github.com/miyakona/usako/runs/619462984?check_suite_focus=true

ちゃんとデバッグしたわけではないですが、コードを読んでると以下のissueと同症状なようでした。
github.com 利用するnodejsのバージョンを12系から10系に落としてみたりもしましたが、うまくいかず…まあそのうちで良いです。
せめて動くバージョンがわかればいいんですけどね。

参考リンク

GWの連休中にデプロイまで終わらせるぞー!と思ったんですが、デプロイがうまく動かないということに連休前に気づいてしまったので、連休中はゲームと料理三昧で過ごしました。
自粛期間もう少し延びそうなので、なにか機能を追加したりしようかなあ。考え中です。