squared 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/README.ruby.md +51 -16
- data/lib/squared/common/class.rb +6 -0
- data/lib/squared/common/format.rb +80 -24
- data/lib/squared/common/shell.rb +9 -1
- data/lib/squared/common/system.rb +4 -2
- data/lib/squared/common/task.rb +1 -1
- data/lib/squared/common.rb +38 -16
- data/lib/squared/config.rb +139 -85
- data/lib/squared/repo/project/base.rb +185 -102
- data/lib/squared/repo/project/git.rb +140 -53
- data/lib/squared/repo/project/node.rb +206 -123
- data/lib/squared/repo/project/python.rb +48 -29
- data/lib/squared/repo/project/ruby.rb +77 -68
- data/lib/squared/repo/project.rb +0 -30
- data/lib/squared/repo/workspace.rb +196 -122
- data/lib/squared/repo.rb +3 -3
- data/lib/squared/version.rb +1 -1
- metadata +2 -2
data/lib/squared/config.rb
CHANGED
@@ -9,82 +9,94 @@ module Squared
|
|
9
9
|
include ::Rake::DSL
|
10
10
|
|
11
11
|
class << self
|
12
|
-
|
13
|
-
|
14
|
-
attr_reader :styles
|
15
|
-
|
16
|
-
def style(name, *args)
|
17
|
-
args = check_style(args)
|
18
|
-
styles[name.to_sym]&.clear&.concat(args)
|
12
|
+
def to_s
|
13
|
+
/[^:]+$/.match(super.to_s)[0]
|
19
14
|
end
|
20
15
|
end
|
21
16
|
|
22
|
-
|
23
|
-
banner: %i[blue],
|
24
|
-
key: %i[bold],
|
25
|
-
value: %i[green],
|
26
|
-
string: %i[yellow],
|
27
|
-
hash: %i[green black!],
|
28
|
-
array: %i[blue black!],
|
29
|
-
number: %i[magenta],
|
30
|
-
undefined: %i[red italic]
|
31
|
-
}.freeze
|
17
|
+
attr_reader :name, :main, :project, :theme
|
32
18
|
|
33
|
-
|
34
|
-
|
35
|
-
def initialize(main = 'package', project: nil, name: nil)
|
19
|
+
def initialize(main, name = nil, project: nil, opts: {}, auto: true, common: true)
|
36
20
|
if project
|
37
|
-
@project =
|
21
|
+
main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
|
38
22
|
@required = true
|
39
23
|
end
|
40
|
-
@name =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
24
|
+
@name = name&.to_s || @project&.name
|
25
|
+
@ext = File.extname(main)
|
26
|
+
@mime = {}
|
27
|
+
@theme = common ? __get__(:theme)[:viewer] : {}
|
28
|
+
if exist?
|
29
|
+
@main = main.chomp(@ext)
|
30
|
+
@name = @main unless @name || @required
|
31
|
+
if auto
|
32
|
+
case @ext
|
33
|
+
when '.json', '.js'
|
34
|
+
add('json', command: File.basename(@main), opts: opts)
|
35
|
+
when '.yaml', '.yml'
|
36
|
+
add('yaml', command: File.basename(@main), opts: opts)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@main = main
|
45
41
|
end
|
46
|
-
|
47
|
-
|
42
|
+
return unless warning? && ((missing = exist? && !File.exist?(main)) || !@name)
|
43
|
+
|
44
|
+
msg, hint = if missing
|
45
|
+
['path not found', realpath]
|
46
|
+
else
|
47
|
+
@required = true
|
48
|
+
project ? [project, 'not found'] : %w[name missing]
|
49
|
+
end
|
50
|
+
warn log_message(:warn, msg, subject: self.class, hint: hint, color: !pipe?)
|
48
51
|
end
|
49
52
|
|
50
53
|
def build
|
51
54
|
return unless enabled?
|
52
55
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
|
57
|
+
|
58
|
+
namespace name do
|
59
|
+
view = @command && @command != name ? @command : 'view'
|
60
|
+
namespace view do
|
61
|
+
if @mime['json'] && (exist? || !::Rake::Task.task_defined?("#{name}:#{view}:json"))
|
62
|
+
desc format_desc(view, %w[json])
|
57
63
|
task :json, [:keys] do |_, args|
|
58
64
|
require 'json'
|
59
|
-
read_keys
|
65
|
+
read_keys(JSON, 'json', *params.(args))
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
63
|
-
if @
|
64
|
-
desc format_desc(
|
69
|
+
if @mime['yaml'] && (exist? || !::Rake::Task.task_defined?("#{name}:#{view}:yaml"))
|
70
|
+
desc format_desc(view, %w[yaml yml])
|
65
71
|
task :yaml, [:keys] do |_, args|
|
66
72
|
require 'yaml'
|
67
|
-
read_keys
|
73
|
+
read_keys(YAML, 'yaml', *params.(args), ext: %w[yml yaml])
|
68
74
|
end
|
69
75
|
end
|
70
76
|
end
|
71
77
|
end
|
78
|
+
|
79
|
+
yield self if block_given?
|
72
80
|
end
|
73
81
|
|
74
|
-
def add(type, gem: nil, parse: nil, ext: [], opts: {}, command:
|
82
|
+
def add(type, gem: nil, parse: nil, ext: [], opts: {}, command: 'view', file: nil)
|
83
|
+
return self if @mime.frozen?
|
84
|
+
|
75
85
|
type = type.to_s
|
76
86
|
if parse && enabled?
|
77
87
|
require(gem || type)
|
78
88
|
obj = eval(parse)
|
79
89
|
ext = as_a(ext)
|
80
|
-
|
81
|
-
|
82
|
-
|
90
|
+
ext << type if ext.empty?
|
91
|
+
file = realpath if file.nil? && exist?
|
92
|
+
namespace name do
|
93
|
+
desc format_desc(command, ext)
|
94
|
+
namespace command do
|
83
95
|
task type, [:keys] do |_, args|
|
84
96
|
if file
|
85
|
-
read_keys
|
97
|
+
read_keys(obj, type, file.to_s, collect_args(args, :keys), ext: ext)
|
86
98
|
else
|
87
|
-
read_keys
|
99
|
+
read_keys(obj, type, args.keys, args.extras, ext: ext)
|
88
100
|
end
|
89
101
|
end
|
90
102
|
end
|
@@ -93,16 +105,19 @@ module Squared
|
|
93
105
|
rescue LoadError, NameError
|
94
106
|
self
|
95
107
|
else
|
96
|
-
@
|
108
|
+
@mime[type] = opts
|
109
|
+
if exist?
|
110
|
+
@command = command
|
111
|
+
@mime.freeze
|
112
|
+
end
|
97
113
|
self
|
98
114
|
end
|
99
115
|
|
100
116
|
def also(path, type = nil, name: nil, gem: nil, parse: nil, opts: {})
|
101
|
-
return self
|
117
|
+
return self if @mime.frozen? || !(file = base_path(path)).exist?
|
102
118
|
|
103
|
-
ext =
|
104
|
-
|
105
|
-
type = (type || ext).to_s
|
119
|
+
ext = mime_type(file)
|
120
|
+
type = type&.to_s || ext
|
106
121
|
if !parse
|
107
122
|
case type
|
108
123
|
when 'json'
|
@@ -112,42 +127,61 @@ module Squared
|
|
112
127
|
parse = 'YAML'
|
113
128
|
end
|
114
129
|
end
|
130
|
+
name ||= file.basename.to_s.chomp(File.extname(file))
|
115
131
|
add(type, gem: gem, parse: parse, ext: ext, opts: opts, command: name, file: file)
|
116
132
|
end
|
117
133
|
|
134
|
+
def style(name, *args)
|
135
|
+
apply_style(theme, name, *args)
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
def extensions
|
140
|
+
exist? ? [@ext.sub('.', '')] : @mime.keys
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_s
|
144
|
+
realpath if exist?
|
145
|
+
|
146
|
+
@mime.keys.map { |ext| "#{main}.#{ext}" }.join(',')
|
147
|
+
end
|
148
|
+
|
149
|
+
def inspect
|
150
|
+
"#<#{self.class}: #{name} => #{exist? ? realpath : "#{main} {#{extensions.join(', ')}}"}>"
|
151
|
+
end
|
152
|
+
|
118
153
|
def enabled?
|
119
|
-
|
154
|
+
return File.exist?(realpath) if exist?
|
155
|
+
|
156
|
+
!@required || (!project.nil? && project.enabled?)
|
120
157
|
end
|
121
158
|
|
122
159
|
protected
|
123
160
|
|
124
|
-
def read_keys(reader, type, file, keys,
|
125
|
-
|
126
|
-
|
127
|
-
ext << type if ext.empty?
|
128
|
-
if path.exist? && path.basename.to_s.include?('.')
|
129
|
-
raise ArgumentError, message(file, fmt, hint: 'invalid') unless ext.include?(fmt)
|
161
|
+
def read_keys(reader, type, file, keys, ext: [type])
|
162
|
+
if (mime = mime_type(file)) && base_path(file).exist?
|
163
|
+
raise ArgumentError, message(file, mime, hint: 'invalid') unless ext.include?(mime)
|
130
164
|
else
|
131
|
-
if ext.include?(
|
165
|
+
if ext.include?(mime)
|
132
166
|
alt = file
|
133
167
|
file = nil
|
134
|
-
ext[0] =
|
168
|
+
ext[0] = mime
|
135
169
|
else
|
136
170
|
keys.unshift(file)
|
137
|
-
alt = "#{
|
138
|
-
alt = @project.base_path(alt) if @project
|
171
|
+
alt = base_path("#{main}.{#{ext.join(',')}}")
|
139
172
|
file = Dir[alt].first
|
140
173
|
end
|
141
|
-
|
174
|
+
unless file
|
142
175
|
raise ArgumentError, message(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", hint: 'not found')
|
143
176
|
end
|
144
177
|
end
|
178
|
+
project&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
|
145
179
|
doc = if reader.respond_to?(:load_file)
|
146
|
-
reader.load_file(file, **@
|
180
|
+
reader.load_file(file, **@mime[type])
|
147
181
|
else
|
148
|
-
reader.parse(File.read(file), **@
|
182
|
+
reader.parse(File.read(file), **@mime[type])
|
149
183
|
end
|
150
|
-
lines = print_keys(type, doc, keys)
|
184
|
+
lines = print_keys(type, doc, keys, file: file)
|
151
185
|
return unless lines
|
152
186
|
|
153
187
|
title = Pathname.new(file)
|
@@ -157,24 +191,25 @@ module Squared
|
|
157
191
|
sub = if pipe?
|
158
192
|
nil
|
159
193
|
else
|
194
|
+
styles = theme
|
160
195
|
[
|
161
|
-
{ pat: /^([^:]
|
162
|
-
{ pat: /^(.*?)(<[^>]+>)(.+)$/m, styles:
|
163
|
-
{ pat: /^(.+)( : (?!undefined)
|
164
|
-
{ pat: /^(.+
|
165
|
-
{ pat: /^(.+
|
166
|
-
{ pat: /^(.+
|
167
|
-
{ pat: /^(.+
|
168
|
-
{ pat: /^(.+
|
196
|
+
{ pat: /^((?:[^:]|(?<! ):(?! ))+)$/, styles: styles[:banner] },
|
197
|
+
{ pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: styles[:undefined], index: 2 },
|
198
|
+
{ pat: /^(.+)( : (?!undefined).+)$/m, styles: styles[:key] },
|
199
|
+
{ pat: /^(.+ : )(-?[\d.]+)(\s*)$/m, styles: styles[:number], index: 2 },
|
200
|
+
{ pat: /^(.+ : ")(.+)("\s*)$/m, styles: styles[:string], index: 2 },
|
201
|
+
{ pat: /^(.+ : \{)(.+)(\}\s*)$/m, styles: styles[:hash], index: 2 },
|
202
|
+
{ pat: /^(.+ : \[)(.+)(\]\s*)$/m, styles: styles[:array], index: 2 },
|
203
|
+
{ pat: /^(.+ : (?!undefined))([^"\[{].*)$/m, styles: styles[:value], index: 2 }
|
169
204
|
]
|
170
205
|
end
|
171
206
|
emphasize(lines, title: title, sub: sub)
|
172
207
|
end
|
173
208
|
|
174
|
-
def print_keys(type, data, keys)
|
209
|
+
def print_keys(type, data, keys, file: nil)
|
175
210
|
out = []
|
176
211
|
pad = 0
|
177
|
-
symbolize = @
|
212
|
+
symbolize = @mime[type][:symbolize_names]
|
178
213
|
keys.each do |key|
|
179
214
|
begin
|
180
215
|
items = key.split('.')
|
@@ -189,6 +224,7 @@ module Squared
|
|
189
224
|
end
|
190
225
|
end
|
191
226
|
rescue StandardError
|
227
|
+
project&.warn "#{Viewer}(#{type}) => #{file ? "#{file} " : ''}{#{key}: undefined}"
|
192
228
|
val = Regexp.escape($!.message)
|
193
229
|
key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
|
194
230
|
s = "<#{$3 || $2 || $1}>"
|
@@ -198,41 +234,59 @@ module Squared
|
|
198
234
|
$2 ? ".#{s}" : "#{s}."
|
199
235
|
end
|
200
236
|
end
|
201
|
-
out << [key, 'undefined']
|
237
|
+
out << [key, pipe? ? nil : 'undefined']
|
202
238
|
else
|
203
|
-
out << [key, val.inspect]
|
239
|
+
out << [key, pipe? ? val : val.inspect]
|
204
240
|
end
|
205
241
|
pad = key.size if key.size > pad
|
206
242
|
end
|
207
243
|
if pipe?
|
208
|
-
|
209
|
-
|
210
|
-
val.start_with?('"') && val.end_with?('"') ? val[1..-2] : val
|
211
|
-
end
|
244
|
+
require 'json'
|
245
|
+
out = out.map { |item| JSON.dump(item[1]) }
|
212
246
|
puts out.join("\n")
|
213
247
|
else
|
214
|
-
out.map { |item| "#{item.
|
248
|
+
out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
|
215
249
|
end
|
216
250
|
end
|
217
251
|
|
218
252
|
def base_path(file)
|
219
|
-
|
253
|
+
project ? project.base_path(file) : Pathname.new(file).realdirpath
|
220
254
|
end
|
221
255
|
|
222
|
-
def
|
223
|
-
|
256
|
+
def mime_type(file)
|
257
|
+
case (ret = File.extname(file).sub('.', '').downcase)
|
258
|
+
when 'yml'
|
259
|
+
'yaml'
|
260
|
+
when 'js'
|
261
|
+
'json'
|
262
|
+
else
|
263
|
+
ret.empty? ? nil : ret
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def format_desc(command, ext)
|
268
|
+
message(name, command, "#{ext.first}[#{exist? ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys*]")
|
224
269
|
end
|
225
270
|
|
226
|
-
def
|
227
|
-
|
271
|
+
def realpath
|
272
|
+
file = main + @ext
|
273
|
+
Pathname.new(file).realdirpath.to_s rescue file
|
274
|
+
end
|
275
|
+
|
276
|
+
def exist?
|
277
|
+
!@ext.empty? && (!@required || !project.nil?)
|
228
278
|
end
|
229
279
|
|
230
280
|
def pipe?
|
231
|
-
return
|
281
|
+
return project.workspace.pipe if project
|
232
282
|
|
233
283
|
val = ENV['PIPE_OUT']
|
234
284
|
!val.nil? && !val.empty? && val != '0'
|
235
285
|
end
|
286
|
+
|
287
|
+
def warning?
|
288
|
+
project ? project.warning : true
|
289
|
+
end
|
236
290
|
end
|
237
291
|
end
|
238
292
|
end
|