squared 0.0.1 → 0.0.3
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/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
|