ペペロミア開発ブログ

React Nativeで開発しているアプリ「ペペロミア」の技術系記事を投稿してます

jqを使ってexpoのapp.jsonの環境毎に設定を切り替えるようにした

もともと、expoのapp.jsonですが、場合によってはdevとproductで分けたい場合があります。

docs.expo.io

ぺペロミアだと以下のiosのGoogleSiginに使用するreservedClientId

■ app.json

"ios": {
  "config": {
    "googleSignIn": {
      "reservedClientId": "***************"
    }
  }
},

devとproductで分けて収集しているsentryAuthTokenが該当します

■ app.json

  "hooks": {
    "postPublish": [
      {
        "file": "sentry-expo/upload-sourcemaps",
        "config": {
          "organization": "freelance-km",
          "project": "peperomia",
          "authToken": "********************"
        }
      }
    ]
  }

今までは、以下の4つを管理して、適時app.jsonに上書きするようにコマンドを仕込んでいましたが、

$ls -al
app.json ←実行時に使用
app.development.json ←開発時に使用
app.product.json ←本番ビルド時に使用
app.template.json ←ローカルお試し用

これだとexpoのバージョンアップやリリースのbuildNumberなど全ファイル更新しなきゃで面倒くさかったので、jqのテンプレートエンジンで統一化するようにしました。

stedolan.github.io

テンプレートエンジンの機能的は、ここ参照

Cookbook · stedolan/jq Wiki · GitHub

まず、install

$ brew install jq

まず、configの下に設定ファイルを置く

■config/development.json

{
  "iosGoogleSignInClientId": "aaa",
  "sentryAuthToken": "bbb"
}

jqのコマンドで特定の値を取得する

$ jq  '.iosGoogleSignInClientId' config/product.json
"aaa"

まずテンプレートとしてjqファイル作成 ■ appBase.jq

{
  "expo": {
    "name": "ペペロミア",
....(略)
    "ios": {
      "supportsTablet": true,
      "buildNumber": "10",
      "bundleIdentifier": "com.wheatandcat.peperomia",
      "infoPlist": {
        "NSPhotoLibraryUsageDescription": "予定作成のために使用します。",
        "NSCameraUsageDescription": "予定作成のためにカメラを使用します。",
        "CFBundleDevelopmentRegion": "ja_JP"
      },
      "config": {
        "googleSignIn": {
          "reservedClientId": $iosGoogleSignInClientId
        }
      }
    },
....(略)
  "hooks": {
    "postPublish": [
      {
        "file": "sentry-expo/upload-sourcemaps",
        "config": {
          "organization": "freelance-km",
          "project": "peperomia",
          "authToken": $sentryAuthToken
        }
      }
    ]
  }
}

いろいろ頑張れば、1コマンドでいけそうだけど シェルスクリプトにまとめ、こんな感じ

■createDevelopmentAppjson.sh

#!/bin/sh

iosGoogleSignInClientId=`jq  '.iosGoogleSignInClientId' config/development.json`
sentryAuthToken=`jq '.sentryAuthToken' config/development.json`


# ダブルコーテーションを除外
iosGoogleSignInClientId=${iosGoogleSignInClientId:1}
iosGoogleSignInClientId=${iosGoogleSignInClientId%\"}

sentryAuthToken=${sentryAuthToken:1}
sentryAuthToken=${sentryAuthToken%\"}

#echo ${iosGoogleSignInClientId}
#echo $sentryAuthToken

jq -n --arg iosGoogleSignInClientId $iosGoogleSignInClientId --arg sentryAuthToken $sentryAuthToken -f appBase.jq | tee app.json

ダブルコーテーションを除外しないとエスケープされてしまったので処理追加。 これでapp.jsonの値を変更する場合はappBase.jqを変更するだけになった。