🔧

Chrome拡張機能のmanifestのバージョン管理をNode.js + Pythonで効率化してみた

2021/10/31に公開

はじめに

この記事は、VSCode などで Python を実行したことがあり、Chrome 拡張機能を作成したことがある方向けの記事となりますので、各種設定は行った上で、追記が必要な箇所に絞って書いていこうと思います!

目的

Chrome 拡張機能を作っていく中でもの凄く手間なのが manifest のバージョン管理です。

変数名を変えただけなどたった数文字の変更でも manifest のバージョンを変えてあげないと Chrome での動作確認時に上手く反映されず動作しない事があり、こまめにバージョンを変更する必要がありました。

そのため、バージョンアップ作業をコマンドのみで完結させ、誤入力によるエラーをなくし、作業の効率化を図ろうと Python で自動化するコードを作成しました!

実際に更新する際は以下のコマンドをターミナル上で打てばいいように作ってあります!

完成イメージ

npm

npm run patch   # 後継互換性のあるバグ改修
npm run minor   # 後継互換性のある機能追加
npm run major   # 後継互換性のない機能追加
npm run release # リリース版発行

yarn

yarn patch   # 後継互換性のあるバグ改修
yarn minor   # 後継互換性のある機能追加
yarn major   # 後継互換性のない機能追加
yarn release # リリース版発行

コマンド別 バージョン変更例 0.0.1

各コマンドに合わせてバージョンが加算されていきます

コマンド 変更前 変更後
patch 0.0.1 0.0.2
minor 0.0.1 0.1.0
major 0.0.1 1.0.0
release 0.0.1 1.0.0

変更箇所

想定しているファイル構成

.
├── extensions
│   └── manifest.json
├── scripts
│   ├── main.py
│   └── manifest.py
└── package.json

Chrome 拡張機能側の変更点

manifest.json 更新箇所

以下の json データの中のversionが更新されます

manifest.json
{
  "manifest_version": 3,
  "version": "1.0.0",
  ...
}

Node.js

package.json 追記箇所

package.json
{
  ...
  "scripts": {
    ...
    "manifest": "python scripts/main.py manifest",
    "release": "python scripts/main.py release",
    "new": "python scripts/main.py new",
    "major": "python scripts/main.py major",
    "minor": "python scripts/main.py minor",
    "patch": "python scripts/main.py patch"
  },
}

python ファイル

main.py 新規作成

main.py
from manifest import Manifest
import sys

ext = Manifest()

if(len(sys.argv) > 1):
    key = str(sys.argv[1])
    print(key)
    if key == "major":
        ext.update(key)
    elif key == "minor":
        ext.update(key)
    elif key == "patch":
        ext.update(key)
    elif key == "new":
        ext.update(key)
    elif key == "release":
        ext.update(key)
    elif key == "manifest":
        print(ext.load())
    else:
        print("error")

manifest.py 新規作成

manifest.py
from collections import OrderedDict
import os
import sys
import json
import glob


class Manifest:
    data = {
        "fullpath": '',
        "path": '',
        "name": '',
        "dirname": '',
        "json": ''
    }

    def __init__(self, file=''):
        self.data = self.__manifest_data(file)

    def __manifest_data(self, file):
        if(file != ''):
            files = glob.glob(file, recursive=True)
        else:
            files = glob.glob('**/manifest.json', recursive=True)
        if files:
            with open(files[0], encoding='utf-8') as f:
                update_data = json.load(f, object_pairs_hook=OrderedDict)
            return {
                "fullpath": files[0],
                "path": os.path.relpath(files[0]).replace(os.path.basename(files[0]), ''),
                "name": os.path.basename(files[0]),
                "dirname": os.path.basename(os.path.dirname(files[0])),
                "json": update_data
            }
        else:
            return {
                "fullpath": '',
                "path": '',
                "name": '',
                "dirname": '',
                "json": ''
            }

    def load(self):
        with open(self.data["fullpath"], encoding='utf-8') as f:
            update_data = json.load(f, object_pairs_hook=OrderedDict)
        return update_data

    def save(self, dic):
        with open(self.data["fullpath"], 'w', encoding='utf-8') as f:
            json.dump(dic, f, indent=2, ensure_ascii=False)
        self.data = self.__manifest_data(self.data["fullpath"])

    def __setting_version(self, version_str, key):
        version = version_str.split('.')
        if len(version) == 1:
            version.extend(['0', '0'])
        elif len(version) == 2:
            version.extend(['0'])
        if key == "major":
            version[0] = str(int(version[0]) + 1)
            version[1] = str(0)
            version[2] = str(0)
        elif key == "minor":
            version[1] = str(int(version[1]) + 1)
            version[2] = str(0)
        elif key == "patch":
            version[2] = str(int(version[2]) + 1)
        elif key == "release":
            version[0] = str(1)
            version[1] = str(0)
            version[2] = str(0)
        elif key == "new":
            version[0] = str(0)
            version[1] = str(0)
            version[2] = str(1)
        return '.'.join(version)

    def update(self, key):
        json = self.load()
        if 'version' not in json:
            json["version"] = "0.0.1"
        json['version'] = self.__setting_version(json['version'], key)
        self.save(json)
        return json['version']

さいごに

chrome 拡張機能を開発されている方がいらっしゃれば、
参考になるかと思いますのでぜひ試してみてください!

細かい解説については今回は全く触れていないのですが、ご要望があれば追記していこうと思いますのでぜひコメント頂ければと思います!

GitHubで編集を提案

Discussion