squared 0.0.9 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,16 +11,29 @@ module Squared
11
11
  def shell_escape(val, quote: false)
12
12
  return Shellwords.escape(val) unless ::Rake::Win32.windows?
13
13
 
14
- quote ? shell_quote(val, force: false) : val
14
+ quote ? shell_quote(opt, force: false) : opt
15
15
  end
16
16
 
17
17
  def shell_quote(val, force: true)
18
18
  ret = val.to_s.strip
19
- return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|=)(["']).+\1$/m
19
+ return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|\S=|[^=]\s+)(["']).+\1$/m
20
20
 
21
21
  ::Rake::Win32.windows? ? "\"#{double_quote(ret)}\"" : "'#{single_quote(ret)}'"
22
22
  end
23
23
 
24
+ def shell_split(val, quote: false, join: false)
25
+ ret = Shellwords.split(val).map do |opt|
26
+ if (data = /^(--?[^= ]+)(=|\s+)?(["'])?(.+?)\3?$/m.match(opt))
27
+ next opt unless data[2] && !data[3]
28
+
29
+ data[1] + data[2] + shell_quote(data[4], force: !::Rake::Win32.windows?)
30
+ else
31
+ shell_escape(opt, quote: quote)
32
+ end
33
+ end
34
+ join ? ret.join(' ') : ret
35
+ end
36
+
24
37
  def fill_option(val)
25
38
  return "-#{val}" if val.size == 1 || val =~ /^[a-z]\d+$/i
26
39
 
@@ -37,11 +50,7 @@ module Squared
37
50
  end
38
51
 
39
52
  def split_escape(val, char: ',')
40
- val.split(/\s*(?<!\\)#{char}\s*/)
41
- end
42
-
43
- def sanitize_args(*opts)
44
- opts.map { |val| val.include?(' ') ? shell_quote(val) : shell_escape(val) }.join(' ')
53
+ val.split(/\s*(?<!\\)#{char}\s*/o)
45
54
  end
46
55
  end
47
56
  end
@@ -8,43 +8,15 @@ module Squared
8
8
  module System
9
9
  module_function
10
10
 
11
- def shell(*cmd, **kwargs)
11
+ def shell(*args, **kwargs)
12
12
  if RUBY_VERSION =~ /^2\.[0-5]\./
13
13
  exception = kwargs.delete(:exception)
14
- ret = system(*cmd, **kwargs)
14
+ ret = system(*args, **kwargs)
15
15
  raise $?.to_s if !ret && exception
16
16
 
17
17
  ret
18
18
  else
19
- system(*cmd, **kwargs)
20
- end
21
- end
22
-
23
- def confirm(msg, agree: 'Y', cancel: 'N', default: nil, attempts: 5, timeout: 15)
24
- require 'readline'
25
- require 'timeout'
26
- agree = /^#{agree}$/i if agree.is_a?(String)
27
- cancel = /^#{cancel}$/i if cancel.is_a?(String)
28
- Timeout.timeout(timeout) do
29
- begin
30
- while (ch = Readline.readline(msg, true))
31
- ch = ch.chomp
32
- ch = default if ch.empty?
33
- case ch
34
- when agree
35
- return true
36
- when cancel
37
- return false
38
- end
39
- attempts -= 1
40
- exit 1 unless attempts >= 0
41
- end
42
- rescue Interrupt
43
- puts
44
- exit 0
45
- else
46
- false
47
- end
19
+ system(*args, **kwargs)
48
20
  end
49
21
  end
50
22
 
@@ -56,15 +28,14 @@ module Squared
56
28
  subdir = []
57
29
  files = 0
58
30
  dest.mkpath if create
59
- glob = [glob] unless glob.is_a?(::Array)
60
- glob.each do |val|
31
+ (glob.is_a?(::Array) ? glob : [glob]).each do |val|
61
32
  Dir.glob(src.join(val)) do |path|
62
33
  ent = Pathname.new(path)
63
34
  next if ent.directory?
64
35
 
65
36
  target = dest.join(ent.relative_path_from(src))
66
37
  dir = target.dirname
67
- if !subdir.include?(dir.to_s)
38
+ unless subdir.include?(dir.to_s)
68
39
  dir.mkpath
69
40
  subdir << dir.to_s
70
41
  end
@@ -72,13 +43,12 @@ module Squared
72
43
  files += 1
73
44
  end
74
45
  end
75
- puts [dest.realpath, subdir.size.to_s, files.to_s].join(' => ') if verbose
46
+ puts [dest.realpath, subdir.size.to_s, files.to_s].join(Common::ARG[:SPACE]) if verbose
76
47
  end
77
48
 
78
49
  def copy_f(src, dest, overwrite: true, verbose: false)
79
- if !overwrite
80
- path = Pathname.new(dest)
81
- if path.directory?
50
+ unless overwrite
51
+ if (path = Pathname.new(dest)).directory?
82
52
  src = [src] unless src.is_a?(::Array)
83
53
  src = src.reject { |val| path.join(File.basename(val)).exist? }
84
54
  elsif path.exist?
@@ -16,8 +16,9 @@ module Squared
16
16
  warn e if warning
17
17
  end
18
18
 
19
- def invoked?(name)
20
- ::Rake::Task.tasks.any? { |item| item.already_invoked && item.name == name.to_s }
19
+ def invoked?(*name)
20
+ val = name.size > 1 ? name.join(':') : name.first.to_s
21
+ ::Rake::Task.tasks.any? { |obj| obj.already_invoked && obj.name == val }
21
22
  end
22
23
  end
23
24
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Squared
4
+ module Common
5
+ module Utils
6
+ module_function
7
+
8
+ def env(key, default = nil, suffix: @envname, equals: nil, ignore: nil)
9
+ ret = env_value(key, suffix: suffix)
10
+ return ret == equals.to_s unless equals.nil?
11
+
12
+ ret.empty? || (ignore && as_a(ignore).any? { |val| ret == val.to_s }) ? default : ret
13
+ end
14
+
15
+ def env_value(key, default = '', suffix: nil)
16
+ suffix && (ret = ENV["#{key}_#{suffix}"]) ? ret : ENV.fetch(key, default)
17
+ end
18
+
19
+ def env_bool(key, default = false, suffix: nil)
20
+ if key.is_a?(::String)
21
+ case env_value(key, suffix: suffix)
22
+ when ''
23
+ default
24
+ when '0', 'false'
25
+ false
26
+ else
27
+ true
28
+ end
29
+ else
30
+ key.nil? ? default : key
31
+ end
32
+ end
33
+
34
+ def env_pipe(key, default = 1, suffix: nil, root: nil)
35
+ if default.is_a?(String)
36
+ begin
37
+ default = (root ? root.join(default) : Pathname.new(default)).realdirpath
38
+ rescue StandardError => e
39
+ default = 1
40
+ warn e
41
+ end
42
+ end
43
+ case key
44
+ when ::String
45
+ case (ret = env_value(key, suffix: suffix))
46
+ when '0', '1', '2'
47
+ return ret.to_i
48
+ end
49
+ when ::Numeric
50
+ return key if key >= 0 && key <= 2
51
+ end
52
+ default
53
+ end
54
+
55
+ def env_match(key, default = nil, suffix: nil, options: 0, timeout: nil)
56
+ case (ret = env_value(key, suffix: suffix))
57
+ when ''
58
+ default
59
+ when '0'
60
+ false
61
+ when '1'
62
+ true
63
+ else
64
+ Regexp.new(ret, options, timeout: timeout)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -6,6 +6,8 @@ require 'rake'
6
6
  require_relative 'common/base'
7
7
  require_relative 'common/class'
8
8
  require_relative 'common/format'
9
+ require_relative 'common/prompt'
9
10
  require_relative 'common/shell'
10
11
  require_relative 'common/system'
11
12
  require_relative 'common/task'
13
+ require_relative 'common/utils'
@@ -2,13 +2,12 @@
2
2
 
3
3
  require 'json'
4
4
 
5
- require_relative 'common'
6
-
7
5
  module Squared
8
6
  module Config
9
7
  class Viewer
10
8
  include Common
11
9
  include Format
10
+ include Utils
12
11
  include ::Rake::DSL
13
12
 
14
13
  class << self
@@ -18,8 +17,10 @@ module Squared
18
17
  end
19
18
 
20
19
  attr_reader :main, :name, :project, :theme
20
+ attr_accessor :pipe
21
21
 
22
- def initialize(main, name = nil, project: nil, prefix: nil, dump: nil, opts: {}, auto: true, common: true)
22
+ def initialize(main, name = nil, project: nil, prefix: nil, dump: nil, opts: {}, auto: true,
23
+ common: ARG[:COMMON], pipe: ARG[:PIPE], **)
23
24
  if project
24
25
  main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
25
26
  @required = true
@@ -30,6 +31,7 @@ module Squared
30
31
  @dump = dump
31
32
  @mime = {}
32
33
  @theme = common ? __get__(:theme)[:viewer] : {}
34
+ @pipe = env_pipe(pipe, @project ? @project.pipe : 1)
33
35
  if exist?
34
36
  @main = main.chomp(@ext)
35
37
  @name = @main unless @name || @required
@@ -58,10 +60,10 @@ module Squared
58
60
  def build
59
61
  return unless enabled?
60
62
 
61
- params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
62
-
63
63
  namespace(ns = task_name(name)) do
64
64
  view = @command && @command != name ? @command : 'view'
65
+ params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
66
+
65
67
  namespace view do
66
68
  if @mime['json'] && (exist? || !::Rake::Task.task_defined?("#{ns}:#{view}:json"))
67
69
  desc format_desc(view, 'json')
@@ -91,7 +93,7 @@ module Squared
91
93
  require(gem || type)
92
94
  obj = eval(parse)
93
95
  ext << type if (ext = as_a(ext)).empty?
94
- file = realpath if file.nil? && exist?
96
+ file = realpath if !file && exist?
95
97
 
96
98
  namespace task_name(name) do
97
99
  desc format_desc(command, *ext, exist: exist)
@@ -106,7 +108,8 @@ module Squared
106
108
  end
107
109
  end
108
110
  end
109
- rescue LoadError, NameError
111
+ rescue LoadError, NameError => e
112
+ project&.log&.warn e
110
113
  self
111
114
  else
112
115
  @mime[type] = opts
@@ -122,7 +125,7 @@ module Squared
122
125
 
123
126
  ext = mime_type(file)
124
127
  type = type&.to_s || ext
125
- if !parse
128
+ unless parse
126
129
  case type
127
130
  when 'json'
128
131
  parse = 'JSON'
@@ -136,7 +139,7 @@ module Squared
136
139
  end
137
140
 
138
141
  def style(name, *args)
139
- apply_style(theme, name, *args)
142
+ apply_style(theme, name, args)
140
143
  self
141
144
  end
142
145
 
@@ -157,11 +160,15 @@ module Squared
157
160
  def enabled?
158
161
  return File.exist?(realpath) if exist?
159
162
 
160
- !@required || (!project.nil? && project.enabled?)
163
+ !@required || !!project&.enabled?
161
164
  end
162
165
 
163
166
  private
164
167
 
168
+ def puts(*args)
169
+ puts_oe(*args, pipe: pipe)
170
+ end
171
+
165
172
  def read_keys(reader, type, file, keys, ext: [type])
166
173
  if (mime = mime_type(file)) && base_path(file).exist?
167
174
  raise_error(file, mime, hint: 'invalid') unless ext.include?(mime)
@@ -190,7 +197,7 @@ module Squared
190
197
  .realpath
191
198
  .to_s
192
199
  .sub(Regexp.new("^#{Regexp.escape(File.join(Dir.pwd, ''))}"), '')
193
- sub = if !pipe?
200
+ sub = unless stdin?
194
201
  [
195
202
  { pat: /^((?:[^:]|(?<! ):(?! ))+)$/, styles: theme[:banner] },
196
203
  { pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: theme[:undefined], index: 2 },
@@ -233,13 +240,13 @@ module Squared
233
240
  $2 ? ".#{s}" : "#{s}."
234
241
  end
235
242
  end
236
- out << [key, pipe? ? JSON.dump(nil) : 'undefined']
243
+ out << [key, stdin? ? JSON.dump(nil) : 'undefined']
237
244
  else
238
- out << [key, @dump == 'json' || pipe? ? JSON.dump(val) : val.inspect]
245
+ out << [key, @dump == 'json' || stdin? ? JSON.dump(val) : val.inspect]
239
246
  end
240
247
  pad = [pad, key.size].max
241
248
  end
242
- if pipe?
249
+ if stdin?
243
250
  puts out.map(&:last).join("\n")
244
251
  else
245
252
  out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
@@ -260,35 +267,33 @@ module Squared
260
267
  'yaml'
261
268
  when 'js'
262
269
  'json'
270
+ when ''
271
+ nil
263
272
  else
264
- ret.empty? ? nil : ret
273
+ ret
265
274
  end
266
275
  end
267
276
 
268
277
  def format_desc(command, *ext, exist: exist?)
269
- message(@prefix || '', *name.split(':'), command,
270
- "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys*]")
278
+ val = "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
279
+ message(@prefix, *name.split(':'), command, val, empty: true)
271
280
  end
272
281
 
273
282
  def realpath
274
- file = main + @ext
275
- Pathname.new(file).realdirpath.to_s rescue file
283
+ base_path(file = main + @ext).to_s rescue file
276
284
  end
277
285
 
278
286
  def exist?
279
287
  !@ext.empty? && (!@required || !project.nil?)
280
288
  end
281
289
 
282
- def pipe?
283
- return project.workspace.pipe if project
284
-
285
- val = ENV['PIPE_OUT']
286
- !val.nil? && !val.empty? && val != '0'
287
- end
288
-
289
290
  def warning?
290
291
  project ? project.workspace.warning : true
291
292
  end
293
+
294
+ def stdin?
295
+ pipe == 0
296
+ end
292
297
  end
293
298
  end
294
299
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.11'
5
5
  end