squared 0.1.3 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,44 +20,80 @@ module Squared
20
20
  end
21
21
  end
22
22
 
23
- def copy_d(src, dest, glob: ['**/*'], pass: nil, create: false, verbose: true)
24
- src = ::Pathname.new(src)
25
- dest = ::Pathname.new(dest)
23
+ def copy_dir(src, dest, glob = ['**/*'], create: false, link: nil, force: false, pass: nil, verbose: true)
24
+ src = Pathname.new(src)
25
+ dest = Pathname.new(dest)
26
26
  raise "#{dest} (not found)" if !create && !dest.parent.exist?
27
27
 
28
- subdir = []
29
- files = 0
28
+ subdir = {}
30
29
  dest.mkpath if create
31
30
  if pass
32
31
  exclude = []
33
- (pass.is_a?(::Array) ? pass : [pass]).each { |val| exclude += ::Dir.glob(src.join(val)) }
32
+ pass = [pass] unless pass.is_a?(::Array)
33
+ pass.each { |val| exclude += Dir.glob(src.join(val)) }
34
34
  end
35
35
  (glob.is_a?(::Array) ? glob : [glob]).each do |val|
36
- ::Dir.glob(src.join(val)) do |path|
37
- next if exclude&.include?(path) || (path = ::Pathname.new(path)).directory?
36
+ Dir.glob(src.join(val)) do |path|
37
+ next if exclude&.include?(path) || (path = Pathname.new(path)).directory?
38
38
 
39
- target = dest.join(path.relative_path_from(src))
40
- dir = target.dirname
41
- unless subdir.include?(dir.to_s)
39
+ dir = dest.join(path.relative_path_from(src)).dirname
40
+ if (data = subdir[dir.to_s])
41
+ data << path
42
+ else
42
43
  dir.mkpath
43
- subdir << dir.to_s
44
+ subdir[dir.to_s] = [path]
44
45
  end
45
- copy_f path, target
46
- files += 1
47
46
  end
48
47
  end
49
- puts [dest.realpath, subdir.size.to_s, files.to_s].join(' => ') if verbose
48
+ count = 0
49
+ soft = 0
50
+ subdir.each do |dir, files|
51
+ if link
52
+ items = files.dup
53
+ files.clear
54
+ items.each do |file|
55
+ if file.exist?
56
+ if file.symlink?
57
+ next unless force
58
+ else
59
+ files << file
60
+ next
61
+ end
62
+ end
63
+ if link == 'hard'
64
+ FileUtils.ln(file, dir, force: force, verbose: false)
65
+ else
66
+ FileUtils.ln_s(file, dir, force: force, verbose: false)
67
+ end
68
+ soft += 1
69
+ end
70
+ end
71
+ next if files.empty?
72
+
73
+ out = FileUtils.cp(files, dir, verbose: false)
74
+ count += out.size
75
+ end
76
+ puts [dest.realpath, subdir.size, soft > 0 ? "#{count}+#{soft}" : count].join(' => ') if verbose
50
77
  end
51
78
 
52
- def copy_f(src, dest, overwrite: true, verbose: false)
53
- unless overwrite
54
- if (path = ::Pathname.new(dest)).directory?
55
- src = (src.is_a?(::Array) ? src : [src]).reject { |val| path.join(::File.basename(val)).exist? }
79
+ def copy_guard(src, dest, link: nil, force: false, verbose: true)
80
+ unless force
81
+ if (path = Pathname.new(dest)).directory?
82
+ src = [src] unless src.is_a?(::Array)
83
+ src = src.reject { |val| path.join(File.basename(val)).exist? }
84
+ return if src.empty?
56
85
  elsif path.exist?
57
86
  return
58
87
  end
59
88
  end
60
- ::FileUtils.cp(src, dest, verbose: verbose)
89
+ case link
90
+ when 'hard', 1
91
+ FileUtils.ln(src, dest, force: force, verbose: verbose)
92
+ when true, 'soft', 0
93
+ FileUtils.ln_s(src, dest, force: force, verbose: verbose)
94
+ else
95
+ FileUtils.cp(src, dest, verbose: verbose)
96
+ end
61
97
  end
62
98
  end
63
99
  end
@@ -9,7 +9,7 @@ module Squared
9
9
  module_function
10
10
 
11
11
  def task_invoke(*cmd, args: [], exception: true, warning: true)
12
- cmd.each { |name| ::Rake::Task[name].invoke(*args) }
12
+ cmd.each { |name| Rake::Task[name].invoke(*args) }
13
13
  rescue StandardError => e
14
14
  raise if exception
15
15
 
@@ -28,10 +28,10 @@ module Squared
28
28
  end
29
29
 
30
30
  def task_invoked?(*args)
31
- ::Rake::Task.tasks.any? do |obj|
31
+ Rake::Task.tasks.any? do |obj|
32
32
  next unless obj.already_invoked
