ken_nogi/Pleasanter/.claude/js/resolve-project.js
Kenichiro NOGI ce58cb4be4 初回コミット: dev配下(NodeSrv/Pleasanter等)をGitea管理下に統合
GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。
NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは
別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter
インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:37:06 +09:00

186 lines
8.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* resolve-project.js
* ------------------------------------------------------------
* 各スクリプトを ClaudePleasanter直下から直接実行する運用に合わせ、
* 「どのプロジェクト(サイト)フォルダに対して実行するか」「どのサーバー環境
* (本番/テスト)に対して実行するか」を解決する共通ヘルパー。
*
* 使い方(各スクリプトの実行時):
* node .claude/js/get-site-config.js --project="IC(東京)【引継依頼】" --env=production
* node .claude/js/get-site-config.js -p IC東京 --env=development
* フォルダ名の完全一致が無い場合、部分一致大文字小文字無視で1件に絞れれば採用する
*
* --env は production本番: nextoffice.next-hd.co.jp / developmentテスト: neo999.next-hd.net /
* staging検証: nextoffice2.next-hd.net、2026-08-29追加のいずれかを必須指定する
* (誤送信事故防止のためデフォルト値は設けない)。
* 接続先情報BaseUrl/ApiKey/ApiVersionはリポジトリルート直下の
* config_production.json / config_development.json / config_staging.json に集約されており、
* loadServerConfig(env) で読み込む。各プロジェクトのSiteIdはプロジェクト直下の
* siteid.json{"SiteId": "..."}) に置き、loadSiteId(baseDir) で読み込む
* 旧config.jsonからの移行。config.jsonにはBaseUrl/ApiKeyも同居していたため、
* 本番/テストのconfigsデータが同一フォルダに混在する事故要因になっていた
*
* 複数コマンドを同じプロジェクト向けに連続実行する場合は、--project の代わりに
* 環境変数 PLEASANTER_PROJECT_ROOT にプロジェクトフォルダの絶対パスを設定してもよい
* --project指定があればそちらを優先する。--env も同様に環境変数
* PLEASANTER_ENV で指定可能(--env指定があればそちらを優先する
* ------------------------------------------------------------
*/
const fs = require("fs");
const path = require("path");
const REPO_ROOT = path.join(__dirname, "..", "..");
const VALID_ENVS = ["production", "development", "staging"];
function listProjectCandidates() {
return fs.readdirSync(REPO_ROOT).filter((name) => {
if (name.startsWith(".")) return false;
const full = path.join(REPO_ROOT, name);
return fs.statSync(full).isDirectory();
});
}
// argvから --project=X / --project X / -p X を取り除き、{ value, argv(残り) } を返す
function extractProjectFlag(argv) {
const rest = [];
let value = null;
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a.startsWith("--project=")) {
value = a.slice("--project=".length);
} else if (a === "--project" || a === "-p") {
value = argv[++i];
} else {
rest.push(a);
}
}
return { value, argv: rest };
}
// argvから --env=production|development を取り除き、{ value, argv(残り) } を返す
function extractEnvFlag(argv) {
const rest = [];
let value = null;
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a.startsWith("--env=")) {
value = a.slice("--env=".length);
} else if (a === "--env") {
value = argv[++i];
} else {
rest.push(a);
}
}
return { value, argv: rest };
}
function printCandidates() {
console.error("利用可能なプロジェクト:");
for (const c of listProjectCandidates()) console.error(` - ${c}`);
}
// argv既定: process.argv.slice(2)からサーバー環境production/developmentを解決する。
// 未指定・不正値は誤送信事故防止のためエラー終了する(デフォルト値は設けない)。
// 戻り値: { env: "production"|"development", argv: --env指定を取り除いた残りの引数配列 }
function resolveEnv(argv) {
const { value, argv: rest } = extractEnvFlag(argv);
const env = value || process.env.PLEASANTER_ENV;
if (!env) {
console.error("[エラー] サーバー環境が指定されていません。");
console.error('使い方: --env=production (本番) / --env=development (テスト) / --env=staging (検証) のいずれかを指定するか、環境変数 PLEASANTER_ENV を設定してください。');
process.exit(1);
}
if (!VALID_ENVS.includes(env)) {
console.error(`[エラー] 不正な --env 値です: ${env}`);
console.error(`指定可能な値: ${VALID_ENVS.join(" / ")}`);
process.exit(1);
}
return { env, argv: rest };
}
// argv既定: process.argv.slice(2))からプロジェクトフォルダとサーバー環境を解決する。
// 戻り値: { baseDir: 絶対パス, env: "production"|"development", argv: 残りの引数配列 }
function resolveProjectRoot(argv = process.argv.slice(2)) {
const { value, argv: afterProject } = extractProjectFlag(argv);
const { env, argv: rest } = resolveEnv(afterProject);
const name = value || process.env.PLEASANTER_PROJECT_ROOT;
if (!name) {
console.error("[エラー] 対象プロジェクトが指定されていません。");
console.error('使い方: --project="<フォルダ名>" を指定するか、環境変数 PLEASANTER_PROJECT_ROOT にプロジェクトフォルダの絶対パスを設定してください。');
printCandidates();
process.exit(1);
}
if (path.isAbsolute(name) && fs.existsSync(name)) return { baseDir: name, env, argv: rest };
const direct = path.join(REPO_ROOT, name);
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) return { baseDir: direct, env, argv: rest };
const candidates = listProjectCandidates().filter((c) => c.toLowerCase().includes(name.toLowerCase()));
if (candidates.length === 1) return { baseDir: path.join(REPO_ROOT, candidates[0]), env, argv: rest };
if (candidates.length > 1) {
console.error(`[エラー] "${name}" に一致するプロジェクトが複数見つかりました: ${candidates.join(", ")}`);
console.error("フォルダ名をフルで指定してください。");
process.exit(1);
}
console.error(`[エラー] プロジェクトフォルダが見つかりません: ${name}`);
printCandidates();
process.exit(1);
}
// リポジトリルート直下の config_{env}.jsonBaseUrl/ApiKey/ApiVersion。
// LoginId/Password等はget-page-html.js用の任意項目としてそのまま透過を読み込む。
function loadServerConfig(env) {
if (!VALID_ENVS.includes(env)) {
console.error(`[エラー] 不正な env 値です: ${env}`);
process.exit(1);
}
const configPath = path.join(REPO_ROOT, `config_${env}.json`);
if (!fs.existsSync(configPath)) {
console.error(`[エラー] サーバー接続設定ファイルが見つかりません: ${configPath}`);
process.exit(1);
}
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
if (!config.BaseUrl || !config.ApiKey) {
console.error(`[エラー] ${configPath} に BaseUrl / ApiKey を設定してください。`);
process.exit(1);
}
return config;
}
// プロジェクト直下の siteid.json{"SiteId": "..."}) からSiteIdを読み込む。
// 旧config.jsonが残っている場合は移行を促すエラーにする。
function loadSiteId(baseDir) {
const siteIdPath = path.join(baseDir, "siteid.json");
if (!fs.existsSync(siteIdPath)) {
const legacyConfigPath = path.join(baseDir, "config.json");
if (fs.existsSync(legacyConfigPath)) {
console.error(`[エラー] ${legacyConfigPath} は廃止されました。siteid.json{"SiteId": "..."}) に移行してください。`);
} else {
console.error(`[エラー] siteid.json が見つかりません: ${siteIdPath}`);
}
process.exit(1);
}
const siteid = JSON.parse(fs.readFileSync(siteIdPath, "utf-8"));
if (!siteid.SiteId) {
console.error(`[エラー] ${siteIdPath} に SiteId を設定してください。`);
process.exit(1);
}
return siteid.SiteId;
}
module.exports = {
resolveProjectRoot,
resolveEnv,
loadServerConfig,
loadSiteId,
REPO_ROOT,
VALID_ENVS,
listProjectCandidates,
};