clir 0.22.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 +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +229 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +44 -0
- data/Manual/Manuel_fr.md +222 -0
- data/Manual/Manuel_fr.pdf +0 -0
- data/README.md +63 -0
- data/REFLEXIONS.md +8 -0
- data/Rakefile +10 -0
- data/TODO.md +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/clir.gemspec +40 -0
- data/lib/clir/Array.ext.rb +9 -0
- data/lib/clir/CLI.mod.rb +237 -0
- data/lib/clir/CSV_extension.rb +177 -0
- data/lib/clir/Config.cls.rb +25 -0
- data/lib/clir/Date_utils.rb +161 -0
- data/lib/clir/File_extension.rb +127 -0
- data/lib/clir/Integer.ext.rb +43 -0
- data/lib/clir/Labelizor.rb +231 -0
- data/lib/clir/Replayer.cls.rb +90 -0
- data/lib/clir/String.ext.rb +304 -0
- data/lib/clir/Symbol.ext.rb +20 -0
- data/lib/clir/TTY-Prompt.cls.rb +415 -0
- data/lib/clir/Table.rb +369 -0
- data/lib/clir/console_methods.rb +42 -0
- data/lib/clir/helpers_methods.rb +68 -0
- data/lib/clir/state_methods.rb +48 -0
- data/lib/clir/utils_methods.rb +57 -0
- data/lib/clir/utils_numbers.rb +50 -0
- data/lib/clir/version.rb +3 -0
- data/lib/clir.rb +36 -0
- metadata +136 -0
data/lib/clir/Table.rb
ADDED
@@ -0,0 +1,369 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
=begin
|
4
|
+
|
5
|
+
Class Clir::Table
|
6
|
+
-----------------
|
7
|
+
Construction d'une table en console
|
8
|
+
|
9
|
+
Contrairement à Labelizor qui ne construit des tables qu'à
|
10
|
+
deux colonnes, avec <<< libelle, valeur >>>, cette classe permet
|
11
|
+
de construire des affichages à plusieurs colonnes.
|
12
|
+
|
13
|
+
|
14
|
+
@usage
|
15
|
+
|
16
|
+
# Pour définir la table
|
17
|
+
tb = CLITable.new(
|
18
|
+
colonnes_totaux: {3 => :euros},
|
19
|
+
# On comptera le total de la 3e colonnes et l'on transformera
|
20
|
+
# toutes les valeurs en euros (avec la méthode :€)
|
21
|
+
header: ["TITRE", "NOMBRE", "REDEVANCE"],
|
22
|
+
gutter: 3,
|
23
|
+
align: {right: [3]}
|
24
|
+
# La 3e colonne sera alignée à droite (sur le '€' ici)
|
25
|
+
)
|
26
|
+
|
27
|
+
# Pour ajouter une ligne
|
28
|
+
tb << [titre, nombre, redevance]
|
29
|
+
|
30
|
+
# Pour l'afficher
|
31
|
+
tb.display
|
32
|
+
|
33
|
+
=end
|
34
|
+
module Clir
|
35
|
+
class Table
|
36
|
+
attr_reader :params
|
37
|
+
|
38
|
+
attr_reader :column_count
|
39
|
+
|
40
|
+
##
|
41
|
+
# Instanciation
|
42
|
+
#
|
43
|
+
# @param params {Hash}
|
44
|
+
#
|
45
|
+
# Définition générale de la table.
|
46
|
+
#
|
47
|
+
# :colonnes_totaux {Hash} Table des indices (1-start) des
|
48
|
+
# colonnes dont il faut faire la somme.
|
49
|
+
# Avec en clé l'indice réel de la colonne et
|
50
|
+
# en valeur soit nil pour un nombre normal,
|
51
|
+
# soit :euros pour une somme financière.
|
52
|
+
# Si cette donnée est définie, une nouvelle
|
53
|
+
# ligne sera ajoutée au bout du tableau avec
|
54
|
+
# la somme de cette colonne.
|
55
|
+
#
|
56
|
+
# :header {Array} Entête, nom de chaque colonne. On peut
|
57
|
+
# utiliser les retours de chariot pour faire deux
|
58
|
+
# lignes.
|
59
|
+
# :gutter {Integer} Goutière entre chaque colonne. 4 par défaut
|
60
|
+
# :indent {Integer} Indentation initiale, en nombre d'espaces
|
61
|
+
#
|
62
|
+
#
|
63
|
+
# :char_separator {String} La caractère pour faire les lignes
|
64
|
+
# horizontales de séparation. Une étoile par
|
65
|
+
# défaut.
|
66
|
+
#
|
67
|
+
# @option params [Hash] :align Définition de l'alignement dans les colonnes.
|
68
|
+
# En clé l'indice 1-start de la colonne, en
|
69
|
+
# valeur une valeur parmi :right, :left et :center
|
70
|
+
# @option params [Array|Hash|Integer] :max_widths
|
71
|
+
# Max width for columns. If it's a integer, it's
|
72
|
+
# the max width for each column.
|
73
|
+
# If it's an Array, it's the definition of each
|
74
|
+
# column in order. For example, [4, 5, 6] means
|
75
|
+
# 4 signs for the first column, 5 for the second
|
76
|
+
# one and 6 for the third column. Columns without
|
77
|
+
# max widths must have nil value.
|
78
|
+
# If it's a Hash, the key is the column index
|
79
|
+
# (1-start) and the value is the max lenght in
|
80
|
+
# signs.
|
81
|
+
#
|
82
|
+
def initialize(params = nil)
|
83
|
+
@params = params || {}
|
84
|
+
@lines = []
|
85
|
+
add_header_lines
|
86
|
+
end
|
87
|
+
|
88
|
+
def display
|
89
|
+
#
|
90
|
+
# On définit l'alignement de chaque colonne
|
91
|
+
#
|
92
|
+
define_colonnes_align
|
93
|
+
|
94
|
+
#
|
95
|
+
# On fait les totaux des colonnes désignées
|
96
|
+
#
|
97
|
+
formate_cells_totaux unless colonnes_totaux.nil?
|
98
|
+
|
99
|
+
#
|
100
|
+
# On mesure les largeurs des colonnes
|
101
|
+
#
|
102
|
+
calc_column_widths
|
103
|
+
|
104
|
+
#
|
105
|
+
# On ajoute une séparation à la toute fin
|
106
|
+
#
|
107
|
+
add(separation)
|
108
|
+
|
109
|
+
#
|
110
|
+
# Séparation toujours
|
111
|
+
#
|
112
|
+
puts "\n\n"
|
113
|
+
|
114
|
+
#
|
115
|
+
# Écriture du titre (if any)
|
116
|
+
#
|
117
|
+
traite_titre if @params[:title]
|
118
|
+
|
119
|
+
#
|
120
|
+
# Boucle sur chaque ligne d'entête
|
121
|
+
#
|
122
|
+
@header_lines.each do |cols|
|
123
|
+
traite_colonnes( cols, is_header = true )
|
124
|
+
end
|
125
|
+
#
|
126
|
+
# Boucle sur chaque ligne de données
|
127
|
+
#
|
128
|
+
@lines.each do |cols|
|
129
|
+
traite_colonnes( cols, is_header = false)
|
130
|
+
end
|
131
|
+
puts "\n\n"
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def traite_titre
|
136
|
+
puts "#{indent}#{char_separator} #{params[:title].upcase} #{char_separator}\n#{indent}#{separation}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def traite_colonnes(cols, for_header = false)
|
140
|
+
line =
|
141
|
+
case cols
|
142
|
+
when Array
|
143
|
+
' ' + cols.collect.with_index do |col, idx|
|
144
|
+
alignment = for_header ? :ljust : colonne_aligns[idx]
|
145
|
+
col = col.to_s
|
146
|
+
if col.length > @column_widths[idx]
|
147
|
+
col[0...(@column_widths[idx] - 1)] + '…'
|
148
|
+
else
|
149
|
+
col.to_s.send(alignment, @column_widths[idx])
|
150
|
+
end
|
151
|
+
end.join(gutter) + ' '
|
152
|
+
when :separation then separation
|
153
|
+
when String then cols
|
154
|
+
end
|
155
|
+
#
|
156
|
+
# Écriture de la ligne
|
157
|
+
#
|
158
|
+
puts indent + line
|
159
|
+
end
|
160
|
+
|
161
|
+
def add(ary)
|
162
|
+
@lines << ary
|
163
|
+
end
|
164
|
+
alias :<< :add
|
165
|
+
|
166
|
+
# Building header
|
167
|
+
#
|
168
|
+
# On part toujours du principe qu'il y a deux lignes, et si
|
169
|
+
# l'une est vide, on n'en met qu'une seule.
|
170
|
+
def add_header_lines
|
171
|
+
@header_lines = []
|
172
|
+
return if params[:header].nil?
|
173
|
+
two_lines = false
|
174
|
+
line1 = []
|
175
|
+
line2 = []
|
176
|
+
params[:header].each do |lib|
|
177
|
+
lib1, lib2 =
|
178
|
+
if lib.match?("\n")
|
179
|
+
two_lines = true
|
180
|
+
lib.split("\n")
|
181
|
+
else
|
182
|
+
['', lib]
|
183
|
+
end
|
184
|
+
line1 << lib1
|
185
|
+
line2 << lib2
|
186
|
+
end
|
187
|
+
@column_count = line2.count
|
188
|
+
@header_lines << line1 if two_lines
|
189
|
+
@header_lines << line2
|
190
|
+
@header_lines << :separation
|
191
|
+
end
|
192
|
+
|
193
|
+
def table_width
|
194
|
+
@table_width ||= @column_widths.sum + (gutter_width * (column_count - 1))
|
195
|
+
end
|
196
|
+
|
197
|
+
def separation
|
198
|
+
@separation ||= char_separator * (table_width + 4)
|
199
|
+
end
|
200
|
+
|
201
|
+
def char_separator
|
202
|
+
@char_separator ||= params[:char_separator] || '*'
|
203
|
+
end
|
204
|
+
|
205
|
+
def gutter
|
206
|
+
@gutter ||= ' ' * gutter_width
|
207
|
+
end
|
208
|
+
|
209
|
+
def gutter_width
|
210
|
+
@gutter_width ||= params[:gutter] || 4
|
211
|
+
end
|
212
|
+
|
213
|
+
def indent
|
214
|
+
@indent ||= ' ' * (params[:indent] || 2)
|
215
|
+
end
|
216
|
+
|
217
|
+
def align
|
218
|
+
@align ||= params[:align]
|
219
|
+
end
|
220
|
+
|
221
|
+
def max_widths
|
222
|
+
@max_widths ||= params[:max_widths]
|
223
|
+
end
|
224
|
+
|
225
|
+
def colonnes_totaux
|
226
|
+
@colonnes_totaux ||= params[:colonnes_totaux]
|
227
|
+
end
|
228
|
+
|
229
|
+
# Alignement des colonnes
|
230
|
+
def colonne_aligns
|
231
|
+
@colonne_aligns
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def define_colonnes_align
|
238
|
+
#
|
239
|
+
# Par défaut tous les colonnes sont alignés à gauche
|
240
|
+
#
|
241
|
+
@colonne_aligns = Array.new(column_count, :ljust)
|
242
|
+
return if align.nil?
|
243
|
+
align.each do |indice_colonne, alignment|
|
244
|
+
|
245
|
+
@colonne_aligns[indice_colonne - 1] = case alignment
|
246
|
+
when :right then :rjust
|
247
|
+
when :left then :ljust
|
248
|
+
when :center then :cjust
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
#
|
254
|
+
# Note : requis avant de compter la largeur des colonnes, car
|
255
|
+
# les totaux peuvent changer la donne
|
256
|
+
#
|
257
|
+
def formate_cells_totaux
|
258
|
+
#
|
259
|
+
# On fait la ligne de total
|
260
|
+
#
|
261
|
+
make_totaux_line
|
262
|
+
#
|
263
|
+
# On formate toutes les valeurs. Car elles ont été données
|
264
|
+
# en nombre (x) et non pas en euros (€(x)) pour pouvoir calcu-
|
265
|
+
# ler les totaux.
|
266
|
+
#
|
267
|
+
@lines.each do |cols|
|
268
|
+
next unless cols.is_a?(Array)
|
269
|
+
colonnes_totaux.each do |idx, type|
|
270
|
+
real_idx = idx - 1
|
271
|
+
case type
|
272
|
+
when NilClass
|
273
|
+
# Rien à faire
|
274
|
+
when Symbol
|
275
|
+
cols[real_idx] = send(type, cols[real_idx])
|
276
|
+
when Proc
|
277
|
+
cols[real_idx] = type.call(cols[real_idx])
|
278
|
+
else
|
279
|
+
cols[real_idx] = "#{cols[real_idx]} #{type}"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
# Calc of the column width. Either defined by widthest value or
|
287
|
+
# header, either by max_widths option parameter.
|
288
|
+
#
|
289
|
+
def calc_column_widths
|
290
|
+
#
|
291
|
+
# Pour collecter les largeurs de colonnes
|
292
|
+
#
|
293
|
+
@column_widths = Array.new(column_count, 0)
|
294
|
+
#
|
295
|
+
# Pour savoir si les largeurs maximales sont définies et
|
296
|
+
# prendre les valeurs.
|
297
|
+
# @rappel : les largeurs peuvent être définies par un integer
|
298
|
+
# un Hash ou un Array.
|
299
|
+
#
|
300
|
+
maxes = case max_widths
|
301
|
+
when Integer
|
302
|
+
Array.new(column_count, max_widths)
|
303
|
+
when Hash
|
304
|
+
cw = Array.new(column_count, nil)
|
305
|
+
max_widths.each do |idx_col, val|
|
306
|
+
cw[idx_col - 1] = val
|
307
|
+
end
|
308
|
+
cw
|
309
|
+
when Array
|
310
|
+
max_widths # must be all defined
|
311
|
+
else
|
312
|
+
Array.new(column_count, nil)
|
313
|
+
end
|
314
|
+
#
|
315
|
+
# Les largeurs de colonne seraient-elles déjà toutes définies ?
|
316
|
+
#
|
317
|
+
zero_found = false
|
318
|
+
maxes.each do |width|
|
319
|
+
zero_found = true and break if width == 0 || width.nil?
|
320
|
+
end
|
321
|
+
unless zero_found
|
322
|
+
@column_widths = maxes
|
323
|
+
return # fini
|
324
|
+
end
|
325
|
+
|
326
|
+
#
|
327
|
+
# Boucles sur chaque ligne
|
328
|
+
#
|
329
|
+
(@header_lines + @lines).each do |cols|
|
330
|
+
next unless cols.is_a?(Array)
|
331
|
+
cols.each_with_index do |col, col_idx|
|
332
|
+
if maxes[col_idx]
|
333
|
+
#
|
334
|
+
# Si la largeur max est définie pour cette colonne
|
335
|
+
# @note
|
336
|
+
# Pour le moment, sera répété pour chaque ligne…
|
337
|
+
#
|
338
|
+
@column_widths[col_idx] = max_widths[col_idx]
|
339
|
+
else
|
340
|
+
#
|
341
|
+
# S'il faut prendre la plus large colonne
|
342
|
+
#
|
343
|
+
len = col.to_s.length
|
344
|
+
@column_widths[col_idx] = len if len > @column_widths[col_idx]
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def make_totaux_line
|
351
|
+
totaux_line = Array.new(column_count, '')
|
352
|
+
max_index = colonnes_totaux.keys.min
|
353
|
+
totaux_line[max_index - 2] = 'TOTAUX' unless max_index == 1
|
354
|
+
colonnes_totaux.each do |idx, type|
|
355
|
+
totaux_line[idx - 1] = 0
|
356
|
+
end
|
357
|
+
@lines.each do |cols|
|
358
|
+
colonnes_totaux.each do |idx, type|
|
359
|
+
real_idx = idx - 1
|
360
|
+
# puts "totaux_line[real_idx] = #{totaux_line[real_idx].inspect}"
|
361
|
+
# puts "cols[real_idx] = #{cols[real_idx].inspect}:#{cols[real_idx].class}"
|
362
|
+
totaux_line[real_idx] += cols[real_idx].to_i
|
363
|
+
end
|
364
|
+
end
|
365
|
+
add(:separation)
|
366
|
+
add(totaux_line)
|
367
|
+
end
|
368
|
+
end #/class Table
|
369
|
+
end #/module Clir
|
@@ -0,0 +1,42 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Console method
|
4
|
+
|
5
|
+
=end
|
6
|
+
|
7
|
+
# To wach (empty) the console
|
8
|
+
def clear
|
9
|
+
# puts "\n" # pour certaines méthodes
|
10
|
+
STDOUT.write "\n\033c"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Write +str+ at column +column+ and line +line+
|
14
|
+
def write_at(str, line, column)
|
15
|
+
msg = "\e[#{line};#{column}H#{str}"
|
16
|
+
if test?
|
17
|
+
puts msg
|
18
|
+
else
|
19
|
+
STDOUT.write msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# @return column count of the console
|
25
|
+
def console_width
|
26
|
+
`tput cols`.strip.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return lines count of the console
|
30
|
+
def console_height
|
31
|
+
`tput lines`.strip.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
# Use 'less' command to display +texte+
|
35
|
+
def less(texte)
|
36
|
+
if debug?
|
37
|
+
puts texte
|
38
|
+
else
|
39
|
+
exec "echo \"#{texte.gsub(/\"/,'\\"')}\" | less -r"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# --- Helpers pour console ---
|
2
|
+
|
3
|
+
##
|
4
|
+
# Pour "labeliser" une table de label <> valeur
|
5
|
+
#
|
6
|
+
# @param ary {Array}
|
7
|
+
# Liste des valeurs, sous la forme
|
8
|
+
# [
|
9
|
+
# ['<label>', '<valeur>'[ :couleur|options]],
|
10
|
+
# ['<label>', '<valeur>'[ :couleur|options]],
|
11
|
+
# etc,
|
12
|
+
# ]
|
13
|
+
# Produira :
|
14
|
+
# label valeur
|
15
|
+
# label valeur
|
16
|
+
# etc.
|
17
|
+
#
|
18
|
+
# Le 3e paramètre de chaque item peut définir SOIT la couleur
|
19
|
+
# comme un symbole (par exemple :vert), SOIT une table qui
|
20
|
+
# peut contenir :
|
21
|
+
# color: La couleur à appliquer
|
22
|
+
# detail: Un texte à ajouter après la valeur (en gris)
|
23
|
+
#
|
24
|
+
# @param params {Hash|Nil}
|
25
|
+
#
|
26
|
+
# Paramètres définissant la table à obtenir avec :
|
27
|
+
#
|
28
|
+
# :indent Identation avant le label (soit un nombre
|
29
|
+
# d'espace soit l'indentation elle-même)
|
30
|
+
# :gutter Taille (en espace) de la gouttière entre les
|
31
|
+
# libellés et les valeurs (4 par défaut)
|
32
|
+
# :label_width Pour forcer la taille des libellés. Sinon,
|
33
|
+
# elle sera calculée d'après le plus grand
|
34
|
+
# label.
|
35
|
+
def labelize(ary, params = nil)
|
36
|
+
#
|
37
|
+
# On peut traiter une simple ligne ou un tableau
|
38
|
+
#
|
39
|
+
ary = [ary] unless ary.is_a?(Array)
|
40
|
+
#
|
41
|
+
# Les paramètres à appliquer
|
42
|
+
#
|
43
|
+
params ||= {}
|
44
|
+
params.key?(:gutter) || params.merge!(gutter: 4)
|
45
|
+
params.key?(:label_width) || begin
|
46
|
+
params.merge!(label_width: ary.max { |a,b| a[0].length <=> b[0].length }[0].length + params[:gutter] )
|
47
|
+
end
|
48
|
+
(params.key?(:indent) && params[:indent]) || params.merge!(indent:'')
|
49
|
+
params[:indent] = ' '*params[:indent] if params[:indent].is_a?(Integer)
|
50
|
+
#
|
51
|
+
# On construit la ligne ou chaque ligne du tableau
|
52
|
+
#
|
53
|
+
ary.collect do |lib, val, options|
|
54
|
+
params_line = params.dup
|
55
|
+
case options
|
56
|
+
when Symbol then params_line.merge!(color: options)
|
57
|
+
when Hash then params_line.merge!(options)
|
58
|
+
end
|
59
|
+
params[:indent] + label_value_line(lib, val, params_line)
|
60
|
+
end.join("\n")
|
61
|
+
end
|
62
|
+
def label_value_line(label, value, params = nil)
|
63
|
+
str = "#{label.to_s.ljust(params[:label_width])}#{value}"
|
64
|
+
str = str.send(params[:color]) unless params[:color].nil?
|
65
|
+
str = str + ' ' + params[:detail].gris if params[:detail]
|
66
|
+
return str
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
def verbose?
|
4
|
+
Clir::State.verbose?
|
5
|
+
end
|
6
|
+
|
7
|
+
def debug?
|
8
|
+
Clir::State.debug?
|
9
|
+
end
|
10
|
+
|
11
|
+
def test?
|
12
|
+
Clir::State.test?
|
13
|
+
end
|
14
|
+
|
15
|
+
def help?
|
16
|
+
Clir::State.help?
|
17
|
+
end
|
18
|
+
|
19
|
+
module Clir
|
20
|
+
class State
|
21
|
+
class << self
|
22
|
+
|
23
|
+
def verbose?
|
24
|
+
:TRUE == @__isverbose ||= true_or_false(CLI.options[:verbose] === true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def debug?
|
28
|
+
:TRUE == @__debugon ||= true_or_false(CLI.options[:debug] === true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test?
|
32
|
+
:TRUE == @__teston ||= true_or_false((CLI.options[:test]||CLI.options[:tests]) === true || ENV['CLI_TEST'] == 'true' || ENV['CLI_TESTS'] == 'true' || File.exist?(CLI::MARKER_TESTS_FILE))
|
33
|
+
end
|
34
|
+
|
35
|
+
def help?
|
36
|
+
:TRUE == @__helpon ||= true_or_false(CLI.options[:help] === true || ['help','aide'].include?(CLI.main_command))
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset
|
40
|
+
@__isverbose = nil
|
41
|
+
@__debugon = nil
|
42
|
+
@__teston = nil
|
43
|
+
@__helpon = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
end #/<< self
|
47
|
+
end #/class State
|
48
|
+
end #/module Clir
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# require 'fileutils'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Require all ruby file deep in folder +dossier+
|
5
|
+
#
|
6
|
+
def require_folder(dossier)
|
7
|
+
Dir["#{dossier}/**/*.rb"].each{|m|require(m)}
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# Like 'mkdir -p' command
|
12
|
+
#
|
13
|
+
def mkdir(pth)
|
14
|
+
FileUtils.mkdir_p(pth)
|
15
|
+
return pth
|
16
|
+
end
|
17
|
+
alias :mkdir_p :mkdir
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
# To round a number
|
22
|
+
#
|
23
|
+
def round(n, decim = 2)
|
24
|
+
r = n.to_f.round(decim)
|
25
|
+
r.to_f == r.to_i ? r.to_i : r.to_f
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# To copy in the clipboard
|
30
|
+
#
|
31
|
+
def clip(ca, silent = false)
|
32
|
+
`printf "#{ca.gsub(/"/, '\\"').strip}" | pbcopy`
|
33
|
+
silent || puts("\n(“#{ca}“ copié dans le presse-papier)".gris)
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# To delete (unlink) folder of file if it exists
|
38
|
+
#
|
39
|
+
# @return TRUE if file existed (and have been deleted).
|
40
|
+
#
|
41
|
+
def delete_if_exist(pth)
|
42
|
+
if File.exist?(pth)
|
43
|
+
if File.directory?(pth)
|
44
|
+
FileUtils.rm_rf(pth)
|
45
|
+
else
|
46
|
+
File.delete(pth)
|
47
|
+
end
|
48
|
+
return not(File.exist?(pth))
|
49
|
+
else
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def true_or_false(value)
|
55
|
+
value ? :TRUE : :FALSE
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
# @return [String] La valeur exprimée en euro
|
5
|
+
# @example
|
6
|
+
# €("12") # => '12 €'
|
7
|
+
# €("12", true) # => '12.00 €'
|
8
|
+
# €(12.5698) # => '12.57 €'
|
9
|
+
# @param [String|Integer|Float] Number to return as euro value
|
10
|
+
def €(value, with_cents = false)
|
11
|
+
if value.is_a?(Integer)
|
12
|
+
"#{value}#{".00" if with_cents} €"
|
13
|
+
elsif value.to_f.to_s != value.to_s
|
14
|
+
raise "Bad value. #{value.inspect} can't be converted to euros."
|
15
|
+
else
|
16
|
+
n, d = value.to_f.round(2).to_s.split('.')
|
17
|
+
d = d.ljust(2,'0')
|
18
|
+
"#{n}.#{d} €"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String] Value +value+ as pourcentage
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# pcent(12) # => "12 %"
|
26
|
+
# pcent(12, 3) # => "12.000 %"
|
27
|
+
# pcent(12.436, 1) # => "12.4 %"
|
28
|
+
# pcent(12.436, true) # => "12.4 %"
|
29
|
+
# pcent(12.436, 2) # => "12.44 %"
|
30
|
+
#
|
31
|
+
# @param value [Integer|String|Float] The value to convert
|
32
|
+
# @param with_cents [TrueClass|Integer] Decimal value. If true,
|
33
|
+
# 1 decimal is used ("10.1 %")
|
34
|
+
#
|
35
|
+
def pcent(value, with_cents = nil)
|
36
|
+
if value.is_a?(Integer)
|
37
|
+
value = value.to_s
|
38
|
+
elsif value == value.to_i.to_s
|
39
|
+
value = value.to_i.to_s
|
40
|
+
elsif value.to_f.to_s != value.to_s
|
41
|
+
raise "Bad value. #{value.inspect}:#{value.class} can't be converted to pourcentage."
|
42
|
+
end
|
43
|
+
with_cents = 1 if with_cents == true
|
44
|
+
if with_cents
|
45
|
+
n, d = value.to_f.round(with_cents).to_s.split('.')
|
46
|
+
d = d.ljust(with_cents,'0')
|
47
|
+
value = "#{n}.#{d}"
|
48
|
+
end
|
49
|
+
"#{value} %"
|
50
|
+
end
|
data/lib/clir/version.rb
ADDED
data/lib/clir.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
@usage
|
4
|
+
|
5
|
+
~~~ruby
|
6
|
+
require 'clir'
|
7
|
+
CLI.init
|
8
|
+
...
|
9
|
+
~~~
|
10
|
+
|
11
|
+
=end
|
12
|
+
require 'fileutils'
|
13
|
+
require "clir/version"
|
14
|
+
require 'clir/String.ext'
|
15
|
+
require 'clir/CLI.mod'
|
16
|
+
require 'clir/Array.ext'
|
17
|
+
require 'clir/Integer.ext'
|
18
|
+
require 'clir/Symbol.ext'
|
19
|
+
require 'clir/File_extension'
|
20
|
+
require 'clir/CSV_extension'
|
21
|
+
require 'clir/Config.cls'
|
22
|
+
require 'clir/utils_methods'
|
23
|
+
require 'clir/utils_numbers'
|
24
|
+
require 'clir/Date_utils'
|
25
|
+
require 'clir/helpers_methods'
|
26
|
+
require 'clir/state_methods'
|
27
|
+
require 'clir/console_methods'
|
28
|
+
require 'clir/TTY-Prompt.cls'
|
29
|
+
require 'clir/Replayer.cls'
|
30
|
+
require 'clir/Table'
|
31
|
+
require 'clir/Labelizor'
|
32
|
+
|
33
|
+
module Clir
|
34
|
+
class Error < StandardError; end
|
35
|
+
# Your code goes here...
|
36
|
+
end
|