rufio 0.61.0 → 0.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -18
- data/README.md +191 -150
- data/README_ja.md +331 -0
- data/examples/bookmarks.yml +14 -0
- data/examples/config.rb +68 -0
- data/examples/script_paths.yml +11 -0
- data/lib/rufio/application.rb +1 -1
- data/lib/rufio/bookmark_manager.rb +3 -3
- data/lib/rufio/bookmark_storage.rb +61 -60
- data/lib/rufio/config.rb +214 -0
- data/lib/rufio/config_loader.rb +144 -37
- data/lib/rufio/keybind_handler.rb +14 -9
- data/lib/rufio/script_config_loader.rb +27 -12
- data/lib/rufio/script_path_manager.rb +50 -89
- data/lib/rufio/version.rb +1 -1
- metadata +6 -14
- data/README_EN.md +0 -610
- data/config_example.rb +0 -88
- data/examples/config.yml +0 -8
- data/scripts/test_jobs/build_simulation.sh +0 -29
- data/scripts/test_jobs/deploy_simulation.sh +0 -37
- data/scripts/test_jobs/quick.sh +0 -11
- data/scripts/test_jobs/random_result.sh +0 -23
- data/scripts/test_jobs/slow_fail.sh +0 -10
- data/scripts/test_jobs/slow_success.sh +0 -10
- data/scripts/test_jobs/very_slow.sh +0 -19
- data/test_delete/test1.txt +0 -1
- data/test_delete/test2.txt +0 -1
data/README_ja.md
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# rufio
|
|
2
|
+
|
|
3
|
+
**Runtime Unified Flow I/O Operator**
|
|
4
|
+
|
|
5
|
+
ファイルを起点に、ツールとスクリプトを実行・連携させるTUIファイルマネージャー。
|
|
6
|
+
Ruby/Python/PowerShellに対応し、開発ワークフローを一箇所に統合します。
|
|
7
|
+
|
|
8
|
+
A TUI file manager as a unified runtime environment for tools and scripts.
|
|
9
|
+
|
|
10
|
+
**日本語** | [English](./README.md)
|
|
11
|
+
|
|
12
|
+
## コンセプト
|
|
13
|
+
|
|
14
|
+
rufioは単なるファイルマネージャーではありません。**ツールランタイム実行環境**です。
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────────────────────────────────────────────────┐
|
|
18
|
+
│ rufio │
|
|
19
|
+
│ Runtime Unified Flow I/O Operator │
|
|
20
|
+
├─────────────────────────────────────────────────────────┤
|
|
21
|
+
│ Files ──→ Scripts ──→ Tools ──→ Output │
|
|
22
|
+
│ ↑ │ │
|
|
23
|
+
│ └───────────── Feedback ────────────┘ │
|
|
24
|
+
└─────────────────────────────────────────────────────────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **ファイル操作**: 従来のファイルマネージャー機能
|
|
28
|
+
- **スクリプト実行**: Ruby/Python/PowerShellスクリプトをファイルコンテキストで実行
|
|
29
|
+
- **ツール連携**: 外部ツール(git, fzf, rga等)とのシームレスな統合
|
|
30
|
+
- **統一I/O**: すべての入出力を単一のフローで管理
|
|
31
|
+
|
|
32
|
+
## 特徴
|
|
33
|
+
|
|
34
|
+
### ツールランタイムとして
|
|
35
|
+
|
|
36
|
+
- **マルチ言語スクリプト対応**: Ruby, Python, PowerShell
|
|
37
|
+
- **スクリプトパス管理**: 複数のスクリプトディレクトリを登録・管理
|
|
38
|
+
- **コマンド補完**: `@`プレフィックスでスクリプトをTab補完
|
|
39
|
+
- **ジョブ管理**: バックグラウンドでスクリプト/コマンドを実行
|
|
40
|
+
- **実行ログ**: すべての実行結果を自動記録
|
|
41
|
+
|
|
42
|
+
### ファイルマネージャーとして
|
|
43
|
+
|
|
44
|
+
- **Vimライクなキーバインド**: 直感的なナビゲーション
|
|
45
|
+
- **リアルタイムプレビュー**: ファイル内容を即座に表示
|
|
46
|
+
- **高速検索**: fzf/rgaとの連携
|
|
47
|
+
- **ブックマーク**: よく使うディレクトリに素早くアクセス
|
|
48
|
+
- **zoxide連携**: スマートなディレクトリ履歴
|
|
49
|
+
|
|
50
|
+
### クロスプラットフォーム
|
|
51
|
+
|
|
52
|
+
- **macOS**: ネイティブサポート
|
|
53
|
+
- **Linux**: ネイティブサポート
|
|
54
|
+
- **Windows**: PowerShellスクリプト対応
|
|
55
|
+
|
|
56
|
+
## インストール
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
gem install rufio
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
または、Gemfileに追加:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
gem 'rufio'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## クイックスタート
|
|
69
|
+
|
|
70
|
+
### 1. 起動
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
rufio # カレントディレクトリで起動
|
|
74
|
+
rufio /path/to # 指定したディレクトリで起動
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. スクリプトパスを登録
|
|
78
|
+
|
|
79
|
+
1. スクリプトを配置したいディレクトリに移動
|
|
80
|
+
2. `B` → `2` でスクリプトパスに追加
|
|
81
|
+
|
|
82
|
+
### 3. スクリプトを実行
|
|
83
|
+
|
|
84
|
+
1. `:` でコマンドモードを起動
|
|
85
|
+
2. `@` + スクリプト名の一部を入力
|
|
86
|
+
3. `Tab` で補完
|
|
87
|
+
4. `Enter` で実行
|
|
88
|
+
|
|
89
|
+
## キーバインド
|
|
90
|
+
|
|
91
|
+
### 基本操作
|
|
92
|
+
|
|
93
|
+
| キー | 機能 |
|
|
94
|
+
|------|------|
|
|
95
|
+
| `j/k` | 上下移動 |
|
|
96
|
+
| `h/l` | 親/子ディレクトリ |
|
|
97
|
+
| `g/G` | 先頭/末尾 |
|
|
98
|
+
| `Enter` | ディレクトリに入る/ファイルを開く |
|
|
99
|
+
| `q` | 終了 |
|
|
100
|
+
|
|
101
|
+
### ファイル操作
|
|
102
|
+
|
|
103
|
+
| キー | 機能 |
|
|
104
|
+
|------|------|
|
|
105
|
+
| `Space` | 選択/選択解除 |
|
|
106
|
+
| `o` | 外部エディタで開く |
|
|
107
|
+
| `a/A` | ファイル/ディレクトリ作成 |
|
|
108
|
+
| `r` | リネーム |
|
|
109
|
+
| `d` | 削除 |
|
|
110
|
+
| `m/c/x` | 移動/コピー/削除(選択済み) |
|
|
111
|
+
|
|
112
|
+
### 検索・フィルター
|
|
113
|
+
|
|
114
|
+
| キー | 機能 |
|
|
115
|
+
|------|------|
|
|
116
|
+
| `f` | フィルターモード |
|
|
117
|
+
| `s` | fzfでファイル検索 |
|
|
118
|
+
| `F` | rgaでファイル内容検索 |
|
|
119
|
+
|
|
120
|
+
### ナビゲーション
|
|
121
|
+
|
|
122
|
+
| キー | 機能 |
|
|
123
|
+
|------|------|
|
|
124
|
+
| `b` | ブックマーク追加 |
|
|
125
|
+
| `B` | ブックマークメニュー |
|
|
126
|
+
| `0` | 起動ディレクトリに戻る |
|
|
127
|
+
| `1-9` | ブックマークにジャンプ |
|
|
128
|
+
| `z` | zoxide履歴 |
|
|
129
|
+
|
|
130
|
+
### ツールランタイム
|
|
131
|
+
|
|
132
|
+
| キー | 機能 |
|
|
133
|
+
|------|------|
|
|
134
|
+
| `:` | コマンドモード |
|
|
135
|
+
| `J` | ジョブモード |
|
|
136
|
+
| `L` | 実行ログ表示 |
|
|
137
|
+
| `?` | ヘルプ |
|
|
138
|
+
|
|
139
|
+
## コマンドモード
|
|
140
|
+
|
|
141
|
+
`:` でコマンドモードを起動し、様々なコマンドを実行できます。
|
|
142
|
+
|
|
143
|
+
### スクリプト実行
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
:@build # @で始まるとスクリプト補完
|
|
147
|
+
:@deploy.rb # 登録済みスクリプトを実行
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### シェルコマンド
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
:!git status # !で始まるとシェルコマンド
|
|
154
|
+
:!ls -la # バックグラウンドで実行
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 組み込みコマンド
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
:hello # 挨拶メッセージ
|
|
161
|
+
:stop # rufioを終了
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## スクリプトパス
|
|
165
|
+
|
|
166
|
+
### スクリプトパスとは
|
|
167
|
+
|
|
168
|
+
スクリプトファイルを配置するディレクトリを登録する機能です。登録したディレクトリ内のスクリプトは、コマンドモードで `@` プレフィックスを使って実行できます。
|
|
169
|
+
|
|
170
|
+
### 管理方法
|
|
171
|
+
|
|
172
|
+
`B` → `3` でスクリプトパス管理メニューを開きます:
|
|
173
|
+
|
|
174
|
+
- 登録済みパスの一覧表示
|
|
175
|
+
- `d`: パスを削除
|
|
176
|
+
- `Enter`: ディレクトリにジャンプ
|
|
177
|
+
- `ESC`: メニューを閉じる
|
|
178
|
+
|
|
179
|
+
### 対応スクリプト
|
|
180
|
+
|
|
181
|
+
| 拡張子 | 言語 |
|
|
182
|
+
|--------|------|
|
|
183
|
+
| `.rb` | Ruby |
|
|
184
|
+
| `.py` | Python |
|
|
185
|
+
| `.ps1` | PowerShell |
|
|
186
|
+
| `.sh` | Shell (bash/zsh) |
|
|
187
|
+
|
|
188
|
+
## DSLコマンド
|
|
189
|
+
|
|
190
|
+
`~/.config/rufio/commands.rb` でカスタムコマンドを定義できます:
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
command "hello" do
|
|
194
|
+
ruby { "Hello from rufio!" }
|
|
195
|
+
description "挨拶コマンド"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
command "status" do
|
|
199
|
+
shell "git status"
|
|
200
|
+
description "Gitステータス"
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
command "build" do
|
|
204
|
+
script "~/.config/rufio/scripts/build.rb"
|
|
205
|
+
description "ビルド実行"
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 設定
|
|
210
|
+
|
|
211
|
+
### 設定ファイル構成
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
~/.config/rufio/
|
|
215
|
+
├── config.rb # メイン設定(スクリプトパス、カラー等)
|
|
216
|
+
├── commands.rb # DSLコマンド定義
|
|
217
|
+
├── bookmarks.json # ブックマーク
|
|
218
|
+
├── scripts/ # スクリプトファイル
|
|
219
|
+
└── logs/ # 実行ログ
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 設定例
|
|
223
|
+
|
|
224
|
+
```ruby
|
|
225
|
+
# ~/.config/rufio/config.rb
|
|
226
|
+
|
|
227
|
+
# スクリプトパス - スクリプトを配置するディレクトリ
|
|
228
|
+
SCRIPT_PATHS = [
|
|
229
|
+
'~/.config/rufio/scripts',
|
|
230
|
+
'~/my-scripts',
|
|
231
|
+
'./scripts'
|
|
232
|
+
].freeze
|
|
233
|
+
|
|
234
|
+
# カラー設定(HSL形式推奨)
|
|
235
|
+
COLORS = {
|
|
236
|
+
directory: { hsl: [220, 80, 60] },
|
|
237
|
+
file: { hsl: [0, 0, 90] },
|
|
238
|
+
executable: { hsl: [120, 70, 50] },
|
|
239
|
+
selected: { hsl: [50, 90, 70] },
|
|
240
|
+
preview: { hsl: [180, 60, 65] }
|
|
241
|
+
}.freeze
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### ローカル設定
|
|
245
|
+
|
|
246
|
+
プロジェクトルートに `rufio.rb` を配置すると、そのプロジェクト専用のスクリプトパスを設定できます:
|
|
247
|
+
|
|
248
|
+
```ruby
|
|
249
|
+
# ./rufio.rb(プロジェクトルート)
|
|
250
|
+
SCRIPT_PATHS = [
|
|
251
|
+
'./scripts',
|
|
252
|
+
'./bin'
|
|
253
|
+
].freeze
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## 外部ツール連携
|
|
257
|
+
|
|
258
|
+
rufioは以下の外部ツールと連携して機能を拡張します:
|
|
259
|
+
|
|
260
|
+
| ツール | 用途 | キー |
|
|
261
|
+
|--------|------|------|
|
|
262
|
+
| fzf | ファイル名検索 | `s` |
|
|
263
|
+
| rga | ファイル内容検索 | `F` |
|
|
264
|
+
| zoxide | ディレクトリ履歴 | `z` |
|
|
265
|
+
|
|
266
|
+
### インストール
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# macOS
|
|
270
|
+
brew install fzf rga zoxide
|
|
271
|
+
|
|
272
|
+
# Ubuntu/Debian
|
|
273
|
+
apt install fzf zoxide
|
|
274
|
+
# rgaは別途インストール: https://github.com/phiresky/ripgrep-all
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## 高度な機能
|
|
278
|
+
|
|
279
|
+
### ネイティブスキャナー(実験的)
|
|
280
|
+
|
|
281
|
+
高速なディレクトリスキャンのためのネイティブ実装をサポート:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
rufio --native # 自動検出
|
|
285
|
+
rufio --native=zig # Zig実装
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### JITコンパイラ
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
rufio --yjit # Ruby 3.1+ YJIT
|
|
292
|
+
rufio --zjit # Ruby 3.4+ ZJIT
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### ヘルスチェック
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
rufio -c # システム依存関係をチェック
|
|
299
|
+
rufio --check-health # 同上
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## 開発
|
|
303
|
+
|
|
304
|
+
### 必要な環境
|
|
305
|
+
|
|
306
|
+
- Ruby 2.7.0以上
|
|
307
|
+
- io-console, pastel, tty-cursor, tty-screen gems
|
|
308
|
+
|
|
309
|
+
### 開発版の実行
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
git clone https://github.com/masisz/rufio
|
|
313
|
+
cd rufio
|
|
314
|
+
bundle install
|
|
315
|
+
./bin/rufio
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### テスト
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
bundle exec rake test
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## ライセンス
|
|
325
|
+
|
|
326
|
+
MIT License
|
|
327
|
+
|
|
328
|
+
## 貢献
|
|
329
|
+
|
|
330
|
+
バグ報告や機能リクエストは [GitHub Issues](https://github.com/masisz/rufio/issues) でお願いします。
|
|
331
|
+
プルリクエストも歓迎です!
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ~/.config/rufio/bookmarks.yml
|
|
2
|
+
# List of bookmarks
|
|
3
|
+
#
|
|
4
|
+
# Press 1-9 keys to jump directly to bookmarks.
|
|
5
|
+
# Press B key to open bookmark menu for add/remove operations.
|
|
6
|
+
|
|
7
|
+
- path: ~/Documents
|
|
8
|
+
name: Documents
|
|
9
|
+
- path: ~/Downloads
|
|
10
|
+
name: Downloads
|
|
11
|
+
- path: ~/projects
|
|
12
|
+
name: Projects
|
|
13
|
+
- path: ~/.config
|
|
14
|
+
name: Config
|
data/examples/config.rb
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ~/.config/rufio/config.rb
|
|
4
|
+
# rufio DSL Configuration File
|
|
5
|
+
#
|
|
6
|
+
# This file defines the configuration for rufio.
|
|
7
|
+
# Script paths and bookmarks are managed in separate YAML files.
|
|
8
|
+
|
|
9
|
+
# ========================================
|
|
10
|
+
# Language Setting
|
|
11
|
+
# ========================================
|
|
12
|
+
# 'en' (English) or 'ja' (Japanese)
|
|
13
|
+
LANGUAGE = 'ja'
|
|
14
|
+
|
|
15
|
+
# ========================================
|
|
16
|
+
# Color Settings
|
|
17
|
+
# ========================================
|
|
18
|
+
# HSL format: [hue(0-360), saturation(0-100), lightness(0-100)]
|
|
19
|
+
COLORS = {
|
|
20
|
+
directory: { hsl: [220, 80, 60] }, # Blue
|
|
21
|
+
file: { hsl: [0, 0, 90] }, # White
|
|
22
|
+
executable: { hsl: [120, 70, 50] }, # Green
|
|
23
|
+
selected: { hsl: [50, 90, 70] }, # Yellow
|
|
24
|
+
preview: { hsl: [180, 60, 65] } # Cyan
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
# ========================================
|
|
28
|
+
# Keybind Settings
|
|
29
|
+
# ========================================
|
|
30
|
+
KEYBINDS = {
|
|
31
|
+
quit: %w[q ESC],
|
|
32
|
+
up: %w[k UP],
|
|
33
|
+
down: %w[j DOWN],
|
|
34
|
+
left: %w[h LEFT],
|
|
35
|
+
right: %w[l RIGHT ENTER],
|
|
36
|
+
top: %w[g],
|
|
37
|
+
bottom: %w[G],
|
|
38
|
+
refresh: %w[r],
|
|
39
|
+
search: %w[/],
|
|
40
|
+
open_file: %w[o SPACE]
|
|
41
|
+
}.freeze
|
|
42
|
+
|
|
43
|
+
# ========================================
|
|
44
|
+
# Application Associations
|
|
45
|
+
# ========================================
|
|
46
|
+
# Specify which application to open for each file extension
|
|
47
|
+
APPLICATIONS = {
|
|
48
|
+
%w[txt md rb py js html css json xml yaml yml] => 'code',
|
|
49
|
+
%w[jpg jpeg png gif bmp svg webp] => 'open',
|
|
50
|
+
%w[mp4 avi mkv mov wmv] => 'open',
|
|
51
|
+
%w[pdf] => 'open',
|
|
52
|
+
%w[doc docx xls xlsx ppt pptx] => 'open',
|
|
53
|
+
:default => 'open'
|
|
54
|
+
}.freeze
|
|
55
|
+
|
|
56
|
+
# ========================================
|
|
57
|
+
# Command History Size
|
|
58
|
+
# ========================================
|
|
59
|
+
COMMAND_HISTORY_SIZE = 1000
|
|
60
|
+
|
|
61
|
+
# ========================================
|
|
62
|
+
# Script Paths and Bookmarks
|
|
63
|
+
# ========================================
|
|
64
|
+
# script_paths.yml - List of script directories
|
|
65
|
+
# bookmarks.yml - List of bookmarks
|
|
66
|
+
#
|
|
67
|
+
# These files are automatically loaded by rufio.
|
|
68
|
+
# You can edit them manually or manage via rufio's UI.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ~/.config/rufio/script_paths.yml
|
|
2
|
+
# List of script directories
|
|
3
|
+
#
|
|
4
|
+
# Scripts in registered directories can be executed
|
|
5
|
+
# from rufio's command mode (:).
|
|
6
|
+
#
|
|
7
|
+
# Example: :build -> executes build.sh or build.rb in script_paths
|
|
8
|
+
|
|
9
|
+
- ~/.config/rufio/scripts
|
|
10
|
+
- ~/bin
|
|
11
|
+
- ~/scripts
|
data/lib/rufio/application.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Rufio
|
|
|
21
21
|
terminal_ui = TerminalUI.new(test_mode: test_mode)
|
|
22
22
|
|
|
23
23
|
# バックグラウンドコマンド実行用の設定
|
|
24
|
-
log_dir = File.join(Dir.home, '.config', 'rufio', '
|
|
24
|
+
log_dir = File.join(Dir.home, '.config', 'rufio', 'logs')
|
|
25
25
|
FileUtils.mkdir_p(log_dir) unless Dir.exist?(log_dir)
|
|
26
26
|
command_logger = CommandLogger.new(log_dir)
|
|
27
27
|
background_executor = BackgroundCommandExecutor.new(command_logger)
|
|
@@ -15,12 +15,12 @@ module Rufio
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def create_default_bookmark
|
|
18
|
-
#
|
|
18
|
+
# 必要に応じて古いconfig.ymlからマイグレーション
|
|
19
19
|
ConfigLoader.migrate_bookmarks_if_needed
|
|
20
20
|
|
|
21
|
-
# YAML
|
|
21
|
+
# 新形式のYAMLストレージを使用(bookmarks.yml)
|
|
22
22
|
storage = ConfigLoader.bookmark_storage
|
|
23
|
-
Bookmark.new(ConfigLoader::
|
|
23
|
+
Bookmark.new(ConfigLoader::BOOKMARKS_YML, storage: storage)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
public
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'json'
|
|
4
4
|
require 'yaml'
|
|
5
5
|
require 'fileutils'
|
|
6
|
+
require_relative 'config'
|
|
6
7
|
|
|
7
8
|
module Rufio
|
|
8
9
|
# ブックマークストレージの基底クラス
|
|
@@ -28,16 +29,21 @@ module Rufio
|
|
|
28
29
|
|
|
29
30
|
def valid_bookmark?(bookmark)
|
|
30
31
|
bookmark.is_a?(Hash) &&
|
|
31
|
-
bookmark.key?(:path) &&
|
|
32
|
-
bookmark.key?(:name)
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
(bookmark.key?(:path) || bookmark.key?('path')) &&
|
|
33
|
+
(bookmark.key?(:name) || bookmark.key?('name'))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def normalize_bookmark(bookmark)
|
|
37
|
+
{
|
|
38
|
+
path: bookmark[:path] || bookmark['path'],
|
|
39
|
+
name: bookmark[:name] || bookmark['name']
|
|
40
|
+
}
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
def filter_valid_bookmarks(bookmarks)
|
|
38
44
|
return [] unless bookmarks.is_a?(Array)
|
|
39
45
|
|
|
40
|
-
bookmarks.select { |b| valid_bookmark?(b) }
|
|
46
|
+
bookmarks.select { |b| valid_bookmark?(b) }.map { |b| normalize_bookmark(b) }
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
|
|
@@ -63,15 +69,24 @@ module Rufio
|
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
71
|
|
|
66
|
-
# YAML
|
|
72
|
+
# YAML形式のブックマークストレージ(新旧形式対応)
|
|
73
|
+
# 新形式: bookmarks.yml(配列形式)
|
|
74
|
+
# 旧形式: config.yml(bookmarksセクション)
|
|
67
75
|
class YamlBookmarkStorage < BookmarkStorage
|
|
68
76
|
def load
|
|
69
77
|
return [] unless File.exist?(@file_path)
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
# 新形式: bookmarks.yml(配列形式)
|
|
80
|
+
if @file_path.end_with?('bookmarks.yml')
|
|
81
|
+
return Config.load_bookmarks_from_yml(@file_path)
|
|
82
|
+
end
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
# 旧形式: config.yml(bookmarksセクション)
|
|
85
|
+
yaml = YAML.safe_load(File.read(@file_path), symbolize_names: true)
|
|
86
|
+
return [] unless yaml.is_a?(Hash)
|
|
87
|
+
|
|
88
|
+
bookmarks = yaml[:bookmarks] || []
|
|
89
|
+
filter_valid_bookmarks(bookmarks)
|
|
75
90
|
rescue StandardError
|
|
76
91
|
[]
|
|
77
92
|
end
|
|
@@ -79,70 +94,56 @@ module Rufio
|
|
|
79
94
|
def save(bookmarks)
|
|
80
95
|
ensure_directory
|
|
81
96
|
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
# 新形式: bookmarks.yml(配列形式)
|
|
98
|
+
if @file_path.end_with?('bookmarks.yml')
|
|
99
|
+
Config.save_bookmarks_to_yml(@file_path, bookmarks)
|
|
100
|
+
return true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# 旧形式: config.yml(bookmarksセクション - 既存の設定を保持)
|
|
104
|
+
existing = if File.exist?(@file_path)
|
|
105
|
+
YAML.safe_load(File.read(@file_path), symbolize_names: false) || {}
|
|
106
|
+
else
|
|
107
|
+
{}
|
|
108
|
+
end
|
|
88
109
|
|
|
89
|
-
|
|
90
|
-
bookmarks_for_yaml = bookmarks.map do |b|
|
|
110
|
+
existing['bookmarks'] = bookmarks.map do |b|
|
|
91
111
|
{ 'path' => b[:path], 'name' => b[:name] }
|
|
92
112
|
end
|
|
93
113
|
|
|
94
|
-
|
|
95
|
-
existing_config_string_keys = deep_stringify_keys(existing_config)
|
|
96
|
-
existing_config_string_keys['bookmarks'] = bookmarks_for_yaml
|
|
97
|
-
|
|
98
|
-
File.write(@file_path, YAML.dump(existing_config_string_keys))
|
|
114
|
+
File.write(@file_path, YAML.dump(existing))
|
|
99
115
|
true
|
|
100
116
|
rescue StandardError => e
|
|
101
117
|
warn "Failed to save bookmarks to YAML: #{e.message}"
|
|
102
118
|
false
|
|
103
119
|
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# JSONからYAMLへのマイグレーター
|
|
123
|
+
class BookmarkMigrator
|
|
124
|
+
# @param json_path [String] JSONファイルのパス
|
|
125
|
+
# @param yaml_path [String] YAMLファイルのパス
|
|
126
|
+
# @return [Boolean] マイグレーションが実行されたかどうか
|
|
127
|
+
def self.migrate(json_path, yaml_path)
|
|
128
|
+
return false unless File.exist?(json_path)
|
|
104
129
|
|
|
105
|
-
|
|
130
|
+
# JSONからブックマークを読み込む
|
|
131
|
+
json_storage = JsonBookmarkStorage.new(json_path)
|
|
132
|
+
bookmarks = json_storage.load
|
|
106
133
|
|
|
107
|
-
|
|
108
|
-
return hash unless hash.is_a?(Hash)
|
|
134
|
+
return false if bookmarks.empty?
|
|
109
135
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
deep_stringify_keys(v)
|
|
114
|
-
when Array
|
|
115
|
-
v.map { |item| item.is_a?(Hash) ? deep_stringify_keys(item) : item }
|
|
116
|
-
else
|
|
117
|
-
v
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
136
|
+
# YAMLに保存
|
|
137
|
+
yaml_storage = YamlBookmarkStorage.new(yaml_path)
|
|
138
|
+
yaml_storage.save(bookmarks)
|
|
122
139
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
json_storage = JsonBookmarkStorage.new(json_path)
|
|
131
|
-
bookmarks = json_storage.load
|
|
132
|
-
|
|
133
|
-
# YAMLに保存
|
|
134
|
-
yaml_storage = YamlBookmarkStorage.new(yaml_path)
|
|
135
|
-
yaml_storage.save(bookmarks)
|
|
136
|
-
|
|
137
|
-
# JSONファイルをバックアップして削除
|
|
138
|
-
backup_path = "#{json_path}.bak"
|
|
139
|
-
FileUtils.mv(json_path, backup_path)
|
|
140
|
-
|
|
141
|
-
true
|
|
142
|
-
rescue StandardError => e
|
|
143
|
-
warn "Failed to migrate bookmarks: #{e.message}"
|
|
144
|
-
false
|
|
145
|
-
end
|
|
140
|
+
# JSONファイルをバックアップ
|
|
141
|
+
FileUtils.mv(json_path, "#{json_path}.bak")
|
|
142
|
+
|
|
143
|
+
true
|
|
144
|
+
rescue StandardError => e
|
|
145
|
+
warn "Migration failed: #{e.message}"
|
|
146
|
+
false
|
|
146
147
|
end
|
|
147
148
|
end
|
|
148
149
|
end
|