33
33
 
34
- args.any? { |val| val.is_a?(::Regexp) ? val.match?(obj.name) : val == obj.name }
34
+ args.any? { |val| val.is_a?(::Regexp) ? obj.name =~ val : val == obj.name }
35
35
  end
36
36
  end
37
37
 
@@ -64,7 +64,7 @@ module Squared
64
64
  def env_pipe(key, default = 1, suffix: nil, root: nil)
65
65
  if default.is_a?(::String)
66
66
  begin
67
- default = (root ? root.join(default) : ::Pathname.new(default)).realdirpath
67
+ default = (root ? root.join(default) : Pathname.new(default)).realdirpath
68
68
  rescue StandardError => e
69
69
  default = 1
70
70
  warn e
@@ -91,7 +91,7 @@ module Squared
91
91
  when '1'
92
92
  true
93
93
  else
94
- ::Regexp.new(ret, options, timeout: timeout)
94
+ Regexp.new(ret, options, timeout: timeout)
95
95
  end
96
96
  end
97
97
  end
@@ -11,41 +11,77 @@ module Squared
11
11
  include Utils
12
12
  include Rake::DSL
13
13
 
14
- def self.to_s
15
- super.match(/[^:]+\z/)[0]
14
+ class << self
15
+ def parse(gem, namespace, ext = [pkg])
16
+ require gem
17
+ obj = eval(namespace)
18
+ ext = [ext] unless ext.is_a?(Array)
19
+ ext.each { |val| @@mime_obj[val] = [obj, ext] }
20
+ rescue LoadError, NameError => e
21
+ warn e
22
+ nil
23
+ else
24
+ @@mime_obj[ext.first]
25
+ end
26
+
27
+ def link(project, main = project.dependfile.basename, name = nil, **kwargs, &blk)
28
+ return unless project.enabled?
29
+
30
+ ret = Viewer.new(main, name, project: project, **kwargs)
31
+ ret.instance_eval(&blk) if block_given?
32
+ ret
33
+ end
34
+
35
+ def to_s
36
+ super.match(/[^:]+\z/)[0]
37
+ end
16
38
  end
17
39
 
40
+ @@mime_obj = {}
41
+ @@task_desc = Rake::TaskManager.record_task_metadata
42
+
18
43
  attr_reader :main, :name, :project, :theme
19
44
  attr_accessor :pipe
20
45
 
