kintone プラグインアップロード処理用プラグインIDセット

[kintone プラグインアップロード処理](https://qiita.com/rex0220/items/ea321d0573b83607ab2c)用に、既存のプラグインIDをファイルにセット（メモ）

# 概要

作業手順をメモ

・[kintone プラグイン一覧取得](https://qiita.com/rex0220/items/6ab8475e87c5de08e21d)で、プラグインID とプラグイン名を取得
・各プラグインの 「manifest.json」ファイルからファイルパスとプラグイン名を取得
・プラグイン名でマッチングして、プラグインIDとファイルパスを取得して、ファイル作成コマンド作成

# kintone プラグイン一覧取得

kintone 開発環境から、[kintone プラグイン一覧取得](https://qiita.com/rex0220/items/6ab8475e87c5de08e21d)で、一覧作成

```listPluginID.txt
*** Plugin List ***
# pluginId, name, version, pluginStore
1 gbjnadbngbniopdeibcjihdkhkcinljf : 項目絞り込み, 24, false
2 jaclnkdjcojbnailjnbfklhkcofaaeec : sample-test1, 1, false
3 bdikedheinambdonmgjghplaoakphdfd : 一括更新, 13, false
...
```

# ファイルパス・プラグイン名一覧作成

下記のような manifest.json ファイルから、"項目絞り込み"を取得して一覧にします。
ディレクトリやファイル操作は、シェルのほうがやりやすいので、シェル処理にします。

- manifest.jsonの内容

```manifest.json
{
  "manifest_version": 1,
  "version": 24,
  "type": "APP",
  "name": {
    "ja": "項目絞り込み",
    "en": "Narrow down values.",
    "zh": "Narrow down values."
  },
  "description": {
    "ja": "項目値の絞り込みを行うプラグインです。",
    "en": "This plugin narrows down values.",
    "zh": "This plugin narrows down values."
  },
}
```

- 各プラグインのディレクトリ構成

![2024-07-18_16h35_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d6ac07f3-bc6f-e819-95d8-dd0abcd6f4d2.png)

- 各プラグインのディレクトリから、manifest.json を探して、name を取得

シェルはしばらく触っていなかったのですが、jq コマンドで json を処理できるようです。
chatGPT に教えてもらいました。いろいろ便利になっています。

```.sh
$ find . -path "*/prod/manifest.json" -exec sh -c 'echo -n "{}: "; jq -r ".name.ja" "{}"' \; > listPluginPath.txt
```
- 処理結果

```listPluginPath.txt
./action-control/prod/manifest.json: アクション表示制御
./aggregate/prod/manifest.json: アプリ集計
./bulk-approval/prod/manifest.json: 一括承認
...
```

# プラグイン名でマッチングして、プラグインIDファイル作成コマンドを作成

こちらは、node で作成


```pluginMatch.js
const fs = require('fs');
const path = require('path');

// ファイル名
const pluginListFile = 'listPluginID.txt';
const manifestListFile = 'listPluginPath.txt';

console.log('test0');

// プラグインIDと名称のマッピングを作成するための関数
function createPluginMap() {
    const pluginMap = {};
    const data = fs.readFileSync(pluginListFile, 'utf8');

    try {
        // 行ごとに処理
        data.split('\n').forEach(line => {
            // 行の先頭に番号とIDがあり、コロンで区切られている
            const match = line.match(/^(\d+)\s([a-z0-9]{32})\s:\s(.+),\s\d+,\s\w+$/);
            if (match) {
                const [, , id, name] = match;
                pluginMap[name.trim()] = id.trim();
            }
        });

        return pluginMap;

    }
    catch(error) {
        console.log('Err1:'), error;
    }
  
}

// manifest_list.txt の内容を処理する関数
function processManifestFile(pluginMap) {
    try {
        const data = fs.readFileSync(manifestListFile, 'utf8');

        // 行ごとに処理
        data.split('\n').forEach(line => {
            const [filePath, name] = line.split(': ');
            if (name && pluginMap[name.trim()]) {
                const pluginId = pluginMap[name.trim()];
                const dirPath = (path.dirname(filePath))
                const outPath = dirPath.replace("/prod","/pluginId.txt");
                console.log(`"${pluginId}" > ` + outPath);
            }
        });    
    }
    catch(error) {
        console.log('Err2:', error);
    }
}


// メイン処理
function main() {
    console.log('test1');
    const pluginMap = createPluginMap();
    // console.log('test2', pluginMap);
    processManifestFile(pluginMap);
}


main();
```

- 処理結果

処理結果をテキストで確認後、シェルで実行

```.txt
"fjnoboohpdkgkiajpogkgfhdlipoddop" > ./action-control/pluginId.txt
"dnfmecefagpmheminfphakcfaoephohi" > ./aggregate/pluginId.txt
"cmgkjadcnibmpfnpmfmlcgapamkkdnkg" > ./bulk-approval/pluginId.txt
"bdikedheinambdonmgjghplaoakphdfd" > ./bulk-update/pluginId.txt
"oekapkklfjhakkcfefjpldkbpkialkof" > ./autocomplete/pluginId.txt
...
```