cc 1.1.5 → 1.2.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/cc.rb +1 -0
  3. data/shell-tools.rb +264 -0
  4. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f4f552fd0a586d4321f95a788b210de1ae859f187f03ff92dff524c16021d49
4
- data.tar.gz: 857478152baa7bc3ced3d103f8f8eb6797989563d7242e25dc7b7e1564b98be2
3
+ metadata.gz: 9d516f93659f22c9c1cc96949b6b28a18f9b0a4488df88d0534b93e02d384ec1
4
+ data.tar.gz: cacf6949dfacd5676274f8189eb6f103ab10bbd8449e97d5ed719647c39fbb83
5
5
  SHA512:
6
- metadata.gz: de7cb9814ffcc3b8acae9c5ad48b5a46e61d7524a28c4cd44ae7a8bd6de7ae8374bfb19474cd0cfcd7174e399c11acf1867a3bd48fb959f526bdf6cc113a8e9b
7
- data.tar.gz: 81d1bcb0123efe87e9a037364cfc4da673ccf6804b0bcadab97f4da30d9385ac3c9035c5f61a65894169bde84aad2487c8f3f47e87c3c47d690714d5b2d349bf
6
+ metadata.gz: 439bf5ca21f7ebc3ae75e9f15864e739554aed7d1020a686a1890bf75defcf7e2ce338ae9f47266eda782c8cb8589ae79b9c9581aa0bef7b9bebdebb3305a0d6
7
+ data.tar.gz: 82b49a5413e171490cb09f9ba0057c5efa39642c7c4814b1463fd90b272225d52e547bb23b87188797358f42f14d92a5d953aa11af6acf9e6141f816fde196ea
data/cc.rb CHANGED
@@ -10,6 +10,7 @@ $modlist = [
10
10
  'file',
11
11
  'kernel',
12
12
  'monkey-patch',
13
+ 'shell-tools',
13
14
  'number',
14
15
  'regexp',
15
16
  'string',
data/shell-tools.rb ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'io/console'
5
+
6
+ class ProgressBar
7
+ # 预设主题
8
+ THEMES = {
9
+ classic: { fill: '█', empty: '░', left: '[', right: ']', arrow: '>' },
10
+ modern: { fill: '●', empty: '○', left: '', right: '', arrow: '▶' },
11
+ blocks: { fill: '■', empty: '□', left: '│', right: '│', arrow: '▶' },
12
+ dots: { fill: '◉', empty: '◎', left: '⟨', right: '⟩', arrow: '→' },
13
+ minimal: { fill: '=', empty: '-', left: '[', right: ']', arrow: '>' },
14
+ hearts: { fill: '♥', empty: '♡', left: ' ', right: ' ', arrow: '💕' }
15
+ }
16
+
17
+ attr_reader :total, :current, :start_time
18
+
19
+ def initialize(total, title: "Processing", theme: :modern, width: 40, show_percentage: true, show_eta: true, color: true)
20
+ @total = total
21
+ @current = 0
22
+ @title = title
23
+ @theme = THEMES[theme] || THEMES[:modern]
24
+ @width = width
25
+ @show_percentage = show_percentage
26
+ @show_eta = show_eta
27
+ @color = color
28
+ @start_time = Time.now
29
+ @last_update = 0
30
+ @mutex = Mutex.new
31
+
32
+ # ANSI 颜色代码
33
+ @colors = {
34
+ reset: "\e[0m",
35
+ bold: "\e[1m",
36
+ green: "\e[32m",
37
+ yellow: "\e[33m",
38
+ blue: "\e[34m",
39
+ magenta: "\e[35m",
40
+ cyan: "\e[36m",
41
+ gray: "\e[90m"
42
+ }
43
+
44
+ # 隐藏光标
45
+ print "\e[?25l"
46
+ end
47
+
48
+ # 更新进度
49
+ def update(step = 1)
50
+ @mutex.synchronize do
51
+ @current += step
52
+ @current = @total if @current > @total
53
+ refresh if should_refresh?
54
+ end
55
+ end
56
+
57
+ # 直接设置进度
58
+ def set(value)
59
+ @mutex.synchronize do
60
+ @current = [[value, @total].min, 0].max
61
+ refresh
62
+ end
63
+ end
64
+
65
+ # 完成进度条
66
+ def finish(message: "Done!")
67
+ @mutex.synchronize do
68
+ @current = @total
69
+ refresh
70
+ puts # 换行
71
+ show_cursor
72
+ puts colorize(message, :green) unless message.empty?
73
+ end
74
+ end
75
+
76
+ # 显示统计信息
77
+ def stats
78
+ elapsed = Time.now - @start_time
79
+ rate = @current / elapsed rescue 0
80
+ {
81
+ total: @total,
82
+ current: @current,
83
+ percentage: (@current.to_f / @total * 100).round(1),
84
+ elapsed: format_time(elapsed),
85
+ eta: format_time(eta),
86
+ rate: rate.round(2)
87
+ }
88
+ end
89
+
90
+ # 清理资源
91
+ def dispose
92
+ show_cursor
93
+ end
94
+
95
+ private
96
+
97
+ def should_refresh?
98
+ now = Time.now.to_f
99
+ return false if now - @last_update < 0.05 # 限制刷新率 20fps
100
+ @last_update = now
101
+ true
102
+ end
103
+
104
+ def refresh
105
+ percentage = @current.to_f / @total
106
+ filled = (percentage * @width).round
107
+ empty = @width - filled
108
+
109
+ bar = @theme[:fill] * filled +
110
+ (@current < @total ? @theme[:arrow] : @theme[:fill]) +
111
+ @theme[:empty] * [empty - 1, 0].max
112
+
113
+ # 构建输出字符串
114
+ parts = []
115
+
116
+ # 标题
117
+ parts << colorize(sprintf("%-15s", @title), :bold)
118
+
119
+ # 进度条
120
+ bar_color = percentage >= 1.0 ? :green : (percentage > 0.5 ? :cyan : :yellow)
121
+ parts << "#{@theme[:left]}#{colorize(bar, bar_color)}#{@theme[:right]}"
122
+
123
+ # 百分比
124
+ if @show_percentage
125
+ parts << colorize(sprintf("%6.1f%%", percentage * 100), :magenta)
126
+ end
127
+
128
+ # 计数
129
+ parts << colorize("[#{@current}/#{@total}]", :gray)
130
+
131
+ # ETA
132
+ if @show_eta && @current > 0 && @current < @total
133
+ parts << colorize("ETA: #{format_time(eta)}", :blue)
134
+ end
135
+
136
+ # 清除行并输出
137
+ print "\r\e[K" + parts.join(' ')
138
+ $stdout.flush
139
+ end
140
+
141
+ def eta
142
+ return 0 if @current == 0
143
+ elapsed = Time.now - @start_time
144
+ remaining = @total - @current
145
+ (elapsed / @current) * remaining
146
+ end
147
+
148
+ def format_time(seconds)
149
+ return "0s" if seconds < 1
150
+ if seconds < 60
151
+ "#{seconds.round}s"
152
+ elsif seconds < 3600
153
+ "#{(seconds / 60).floor}m #{(seconds % 60).round}s"
154
+ else
155
+ "#{(seconds / 3600).floor}h #{((seconds % 3600) / 60).floor}m"
156
+ end
157
+ end
158
+
159
+ def colorize(text, color)
160
+ return text unless @color
161
+ "#{@colors[color]}#{text}#{@colors[:reset]}"
162
+ end
163
+
164
+ def show_cursor
165
+ print "\e[?25h"
166
+ end
167
+ end
168
+
169
+ # 辅助方法(用于示例中的颜色输出)
170
+ def colorize(text, color)
171
+ colors = { green: "\e[32m", yellow: "\e[33m", gray: "\e[90m", reset: "\e[0m" }
172
+ "#{colors[color]}#{text}#{colors[:reset]}"
173
+ end
174
+
175
+ =begin
176
+ # ==================== 使用示例 ====================
177
+ puts "🚀 Ruby Fancy Progress Bar Demo"
178
+ puts "=" * 50
179
+
180
+ # 示例 1: 基础用法
181
+ puts "\n📊 示例 1: 基础文件处理"
182
+ bar = ProgressBar.new(100, title: "Downloading", theme: :modern)
183
+ 100.times do |i|
184
+ sleep(0.03) # 模拟工作
185
+ bar.update
186
+ end
187
+ bar.finish(message: "✅ 下载完成!")
188
+
189
+ # 示例 2: 不同主题展示
190
+ puts "\n🎨 示例 2: 主题展示"
191
+ [:classic, :blocks, :dots, :minimal].each do |theme_name|
192
+ bar = ProgressBar.new(50, title: theme_name.to_s, theme: theme_name, width: 30)
193
+ 50.times do
194
+ sleep(0.02)
195
+ bar.update
196
+ end
197
+ bar.finish(message: "")
198
+ end
199
+
200
+ # 示例 3: 批量任务处理(带错误处理)
201
+ puts "\n📁 示例 3: 批量文件处理"
202
+ files = (1..20).map { |n| "file_#{n}.txt" }
203
+ bar = ProgressBar.new(files.size, title: "Processing", theme: :hearts, color: true)
204
+ processed = []
205
+ files.each do |file|
206
+ sleep(0.1) # 模拟处理时间
207
+ processed << file
208
+ bar.update
209
+ # 模拟偶尔的错误
210
+ if rand < 0.1
211
+ print "\n⚠️ #{colorize("警告: #{file} 处理异常", :yellow)}"
212
+ end
213
+ end
214
+ bar.finish(message: "✨ 处理了 #{processed.size} 个文件")
215
+
216
+ # 示例 4: 嵌套进度条(多阶段任务)
217
+ puts "\n🏗️ 示例 4: 多阶段构建任务"
218
+ phases = [
219
+ { name: "Compiling", items: 30 },
220
+ { name: "Testing", items: 20 },
221
+ { name: "Packaging", items: 15 }
222
+ ]
223
+ phases.each do |phase|
224
+ puts "\n阶段: #{phase[:name]}"
225
+ bar = ProgressBar.new(phase[:items], title: phase[:name], theme: :modern)
226
+ phase[:items].times do
227
+ sleep(0.05)
228
+ bar.update
229
+ end
230
+ bar.finish(message: "")
231
+ end
232
+ puts colorize("🎉 所有阶段完成!", :green)
233
+
234
+ # 示例 5: 实时速度显示(大数据处理)
235
+ puts "\n⚡ 示例 5: 大数据处理(带实时统计)"
236
+ total_items = 1000
237
+ bar = ProgressBar.new(total_items, title: "BigData", theme: :blocks, width: 50)
238
+ total_items.times do |i|
239
+ sleep(0.01) # 模拟快速处理
240
+ # 每 100 个显示一次统计
241
+ if i % 100 == 0 && i > 0
242
+ s = bar.stats
243
+ print "\n #{colorize("速度: #{s[:rate]} items/s | 已用: #{s[:elapsed]} | 剩余: #{s[:eta]}", :gray)}"
244
+ end
245
+ bar.update
246
+ end
247
+ bar.finish
248
+
249
+ # 示例 6: 手动控制进度(非均匀任务)
250
+ puts "\n🎮 示例 6: 手动进度控制(非均匀任务)"
251
+ bar = ProgressBar.new(100, title: "Uploading", theme: :dots)
252
+ # 模拟不同大小的文件上传
253
+ uploads = [10, 25, 5, 30, 20, 10]
254
+ uploads.each_with_index do |size, idx|
255
+ sleep(0.3) # 模拟上传时间
256
+ bar.set(bar.current + size)
257
+ print "\n 上传了 chunk_#{idx + 1}.bin (#{size}MB)"
258
+ end
259
+ bar.finish(message: "上传完成")
260
+ # 确保光标显示
261
+ print "\e[?25h"
262
+ puts "\n" + "=" * 50
263
+ puts "✨ 所有演示完成! 你可以复制 ProgressBar 类到你的项目中使用。"
264
+ =end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt
@@ -32,6 +32,7 @@ files:
32
32
  - monkey-patch.rb
33
33
  - number.rb
34
34
  - regexp.rb
35
+ - shell-tools.rb
35
36
  - string.rb
36
37
  - tree.rb
37
38
  homepage: https://github.com/ChenMeng1365/custom-core