21
- def initialize(main, name = nil, project: nil, prefix: nil, dump: nil, opts: {}, auto: true,
46
+ def initialize(main, name = nil, project: nil, prefix: nil, command: nil, dump: nil, opts: {}, auto: true,
22
47
  common: ARG[:COMMON], pipe: ARG[:PIPE], **)
23
- if project
24
- main = @project.basepath(main).to_s if (@project = __get__(:project)[project.to_s])
48
+ if project && (project.respond_to?(:workspace) || (project = __get__(:project)[project.to_s]))
49
+ main = project.basepath(main).to_s
50
+ @project = project
25
51
  @required = true
26
52
  end
27
- @name = name&.to_s || @project&.name
28
- @prefix = prefix
29
- @ext = File.extname(main).downcase
53
+ @name = name || @project&.name
54
+ @prefix = prefix unless @project
55
+ @ext = File.extname(main)
30
56
  @dump = dump
31
57
  @mime = {}
32
58
  @theme = common ? __get__(:theme)[:viewer] : {}
33
59
  @pipe = env_pipe(pipe, @project ? @project.pipe : 1)
34
- if exist?
60
+ if target?
35
61
  @main = main.chomp(@ext)
36
62
  @name = @main unless @name || @required
37
63
  if auto
38
- case @ext
39
- when '.json', '.js'
40
- add('json', command: File.basename(@main), opts: opts)
41
- when '.yaml', '.yml'
42
- add('yaml', command: File.basename(@main), opts: opts)
64
+ unless command
65
+ command = File.basename(@main)
66
+ command = ARG[:VIEW] if command == @name
67
+ end
68
+ ext = @ext[1..-1].downcase
69
+ if (data = @@mime_obj[ext])
70
+ add(data[1].first, command: command, opts: opts, ext: data[1])
71
+ else
72
+ case ext
73
+ when 'json', 'js'
74
+ add('json', command: command, opts: opts)
75
+ when 'yaml', 'yml'
76
+ add('yaml', command: command, opts: opts)
77
+ end
43
78
  end
44
79
  end
45
80
  else
46
81
  @main = main
82
+ @command = command || ARG[:VIEW]
47
83
  end
48
- return unless warning? && ((missing = exist? && !File.exist?(main)) || !@name)
84
+ return unless warning? && ((missing = target? && !File.exist?(main)) || !@name)
49
85
 
50
86
  msg, hint = if missing
51
87
  ['path not found', realpath]
@@ -60,21 +96,24 @@ module Squared
60
96
  return unless enabled?
61
97
 
62
98
  namespace(ns = task_name(name)) do
63
- view = @command && @command != name ? @command : 'view'
64
- params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
65
- namespace view do
66
- if @mime['json'] && (exist? || !Rake::Task.task_defined?("#{ns}:#{view}:json"))
67
- desc format_desc(view, 'json')
68
- task 'json', [:keys] do |_, args|
69
- read_keys(JSON, 'json', *params.(args))
70
- end
71
- end
99
+ @mime.each do |type, items|
100
+ items.each do |command, file, opts|
101
+ next if Rake::Task.task_defined?("#{ns}:#{command}:#{type}")
102
+
103
+ namespace command do
104
+ unless (data = @@mime_obj[type])
105
+ ext = [type]
106
+ ext << 'yml' if type == 'yaml'
107
+ next unless (data = Viewer.parse(type, type.upcase, ext))
108
+ end
109
+ obj, ext = data
110
+ target = file || target? ? file || realpath : nil
72
111
 
73
- if @mime['yaml'] && (exist? || !Rake::Task.task_defined?("#{ns}:#{view}:yaml"))
74
- desc format_desc(view, 'yaml', 'yml')
75
- task 'yaml', [:keys] do |_, args|
76
- require 'yaml'
77
- read_keys(YAML, 'yaml', *params.(args), ext: ['yml', 'yaml'])
112
+ task_desc(command, *ext, target: target)
113
+ task type, [:keys] do |_, args|
114
+ params = target ? [target, args.to_a] : [args.keys, args.extras]
115
+ read_keys(obj, ext.first, *params, ext: ext, opts: opts)
116
+ end
78
117
  end
79
118
  end
80
119
  end
@@ -82,57 +121,52 @@ module Squared
82
121
  yield self if block_given?
83
122
  end
84
123
 
85
- def add(type, gem: nil, parse: nil, ext: nil, opts: {}, command: 'view', file: nil, exist: nil)
124
+ def add(type, ext: nil, opts: {}, command: ARG[:VIEW], gem: nil, namespace: nil, file: nil)
86
125
  return self if @mime.frozen?
87
126
 
88
- type = type.to_s
89
- if parse && enabled?
90
- require(gem || type)
91
- obj = eval(parse)
92
- ext << type if (ext = as_a(ext)).empty?
93
- file = realpath if !file && exist?
94
-
95
- namespace task_name(name) do
96
- namespace command do
97
- desc format_desc(command, *ext, exist: exist)
98
- task type, [:keys] do |_, args|
99
- if file
100
- read_keys(obj, type, file.to_s, args.to_a, ext: ext)
101
- else
102
- read_keys(obj, type, args.keys, args.extras, ext: ext)
103
- end
127
+ if enabled?
128
+ if namespace
129
+ require(gem || type)
130
+ obj = eval(namespace)
131
+ else
132
+ as_a(ext).each do |val|
133
+ next unless (data = @@mime_obj[val])
134
+
135
+ obj = data.first
136
+ break
137
+ end
138
+ end
139
+ if obj
140
+ ext << type if (ext = as_a(ext)).empty?
141
+ if !file && target?
142
+ ext.each do |val|
143
+ next unless (out = basepath("#{main}.#{val}")).exist?
144
+
145
+ file = out
146
+ break
104
147
  end
105
148
  end
106
149
  end
107
150
  end
108
151
  rescue LoadError, NameError => e
109
- project&.log&.warn e
152
+ log&.warn e
110
153
  self
111
154
  else
112
- @mime[type] = opts
113
- if exist?
114
- @command = command
155
+ (@mime[type] ||= []) << [command || @command, file, opts]
156
+ if target?
157
+ @mime[type].freeze
115
158
  @mime.freeze
116
159
  end
117
160
  self
118
161
  end
119
162
 
120
- def also(path, type = nil, name: nil, gem: nil, parse: nil, opts: {})
163
+ def also(path, type = nil, name: nil, **kwargs)
121
164
  return self if @mime.frozen? || !(file = basepath(path)).exist?
122
165
 
123
166
  ext = mimetype(file)
124
- type = type&.to_s || ext
125
- unless parse
126
- case type
127
- when 'json'
128
- parse = 'JSON'
129
- when 'yaml', 'yml'
130
- type = 'yaml'
131
- parse = 'YAML'
132
- end
133
- end
167
+ type ||= ext
134
168
  name ||= file.basename.to_s.chomp(File.extname(file))
135
- add(type, gem: gem, parse: parse, ext: ext, opts: opts, command: name, file: file, exist: true)
169
+ add(type, ext: ext, command: name, file: file, **kwargs)
136
170
  end
137
171
 
138
172
  def style(name, *args)
@@ -141,23 +175,23 @@ module Squared
141
175
  end
142
176
 
143
177
  def enabled?
144
- return File.exist?(realpath) if exist?
178
+ return File.exist?(realpath) if target?
145
179
 
146
180
  !@required || !!project&.enabled?
147
181
  end
148
182
 
149
183
  def extensions
150
- exist? ? [@ext.sub('.', '')] : @mime.keys
184
+ target? ? [@ext.sub('.', '').downcase] : @mime.keys
151
185
  end
152
186
 
153
187
  def to_s
154
- realpath if exist?
188
+ realpath if target?
155
189
 
156
190
  @mime.keys.map { |ext| "#{main}.#{ext}" }.join(',')
157
191
  end
158
192
 
159
193
  def inspect
160
- "#<#{self.class}: #{name} => #{exist? ? realpath : "#{main} {#{extensions.join(', ')}}"}>"
194
+ "#<#{self.class}: #{name} => #{target? ? realpath : "#{main} {#{extensions.join(', ')}}"}>"
161
195
  end
162
196
 
163
197
  private
@@ -166,7 +200,11 @@ module Squared
166
200
  puts_oe(*args, pipe: pipe)
167
201
  end
168
202
 
169
- def read_keys(reader, type, file, keys, ext: [type])
203
+ def log
204
+ project&.log
205
+ end
206
+
207
+ def read_keys(reader, type, file, keys, ext: [type], opts: {})
170
208
  if file && (mime = mimetype(file)) && basepath(file).exist?
171
209
  raise_error(file, mime, hint: 'invalid') unless ext.include?(mime)
172
210
  else
@@ -187,14 +225,15 @@ module Squared
187
225
  raise_error(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", **args)
188
226
  end
189
227
  end
190
- project&.log&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
228
+ log&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
229
+ return puts File.read(file) if keys.last == '*'
230
+
191
231
  doc = if reader.respond_to?(:load_file)
192
- reader.load_file(file, **@mime[type])
232
+ reader.load_file(file, **opts)
193
233
  else
194
- reader.parse(File.read(file), **@mime[type])
234
+ reader.parse(File.read(file), **opts)
195
235
  end
196
- lines = print_keys(type, doc, keys, file: file)
197
- return unless lines
236
+ return unless (lines = print_keys(type, doc, keys, file: file, opts: opts))
198
237
 
199
238
  title = Pathname.new(file)
200
239
  .realpath
@@ -213,13 +252,13 @@ module Squared
213
252
  { pat: /\A(.+ : (?!undefined))([^"\[{].*)\z/m, styles: theme[:value],
214
253
  index: 2 }
215
254
  ]
216
- end)
255
+ end, border: theme[:border])
217
256
  end
218
257
 
219
- def print_keys(type, data, keys, file: nil)
258
+ def print_keys(type, data, keys, file: nil, opts: {})
220
259
  out = []
221
260
  pad = 0
222
- symbolize = @mime[type][:symbolize_names]
261
+ symbolize = opts[:symbolize_names]
223
262
  keys.each do |key|
224
263
  begin
225
264
  items = key.split('.')
@@ -234,7 +273,7 @@ module Squared
234
273
  end
235
274
  end
236
275
  rescue StandardError
237
- project&.log&.warn "#{Viewer}(#{type}) => #{file && "#{file} "}{#{key}: undefined}"
276
+ log&.warn "#{Viewer}(#{type}) => #{file && "#{file} "}{#{key}: undefined}"
238
277
  val = Regexp.escape($!.message)
239
278
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
240
279
  s = "<#{$3 || $2 || $1}>"
@@ -258,17 +297,26 @@ module Squared
258
297
  end
259
298
 
260
299
  def task_name(val)
261
- @prefix ? "#{@prefix}:#{val}" : val.to_s
300
+ if project
301
+ project.workspace.task_name(val)
302
+ else
303
+ @prefix ? "#{@prefix}:#{val}" : val.to_s
304
+ end
262
305
  end
263
306
 
264
- def format_desc(command, *ext, exist: exist?)
265
- return unless Rake::TaskManager.record_task_metadata
307
+ def task_desc(command, *ext, target: nil)
308
+ return unless @@task_desc
266
309
 
267
- val = "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
268
- message(@prefix, *name.split(':'), command, val, empty: true)
310
+ val = "#{ext.first}[#{target ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
311
+ args = *name.split(':').push(command, val)
312
+ if project
313
+ project.workspace.task_desc(*args)
314
+ else
315
+ desc message(@prefix, *args, empty: true)
316
+ end
269
317
  end
270
318
 
271
- def exist?
319
+ def target?
272
320
  !@ext.empty? && (!@required || !project.nil?)
273
321
  end
274
322
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.1.3'
4
+ VERSION = '0.2.1'
5
5
  end