squared 0.1.5 → 0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -15
- data/README.md +3 -0
- data/README.ruby.md +126 -46
- data/lib/squared/app.rb +0 -2
- data/lib/squared/common/base.rb +20 -14
- data/lib/squared/common/class.rb +18 -1
- data/lib/squared/common/format.rb +9 -9
- data/lib/squared/common/shell.rb +20 -12
- data/lib/squared/common/system.rb +56 -20
- data/lib/squared/common/utils.rb +5 -5
- data/lib/squared/config.rb +130 -82
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +168 -51
- data/lib/squared/workspace/project/base.rb +358 -147
- data/lib/squared/workspace/project/git.rb +708 -273
- data/lib/squared/workspace/project/node.rb +175 -104
- data/lib/squared/workspace/project/python.rb +190 -75
- data/lib/squared/workspace/project/ruby.rb +337 -171
- data/lib/squared/workspace/repo.rb +35 -46
- data/lib/squared/workspace/series.rb +16 -14
- data/squared.gemspec +0 -1
- metadata +2 -16
@@ -20,44 +20,80 @@ module Squared
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
src =
|
25
|
-
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
|
-
|
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
|
-
|
37
|
-
next if exclude&.include?(path) || (path =
|
36
|
+
Dir.glob(src.join(val)) do |path|
|
37
|
+
next if exclude&.include?(path) || (path = Pathname.new(path)).directory?
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
44
|
+
subdir[dir.to_s] = [path]
|
44
45
|
end
|
45
|
-
copy_f path, target
|
46
|
-
files += 1
|
47
46
|
end
|
48
47
|
end
|
49
|
-
|
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
|
53
|
-
unless
|
54
|
-
if (path =
|
55
|
-
src =
|
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
|
-
|
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
|
data/lib/squared/common/utils.rb
CHANGED
@@ -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|
|
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
|
-
|
31
|
+
Rake::Task.tasks.any? do |obj|
|
32
32
|
next unless obj.already_invoked
|
33
33
|
|
34
|
-
args.any? { |val| val.is_a?(::Regexp) ?
|
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) :
|
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
|
-
|
94
|
+
Regexp.new(ret, options, timeout: timeout)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
data/lib/squared/config.rb
CHANGED
@@ -11,41 +11,77 @@ module Squared
|
|
11
11
|
include Utils
|
12
12
|
include Rake::DSL
|
13
13
|
|
14
|
-
|
15
|
-
|
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 =
|
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
|
28
|
-
@prefix = prefix
|
29
|
-
@ext = File.extname(main)
|
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
|
60
|
+
if target?
|
35
61
|
@main = main.chomp(@ext)
|
36
62
|
@name = @main unless @name || @required
|
37
63
|
if auto
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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 =
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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,
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
152
|
+
log&.warn e
|
110
153
|
self
|
111
154
|
else
|
112
|
-
@mime[type]
|
113
|
-
if
|
114
|
-
@
|
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,
|
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
|
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,
|
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
|
178
|
+
return File.exist?(realpath) if target?
|
145
179
|
|
146
180
|
!@required || !!project&.enabled?
|
147
181
|
end
|
148
182
|
|
149
183
|
def extensions
|
150
|
-
|
184
|
+
target? ? [@ext.sub('.', '').downcase] : @mime.keys
|
151
185
|
end
|
152
186
|
|
153
187
|
def to_s
|
154
|
-
realpath if
|
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} => #{
|
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
|
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
|
-
|
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,
|
232
|
+
reader.load_file(file, **opts)
|
193
233
|
else
|
194
|
-
reader.parse(File.read(file),
|
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 =
|
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
|
-
|
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
|
-
|
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
|
265
|
-
return unless
|
307
|
+
def task_desc(command, *ext, target: nil)
|
308
|
+
return unless @@task_desc
|
266
309
|
|
267
|
-
val = "#{ext.first}[#{
|
268
|
-
|
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
|
319
|
+
def target?
|
272
320
|
!@ext.empty? && (!@required || !project.nil?)
|
273
321
|
end
|
274
322
|
|
data/lib/squared/version.rb
CHANGED