rufio 0.30.0 → 0.31.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_v0.31.0.md +125 -0
- data/README.md +55 -0
- data/bin/rufio +80 -9
- data/lib/rufio/version.rb +1 -1
- data/retag.sh +55 -0
- metadata +8 -6
- data/docs/PLUGIN_GUIDE.md +0 -431
- data/docs/plugin_example.rb +0 -119
- data/rufio.gemspec +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7c5ebea1d23ee7dfd964bdfa8b3ed9a99fa404b6c1f4fc5f1af3afaa2567f42
|
|
4
|
+
data.tar.gz: 3f74121e14480e2d75a12cccca5c2984f6e7da5f894a89d8fb782a9a3fd9428e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 410b4b98fd4ea4ba3ef077fb31432f7974377be3e971bba1b60f390be99a8547e1cd5afb7b0209d631ed85cd5b87d519571b0fe1f1d6fb76ef58801be2911895
|
|
7
|
+
data.tar.gz: 345156bf65cae10f7a64756c9882d065e483519fb2f3ec6360dfbe729e0c88a7d42ada9c9b920b25dfa5ce2e81e216281677c239ae4b21672996535bb3799912
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Changelog - v0.31.0
|
|
2
|
+
|
|
3
|
+
## 🚀 New Features
|
|
4
|
+
|
|
5
|
+
### Experimental Native Scanner Implementation
|
|
6
|
+
|
|
7
|
+
Added high-performance directory scanning with Rust/Go implementations. By default, uses stable Ruby implementation with optional native implementations available via command-line options.
|
|
8
|
+
|
|
9
|
+
#### Implementation Languages
|
|
10
|
+
- **Rust implementation** (`lib_rust/scanner/`): Fastest, memory-safe
|
|
11
|
+
- **Go implementation** (`lib_go/scanner/`): Fast, excellent concurrency
|
|
12
|
+
- **Ruby implementation** (default): Stable, no dependencies
|
|
13
|
+
|
|
14
|
+
#### NativeScanner Abstraction Layer
|
|
15
|
+
- `lib/rufio/native_scanner.rb`: Unified interface independent of implementation
|
|
16
|
+
- Automatic fallback (falls back to Ruby if native implementation unavailable)
|
|
17
|
+
|
|
18
|
+
#### Launch Options
|
|
19
|
+
```bash
|
|
20
|
+
# Default (Ruby implementation)
|
|
21
|
+
rufio
|
|
22
|
+
|
|
23
|
+
# Enable native implementation (auto-detect: Rust > Go > Ruby)
|
|
24
|
+
rufio --native
|
|
25
|
+
rufio --native=auto
|
|
26
|
+
|
|
27
|
+
# Force Rust implementation
|
|
28
|
+
rufio --native=rust
|
|
29
|
+
|
|
30
|
+
# Force Go implementation
|
|
31
|
+
rufio --native=go
|
|
32
|
+
|
|
33
|
+
# Environment variable control
|
|
34
|
+
RUFIO_NATIVE=rust rufio
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Priority
|
|
38
|
+
- **Default**: Ruby (stability focused)
|
|
39
|
+
- **`--native=auto`**: Rust > Go > Ruby
|
|
40
|
+
- **`--native=rust`**: Rust (fallback to Ruby if unavailable)
|
|
41
|
+
- **`--native=go`**: Go (fallback to Ruby if unavailable)
|
|
42
|
+
|
|
43
|
+
## 🔧 Improvements
|
|
44
|
+
|
|
45
|
+
### GitHub Actions CI/CD
|
|
46
|
+
- **Build**: Automatically build native libraries on 3 OSes (Linux, macOS, Windows)
|
|
47
|
+
- **Test**: Run tests on all platforms (both Ruby fallback and native implementations)
|
|
48
|
+
- **Release**: Auto-build and publish gem on tag push, attach binaries
|
|
49
|
+
|
|
50
|
+
### Development Environment
|
|
51
|
+
- `.gitignore`: Ignore build artifacts (`target/`, `*.dylib`, `*.so`, `*.dll`, etc.)
|
|
52
|
+
- gemspec: Configure to include native libraries in gem (optional)
|
|
53
|
+
|
|
54
|
+
### Command-Line Argument Processing
|
|
55
|
+
- Added `--native` option
|
|
56
|
+
- Improved argument parser (accurate path and option discrimination)
|
|
57
|
+
- Added native scanner description to `--help`
|
|
58
|
+
|
|
59
|
+
## 📦 Dependencies
|
|
60
|
+
|
|
61
|
+
### Ruby Dependencies (unchanged)
|
|
62
|
+
- io-console ~> 0.6
|
|
63
|
+
- pastel ~> 0.8
|
|
64
|
+
- tty-cursor ~> 0.7
|
|
65
|
+
- tty-screen ~> 0.8
|
|
66
|
+
- ffi (only when using native scanner)
|
|
67
|
+
|
|
68
|
+
### Build-time Dependencies (optional)
|
|
69
|
+
- **Rust**: cargo, rustc (to build Rust implementation)
|
|
70
|
+
- **Go**: go 1.21+ (to build Go implementation)
|
|
71
|
+
|
|
72
|
+
## 🧪 Tests
|
|
73
|
+
|
|
74
|
+
Added new tests:
|
|
75
|
+
- `test/test_rust_scanner.rb`: Rust scanner tests
|
|
76
|
+
- `test/test_go_scanner.rb`: Go scanner tests
|
|
77
|
+
- `test/test_native_scanner.rb`: NativeScanner abstraction layer tests
|
|
78
|
+
- Verify default mode is Ruby
|
|
79
|
+
- Mode switching tests
|
|
80
|
+
- Auto-detection tests
|
|
81
|
+
- Fallback behavior tests
|
|
82
|
+
|
|
83
|
+
All tests passing: 279+ runs, 1299+ assertions, 0 failures, 0 errors
|
|
84
|
+
|
|
85
|
+
## 📝 Documentation
|
|
86
|
+
|
|
87
|
+
- README.md: Added launch options documentation
|
|
88
|
+
- Help message: Detailed `--native` option description
|
|
89
|
+
|
|
90
|
+
## 🔒 Compatibility
|
|
91
|
+
|
|
92
|
+
- **Backward compatibility**: Fully maintained (default is Ruby implementation)
|
|
93
|
+
- **Native libraries**: Optional (works without them)
|
|
94
|
+
- **Platforms**: Linux, macOS, Windows supported
|
|
95
|
+
|
|
96
|
+
## 📌 Notes
|
|
97
|
+
|
|
98
|
+
### Experimental Feature
|
|
99
|
+
Rust/Go implementations are experimental:
|
|
100
|
+
- Not used by default (requires `--native` option)
|
|
101
|
+
- Thorough testing recommended for production use
|
|
102
|
+
- Use default Ruby implementation if issues occur
|
|
103
|
+
|
|
104
|
+
### Build Instructions
|
|
105
|
+
|
|
106
|
+
#### Rust Implementation
|
|
107
|
+
```bash
|
|
108
|
+
cd lib_rust/scanner
|
|
109
|
+
cargo build --release
|
|
110
|
+
make install
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Go Implementation
|
|
114
|
+
```bash
|
|
115
|
+
cd lib_go/scanner
|
|
116
|
+
make install
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 🙏 Acknowledgments
|
|
120
|
+
|
|
121
|
+
Native Rust/Go implementations enable faster scanning of large directories. We welcome your feedback.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
Release Date: 2026-01-01
|
data/README.md
CHANGED
|
@@ -46,6 +46,61 @@ rufio # カレントディレクトリで起動
|
|
|
46
46
|
rufio /path/to # 指定したディレクトリで起動
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### ネイティブスキャナー(実験的機能)
|
|
50
|
+
|
|
51
|
+
rufio v0.31.0以降では、高速なディレクトリスキャンのためのネイティブ実装(Rust/Go)をサポートしています。デフォルトは安定したRuby実装を使用し、オプションでネイティブ実装に切り替え可能です。
|
|
52
|
+
|
|
53
|
+
#### 起動オプション
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# デフォルト(Ruby実装 - 安定)
|
|
57
|
+
rufio
|
|
58
|
+
|
|
59
|
+
# ネイティブ実装を有効化(自動検出: Rust > Go > Ruby)
|
|
60
|
+
rufio --native
|
|
61
|
+
rufio --native=auto
|
|
62
|
+
|
|
63
|
+
# Rust実装を強制使用
|
|
64
|
+
rufio --native=rust
|
|
65
|
+
rufio --native rust /path/to/dir
|
|
66
|
+
|
|
67
|
+
# Go実装を強制使用
|
|
68
|
+
rufio --native=go
|
|
69
|
+
rufio --native go /path/to/dir
|
|
70
|
+
|
|
71
|
+
# 環境変数でも制御可能
|
|
72
|
+
RUFIO_NATIVE=rust rufio
|
|
73
|
+
RUFIO_NATIVE=go rufio /path/to/dir
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### ネイティブ実装について
|
|
77
|
+
|
|
78
|
+
- **Rust実装**: 最も高速でメモリ安全。推奨。
|
|
79
|
+
- **Go実装**: 高速で並行処理に優れる。
|
|
80
|
+
- **Ruby実装** (デフォルト): 依存なし、安定動作保証。
|
|
81
|
+
|
|
82
|
+
#### ビルド方法
|
|
83
|
+
|
|
84
|
+
ネイティブ実装を使用するには、事前にビルドが必要です:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Rust実装のビルド
|
|
88
|
+
cd lib_rust/scanner
|
|
89
|
+
cargo build --release
|
|
90
|
+
make install
|
|
91
|
+
|
|
92
|
+
# Go実装のビルド
|
|
93
|
+
cd lib_go/scanner
|
|
94
|
+
make install
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### 注意事項
|
|
98
|
+
|
|
99
|
+
- ネイティブ実装は実験的機能です
|
|
100
|
+
- デフォルトではRuby実装を使用(`--native`オプションなし)
|
|
101
|
+
- ネイティブライブラリがない場合、自動的にRuby実装にフォールバック
|
|
102
|
+
- gemインストール時はネイティブライブラリが含まれます(ビルド不要)
|
|
103
|
+
|
|
49
104
|
### ヘルスチェック
|
|
50
105
|
|
|
51
106
|
```bash
|
data/bin/rufio
CHANGED
|
@@ -6,27 +6,98 @@ require_relative '../lib/rufio'
|
|
|
6
6
|
# プラグインを読み込む
|
|
7
7
|
Rufio::PluginManager.load_all
|
|
8
8
|
|
|
9
|
-
#
|
|
9
|
+
# コマンドライン引数のパース
|
|
10
|
+
native_mode = nil
|
|
11
|
+
start_directory = nil
|
|
12
|
+
skip_next = false
|
|
13
|
+
|
|
14
|
+
ARGV.each_with_index do |arg, idx|
|
|
15
|
+
if skip_next
|
|
16
|
+
skip_next = false
|
|
17
|
+
next
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
case arg
|
|
21
|
+
when '--native'
|
|
22
|
+
# 次の引数がモード指定かチェック
|
|
23
|
+
if idx + 1 < ARGV.length && !ARGV[idx + 1].start_with?('--') && !ARGV[idx + 1].start_with?('/')
|
|
24
|
+
next_arg = ARGV[idx + 1]
|
|
25
|
+
if %w[rust go auto ruby].include?(next_arg)
|
|
26
|
+
native_mode = next_arg
|
|
27
|
+
skip_next = true
|
|
28
|
+
else
|
|
29
|
+
native_mode = 'auto'
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
native_mode = 'auto'
|
|
33
|
+
end
|
|
34
|
+
when /^--native=(rust|go|auto|ruby)$/
|
|
35
|
+
native_mode = $1
|
|
36
|
+
when '-c', '--check-health', '--help', '-h'
|
|
37
|
+
# これらは後で処理
|
|
38
|
+
when /^--/
|
|
39
|
+
# 未知のオプションは無視
|
|
40
|
+
else
|
|
41
|
+
# 最初の非オプション引数をディレクトリとして扱う
|
|
42
|
+
start_directory ||= arg
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# ネイティブスキャナーモードを設定(native_scannerが存在する場合のみ)
|
|
47
|
+
if native_mode && defined?(Rufio::NativeScanner)
|
|
48
|
+
Rufio::NativeScanner.mode = native_mode
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# 環境変数でも制御可能
|
|
52
|
+
if ENV['RUFIO_NATIVE'] && defined?(Rufio::NativeScanner)
|
|
53
|
+
Rufio::NativeScanner.mode = ENV['RUFIO_NATIVE']
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# コマンド処理
|
|
10
57
|
if ARGV.include?('--check-health') || ARGV.include?('-c')
|
|
11
58
|
# ヘルスチェック実行
|
|
12
59
|
health_checker = Rufio::HealthChecker.new
|
|
13
60
|
success = health_checker.run_check
|
|
14
61
|
exit(success ? 0 : 1)
|
|
15
|
-
elsif ARGV.include?('--help')
|
|
62
|
+
elsif ARGV.include?('--help') || ARGV.include?('-h')
|
|
16
63
|
puts "rufio - Terminal-based file manager"
|
|
17
64
|
puts ""
|
|
18
65
|
puts "Usage:"
|
|
19
|
-
puts " rufio [DIRECTORY]
|
|
20
|
-
puts "
|
|
21
|
-
puts "
|
|
66
|
+
puts " rufio [OPTIONS] [DIRECTORY]"
|
|
67
|
+
puts ""
|
|
68
|
+
puts "Options:"
|
|
69
|
+
puts " -c, --check-health Check system dependencies"
|
|
70
|
+
puts " -h, --help Show this help message"
|
|
71
|
+
if defined?(Rufio::NativeScanner)
|
|
72
|
+
puts " --native[=MODE] Enable native scanner (experimental)"
|
|
73
|
+
puts " MODE: auto|rust|go (default: auto)"
|
|
74
|
+
puts ""
|
|
75
|
+
puts "Native Scanner:"
|
|
76
|
+
puts " By default, rufio uses Ruby implementation for stability."
|
|
77
|
+
puts " Native scanners (Rust/Go) are experimental and can be enabled with --native."
|
|
78
|
+
puts ""
|
|
79
|
+
puts " --native Auto-detect (Rust > Go > Ruby)"
|
|
80
|
+
puts " --native=rust Use Rust implementation"
|
|
81
|
+
puts " --native=go Use Go implementation"
|
|
82
|
+
puts " --native=auto Same as --native"
|
|
83
|
+
puts " --native=ruby Use Ruby implementation (default)"
|
|
84
|
+
puts ""
|
|
85
|
+
puts " Environment variable: RUFIO_NATIVE=rust|go|auto"
|
|
86
|
+
end
|
|
22
87
|
puts ""
|
|
23
88
|
puts "Examples:"
|
|
24
|
-
puts " rufio
|
|
25
|
-
puts " rufio /path/to/dir
|
|
26
|
-
|
|
89
|
+
puts " rufio # Start in current directory"
|
|
90
|
+
puts " rufio /path/to/dir # Start in specific directory"
|
|
91
|
+
if defined?(Rufio::NativeScanner)
|
|
92
|
+
puts " rufio --native # Use native scanner (auto-detect)"
|
|
93
|
+
puts " rufio --native=rust # Use Rust scanner"
|
|
94
|
+
puts " rufio --native rust /tmp # Use Rust scanner in /tmp"
|
|
95
|
+
puts " RUFIO_NATIVE=rust rufio # Use Rust via environment variable"
|
|
96
|
+
end
|
|
97
|
+
puts " rufio -c # Check dependencies"
|
|
27
98
|
exit(0)
|
|
28
99
|
else
|
|
29
|
-
start_directory
|
|
100
|
+
start_directory ||= Dir.pwd
|
|
30
101
|
|
|
31
102
|
# アプリケーション開始
|
|
32
103
|
app = Rufio::Application.new(start_directory)
|
data/lib/rufio/version.rb
CHANGED
data/retag.sh
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/zsh
|
|
2
|
+
|
|
3
|
+
# 使い方: ./retag.sh v0.31.0
|
|
4
|
+
|
|
5
|
+
# 引数チェック
|
|
6
|
+
if [ $# -eq 0 ]; then
|
|
7
|
+
echo "使い方: $0 <タグ名>"
|
|
8
|
+
echo "例: $0 v0.31.0"
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
TAG_NAME=$1
|
|
13
|
+
|
|
14
|
+
echo "=== タグ再作成スクリプト ==="
|
|
15
|
+
echo "タグ: $TAG_NAME"
|
|
16
|
+
echo ""
|
|
17
|
+
|
|
18
|
+
# 1. ローカルのタグを削除
|
|
19
|
+
echo "1. ローカルタグを削除中..."
|
|
20
|
+
if git tag -d $TAG_NAME; then
|
|
21
|
+
echo "✓ ローカルタグを削除しました"
|
|
22
|
+
else
|
|
23
|
+
echo "⚠ ローカルタグが存在しないか、削除に失敗しました"
|
|
24
|
+
fi
|
|
25
|
+
echo ""
|
|
26
|
+
|
|
27
|
+
# 2. リモートのタグを削除
|
|
28
|
+
echo "2. リモートタグを削除中..."
|
|
29
|
+
if git push origin :refs/tags/$TAG_NAME; then
|
|
30
|
+
echo "✓ リモートタグを削除しました"
|
|
31
|
+
else
|
|
32
|
+
echo "⚠ リモートタグの削除に失敗しました(存在しない可能性があります)"
|
|
33
|
+
fi
|
|
34
|
+
echo ""
|
|
35
|
+
|
|
36
|
+
# 3. タグを再作成
|
|
37
|
+
echo "3. タグを再作成中..."
|
|
38
|
+
if git tag $TAG_NAME; then
|
|
39
|
+
echo "✓ タグを再作成しました"
|
|
40
|
+
else
|
|
41
|
+
echo "✗ タグの再作成に失敗しました"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# 4. タグをプッシュ
|
|
47
|
+
echo "4. タグをプッシュ中..."
|
|
48
|
+
if git push origin $TAG_NAME; then
|
|
49
|
+
echo "✓ タグをプッシュしました"
|
|
50
|
+
echo ""
|
|
51
|
+
echo "🎉 完了!GitHub Actionsが実行されます。"
|
|
52
|
+
else
|
|
53
|
+
echo "✗ タグのプッシュに失敗しました"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rufio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.31.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- masisz
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-01-01 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: io-console
|
|
@@ -121,6 +122,7 @@ files:
|
|
|
121
122
|
- CHANGELOG_v0.20.0.md
|
|
122
123
|
- CHANGELOG_v0.21.0.md
|
|
123
124
|
- CHANGELOG_v0.30.0.md
|
|
125
|
+
- CHANGELOG_v0.31.0.md
|
|
124
126
|
- CHANGELOG_v0.4.0.md
|
|
125
127
|
- CHANGELOG_v0.5.0.md
|
|
126
128
|
- CHANGELOG_v0.6.0.md
|
|
@@ -132,8 +134,6 @@ files:
|
|
|
132
134
|
- Rakefile
|
|
133
135
|
- bin/rufio
|
|
134
136
|
- config_example.rb
|
|
135
|
-
- docs/PLUGIN_GUIDE.md
|
|
136
|
-
- docs/plugin_example.rb
|
|
137
137
|
- info/help.md
|
|
138
138
|
- info/keybindings.md
|
|
139
139
|
- info/welcome.md
|
|
@@ -169,7 +169,7 @@ files:
|
|
|
169
169
|
- lib/rufio/version.rb
|
|
170
170
|
- lib/rufio/zoxide_integration.rb
|
|
171
171
|
- publish_gem.zsh
|
|
172
|
-
-
|
|
172
|
+
- retag.sh
|
|
173
173
|
- test_delete/test1.txt
|
|
174
174
|
- test_delete/test2.txt
|
|
175
175
|
homepage: https://github.com/masisz/rufio
|
|
@@ -180,6 +180,7 @@ metadata:
|
|
|
180
180
|
homepage_uri: https://github.com/masisz/rufio
|
|
181
181
|
source_code_uri: https://github.com/masisz/rufio
|
|
182
182
|
changelog_uri: https://github.com/masisz/rufio/blob/main/CHANGELOG.md
|
|
183
|
+
post_install_message:
|
|
183
184
|
rdoc_options: []
|
|
184
185
|
require_paths:
|
|
185
186
|
- lib
|
|
@@ -194,7 +195,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
194
195
|
- !ruby/object:Gem::Version
|
|
195
196
|
version: '0'
|
|
196
197
|
requirements: []
|
|
197
|
-
rubygems_version: 4.
|
|
198
|
+
rubygems_version: 3.4.19
|
|
199
|
+
signing_key:
|
|
198
200
|
specification_version: 4
|
|
199
201
|
summary: Ruby file manager
|
|
200
202
|
test_files: []
|
data/docs/PLUGIN_GUIDE.md
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
# Rufio プラグインガイド
|
|
2
|
-
|
|
3
|
-
Rufioのプラグインシステムを使って、機能を拡張する方法を説明します。
|
|
4
|
-
|
|
5
|
-
## 目次
|
|
6
|
-
|
|
7
|
-
1. [プラグインの基本](#プラグインの基本)
|
|
8
|
-
2. [プラグインの作成](#プラグインの作成)
|
|
9
|
-
3. [プラグインの設定](#プラグインの設定)
|
|
10
|
-
4. [高度な機能](#高度な機能)
|
|
11
|
-
5. [トラブルシューティング](#トラブルシューティング)
|
|
12
|
-
|
|
13
|
-
## プラグインの基本
|
|
14
|
-
|
|
15
|
-
### プラグインとは?
|
|
16
|
-
|
|
17
|
-
プラグインは、Rufioに新しい機能を追加するためのRubyモジュールです。
|
|
18
|
-
|
|
19
|
-
### プラグインの種類
|
|
20
|
-
|
|
21
|
-
1. **組み込みプラグイン**: Rufio本体に含まれる
|
|
22
|
-
- 場所: `lib/rufio/plugins/`
|
|
23
|
-
- 例: `FileOperations`
|
|
24
|
-
|
|
25
|
-
2. **ユーザープラグイン**: ユーザーが作成する
|
|
26
|
-
- 場所: `~/.rufio/plugins/`
|
|
27
|
-
- 自由にカスタマイズ可能
|
|
28
|
-
|
|
29
|
-
## プラグインの作成
|
|
30
|
-
|
|
31
|
-
### ステップ1: ディレクトリの準備
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# プラグインディレクトリを作成
|
|
35
|
-
mkdir -p ~/.rufio/plugins
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### ステップ2: プラグインファイルの作成
|
|
39
|
-
|
|
40
|
-
`~/.rufio/plugins/my_plugin.rb`を作成:
|
|
41
|
-
|
|
42
|
-
```ruby
|
|
43
|
-
# frozen_string_literal: true
|
|
44
|
-
|
|
45
|
-
module Rufio
|
|
46
|
-
module Plugins
|
|
47
|
-
class MyPlugin < Plugin
|
|
48
|
-
# プラグイン名(必須)
|
|
49
|
-
def name
|
|
50
|
-
"MyPlugin"
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# 説明(オプション)
|
|
54
|
-
def description
|
|
55
|
-
"私のカスタムプラグイン"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# バージョン(オプション)
|
|
59
|
-
def version
|
|
60
|
-
"1.0.0"
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# コマンドの定義(オプション)
|
|
64
|
-
def commands
|
|
65
|
-
{
|
|
66
|
-
hello: method(:say_hello)
|
|
67
|
-
}
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
private
|
|
71
|
-
|
|
72
|
-
def say_hello
|
|
73
|
-
puts "Hello from MyPlugin!"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### ステップ3: プラグインの読み込み
|
|
81
|
-
|
|
82
|
-
Rufioを起動すると、自動的に`~/.rufio/plugins/`内のプラグインが読み込まれます。
|
|
83
|
-
|
|
84
|
-
## プラグインの設定
|
|
85
|
-
|
|
86
|
-
### 設定ファイルの作成
|
|
87
|
-
|
|
88
|
-
`~/.rufio/config.yml`:
|
|
89
|
-
|
|
90
|
-
```yaml
|
|
91
|
-
plugins:
|
|
92
|
-
# プラグイン名を小文字で指定
|
|
93
|
-
myplugin:
|
|
94
|
-
enabled: true
|
|
95
|
-
|
|
96
|
-
# 無効化したいプラグイン
|
|
97
|
-
fileoperations:
|
|
98
|
-
enabled: false
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### 設定のルール
|
|
102
|
-
|
|
103
|
-
- **プラグイン名**: 大文字小文字を区別せず、小文字に統一されます
|
|
104
|
-
- `MyPlugin`, `myplugin`, `MYPLUGIN` → すべて `myplugin` として扱われます
|
|
105
|
-
- **デフォルト**: 設定に記載のないプラグインは**有効**です
|
|
106
|
-
- **enabled**: `true`で有効、`false`で無効
|
|
107
|
-
|
|
108
|
-
## 高度な機能
|
|
109
|
-
|
|
110
|
-
### 外部gemへの依存
|
|
111
|
-
|
|
112
|
-
プラグインが外部gemに依存する場合、`requires`を使用:
|
|
113
|
-
|
|
114
|
-
```ruby
|
|
115
|
-
module Rufio
|
|
116
|
-
module Plugins
|
|
117
|
-
class AdvancedPlugin < Plugin
|
|
118
|
-
# 依存するgemを宣言
|
|
119
|
-
requires 'httparty', 'nokogiri'
|
|
120
|
-
|
|
121
|
-
def name
|
|
122
|
-
"AdvancedPlugin"
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def description
|
|
126
|
-
"HTTPartyとNokogiriを使用"
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
private
|
|
130
|
-
|
|
131
|
-
def fetch_and_parse
|
|
132
|
-
require 'httparty'
|
|
133
|
-
require 'nokogiri'
|
|
134
|
-
|
|
135
|
-
response = HTTParty.get('https://example.com')
|
|
136
|
-
doc = Nokogiri::HTML(response.body)
|
|
137
|
-
# 処理...
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
gemが不足している場合、以下のメッセージが表示されます:
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
⚠️ Plugin 'AdvancedPlugin' は以下のgemに依存していますが、インストールされていません:
|
|
148
|
-
- httparty
|
|
149
|
-
- nokogiri
|
|
150
|
-
|
|
151
|
-
以下のコマンドでインストールしてください:
|
|
152
|
-
gem install httparty nokogiri
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### コマンドの定義
|
|
156
|
-
|
|
157
|
-
プラグインは複数のコマンドを提供できます:
|
|
158
|
-
|
|
159
|
-
```ruby
|
|
160
|
-
def commands
|
|
161
|
-
{
|
|
162
|
-
search: method(:search_files),
|
|
163
|
-
count: method(:count_files),
|
|
164
|
-
list: method(:list_files)
|
|
165
|
-
}
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
private
|
|
169
|
-
|
|
170
|
-
def search_files
|
|
171
|
-
# 検索処理
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def count_files
|
|
175
|
-
# カウント処理
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def list_files
|
|
179
|
-
# 一覧表示
|
|
180
|
-
end
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## プラグインの例
|
|
184
|
-
|
|
185
|
-
### 1. ファイル検索プラグイン
|
|
186
|
-
|
|
187
|
-
```ruby
|
|
188
|
-
module Rufio
|
|
189
|
-
module Plugins
|
|
190
|
-
class FileSearchPlugin < Plugin
|
|
191
|
-
def name
|
|
192
|
-
"FileSearch"
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def description
|
|
196
|
-
"ファイル名で検索"
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def commands
|
|
200
|
-
{
|
|
201
|
-
search: method(:search_files),
|
|
202
|
-
find_ext: method(:find_by_extension)
|
|
203
|
-
}
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
private
|
|
207
|
-
|
|
208
|
-
def search_files(query = "*")
|
|
209
|
-
Dir.glob("**/*#{query}*").each do |file|
|
|
210
|
-
puts file if File.file?(file)
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def find_by_extension(ext)
|
|
215
|
-
Dir.glob("**/*.#{ext}").each do |file|
|
|
216
|
-
puts file
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### 2. Git統合プラグイン
|
|
225
|
-
|
|
226
|
-
```ruby
|
|
227
|
-
module Rufio
|
|
228
|
-
module Plugins
|
|
229
|
-
class GitPlugin < Plugin
|
|
230
|
-
def name
|
|
231
|
-
"Git"
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def description
|
|
235
|
-
"Git操作の統合"
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def commands
|
|
239
|
-
{
|
|
240
|
-
status: method(:git_status),
|
|
241
|
-
branch: method(:current_branch),
|
|
242
|
-
log: method(:git_log)
|
|
243
|
-
}
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
private
|
|
247
|
-
|
|
248
|
-
def git_status
|
|
249
|
-
system('git status') if git_available?
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
def current_branch
|
|
253
|
-
if git_available?
|
|
254
|
-
branch = `git branch --show-current`.strip
|
|
255
|
-
puts "ブランチ: #{branch}"
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def git_log
|
|
260
|
-
system('git log --oneline -10') if git_available?
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def git_available?
|
|
264
|
-
if system('which git > /dev/null 2>&1')
|
|
265
|
-
true
|
|
266
|
-
else
|
|
267
|
-
puts "⚠️ gitがインストールされていません"
|
|
268
|
-
false
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### 3. システム情報プラグイン
|
|
277
|
-
|
|
278
|
-
```ruby
|
|
279
|
-
module Rufio
|
|
280
|
-
module Plugins
|
|
281
|
-
class SystemInfoPlugin < Plugin
|
|
282
|
-
def name
|
|
283
|
-
"SystemInfo"
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
def description
|
|
287
|
-
"システム情報を表示"
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def commands
|
|
291
|
-
{
|
|
292
|
-
info: method(:show_system_info),
|
|
293
|
-
disk: method(:show_disk_usage)
|
|
294
|
-
}
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
private
|
|
298
|
-
|
|
299
|
-
def show_system_info
|
|
300
|
-
puts "OS: #{RbConfig::CONFIG['host_os']}"
|
|
301
|
-
puts "Ruby: #{RUBY_VERSION}"
|
|
302
|
-
puts "ホームディレクトリ: #{ENV['HOME']}"
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def show_disk_usage
|
|
306
|
-
puts "ディスク使用量:"
|
|
307
|
-
system('df -h .')
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
## プラグインの仕組み
|
|
315
|
-
|
|
316
|
-
### 自動登録
|
|
317
|
-
|
|
318
|
-
プラグインは`Rufio::Plugin`を継承すると、自動的に`PluginManager`に登録されます:
|
|
319
|
-
|
|
320
|
-
```ruby
|
|
321
|
-
class MyPlugin < Plugin
|
|
322
|
-
# 継承した時点で自動登録される
|
|
323
|
-
end
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### 初期化時の依存チェック
|
|
327
|
-
|
|
328
|
-
プラグインがインスタンス化されるとき、`requires`で宣言したgemがインストールされているかチェックされます:
|
|
329
|
-
|
|
330
|
-
```ruby
|
|
331
|
-
def initialize
|
|
332
|
-
check_dependencies! # 自動的に呼ばれる
|
|
333
|
-
end
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## トラブルシューティング
|
|
337
|
-
|
|
338
|
-
### プラグインが読み込まれない
|
|
339
|
-
|
|
340
|
-
**症状**: プラグインを作成したのに動作しない
|
|
341
|
-
|
|
342
|
-
**確認事項**:
|
|
343
|
-
1. ファイルの場所: `~/.rufio/plugins/` に配置されているか
|
|
344
|
-
2. ファイル名: `.rb`拡張子がついているか
|
|
345
|
-
3. 構文エラー: Rubyの構文が正しいか
|
|
346
|
-
4. 設定ファイル: `config.yml`で無効化されていないか
|
|
347
|
-
|
|
348
|
-
### 依存gemが見つからない
|
|
349
|
-
|
|
350
|
-
**症状**: プラグイン起動時にエラーが出る
|
|
351
|
-
|
|
352
|
-
**解決方法**:
|
|
353
|
-
```bash
|
|
354
|
-
# エラーメッセージに表示されたgemをインストール
|
|
355
|
-
gem install <gem名>
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
### プラグインが無効化されている
|
|
359
|
-
|
|
360
|
-
**症状**: プラグインが読み込まれない(エラーなし)
|
|
361
|
-
|
|
362
|
-
**確認**: `~/.rufio/config.yml`を確認
|
|
363
|
-
|
|
364
|
-
```yaml
|
|
365
|
-
plugins:
|
|
366
|
-
myplugin:
|
|
367
|
-
enabled: false # ← これを true に変更
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
## ベストプラクティス
|
|
371
|
-
|
|
372
|
-
### 1. わかりやすい名前をつける
|
|
373
|
-
|
|
374
|
-
```ruby
|
|
375
|
-
def name
|
|
376
|
-
"MyAwesomePlugin" # 明確で分かりやすい名前
|
|
377
|
-
end
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
### 2. 説明を書く
|
|
381
|
-
|
|
382
|
-
```ruby
|
|
383
|
-
def description
|
|
384
|
-
"このプラグインは〇〇の機能を提供します"
|
|
385
|
-
end
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### 3. エラーハンドリング
|
|
389
|
-
|
|
390
|
-
```ruby
|
|
391
|
-
def my_command
|
|
392
|
-
# エラーが起きる可能性のある処理
|
|
393
|
-
result = some_operation
|
|
394
|
-
rescue StandardError => e
|
|
395
|
-
puts "⚠️ エラーが発生しました: #{e.message}"
|
|
396
|
-
end
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### 4. 外部コマンドの確認
|
|
400
|
-
|
|
401
|
-
```ruby
|
|
402
|
-
def command_available?(cmd)
|
|
403
|
-
system("which #{cmd} > /dev/null 2>&1")
|
|
404
|
-
end
|
|
405
|
-
|
|
406
|
-
def my_feature
|
|
407
|
-
unless command_available?('git')
|
|
408
|
-
puts "⚠️ gitがインストールされていません"
|
|
409
|
-
return
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
# 処理...
|
|
413
|
-
end
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
## 参考
|
|
417
|
-
|
|
418
|
-
- サンプルプラグイン: `docs/plugin_example.rb`
|
|
419
|
-
- 組み込みプラグイン: `lib/rufio/plugins/file_operations.rb`
|
|
420
|
-
- プラグイン基底クラス: `lib/rufio/plugin.rb`
|
|
421
|
-
- プラグインマネージャー: `lib/rufio/plugin_manager.rb`
|
|
422
|
-
|
|
423
|
-
## まとめ
|
|
424
|
-
|
|
425
|
-
1. `~/.rufio/plugins/` にRubyファイルを作成
|
|
426
|
-
2. `Rufio::Plugin`を継承したクラスを定義
|
|
427
|
-
3. 必須メソッド`name`を実装
|
|
428
|
-
4. オプションで`description`、`version`、`commands`を実装
|
|
429
|
-
5. Rufio起動時に自動読み込み
|
|
430
|
-
|
|
431
|
-
プラグインシステムを使って、Rufioを自分好みにカスタマイズしてください!
|
data/docs/plugin_example.rb
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Rufio プラグイン実装例
|
|
4
|
-
# このファイルを ~/.rufio/plugins/ にコピーして使用してください
|
|
5
|
-
|
|
6
|
-
module Rufio
|
|
7
|
-
module Plugins
|
|
8
|
-
# ファイル検索プラグインの例
|
|
9
|
-
class FileSearchPlugin < Plugin
|
|
10
|
-
def name
|
|
11
|
-
"FileSearch"
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def description
|
|
15
|
-
"ファイル名で検索する機能"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def version
|
|
19
|
-
"1.0.0"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def commands
|
|
23
|
-
{
|
|
24
|
-
search: method(:search_files),
|
|
25
|
-
find_by_ext: method(:find_by_extension)
|
|
26
|
-
}
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
# ファイル名で検索
|
|
32
|
-
def search_files(query)
|
|
33
|
-
Dir.glob("**/*#{query}*").each do |file|
|
|
34
|
-
puts file
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# 拡張子でファイルを検索
|
|
39
|
-
def find_by_extension(ext)
|
|
40
|
-
Dir.glob("**/*.#{ext}").each do |file|
|
|
41
|
-
puts file
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Git統合プラグインの例(外部gem依存)
|
|
47
|
-
class GitIntegrationPlugin < Plugin
|
|
48
|
-
# gitコマンドが必要
|
|
49
|
-
# requires 'git' # gemが必要な場合
|
|
50
|
-
|
|
51
|
-
def name
|
|
52
|
-
"GitIntegration"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def description
|
|
56
|
-
"Git操作を統合"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def commands
|
|
60
|
-
{
|
|
61
|
-
git_status: method(:show_git_status),
|
|
62
|
-
git_branch: method(:show_current_branch)
|
|
63
|
-
}
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
private
|
|
67
|
-
|
|
68
|
-
def show_git_status
|
|
69
|
-
if system('which git > /dev/null 2>&1')
|
|
70
|
-
system('git status')
|
|
71
|
-
else
|
|
72
|
-
puts "⚠️ gitがインストールされていません"
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def show_current_branch
|
|
77
|
-
if system('which git > /dev/null 2>&1')
|
|
78
|
-
branch = `git branch --show-current`.strip
|
|
79
|
-
puts "現在のブランチ: #{branch}"
|
|
80
|
-
else
|
|
81
|
-
puts "⚠️ gitがインストールされていません"
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# シンプルなユーティリティプラグイン
|
|
87
|
-
class UtilityPlugin < Plugin
|
|
88
|
-
def name
|
|
89
|
-
"Utility"
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def description
|
|
93
|
-
"便利なユーティリティ機能"
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def commands
|
|
97
|
-
{
|
|
98
|
-
disk_usage: method(:show_disk_usage),
|
|
99
|
-
count_files: method(:count_files_in_directory)
|
|
100
|
-
}
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
def show_disk_usage
|
|
106
|
-
puts "ディスク使用量:"
|
|
107
|
-
system('df -h .')
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def count_files_in_directory
|
|
111
|
-
files = Dir.glob('*').select { |f| File.file?(f) }
|
|
112
|
-
dirs = Dir.glob('*').select { |f| File.directory?(f) }
|
|
113
|
-
|
|
114
|
-
puts "ファイル数: #{files.count}"
|
|
115
|
-
puts "ディレクトリ数: #{dirs.count}"
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
data/rufio.gemspec
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/rufio/version'
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = 'rufio'
|
|
7
|
-
spec.version = Rufio::VERSION
|
|
8
|
-
spec.authors = ['masisz']
|
|
9
|
-
spec.email = ['masisz.1567@gmail.com']
|
|
10
|
-
|
|
11
|
-
spec.summary = 'Ruby file manager'
|
|
12
|
-
spec.description = 'A terminal-based file manager inspired by Yazi, written in Ruby with plugin support'
|
|
13
|
-
spec.homepage = 'https://github.com/masisz/rufio'
|
|
14
|
-
spec.license = 'MIT'
|
|
15
|
-
spec.required_ruby_version = '>= 2.7.0'
|
|
16
|
-
|
|
17
|
-
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
18
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
-
spec.metadata['source_code_uri'] = 'https://github.com/masisz/rufio'
|
|
20
|
-
spec.metadata['changelog_uri'] = 'https://github.com/masisz/rufio/blob/main/CHANGELOG.md'
|
|
21
|
-
|
|
22
|
-
spec.files = Dir.chdir(__dir__) do
|
|
23
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
24
|
-
(File.expand_path(f) == __FILE__) ||
|
|
25
|
-
f.start_with?(*%w[test/ spec/ features/ .git .circleci appveyor Gemfile])
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
spec.bindir = 'bin'
|
|
29
|
-
spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
|
|
30
|
-
spec.require_paths = ['lib']
|
|
31
|
-
|
|
32
|
-
spec.add_dependency 'io-console', '~> 0.6'
|
|
33
|
-
spec.add_dependency 'pastel', '~> 0.8'
|
|
34
|
-
spec.add_dependency 'tty-cursor', '~> 0.7'
|
|
35
|
-
spec.add_dependency 'tty-screen', '~> 0.8'
|
|
36
|
-
|
|
37
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
|
38
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
|
39
|
-
spec.add_development_dependency 'rubocop', '~> 1.21'
|
|
40
|
-
end
|