squared 0.6.9 → 0.7.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.
@@ -130,22 +130,19 @@ module Squared
130
130
  end
131
131
 
132
132
  def check_style(args, empty: true)
133
- ret = []
134
133
  colors = __get__(:colors)
135
- Array(args).flatten.compact.each do |val|
134
+ ret = Array(args).flatten.compact.each_with_object([]) do |val, out|
136
135
  if !val.is_a?(::Numeric)
137
136
  k = val.to_sym
138
- ret << k if colors.key?(k) || colors.key?(k.to_s.sub('bright_', '').to_sym) || TEXT_STYLE.include?(k)
137
+ out << k if colors.key?(k) || colors.key?(k.to_s.sub('bright_', '').to_sym) || TEXT_STYLE.include?(k)
139
138
  elsif val.between?(0, 256)
140
- ret << val
139
+ out << val
141
140
  elsif val < 0 && (b = val.to_s.split('.')[1])
142
141
  b = b[0, 3]
143
- ret << "-0.#{b}".to_f unless b.to_i > 255
142
+ out << "-0.#{b}".to_f unless b.to_i > 255
144
143
  end
145
144
  end
146
- return if ret.empty? && !empty
147
-
148
- ret
145
+ ret unless ret.empty? && !empty
149
146
  end
150
147
 
151
148
  def apply_style(data, key, args, empty: true)
@@ -233,7 +230,7 @@ module Squared
233
230
  args.flatten.each { |val| f.write(val.chomp.stripstyle + br) }
234
231
  end
235
232
  return
236
- rescue StandardError
233
+ rescue
237
234
  pipe = 2
238
235
  end
239
236
  end
@@ -290,7 +287,7 @@ module Squared
290
287
  end
291
288
  out << draw.call(b2, b3)
292
289
  if title
293
- out.concat(title.map! { |t| pr.call(t) })
290
+ out.concat(title.map { |t| pr.call(t) })
294
291
  out << draw.call(b6, b7)
295
292
  end
296
293
  lines.each { |line| out << pr.call(line) }
@@ -44,13 +44,13 @@ module Squared
44
44
  attempts -= 1
45
45
  exit 1 unless attempts > 0
46
46
  end
47
- rescue Interrupt
48
- puts
49
- exit 0
50
- else
51
- exit 1 if force
52
- false
53
47
  end
48
+ rescue Interrupt
49
+ puts
50
+ exit 0
51
+ else
52
+ exit 1 if force
53
+ false
54
54
  end
55
55
 
