rfmt 1.3.3 → 1.3.4
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 +17 -0
- data/Cargo.lock +1 -1
- data/README.md +89 -3
- data/exe/rfmt +3 -0
- data/ext/rfmt/Cargo.toml +1 -1
- data/lib/rfmt/cli.rb +212 -75
- data/lib/rfmt/version.rb +1 -1
- data/lib/rfmt.rb +1 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ac6a3e001e85e27839f04ba78564e5bc16675818b2603a179f62d7fa35c9062
|
|
4
|
+
data.tar.gz: 4957bbc0de84f4e5c72dacf514ea0e87f211979667a50b53f365c005f1ee710a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 470807974090b7b41d5c9bf5dd437cd34d80cdbb45ed1c9af2d97f93c0a01c88e5e709dcb47b6e077909be7bbb586f7df4eb798e2403dd2186a4d08b6770463e
|
|
7
|
+
data.tar.gz: 6620293ef2c43673eecbf478e2c4d3ba1b79a0ad71e67ec984547c0aeda36e03f7c10d848c646a74bc392e4057aeb2f4c4dc56d2602a96e295bf77f0fbedbf3e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.3.4] - 2026-01-17
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- New `rfmt_fast` executable for optimized performance
|
|
7
|
+
- Automatic parallel processing detection logic
|
|
8
|
+
- Enhanced logging and summary display functionality
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Optimize logging and summary display performance
|
|
12
|
+
- Improve parallel execution logic with automatic detection
|
|
13
|
+
- Update README with new features and usage examples
|
|
14
|
+
- Code formatting improvements with Rubocop compliance
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Logger optimization to reduce overhead
|
|
18
|
+
- Parallel processing logic refinements
|
|
19
|
+
|
|
3
20
|
## [1.3.3] - 2026-01-17
|
|
4
21
|
|
|
5
22
|
### Fixed
|
data/Cargo.lock
CHANGED
data/README.md
CHANGED
|
@@ -166,6 +166,12 @@ Format multiple files:
|
|
|
166
166
|
rfmt lib/**/*.rb
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
+
Format all files in your project:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
rfmt .
|
|
173
|
+
```
|
|
174
|
+
|
|
169
175
|
Check if files need formatting (CI/CD):
|
|
170
176
|
|
|
171
177
|
```bash
|
|
@@ -178,12 +184,92 @@ Show diff without modifying files:
|
|
|
178
184
|
rfmt lib/user.rb --diff
|
|
179
185
|
```
|
|
180
186
|
|
|
187
|
+
Quiet mode (minimal output):
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
rfmt --quiet lib/**/*.rb
|
|
191
|
+
```
|
|
192
|
+
|
|
181
193
|
Enable verbose output for debugging:
|
|
182
194
|
|
|
183
195
|
```bash
|
|
184
|
-
rfmt lib/user.rb
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
rfmt --verbose lib/user.rb
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### Common Options
|
|
200
|
+
|
|
201
|
+
| Option | Description |
|
|
202
|
+
|--------|-------------|
|
|
203
|
+
| `--check` | Check formatting without writing files |
|
|
204
|
+
| `--diff` | Show diff of changes |
|
|
205
|
+
| `--quiet` | Minimal output |
|
|
206
|
+
| `--verbose` | Detailed output with timing |
|
|
207
|
+
|
|
208
|
+
### Output Modes
|
|
209
|
+
|
|
210
|
+
**Normal mode** (default):
|
|
211
|
+
```bash
|
|
212
|
+
$ rfmt app/
|
|
213
|
+
Processing 25 file(s)...
|
|
214
|
+
✓ Formatted app/controllers/users_controller.rb
|
|
215
|
+
✓ Formatted app/models/user.rb
|
|
216
|
+
|
|
217
|
+
✓ Processed 25 files
|
|
218
|
+
(3 formatted, 22 unchanged)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Quiet mode** (`--quiet` or `-q`):
|
|
222
|
+
```bash
|
|
223
|
+
$ rfmt --quiet app/
|
|
224
|
+
✓ 3 files formatted
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Verbose mode** (`--verbose` or `-v`):
|
|
228
|
+
```bash
|
|
229
|
+
$ rfmt --verbose app/
|
|
230
|
+
Processing 25 file(s)...
|
|
231
|
+
Using sequential processing for 25 files
|
|
232
|
+
✓ Formatted app/controllers/users_controller.rb
|
|
233
|
+
✓ app/models/application_record.rb already formatted
|
|
234
|
+
...
|
|
235
|
+
|
|
236
|
+
✓ Processed 25 files
|
|
237
|
+
(3 formatted, 22 unchanged)
|
|
238
|
+
|
|
239
|
+
Details:
|
|
240
|
+
Total files: 25
|
|
241
|
+
Total time: 0.45s
|
|
242
|
+
Files/sec: 55.6
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Parallel Processing
|
|
246
|
+
|
|
247
|
+
rfmt automatically chooses the optimal processing mode:
|
|
248
|
+
|
|
249
|
+
- **< 20 files**: Sequential processing (fastest for small batches)
|
|
250
|
+
- **20-49 files**: Automatic based on average file size
|
|
251
|
+
- **≥ 50 files**: Parallel processing (utilizes multiple cores)
|
|
252
|
+
|
|
253
|
+
You can override this behavior:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Force parallel processing
|
|
257
|
+
rfmt --parallel app/
|
|
258
|
+
|
|
259
|
+
# Force sequential processing
|
|
260
|
+
rfmt --no-parallel app/
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Cache Management
|
|
264
|
+
|
|
265
|
+
rfmt uses caching to improve performance on large codebases:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Clear cache if needed
|
|
269
|
+
rfmt cache clear
|
|
270
|
+
|
|
271
|
+
# View cache statistics
|
|
272
|
+
rfmt cache stats
|
|
187
273
|
```
|
|
188
274
|
|
|
189
275
|
### Ruby API
|
data/exe/rfmt
CHANGED
data/ext/rfmt/Cargo.toml
CHANGED
data/lib/rfmt/cli.rb
CHANGED
|
@@ -44,6 +44,10 @@ module Rfmt
|
|
|
44
44
|
|
|
45
45
|
# Command Line Interface for rfmt
|
|
46
46
|
class CLI < Thor
|
|
47
|
+
# Constants
|
|
48
|
+
PROGRESS_THRESHOLD = 20 # Show progress for file counts >= this
|
|
49
|
+
PROGRESS_INTERVAL = 10 # Update progress every N files
|
|
50
|
+
|
|
47
51
|
class_option :config, type: :string, desc: 'Path to configuration file'
|
|
48
52
|
class_option :verbose, type: :boolean, aliases: '-v', desc: 'Verbose output'
|
|
49
53
|
|
|
@@ -54,10 +58,11 @@ module Rfmt
|
|
|
54
58
|
option :check, type: :boolean, desc: "Check if files are formatted (don't write)"
|
|
55
59
|
option :diff, type: :boolean, desc: 'Show diff of changes'
|
|
56
60
|
option :diff_format, type: :string, default: 'unified', desc: 'Diff format: unified, side_by_side, or color'
|
|
57
|
-
option :parallel, type: :boolean,
|
|
61
|
+
option :parallel, type: :boolean, desc: 'Use parallel processing (auto-disabled for <20 files)'
|
|
58
62
|
option :jobs, type: :numeric, desc: 'Number of parallel jobs (default: CPU count)'
|
|
59
63
|
option :cache, type: :boolean, default: true, desc: 'Use cache to skip unchanged files'
|
|
60
64
|
option :cache_dir, type: :string, desc: 'Cache directory (default: ~/.cache/rfmt)'
|
|
65
|
+
option :quiet, type: :boolean, aliases: '-q', desc: 'Minimal output (errors and summary only)'
|
|
61
66
|
def format(*files)
|
|
62
67
|
config = load_config
|
|
63
68
|
files = files.empty? ? config.files_to_format : files.flatten
|
|
@@ -67,33 +72,32 @@ module Rfmt
|
|
|
67
72
|
return
|
|
68
73
|
end
|
|
69
74
|
|
|
70
|
-
# Initialize cache
|
|
71
|
-
cache =
|
|
72
|
-
|
|
73
|
-
Cache.new(**cache_opts)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Filter files using cache
|
|
77
|
-
if cache
|
|
78
|
-
original_count = files.size
|
|
79
|
-
files = files.select { |file| cache.needs_formatting?(file) }
|
|
80
|
-
skipped = original_count - files.size
|
|
81
|
-
say "ℹ Skipped #{skipped} unchanged file(s) (cached)", :cyan if skipped.positive? && options[:verbose]
|
|
82
|
-
end
|
|
75
|
+
# Initialize and use cache if enabled
|
|
76
|
+
cache = initialize_cache_if_enabled
|
|
77
|
+
files = filter_files_with_cache(files, cache)
|
|
83
78
|
|
|
84
79
|
if files.empty?
|
|
85
|
-
say '✓ All files are already formatted (cached)', :
|
|
80
|
+
say '✓ All files are already formatted (cached)', :cyan
|
|
86
81
|
return
|
|
87
82
|
end
|
|
88
83
|
|
|
89
|
-
# Show progress message
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
# Show progress message (unless in quiet mode)
|
|
85
|
+
unless options[:quiet]
|
|
86
|
+
if files.size == 1
|
|
87
|
+
say "Processing #{files.first}...", :blue
|
|
88
|
+
else
|
|
89
|
+
say "Processing #{files.size} file(s)...", :blue
|
|
90
|
+
end
|
|
94
91
|
end
|
|
95
92
|
|
|
96
|
-
|
|
93
|
+
use_parallel = should_use_parallel?(files)
|
|
94
|
+
|
|
95
|
+
if options[:verbose] && files.size > 1
|
|
96
|
+
mode = use_parallel ? "parallel (#{options[:jobs] || 'auto'} jobs)" : 'sequential'
|
|
97
|
+
say "Using #{mode} processing for #{files.size} files", :blue
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
results = if use_parallel
|
|
97
101
|
format_files_parallel(files)
|
|
98
102
|
else
|
|
99
103
|
format_files_sequential(files)
|
|
@@ -140,6 +144,39 @@ module Rfmt
|
|
|
140
144
|
|
|
141
145
|
private
|
|
142
146
|
|
|
147
|
+
# Intelligently decide whether to use parallel processing
|
|
148
|
+
def should_use_parallel?(files)
|
|
149
|
+
return false if files.size <= 1
|
|
150
|
+
|
|
151
|
+
# Check if parallel option was explicitly set via command line
|
|
152
|
+
# Thor sets options[:parallel] to true/false for --parallel/--no-parallel
|
|
153
|
+
# and nil when not specified
|
|
154
|
+
return options[:parallel] unless options[:parallel].nil?
|
|
155
|
+
|
|
156
|
+
# Auto decision based on workload characteristics
|
|
157
|
+
# Calculate total size for better decision
|
|
158
|
+
total_size = files.sum do |f|
|
|
159
|
+
File.size(f)
|
|
160
|
+
rescue StandardError
|
|
161
|
+
0
|
|
162
|
+
end
|
|
163
|
+
avg_size = total_size / files.size.to_f
|
|
164
|
+
|
|
165
|
+
# Decision matrix:
|
|
166
|
+
# - Less than 20 files: sequential (overhead > benefit)
|
|
167
|
+
# - 20-50 files with small size (<10KB avg): sequential
|
|
168
|
+
# - 20-50 files with large size (>10KB avg): parallel
|
|
169
|
+
# - More than 50 files: always parallel
|
|
170
|
+
|
|
171
|
+
if files.size < 20
|
|
172
|
+
false
|
|
173
|
+
elsif files.size < 50
|
|
174
|
+
avg_size > 10_000 # 10KB threshold
|
|
175
|
+
else
|
|
176
|
+
true
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
143
180
|
def load_config
|
|
144
181
|
if options[:config]
|
|
145
182
|
Configuration.new(file: options[:config])
|
|
@@ -148,25 +185,68 @@ module Rfmt
|
|
|
148
185
|
end
|
|
149
186
|
end
|
|
150
187
|
|
|
188
|
+
def initialize_cache_if_enabled
|
|
189
|
+
return nil unless options[:cache]
|
|
190
|
+
|
|
191
|
+
cache_opts = options[:cache_dir] ? { cache_dir: options[:cache_dir] } : {}
|
|
192
|
+
Cache.new(**cache_opts)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def filter_files_with_cache(files, cache)
|
|
196
|
+
return files unless cache
|
|
197
|
+
|
|
198
|
+
original_count = files.size
|
|
199
|
+
filtered = files.select { |file| cache.needs_formatting?(file) }
|
|
200
|
+
|
|
201
|
+
log_cache_skip(original_count - filtered.size)
|
|
202
|
+
filtered
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def log_cache_skip(skipped_count)
|
|
206
|
+
return unless skipped_count.positive? && options[:verbose]
|
|
207
|
+
|
|
208
|
+
say "ℹ Skipped #{skipped_count} unchanged file(s) (cached)", :cyan
|
|
209
|
+
end
|
|
210
|
+
|
|
151
211
|
def format_files_sequential(files)
|
|
152
|
-
|
|
212
|
+
show_progress = should_show_progress?(files)
|
|
213
|
+
|
|
214
|
+
files.map.with_index do |file, index|
|
|
215
|
+
display_progress(index, files.size) if show_progress && (index % PROGRESS_INTERVAL).zero?
|
|
153
216
|
format_single_file(file)
|
|
154
217
|
end
|
|
155
218
|
end
|
|
156
219
|
|
|
220
|
+
def should_show_progress?(files)
|
|
221
|
+
!options[:quiet] && files.size >= PROGRESS_THRESHOLD
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def display_progress(index, total)
|
|
225
|
+
percentage = ((index.to_f / total) * 100).round
|
|
226
|
+
say "[#{index}/#{total}] #{percentage}% complete...", :blue
|
|
227
|
+
end
|
|
228
|
+
|
|
157
229
|
def format_files_parallel(files)
|
|
158
230
|
require 'parallel'
|
|
159
231
|
|
|
160
|
-
|
|
161
|
-
process_count
|
|
162
|
-
|
|
163
|
-
say "Processing #{files.size} files with #{process_count} parallel jobs...", :blue if options[:verbose]
|
|
232
|
+
process_count = determine_process_count
|
|
233
|
+
log_parallel_processing(files.size, process_count)
|
|
164
234
|
|
|
165
235
|
Parallel.map(files, in_processes: process_count) do |file|
|
|
166
236
|
format_single_file(file)
|
|
167
237
|
end
|
|
168
238
|
end
|
|
169
239
|
|
|
240
|
+
def determine_process_count
|
|
241
|
+
options[:jobs] || Parallel.processor_count
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def log_parallel_processing(file_count, process_count)
|
|
245
|
+
return unless options[:verbose]
|
|
246
|
+
|
|
247
|
+
say "Processing #{file_count} files with #{process_count} parallel jobs...", :blue
|
|
248
|
+
end
|
|
249
|
+
|
|
170
250
|
def format_single_file(file)
|
|
171
251
|
start_time = Time.now
|
|
172
252
|
source = File.read(file)
|
|
@@ -191,69 +271,126 @@ module Rfmt
|
|
|
191
271
|
end
|
|
192
272
|
|
|
193
273
|
def handle_results(results, cache = nil)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
274
|
+
stats = process_results(results, cache)
|
|
275
|
+
stats[:total_duration] = results.sum { |r| r[:duration] || 0 }
|
|
276
|
+
cache&.save
|
|
277
|
+
display_summary(stats, results.size)
|
|
278
|
+
exit(1) if should_exit_with_error?(stats)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def process_results(results, cache)
|
|
282
|
+
stats = { changed: 0, errors: 0, failed: 0, duration: 0 }
|
|
197
283
|
|
|
198
284
|
results.each do |result|
|
|
199
285
|
if result[:error]
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
286
|
+
handle_error_result(result, stats)
|
|
287
|
+
elsif result[:changed]
|
|
288
|
+
handle_changed_result(result, stats, cache)
|
|
289
|
+
else
|
|
290
|
+
handle_unchanged_result(result, cache)
|
|
203
291
|
end
|
|
292
|
+
end
|
|
204
293
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if options[:check]
|
|
209
|
-
say "#{result[:file]} needs formatting", :yellow
|
|
210
|
-
failed_count += 1
|
|
211
|
-
show_diff(result[:file], result[:original], result[:formatted]) if options[:diff]
|
|
212
|
-
elsif options[:diff]
|
|
213
|
-
show_diff(result[:file], result[:original], result[:formatted])
|
|
214
|
-
elsif options[:write]
|
|
215
|
-
File.write(result[:file], result[:formatted])
|
|
216
|
-
# Always show formatted files (not just in verbose mode)
|
|
217
|
-
say "✓ Formatted #{result[:file]}", :green
|
|
218
|
-
|
|
219
|
-
# Update cache after successful write
|
|
220
|
-
cache&.mark_formatted(result[:file])
|
|
221
|
-
else
|
|
222
|
-
puts result[:formatted]
|
|
223
|
-
end
|
|
224
|
-
else
|
|
225
|
-
# Show already formatted files in non-check mode
|
|
226
|
-
say "✓ #{result[:file]} already formatted", :cyan unless options[:check]
|
|
294
|
+
stats
|
|
295
|
+
end
|
|
227
296
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
297
|
+
def handle_error_result(result, stats)
|
|
298
|
+
say "Error in #{result[:file]}: #{result[:error]}", :red
|
|
299
|
+
stats[:errors] += 1
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def handle_changed_result(result, stats, cache)
|
|
303
|
+
stats[:changed] += 1
|
|
304
|
+
|
|
305
|
+
if options[:check]
|
|
306
|
+
say "#{result[:file]} needs formatting", :yellow
|
|
307
|
+
stats[:failed] += 1
|
|
308
|
+
show_diff(result[:file], result[:original], result[:formatted]) if options[:diff]
|
|
309
|
+
elsif options[:diff]
|
|
310
|
+
show_diff(result[:file], result[:original], result[:formatted])
|
|
311
|
+
elsif options[:write]
|
|
312
|
+
write_formatted_file(result, cache)
|
|
313
|
+
else
|
|
314
|
+
puts result[:formatted]
|
|
231
315
|
end
|
|
316
|
+
end
|
|
232
317
|
|
|
233
|
-
|
|
234
|
-
|
|
318
|
+
def handle_unchanged_result(result, cache)
|
|
319
|
+
say "✓ #{result[:file]} already formatted", :white if options[:verbose] && !options[:check]
|
|
320
|
+
cache&.mark_formatted(result[:file])
|
|
321
|
+
end
|
|
235
322
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
323
|
+
def write_formatted_file(result, cache)
|
|
324
|
+
File.write(result[:file], result[:formatted])
|
|
325
|
+
say "✓ Formatted #{result[:file]}", :green unless options[:quiet]
|
|
326
|
+
cache&.mark_formatted(result[:file])
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def display_summary(stats, total_files)
|
|
330
|
+
@last_stats = stats # Store for verbose details
|
|
331
|
+
unchanged_count = total_files - stats[:changed] - stats[:errors]
|
|
332
|
+
|
|
333
|
+
if stats[:errors].positive?
|
|
334
|
+
display_error_summary(stats[:errors])
|
|
335
|
+
elsif options[:check] && stats[:failed].positive?
|
|
336
|
+
display_check_failed_summary(stats[:failed])
|
|
337
|
+
elsif options[:quiet]
|
|
338
|
+
display_quiet_summary(stats[:changed])
|
|
246
339
|
else
|
|
247
|
-
|
|
340
|
+
display_normal_summary(stats[:changed], unchanged_count, total_files)
|
|
248
341
|
end
|
|
249
342
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
343
|
+
display_verbose_details(total_files) if options[:verbose] && !options[:quiet]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def display_error_summary(error_count)
|
|
347
|
+
say "\n✗ Failed: #{error_count} error(s) occurred", :red
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def display_check_failed_summary(failed_count)
|
|
351
|
+
say "\n✗ Check failed: #{failed_count} file(s) need formatting", :yellow
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def display_quiet_summary(changed_count)
|
|
355
|
+
say "✓ #{changed_count} files formatted", :cyan if changed_count.positive?
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def display_normal_summary(changed_count, unchanged_count, total_files)
|
|
359
|
+
if total_files == 1
|
|
360
|
+
if changed_count.positive?
|
|
361
|
+
say "\n✓ Formatted 1 file", :cyan
|
|
362
|
+
else
|
|
363
|
+
say "\n✓ File is already formatted", :cyan
|
|
364
|
+
end
|
|
365
|
+
else
|
|
366
|
+
say "\n✓ Processed #{total_files} files", :cyan
|
|
367
|
+
display_file_breakdown(changed_count, unchanged_count)
|
|
254
368
|
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def display_file_breakdown(changed_count, unchanged_count)
|
|
372
|
+
return unless changed_count.positive? || unchanged_count.positive?
|
|
373
|
+
|
|
374
|
+
parts = []
|
|
375
|
+
parts << "#{changed_count} formatted" if changed_count.positive?
|
|
376
|
+
parts << "#{unchanged_count} unchanged" if unchanged_count.positive?
|
|
377
|
+
say " (#{parts.join(', ')})", :white
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def display_verbose_details(total_files)
|
|
381
|
+
say "\nDetails:", :blue
|
|
382
|
+
say " Total files: #{total_files}", :blue
|
|
383
|
+
|
|
384
|
+
# Duration is collected if available
|
|
385
|
+
return unless defined?(@last_stats) && @last_stats[:total_duration]
|
|
386
|
+
|
|
387
|
+
duration = @last_stats[:total_duration].round(2)
|
|
388
|
+
say " Total time: #{duration}s", :blue
|
|
389
|
+
say " Files/sec: #{(total_files / duration).round(1)}", :blue if duration.positive?
|
|
390
|
+
end
|
|
255
391
|
|
|
256
|
-
|
|
392
|
+
def should_exit_with_error?(stats)
|
|
393
|
+
(options[:check] && stats[:failed].positive?) || stats[:errors].positive?
|
|
257
394
|
end
|
|
258
395
|
|
|
259
396
|
def show_diff(file, original, formatted)
|
data/lib/rfmt/version.rb
CHANGED
data/lib/rfmt.rb
CHANGED
|
@@ -102,14 +102,9 @@ module Rfmt
|
|
|
102
102
|
# @param force [Boolean] Overwrite existing file if true
|
|
103
103
|
# @return [Boolean] true if file was created, false if already exists
|
|
104
104
|
def self.init(path = '.rfmt.yml', force: false)
|
|
105
|
-
if File.exist?(path) && !force
|
|
106
|
-
warn "Configuration file already exists: #{path}"
|
|
107
|
-
warn 'Use force: true to overwrite'
|
|
108
|
-
return false
|
|
109
|
-
end
|
|
105
|
+
return false if File.exist?(path) && !force
|
|
110
106
|
|
|
111
107
|
File.write(path, DEFAULT_CONFIG)
|
|
112
|
-
puts "Created rfmt configuration file: #{path}"
|
|
113
108
|
true
|
|
114
109
|
end
|
|
115
110
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rfmt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fujitani sora
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|