JA Deployment Configuration - hiraishikentaro/rails-factorybot-jump GitHub Wiki
Rails FactoryBot Jump は、拡張機能マニフェスト設定、ユーザー設定、ランタイム設定管理を含む多層設定システムを使用します。このガイドでは、デプロイメントと使用のための拡張機能設定のすべての側面をカバーします。
コア拡張機能メタデータ:
{
"name": "rails-factorybot-jump",
"displayName": "Rails FactoryBot Jump",
"description": "RailsテストファイルからFactoryBotファクトリ定義にジャンプ",
"version": "1.2.0",
"icon": "images/icon.png",
"publisher": "hir4ken",
"engines": {
"vscode": "^1.85.0"
}
}
主要設定要素:
- Name: 拡張機能の一意識別子
- Display Name: VSCode で表示されるユーザーフレンドリー名
- Version: リリース用セマンティックバージョニング
- Engine: 最小 VSCode バージョン要件
- Publisher: マーケットプレイス発行者 ID
ソース: package.json#L2-L10
アクティベーションイベント:
{
"activationEvents": ["onLanguage:ruby"]
}
言語サポート設定:
{
"contributes": {
"documentLinkProviders": [
{
"scheme": "file",
"language": "ruby"
}
]
}
}
メリット:
- Ruby ファイルが開かれたときのみ拡張機能がアクティベート
- Ruby 以外のプロジェクトでの最小限のリソース使用
- Ruby ファイルが開かれていないときの自動クリーンアップ
ソース: package.json#L35-L50
登録されたコマンド:
{
"contributes": {
"commands": [
{
"command": "rails-factorybot-jump.jumpToFactory",
"title": "FactoryBotファクトリにジャンプ"
}
]
}
}
コマンド統合:
// src/extension.ts
context.subscriptions.push(
vscode.commands.registerCommand(
"rails-factorybot-jump.gotoLine",
async (args: { uri: string; lineNumber: number }) => {
const uri = vscode.Uri.parse(args.uri);
const document = await vscode.workspace.openTextDocument(uri);
const editor = await vscode.window.showTextDocument(document);
const position = new vscode.Position(args.lineNumber, 0);
editor.selection = new vscode.Selection(position, position);
editor.revealRange(new vscode.Range(position, position));
}
)
);
ソース: package.json#L40-L45, src/extension.ts#L14-L26
設定プロパティ:
{
"contributes": {
"configuration": {
"title": "Rails FactoryBot Jump",
"properties": {
"rails-factorybot-jump.factoryPaths": {
"type": "array",
"default": ["spec/factories/**/*.rb"],
"description": "ファクトリファイルを検索するパス。globパターンをサポート。",
"items": {
"type": "string"
}
}
}
}
}
}
設定機能:
- 型検証: VSCode によって強制される文字列配列
- デフォルト値: Rails プロジェクトの合理的なデフォルト
- 説明: ユーザーフレンドリーヘルプテキスト
- Glob パターンサポート: 柔軟なファイルマッチング
ソース: package.json#L52-L66
ランタイム設定読み込み:
// src/providers/factoryLinkProvider.ts
private getFactoryPaths(): string[] {
const config = vscode.workspace.getConfiguration("rails-factorybot-jump");
const defaultPath = path.posix.join("spec", "factories", "**", "*.rb");
return config.get<string[]>("factoryPaths", [defaultPath]);
}
設定変更処理:
// 設定変更をリッスン
vscode.workspace.onDidChangeConfiguration(async (event) => {
if (event.affectsConfiguration("rails-factorybot-jump.factoryPaths")) {
await this.initializeFactoryFiles();
}
});
デフォルト設定(最小セットアップ):
{
"rails-factorybot-jump.factoryPaths": ["spec/factories/**/*.rb"]
}
カスタム設定(複数ディレクトリ):
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/**/*.rb",
"test/factories/**/*.rb",
"lib/factories/**/*.rb"
]
}
高度な設定(特定のサブディレクトリ):
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/users/**/*.rb",
"spec/factories/posts/**/*.rb",
"app/test_support/factories/**/*.rb"
]
}
ライブ設定リロード:
class FactoryLinkProvider {
private configurationChangeListener: vscode.Disposable;
constructor() {
// 設定変更リスナーを設定
this.configurationChangeListener =
vscode.workspace.onDidChangeConfiguration(
this.handleConfigurationChange.bind(this)
);
}
private async handleConfigurationChange(
event: vscode.ConfigurationChangeEvent
) {
if (event.affectsConfiguration("rails-factorybot-jump")) {
console.log("設定が変更されました。再初期化中...");
// 既存キャッシュをクリア
this.factoryCache.clear();
this.traitCache.clear();
// 新しい設定で再初期化
await this.initializeFactoryFiles();
}
}
}
パス検証:
private validateFactoryPaths(paths: string[]): string[] {
return paths.filter(path => {
// globパターン構文を検証
if (!path || typeof path !== 'string') {
console.warn(`無効なファクトリパス: ${path}`);
return false;
}
// パスが.rbで終わることを確認
if (!path.endsWith('.rb')) {
console.warn(`ファクトリパスは.rbで終わる必要があります: ${path}`);
return false;
}
return true;
});
}
設定サニタイズ:
private sanitizeConfiguration(): void {
const config = vscode.workspace.getConfiguration("rails-factorybot-jump");
const factoryPaths = config.get<string[]>("factoryPaths", []);
// 一貫性のためWindowsパスをPOSIXに変換
const normalizedPaths = factoryPaths.map(path =>
path.replace(/\\/g, '/')
);
// パスを検証してフィルター
const validPaths = this.validateFactoryPaths(normalizedPaths);
if (validPaths.length === 0) {
console.warn("有効なファクトリパスが見つかりません。デフォルトを使用");
this.factoryPaths = ["spec/factories/**/*.rb"];
} else {
this.factoryPaths = validPaths;
}
}
開発設定:
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/**/*.rb",
"test/fixtures/factories/**/*.rb"
],
"rails-factorybot-jump.debugMode": true
}
デバッグ設定機能:
// 開発専用設定
if (process.env.NODE_ENV === "development") {
// 詳細ログを有効化
console.log("ファクトリ発見パス:", this.factoryPaths);
console.log("キャッシュ統計:", {
factories: this.factoryCache.size,
traits: this.traitCache.size,
});
}
テスト環境セットアップ:
// src/test/suite/extension.test.ts
setup(() => {
// テスト用モック設定
const mockConfig = {
get: (key: string) => {
if (key === "factoryPaths") {
return ["test/fixtures/factories/**/*.rb"];
}
return undefined;
},
};
sinon.stub(vscode.workspace, "getConfiguration").returns(mockConfig as any);
});
最適化された本番設定:
{
"rails-factorybot-jump.factoryPaths": ["spec/factories/**/*.rb"]
}
パフォーマンス考慮事項:
- 検索パス数を最小化
- 広いワイルドカードより特定パターンを使用
- 深くネストしたディレクトリ構造を避ける
後方互換性戦略:
private migrateConfiguration(): void {
const config = vscode.workspace.getConfiguration("rails-factorybot-jump");
// レガシー設定キーを処理
const legacyFactoryPath = config.get<string>("factoryPath");
if (legacyFactoryPath && !config.has("factoryPaths")) {
console.log("レガシーfactoryPathをfactoryPathsに移行");
config.update("factoryPaths", [legacyFactoryPath], true);
}
}
スキーマ検証:
private validateConfiguration(): boolean {
const config = vscode.workspace.getConfiguration("rails-factorybot-jump");
const factoryPaths = config.get("factoryPaths");
// 型検証
if (!Array.isArray(factoryPaths)) {
console.error("factoryPathsは配列である必要があります");
return false;
}
// 内容検証
const validPaths = factoryPaths.every(path =>
typeof path === 'string' && path.length > 0
);
if (!validPaths) {
console.error("すべてのファクトリパスは空でない文字列である必要があります");
return false;
}
return true;
}
ワークスペース固有設定:
private getWorkspaceConfiguration(workspaceFolder?: vscode.WorkspaceFolder): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration(
"rails-factorybot-jump",
workspaceFolder?.uri
);
}
private async initializeForWorkspace(workspaceFolder: vscode.WorkspaceFolder): Promise<void> {
const config = this.getWorkspaceConfiguration(workspaceFolder);
const factoryPaths = config.get<string[]>("factoryPaths", []);
// このワークスペース固有のファクトリファイルを処理
await this.processWorkspaceFactories(workspaceFolder, factoryPaths);
}
設定レベル:
- ユーザー設定: すべてのプロジェクトのグローバル設定
- ワークスペース設定: プロジェクト固有設定
- フォルダー設定: マルチルートワークスペースフォルダー設定
優先順序(高い順):
- フォルダー設定
- ワークスペース設定
- ユーザー設定
- デフォルト値
Settings.json 例:
{
"rails-factorybot-jump.factoryPaths": [
"spec/factories/**/*.rb",
"test/factories/**/*.rb"
]
}
ワークスペース設定:
// .vscode/settings.json
{
"rails-factorybot-jump.factoryPaths": ["custom/factories/**/*.rb"]
}
パス解決問題:
private debugPathResolution(): void {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders) {
console.error("ワークスペースフォルダーが見つかりません");
return;
}
console.log("ワークスペースフォルダー:", workspaceFolders.map(f => f.uri.path));
const config = this.getFactoryPaths();
console.log("設定されたファクトリパス:", config);
// 各パスをテスト
config.forEach(async (pattern) => {
const files = await vscode.workspace.findFiles(pattern);
console.log(`パターン"${pattern}"で${files.length}個のファイルが見つかりました`);
});
}
ランタイム設定チェック:
public async validateConfiguration(): Promise<boolean> {
const config = vscode.workspace.getConfiguration("rails-factorybot-jump");
const factoryPaths = config.get<string[]>("factoryPaths");
if (!factoryPaths || factoryPaths.length === 0) {
vscode.window.showWarningMessage(
"Rails FactoryBot Jump: ファクトリパスが設定されていません"
);
return false;
}
// ファイルが見つかるかテスト
for (const pattern of factoryPaths) {
const files = await vscode.workspace.findFiles(pattern, null, 1);
if (files.length > 0) {
return true;
}
}
vscode.window.showWarningMessage(
"Rails FactoryBot Jump: 設定されたパスでファクトリファイルが見つかりません"
);
return false;
}
この包括的な設定システムは、標準的な Rails プロジェクトのシンプルさを維持しながら、さまざまな開発環境に柔軟性を提供します。