56
56
  def choice(msg, list = nil, min: 1, max: 1, multiple: false, index: false, grep: nil, border: nil, auto: true,
@@ -58,12 +58,11 @@ module Squared
58
58
  require 'timeout'
59
59
  if list
60
60
  grep &&= Array(grep).map { |val| Regexp.new(val) }
61
- items = []
62
- list.each do |val|
61
+ items = list.each_with_object([]) do |val, out|
63
62
  next if grep&.none? { |pat| pat.match?(line) }
64
63
 
65
- items << val.to_s.chomp
66
- puts '%2d. %s' % [items.size, val]
64
+ out << val.to_s.chomp
65
+ puts '%2d. %s' % [out.size, val]
67
66
  end
68
67
  max = items.size
69
68
  raise ArgumentError, 'empty selection list' if max == 0
@@ -84,12 +83,13 @@ module Squared
84
83
  between = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
85
84
  Timeout.timeout(timeout) do
86
85
  while (ch = Readline.readline(msg))
87
- unless (ch = ch.strip).empty?
86
+ ch.strip!
87
+ unless ch.empty?
88
88
  if multiple
89
89
  k = if ch == '*'
90
90
  (min..max).to_a
91
91
  else
92
- ch.split(',').map! do |s|
92
+ ch.split(',').flat_map do |s|
93
93
  s.strip!
94
94
  if s =~ /^(\d+)-(\d+)$/
95
95
  next unless between.call($1) && between.call($2)
@@ -103,11 +103,10 @@ module Squared
103
103
  end
104
104
  end
105
105
  unless k.include?(nil)
106
- k.flatten!
107
106
  k.uniq!
108
107
  k.sort!
109
108
  unless multiple.is_a?(::Numeric) && multiple != k.size
110
- return index || !items ? k : k.map! { |i| items[i.pred] }
109
+ return index || !items ? k : k.map { |i| items[i.pred] }
111
110
  end
112
111
  end
113
112
  elsif between.call(ch)
@@ -129,9 +128,7 @@ module Squared
129
128
  end
130
129
 
131
130
  def readline(msg, history = false, force: nil, multiline: nil, &blk)
132
- multiline = if multiline && Readline.respond_to?(:readmultiline)
133
- multiline.is_a?(::Enumerable) || block_given? ? multiline : [multiline.to_s]
134
- end
131
+ multiline = nil unless Readline.respond_to?(:readmultiline)
135
132
  read = lambda do
136
133
  if !multiline
137
134
  Readline.readline(msg, history)
@@ -141,17 +138,19 @@ module Squared
141
138
  Readline.readmultiline(msg, history) do |line|
142
139
  next if line.strip.empty?
143
140
 
144
- multiline.any? { |val| line.split.last.end_with?(val.to_s) }
141
+ Array(multiline).any? { |val| line.split.last.end_with?(val.to_s) }
145
142
  end
146
143
  end
147
144
  end
148
145
  case force
149
- when ::TrueClass, ::FalseClass
150
- msg = "#{msg}%s%s " % if multiline
151
- [' ', multiline.is_a?(::Enumerable) ? "{#{multiline.to_a.join('|')}}" : multiline]
152
- else
153
- [force ? ':' : '?', '']
154
- end
146
+ when true, false
147
+ msg = "#{msg}#{unless msg.match?(/[>:\]}$|]\z/)
148
+ '%s%s' % if multiline.is_a?(::Enumerable)
149
+ [' ', "{#{multiline.to_a.join('|')}}"]
150
+ else
151
+ [multiline || (force ? ':' : '?'), '']
152
+ end
153
+ end} "
155
154
  ret = (read.call || '').strip
156
155
  multiline.each { |val| break if ret.delete_suffix!(val.to_s) } if multiline.is_a?(::Enumerable)
157
156
  exit 1 if force && ret.empty?
@@ -10,26 +10,28 @@ module Squared
10
10
  private_constant :QUOTE_VALUE
11
11
 
12
12
  String.define_method(:stripquote) { sub(QUOTE_VALUE, '\2') }
13
- Array.define_method(:quote!) { |**kwargs| map! { |s| Shell.shell_quote(s, **kwargs) } }
13
+ Array.define_method(:quote!) { |**kwargs| map { |s| Shell.shell_quote(s, **kwargs) } }
14
14
 
15
15
  module_function
16
16
 
17
17
  def shell_escape(val, quote: false, option: false, force: false, double: false, override: false)
18
- if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
18
+ val = val.to_s
19
+ if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val))
19
20
  if (data = r[2].match(QUOTE_VALUE))
20
21
  double = data[1] == '"'
21
22
  override = true
22
23
  elsif !r[3] || r[6]
23
24
  return val
24
25
  end
25
- opt = if r[7].match?(/\A["']/)
26
- "#{r[7]}#{r[7][0]}"
27
- elsif r[7].match?(/["']\z/)
28
- "#{r[7][-1]}#{r[7]}"
26
+ ch = r[7]
27
+ opt = if ch.start_with?('"', "'")
28
+ "#{ch}#{ch[0]}"
29
+ elsif ch.end_with?('"', "'")
30
+ "#{ch[-1]}#{ch}"
29
31
  else
30
- return val unless r[7].match?(/\s/)
32
+ return val unless ch.match?(/\s/)
31
33
 
32
- r[7]
34
+ ch
33
35
  end
34
36
  r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, force: force, double: double, override: override)
35
37
  elsif option && val =~ /\A(-{0,2}[^=\s-][^=\s]*)=(.+)\z/m
@@ -44,10 +46,8 @@ module Squared
44
46
  end
45
47
  elsif Rake::Win32.windows?
46
48
  quote ? shell_quote(val, force: force, double: double) : val
47
- elsif val.empty?
48
- ''
49
49
  else
50
- Shellwords.escape(val)
50
+ val.empty? ? '' : Shellwords.escape(val)
51
51
  end
52
52
  end
53
53
 
@@ -108,7 +108,7 @@ module Squared
108
108
  end
109
109
 
110
110
  def shell_split(val, join: nil, **kwargs)
111
- ret = val.shellsplit.map! { |opt| shell_escape(opt, option: true, double: true, **kwargs) }
111
+ ret = val.shellsplit.map { |opt| shell_escape(opt, option: true, double: true, **kwargs) }
112
112
  return ret unless join
113
113
 
114
114
  ret.join(join.is_a?(::String) ? join : ' ')
@@ -141,7 +141,7 @@ module Squared
141
141
  fill_option(item.first)
142
142
  else
143
143
  flag = item.shift
144
- item.map! { |s| shell_option(flag, s, escape: escape, force: force, **kwargs) }
144
+ item.map { |s| shell_option(flag, s, escape: escape, force: force, **kwargs) }
145
145
  end
146
146
  end.concat(f)
147
147
  end
@@ -153,13 +153,12 @@ module Squared
153
153
  require_relative 'base'
154
154
  key = name.to_s.upcase
155
155
  key = File.basename(key, '.*') if Rake::Win32.windows?
156
- shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
157
- option: false, force: false, double: true)
156
+ shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || PATH[key = key.downcase] ||
157
+ PATH[key.to_sym] || name, option: false, force: false, double: true)
158
158
  end
159
159
 
160
160
  def line_width(lines)
161
- ret = [lines.empty? ? 0 : lines.max_by(&:size).size, 80].max
162
- [ret, Rake.application.terminal_width].min
161
+ [lines.empty? ? 80 : [lines.max_by(&:size).size, 80].max, Rake.application.terminal_width].min
163
162
  end
164
163
 
165
164
  def fill_option(val, **kwargs)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'pathname'
4
4
  require 'rake'
5
+ require 'timeout'
5
6
 
6
7
  module Squared
7
8
  module Common
@@ -11,7 +12,7 @@ module Squared
11
12
 
12
13
  def parse_link(val)
13
14
  case val
14
- when ::TrueClass, 's'
15
+ when 's', true
15
16
  1
16
17
  when 'r'
17
18
  2
@@ -29,23 +30,34 @@ module Squared
29
30
 
30
31
  def shell(*args, name: :system, **kwargs)
31
32
  if RUBY_ENGINE == 'jruby' && Rake::Win32.windows?
32
- e = kwargs[:exception]
33
- if (dir = kwargs[:chdir]) && ((pwd = Dir.pwd) != dir)
34
- Dir.chdir dir
35
- ret = Kernel.send(name, *args)
36
- Dir.chdir pwd
37
- else
38
- ret = Kernel.send(name, *args)
33
+ ex = kwargs[:exception]
34
+ if (dir = kwargs[:chdir]) && Dir.pwd != dir
35
+ pwd = Dir.pwd
36
+ Dir.chdir(dir)
39
37
  end
38
+ ret = Kernel.send(name, *args)
39
+ Dir.chdir(pwd) if pwd
40
40
  elsif RUBY_VERSION < '2.6'
41
- e = kwargs.delete(:exception)
41
+ ex = kwargs.delete(:exception)
42
42
  ret = Kernel.send(name, *args, **kwargs)
43
43
  else
44
44
  return Kernel.send(name, *args, **kwargs)
45
45
  end
46
- return ret unless e && !ret && name == :system
46
+ raise $?.to_s if !ret && ex && name == :system
47
47
 
48
- raise $?.to_s
48
+ ret
49
+ end
50
+
51
+ def shell_t(*args, timeout: 0, **kwargs)
52
+ return shell(*args, **kwargs) unless timeout > 0
53
+
54
+ begin
55
+ Timeout.timeout(timeout) do
56
+ shell(*args, **kwargs)
57
+ end
58
+ rescue Interrupt
59
+ exit 1
60
+ end
49
61
  end
50
62
 
51
63
  def copy_dir(src, dest, glob = ['**/*'], create: false, link: nil, preserve: nil, force: false, verbose: true,
@@ -57,10 +69,7 @@ module Squared
57
69
  subdir = {}
58
70
  target.mkpath if create
59
71
  flags = hidden ? [File::FNM_DOTMATCH] : []
60
- if pass
61
- exclude = []
62
- Array(pass).each { |val| exclude.concat(Dir.glob(val, *flags, base: base)) }
63
- end
72
+ exclude = Array(pass).each_with_object([]) { |val, out| out.concat(Dir.glob(val, *flags, base: base)) } if pass
64
73
  Array(glob).each do |val|
65
74
  Dir.glob(val, *flags, base: base) do |file|
66
75
  next if exclude&.include?(file) || (entry = base + file).directory?
@@ -109,22 +118,22 @@ module Squared
109
118
  end
110
119
 
111
120
  def copy_guard(*src, dest, base: '.', create: false, link: nil, preserve: nil, force: false, verbose: true)
112
- src = src.compact.flatten
121
+ target = src.compact.flatten
113
122
  dest = Pathname.new(dest).realdirpath
114
123
  base = Pathname.new(base).realpath
115
124
  dir = if dest.directory?
116
125
  true
117
- elsif src.size > 1
126
+ elsif target.size > 1
118
127
  raise Errno::ENOENT, dest.cleanpath.to_s unless create && !dest.exist?
119
128
 
120
129
  dest.mkpath
121
130
  true
122
131
  end
123
- targets = src.map! { |file| [base + file, dir ? dest + File.basename(file) : dest] }
124
- return if !force && (targets = targets.reject { |to| to[1].exist? }).empty?
132
+ target.map! { |file| [base + file, dir ? dest + File.basename(file) : dest] }
133
+ return if !force && (target = target.reject { |to| to[1].exist? }).empty?
125
134
 
126
135
  type = System.send :parse_link, link
127
- targets.each do |file, to|
136
+ target.each do |file, to|
128
137
  case type
129
138
  when 0
130
139
  FileUtils.cp(file, to, preserve: preserve, verbose: verbose)
@@ -7,6 +7,35 @@ require 'time'
7
7
  module Squared
8
8
  module Common
9
9
  module Utils
10
+ private
11
+
12
+ def env_value(key, default = '', name: @envname, suffix: nil, strict: false)
13
+ if suffix
14
+ if (ret = ENV[[key, name, suffix].compact.join('_')])
15
+ return ret
16
+ elsif strict
17
+ return default
18
+ end
19
+ end
20
+ if name
21
+ return ret if (ret = ENV["#{key}_#{name}"])
22
+ return default if strict
23
+ end
24
+ ENV.fetch(key, default)
25
+ end
26
+
27
+ def env_yield(ret, default, equals: nil, notequals: nil, ignore: nil)
28
+ if !notequals.nil?
29
+ ret = Array(notequals).none? { |val| ret == val.to_s }
30
+ elsif !equals.nil?
31
+ ret = Array(equals).any? { |val| ret == val.to_s }
32
+ else
33
+ ret = default if ret.empty? || (ignore && Array(ignore).any? { |val| ret == val.to_s })
34
+ return if ret.nil?
35
+ end
36
+ block_given? ? yield(ret) : ret
37
+ end
38
+
10
39
  module_function
11
40
 
12
41
  def as_a(obj, *meth, flat: nil, compact: false, &blk)
@@ -29,29 +58,16 @@ module Squared
29
58
  obj.select(&blk)
30
59
  end
31
60
 
32
- def split_escape(val, char: ',', &blk)
33
- ret = val.split(/\s*(?<!\\)#{char}\s*/)
61
+ def split_escape(val, char: ',', limit: 0, &blk)
62
+ ret = val.split(/(?<!\\)#{char}/, limit).map(&:strip)
34
63
  return ret unless block_given?
35
64
 
36
- ret.each(&blk)
37
- end
38
-
39
- def split_option(val)
40
- val = val.strip
41
- return [val, '', ''] unless (i = val.index('='))
42
-
43
- last = val[i.succ..-1].strip
44
- quote = ''
45
- if last =~ /\A(["'])(.+)\1\z/
46
- last = $2
47
- quote = $1
48
- end
49
- [val[0..i.pred], last, quote]
65
+ ret.each_with_index(&blk)
50
66
  end
51
67
 
52
68
  def task_invoke(*cmd, args: [], exception: true, warning: true)
53
69
  cmd.each { |name| Rake::Task[name].invoke(*args) }
54
- rescue StandardError => e
70
+ rescue => e
55
71
  raise if exception
56
72
 
57
73
  warn e if warning
@@ -119,47 +135,20 @@ module Squared
119
135
  val.utc.strftime(ms ? '%s%L' : '%s').to_i
120
136
  end
121
137
 
122
- def rand_s(size)
123
- if RUBY_VERSION >= '3.1'
124
- require 'random/formatter'
125
- Random.new.alphanumeric(size)
126
- else
127
- (0...size).map { rand(97..122).chr }.join
128
- end
129
- end
130
-
131
- def env(key, default = nil, suffix: nil, strict: false, equals: nil, ignore: nil, **)
132
- ret = env_value(key, suffix: suffix, strict: strict)
133
- return Array(equals).any? { |val| val.to_s == ret } unless equals.nil?
134
-
135
- ret.empty? || (ignore && Array(ignore).any? { |val| val.to_s == ret }) ? default : ret
138
+ def env(key, default = nil, equals: nil, notequals: nil, ignore: nil, **kwargs, &blk)
139
+ env_yield(env_value(key, **kwargs), default, equals: equals, notequals: notequals, ignore: ignore, &blk)
136
140
  end
137
141
 
138
142
  def env_key(*val)
139
143
  val.join('_').gsub(/\W+/, '_').upcase
140
144
  end
141
145
 
142
- def env_value(key, default = '', suffix: nil, strict: false)
143
- if suffix
144
- if (ret = ENV["#{key + (@envname ? "_#{@envname}" : '')}_#{suffix}"])
145
- return ret
146
- elsif strict
147
- return default
148
- end
149
- end
150
- if @envname
151
- return ret if (ret = ENV["#{key}_#{@envname}"])
152
- return default if strict
153
- end
154
- ENV.fetch(key, default)
155
- end
156
-
157
- def env_bool(key, default = false, suffix: nil, strict: false, index: false)
146
+ def env_bool(key, default = false, index: false, **kwargs)
158
147
  case key
159
- when ::NilClass
148
+ when nil
160
149
  default
161
150
  when ::String
162
- case (val = env_value(key, suffix: suffix, strict: strict))
151
+ case (val = env_value(key, **kwargs))
163
152
  when ''
164
153
  default
165
154
  when '0', 'false'
@@ -172,10 +161,10 @@ module Squared
172
161
  end
173
162
  end
174
163
 
175
- def env_pipe(key, default = 1, suffix: nil, strict: false, root: nil)
164
+ def env_pipe(key, default = 1, root: nil, **kwargs)
176
165
  case key
177
166
  when ::String
178
- case (ret = env_value(key, suffix: suffix, strict: strict))
167
+ case (ret = env_value(key, **kwargs))
179
168
  when '0', '1', '2'
180
169
  return ret.to_i
181
170
  end
@@ -186,14 +175,14 @@ module Squared
186
175
 
187
176
  begin
188
177
  (root ? Pathname.new(root) + default : Pathname.new(default)).realdirpath
189
- rescue StandardError => e
178
+ rescue => e
190
179
  warn e
191
180
  1
192
181
  end
193
182
  end
194
183
 
195
- def env_match(key, default = nil, suffix: nil, strict: false, options: 0, timeout: nil)
196
- case (val = env_value(key, suffix: suffix, strict: strict))
184
+ def env_match(key, default = nil, options: 0, timeout: nil, **kwargs)
185
+ case (val = env_value(key, **kwargs))
197
186
  when ''
198
187
  default
199
188
  when '0'
@@ -14,9 +14,9 @@ module Squared
14
14
  class << self
15
15
  def parse(gem, namespace, ext = [gem])
16
16
  require gem
17
- [eval(namespace), Array(ext)].tap do |data|
18
- data.last.each { |key| @@mime_obj[key] = data }
19
- end
17
+ ret = [eval(namespace), Array(ext)]
18
+ ret.last.each { |key| @@mime_obj[key] = ret }
19
+ ret
20
20
  rescue LoadError, NameError => e
21
21
  warn e
22
22
  nil
@@ -42,13 +42,15 @@ module Squared
42
42
 
43
43
  def initialize(main, name = nil, project: nil, command: nil, opts: {}, auto: true,
44
44
  common: ARG[:COMMON], pipe: ARG[:PIPE], **kwargs)
45
- if project && (project.respond_to?(:workspace) || (project = __get__(:project)[project.to_s]))
46
- main = project.basepath(main).to_s
47
- @project = project
48
- @envname = project.instance_variable_get(:@envname)
49
- @required = true
50
- end
51
- @name = name || @project&.name
45
+ @name = if project && (project.respond_to?(:workspace) || (project = __get__(:project)[project.to_s]))
46
+ main = project.basepath(main).to_s
47
+ @project = project
48
+ @envname = project.__send__(:envname_get)
49
+ @required = true
50
+ project.name
51
+ else
52
+ name
53
+ end
52
54
  @prefix = kwargs[:prefix] unless @project
53
55
  @ext = File.extname(main)
54
56
  @dump = kwargs[:dump]
@@ -185,7 +187,7 @@ module Squared
185
187
  def to_s
186
188
  realpath if target?
187
189
 
188
- @mime.keys.map! { |ext| "#{main}.#{ext}" }.join(',')
190
+ @mime.keys.map { |ext| "#{main}.#{ext}" }.join(',')
189
191
  end
190
192
 
191
193
  def inspect
@@ -251,10 +253,9 @@ module Squared
251
253
  end
252
254
 
253
255
  def print_keys(type, data, keys, file: nil, opts: {})
254
- out = []
255
256
  pad = 0
256
257
  symbolize = opts[:symbolize_names]
257
- keys.each do |key|
258
+ values = keys.each_with_object([]) do |key, out|
258
259
  begin
259
260
  items = key.split('.').flat_map { |name| name =~ /^(.+)\[(\d+)\]$/ ? [$1, $2.to_i] : name }
260
261
  items = items.map(&:to_sym) if symbolize
@@ -267,7 +268,7 @@ module Squared
267
268
  val = val[name]
268
269
  end
269
270
  end
270
- rescue StandardError
271
+ rescue
271
272
  log&.warn "#{Viewer}(#{type}) => #{"#{file} " if file}{#{key}: undefined}"
272
273
  val = Regexp.escape($!.message)
273
274
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
@@ -285,9 +286,9 @@ module Squared
285
286
  pad = [pad, key.size].max
286
287
  end
287
288
  if stdin?
288
- puts out.map!(&:last).join("\n")
289
+ puts values.map(&:last).join("\n")
289
290
  else
290
- out.map! { |a, b| '%-*s : %s' % [pad, a, b] }
291
+ values.map { |a, b| '%-*s : %s' % [pad, a, b] }
291
292
  end
292
293
  end
293
294
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.9'
4
+ VERSION = '0.7.0'
5
5
  end