squared 0.0.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 117c669053bf0539d41840f655c1f7cb9a87af7d90366ded3c19803949184cdc
4
- data.tar.gz: 84266b0dd2bc5736eb05b5799692fd4fbed756e8a096343dc85f670e9257ae07
3
+ metadata.gz: ef428776d582a23bb5560efdc5c6f6d77fa5fb1adaecca5f11500b978126283a
4
+ data.tar.gz: cd8dfbae3f5162b55fd081ac65e31f0e2fca1167d4932e52ccd723f128a1a312
5
5
  SHA512:
6
- metadata.gz: 862884efb840359442202f1670ba4b8ff032397a3e6e6d5720289f844f63ec3119045bfb60b1f2c41673472d32861228587e7a33ab0fbf87d2c7df5e5fa37cde
7
- data.tar.gz: f775903d05491cbe92d80e9db391afa970c866fa4ae885666ffe4e95282d102df5b9faab6f20b17d9368243ff73c6552ff3c56ecf11423d6f68eaeaf4f242288
6
+ metadata.gz: e8bf3197a021dadc3bf8d15d4f80d5064a4254359a23b9e7576babe716189e0d17564acae48e018fc64b7caddde250f53eb479cae3e4997d7a3792fe66e07d5a
7
+ data.tar.gz: 312231359e1bd8f7052c91250234750ba9c41f5be1b806e852c60517d4c04e8d4ef55450d1b65fb35a946b2c6138d83bccc8280587b6c5b9832d717fa377c84a
data/README.ruby.md CHANGED
@@ -33,7 +33,7 @@ require "squared"
33
33
 
34
34
  Repo::Workspace
35
35
  .new("squared") # REPO_HOME
36
- .repo("https://github.com/anpham6/squared-repo", "nightly") # Optional
36
+ .repo("https://github.com/anpham6/squared-repo", "nightly", run: 'build') # Optional
37
37
  .run("rake install", ref: :ruby)
38
38
  .clean("rake clean", group: "default") # depend test doc
39
39
  .clean(["build/"], group: "app")
@@ -27,13 +27,13 @@ module Squared
27
27
  private_constant :AIX_TERM, :TEXT_STYLE
28
28
 
29
29
  def enable_aixterm
30
- unless (colors = get!(:colors)).frozen?
30
+ unless (colors = __get__(:colors)).frozen?
31
31
  colors.merge!(AIX_TERM)
32
32
  end
33
33
  block_given? ? yield(self) : self
34
34
  end
35
35
 
36
- def emphasize(val, title: nil, cols: nil, sub: nil)
36
+ def emphasize(val, title: nil, cols: nil, sub: nil, pipe: nil)
37
37
  n = 0
38
38
  if title
39
39
  title = title.to_s
@@ -64,8 +64,12 @@ module Squared
64
64
  out << bord
65
65
  if block_given?
66
66
  yield out
67
+ elsif pipe.respond_to?(:puts)
68
+ pipe.puts out
69
+ elsif err
70
+ defined?(__warn__) == 'method' ? __warn__(out) : warn(out)
67
71
  else
68
- err ? Warning.warn(out) : puts(out)
72
+ puts out
69
73
  end
70
74
  end
71
75
 
@@ -100,7 +104,7 @@ module Squared
100
104
  end
101
105
  else
102
106
  t = type.to_sym
103
- if (c = get!(:colors)[t])
107
+ if (c = __get__(:colors)[t])
104
108
  if index == -1
105
109
  s = wrap.(s, [c])
106
110
  else
@@ -138,7 +142,7 @@ module Squared
138
142
 
139
143
  def check_style(*args, empty: true)
140
144
  ret = []
141
- colors = get!(:colors)
145
+ colors = __get__(:colors)
142
146
  as_a(args, flat: true).each do |val|
143
147
  if !val.is_a?(Numeric)
144
148
  val = val.to_sym
@@ -153,6 +157,17 @@ module Squared
153
157
  !empty && ret.empty? ? nil : ret
154
158
  end
155
159
 
160
+ def apply_style(data, key, *args, empty: true)
161
+ return unless !data.is_a?(Symbol) || (data = __get__(:theme)[data])
162
+
163
+ set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
164
+ if key.is_a?(Hash)
165
+ key.each { |k, v| set.(k, v || args.flatten) }
166
+ else
167
+ set.(key, args.flatten)
168
+ end
169
+ end
170
+
156
171
  def log_title(level, color: true)
157
172
  level = if level.is_a?(::Numeric)
158
173
  case level
@@ -172,7 +187,8 @@ module Squared
172
187
  else
173
188
  level.to_s.downcase.to_sym
174
189
  end
175
- val = get!(:logger)[level] || get!(:logger)[level = :unknown]
190
+ theme = __get__(:theme)[:logger]
191
+ val = theme[level] || theme[level = :unknown]
176
192
  level = +level.to_s.upcase
177
193
  case level
178
194
  when 'WARN', 'ERROR', 'FATAL'
@@ -5,8 +5,6 @@ require 'pathname'
5
5
  module Squared
6
6
  module Common
7
7
  module System
8
- include Common
9
-
10
8
  def shell(*cmd, **kwargs)
11
9
  if /^2\.[0-5]\./.match?(RUBY_VERSION)
12
10
  exception = kwargs.delete(:exception)
@@ -20,7 +18,7 @@ module Squared
20
18
  end
21
19
 
22
20
  def copy_d(src, dest, glob: ['**/*'], create: false, verbose: true)
23
- raise message(src, dest, hint: 'not found') if !create && !dest.exist?
21
+ raise "#{dest} (not found)" if !create && !dest.exist?
24
22
 
25
23
  subdir = []
26
24
  files = 0
@@ -40,7 +38,7 @@ module Squared
40
38
  files += 1
41
39
  end
42
40
  end
43
- puts message(dest.realpath, subdir.size.to_s, files.to_s) if verbose
41
+ puts [dest.realpath, subdir.size.to_s, files.to_s].join(' => ') if verbose
44
42
  end
45
43
 
46
44
  def copy_f(src, dest, overwrite: true, verbose: false)
@@ -16,7 +16,7 @@ module Squared
16
16
  rescue StandardError => e
17
17
  raise if exception
18
18
 
19
- warn e
19
+ defined?(__warn__) == 'method' ? __warn__(e) : warn(e)
20
20
  end
21
21
 
22
22
  def invoked?(name)
@@ -26,22 +26,36 @@ module Squared
26
26
  cyan!: '46',
27
27
  white!: '47'
28
28
  },
29
- logger: {
30
- unknown: %i[cyan],
31
- fatal: %i[white bold red!],
32
- error: %i[red bold],
33
- warn: %i[yellow bold],
34
- info: %i[blue],
35
- debug: %i[green]
36
- }.freeze
29
+ theme: {
30
+ workspace: {},
31
+ project: {},
32
+ viewer: {
33
+ banner: %i[blue bold],
34
+ key: %i[bold],
35
+ value: %i[green],
36
+ string: %i[yellow],
37
+ hash: %i[green black!],
38
+ array: %i[blue black!],
39
+ number: %i[magenta],
40
+ undefined: %i[red italic]
41
+ },
42
+ logger: {
43
+ unknown: %i[cyan],
44
+ fatal: %i[white bold red!],
45
+ error: %i[red bold],
46
+ warn: %i[yellow bold],
47
+ info: %i[blue],
48
+ debug: %i[green]
49
+ }
50
+ }
37
51
  }.compare_by_identity
38
52
  private_constant :VAR
39
53
 
40
- def get!(key)
54
+ def __get__(key)
41
55
  VAR[key.is_a?(::String) ? key.to_sym : key]
42
56
  end
43
57
 
44
- def set!(key, val)
58
+ def __set__(key, val)
45
59
  return if VAR.frozen?
46
60
 
47
61
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
@@ -49,6 +63,7 @@ module Squared
49
63
 
50
64
  def finalize!
51
65
  VAR.each_value(&:freeze)
66
+ VAR[:theme].each_value(&:freeze)
52
67
  VAR.freeze
53
68
  end
54
69
 
@@ -3,68 +3,74 @@
3
3
  module Squared
4
4
  module Config
5
5
  class Viewer
6
- include Common::Format
6
+ include Common
7
+ include Format
7
8
  include Task
8
9
  include ::Rake::DSL
9
10
 
10
11
  class << self
11
- attr_reader :styles
12
-
13
- def style(name, *args)
14
- styles[name.to_sym]&.clear&.concat(args)
15
- end
16
-
17
12
  def to_s
18
13
  /[^:]+$/.match(super.to_s)[0]
19
14
  end
20
15
  end
21
16
 
22
- @styles = {
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
32
-
33
- attr_reader :main, :project, :name
17
+ attr_reader :name, :main, :project, :theme
34
18
 
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 = get!(:project)[project.to_sym]
21
+ main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
38
22
  @required = true
39
23
  end
40
- @name = (name || @project&.name)&.to_s
41
- unless @name
42
- msg, hint = project ? [project, 'not found'] : %w[name missing]
43
- warn log_message(:warn, msg, subject: self.class, hint: hint, color: !pipe?)
44
- @required = true
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
- @main = main
47
- @include = {}
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
 
56
+ params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
57
+
53
58
  namespace name do
54
- namespace :view do
55
- if @include['json'] && !::Rake::Task.task_defined?("#{name}:view:json")
56
- desc format_desc('json')
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 JSON, 'json', args.keys, args.extras
65
+ read_keys(JSON, 'json', *params.(args))
60
66
  end
61
67
  end
62
68
 
63
- if @include['yaml'] && !::Rake::Task.task_defined?("#{name}:view:yaml")
64
- desc format_desc('yaml', 'yml')
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 YAML, 'yaml', args.keys, args.extras, 'yml', 'yaml'
73
+ read_keys(YAML, 'yaml', *params.(args), ext: %w[yml yaml])
68
74
  end
69
75
  end
70
76
  end
@@ -73,20 +79,24 @@ module Squared
73
79
  yield self if block_given?
74
80
  end
75
81
 
76
- def add(type, gem: nil, parse: nil, ext: [], opts: {}, command: nil, file: nil)
82
+ def add(type, gem: nil, parse: nil, ext: [], opts: {}, command: 'view', file: nil)
83
+ return self if @mime.frozen?
84
+
77
85
  type = type.to_s
78
86
  if parse && enabled?
79
87
  require(gem || type)
80
88
  obj = eval(parse)
81
89
  ext = as_a(ext)
90
+ ext << type if ext.empty?
91
+ file = realpath if file.nil? && exist?
82
92
  namespace name do
83
- desc format_desc(ext.first || type, command: command)
84
- namespace(command || :view) do
93
+ desc format_desc(command, ext)
94
+ namespace command do
85
95
  task type, [:keys] do |_, args|
86
96
  if file
87
- read_keys obj, type, file.to_s, collect_args(args, :keys), *ext
97
+ read_keys(obj, type, file.to_s, collect_args(args, :keys), ext: ext)
88
98
  else
89
- read_keys obj, type, args.keys, args.extras, *ext
99
+ read_keys(obj, type, args.keys, args.extras, ext: ext)
90
100
  end
91
101
  end
92
102
  end
@@ -95,16 +105,19 @@ module Squared
95
105
  rescue LoadError, NameError
96
106
  self
97
107
  else
98
- @include[type] = opts
108
+ @mime[type] = opts
109
+ if exist?
110
+ @command = command
111
+ @mime.freeze
112
+ end
99
113
  self
100
114
  end
101
115
 
102
116
  def also(path, type = nil, name: nil, gem: nil, parse: nil, opts: {})
103
- return self unless (file = base_path(path)).exist?
117
+ return self if @mime.frozen? || !(file = base_path(path)).exist?
104
118
 
105
- ext = chop_extname(file).downcase
106
- name ||= file.basename.to_s.chomp(".#{ext}")
107
- type = (type || ext).to_s
119
+ ext = mime_type(file)
120
+ type = type&.to_s || ext
108
121
  if !parse
109
122
  case type
110
123
  when 'json'
@@ -114,49 +127,59 @@ module Squared
114
127
  parse = 'YAML'
115
128
  end
116
129
  end
130
+ name ||= file.basename.to_s.chomp(File.extname(file))
117
131
  add(type, gem: gem, parse: parse, ext: ext, opts: opts, command: name, file: file)
118
132
  end
119
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
+
120
143
  def to_s
121
- @include.keys.map { |ext| "#{main}.#{ext}" }.join(',')
144
+ realpath if exist?
145
+
146
+ @mime.keys.map { |ext| "#{main}.#{ext}" }.join(',')
122
147
  end
123
148
 
124
149
  def inspect
125
- "#<#{self.class}: #{name} => #{main} {#{@include.keys.join(', ')}}>"
150
+ "#<#{self.class}: #{name} => #{exist? ? realpath : "#{main} {#{extensions.join(', ')}}"}>"
126
151
  end
127
152
 
128
153
  def enabled?
129
- !@required || !!project&.enabled?
154
+ return File.exist?(realpath) if exist?
155
+
156
+ !@required || (!project.nil? && project.enabled?)
130
157
  end
131
158
 
132
159
  protected
133
160
 
134
- def read_keys(reader, type, file, keys, *ext)
135
- path = base_path(file)
136
- fmt = chop_extname(file)
137
- ext << type if ext.empty?
138
- if path.exist? && path.basename.to_s.include?('.')
139
- 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)
140
164
  else
141
- if ext.include?(fmt)
165
+ if ext.include?(mime)
142
166
  alt = file
143
167
  file = nil
144
- ext[0] = fmt
168
+ ext[0] = mime
145
169
  else
146
170
  keys.unshift(file)
147
- alt = "#{main}.{#{ext.join(',')}}"
148
- alt = project.base_path(alt) if project
171
+ alt = base_path("#{main}.{#{ext.join(',')}}")
149
172
  file = Dir[alt].first
150
173
  end
151
- if !file
174
+ unless file
152
175
  raise ArgumentError, message(reader.name, "#{File.basename(alt, '.*')}.#{ext.first}", hint: 'not found')
153
176
  end
154
177
  end
155
178
  project&.info "#{Viewer}(#{type}) => #{file} {#{keys.join(', ')}}"
156
179
  doc = if reader.respond_to?(:load_file)
157
- reader.load_file(file, **@include[type])
180
+ reader.load_file(file, **@mime[type])
158
181
  else
159
- reader.parse(File.read(file), **@include[type])
182
+ reader.parse(File.read(file), **@mime[type])
160
183
  end
161
184
  lines = print_keys(type, doc, keys, file: file)
162
185
  return unless lines
@@ -168,15 +191,16 @@ module Squared
168
191
  sub = if pipe?
169
192
  nil
170
193
  else
194
+ styles = theme
171
195
  [
172
- { pat: /^([^:]+|(?<! ):(?! ))+$/, styles: Viewer.styles[:banner] },
173
- { pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: Viewer.styles[:undefined], index: 2 },
174
- { pat: /^(.+)( : (?!undefined).+)$/m, styles: Viewer.styles[:key] },
175
- { pat: /^(.+ : )(-?[\d.]+)(\s*)$/m, styles: Viewer.styles[:number], index: 2 },
176
- { pat: /^(.+ : ")(.+)("\s*)$/m, styles: Viewer.styles[:string], index: 2 },
177
- { pat: /^(.+ : \{)(.+)(\}\s*)$/m, styles: Viewer.styles[:hash], index: 2 },
178
- { pat: /^(.+ : \[)(.+)(\]\s*)$/m, styles: Viewer.styles[:array], index: 2 },
179
- { pat: /^(.+ : (?!undefined))([^"\[{].*)$/m, styles: Viewer.styles[:value], index: 2 }
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 }
180
204
  ]
181
205
  end
182
206
  emphasize(lines, title: title, sub: sub)
@@ -185,7 +209,7 @@ module Squared
185
209
  def print_keys(type, data, keys, file: nil)
186
210
  out = []
187
211
  pad = 0
188
- symbolize = @include[type][:symbolize_names]
212
+ symbolize = @mime[type][:symbolize_names]
189
213
  keys.each do |key|
190
214
  begin
191
215
  items = key.split('.')
@@ -210,20 +234,18 @@ module Squared
210
234
  $2 ? ".#{s}" : "#{s}."
211
235
  end
212
236
  end
213
- out << [key, 'undefined']
237
+ out << [key, pipe? ? nil : 'undefined']
214
238
  else
215
- out << [key, val.inspect]
239
+ out << [key, pipe? ? val : val.inspect]
216
240
  end
217
241
  pad = key.size if key.size > pad
218
242
  end
219
243
  if pipe?
220
- out = out.map do |item|
221
- val = item.last
222
- val.start_with?('"') && val.end_with?('"') ? val[1..-2] : val
223
- end
244
+ require 'json'
245
+ out = out.map { |item| JSON.dump(item[1]) }
224
246
  puts out.join("\n")
225
247
  else
226
- out.map { |item| "#{item.first.ljust(pad)} : #{item.last}" }
248
+ out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
227
249
  end
228
250
  end
229
251
 
@@ -231,12 +253,28 @@ module Squared
231
253
  project ? project.base_path(file) : Pathname.new(file).realdirpath
232
254
  end
233
255
 
234
- def format_desc(type, alt = nil, command: nil)
235
- message(name, command || 'view', "#{type}[#{command.nil? ? "file?=#{main}.#{alt || type}," : ''}keys*]")
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*]")
236
269
  end
237
270
 
238
- def chop_extname(file)
239
- File.extname(file).sub('.', '')
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?)
240
278
  end
241
279
 
242
280
  def pipe?
@@ -245,6 +283,10 @@ module Squared
245
283
  val = ENV['PIPE_OUT']
246
284
  !val.nil? && !val.empty? && val != '0'
247
285
  end
286
+
287
+ def warning?
288
+ project ? project.warning : true
289
+ end
248
290
  end
249
291
  end
250
292
  end
@@ -7,7 +7,8 @@ module Squared
7
7
  module Repo
8
8
  module Project
9
9
  class Base
10
- include Common::System
10
+ include Common
11
+ include System
11
12
  include Shell
12
13
  include Task
13
14
  include ::Rake::DSL
@@ -17,11 +18,17 @@ module Squared
17
18
  include Common::Task
18
19
  include ::Rake::DSL
19
20
 
21
+ def populate(*); end
22
+
20
23
  def tasks
21
24
  [].freeze
22
25
  end
23
26
 
24
- def populate(*); end
27
+ def as_path(val)
28
+ return val if val.is_a?(::Pathname)
29
+
30
+ val.is_a?(::String) ? Pathname.new(val) : nil
31
+ end
25
32
 
26
33
  def to_s
27
34
  /[^:]+$/.match(super.to_s)[0]
@@ -35,25 +42,33 @@ module Squared
35
42
  @@print_order = 0
36
43
  @@tasks = {}
37
44
 
38
- attr_reader :name, :project, :workspace, :group, :path, :logger
45
+ alias __warn__ warn
46
+
47
+ attr_reader :name, :project, :workspace, :group, :path, :logger, :theme
48
+ attr_accessor :warning
39
49
 
40
50
  protected :logger
41
51
 
42
52
  def_delegators :logger, :log, :<<, :debug, :info, :warn, :error, :fatal, :unknown
43
53
 
44
- def initialize(name, project, workspace, **kwargs)
54
+ def initialize(name, path, workspace, *, group: nil, log: nil, common: true, **kwargs)
45
55
  @name = name.to_s
46
- @path = workspace.root_path(project.to_s)
56
+ @path = workspace.root_path(path.to_s)
47
57
  @project = @path.basename.to_s
48
58
  @workspace = workspace
49
- @group = kwargs[:group]&.to_s
59
+ @group = group&.to_s
50
60
  @depend = kwargs[:depend]
51
61
  @doc = kwargs[:doc]
52
62
  @test = kwargs[:test]
53
63
  @output = [kwargs[:run], nil]
54
64
  @copy = kwargs[:copy]
55
65
  @clean = kwargs[:clean]
56
- log = kwargs[:log]
66
+ @theme = if common
67
+ workspace.theme
68
+ else
69
+ __get__(:theme)[:project][to_sym] ||= {}
70
+ end
71
+ @warning = workspace.warning
57
72
  log = { file: log } unless log.is_a?(::Hash)
58
73
  if (logfile = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
59
74
  logfile = case auto
@@ -72,7 +87,7 @@ module Squared
72
87
  logfile.realdirpath
73
88
  rescue StandardError => e
74
89
  logfile = nil
75
- Warning.warn e
90
+ __warn__ e if @warning
76
91
  end
77
92
  end
78
93
  @logger = Logger.new(logfile, progname: @name, level: env('LOG_LEVEL') || log[:level] || Logger::INFO)
@@ -162,6 +177,10 @@ module Squared
162
177
  run(@depend, exception: workspace.exception) if @depend
163
178
  end
164
179
 
180
+ def copy(*)
181
+ run_s @copy
182
+ end
183
+
165
184
  def doc
166
185
  build @doc if @doc
167
186
  end
@@ -170,10 +189,6 @@ module Squared
170
189
  build @test if @test
171
190
  end
172
191
 
173
- def copy(*)
174
- run_s @copy
175
- end
176
-
177
192
  def clean
178
193
  return unless @clean
179
194
 
@@ -194,7 +209,7 @@ module Squared
194
209
  begin
195
210
  File.delete(file) if File.file?(file)
196
211
  rescue StandardError => e
197
- warn e
212
+ error e
198
213
  end
199
214
  end
200
215
  end
@@ -202,10 +217,6 @@ module Squared
202
217
  end
203
218
  end
204
219
 
205
- def styles
206
- workspace.styles
207
- end
208
-
209
220
  def base_path(*args)
210
221
  path.join(*args)
211
222
  end
@@ -349,7 +360,7 @@ module Squared
349
360
 
350
361
  if verbose?
351
362
  pad = 0
352
- if (args = styles[:banner])
363
+ if (args = theme[:banner])
353
364
  if args.any? { |s| s.to_s.end_with?('!') }
354
365
  pad = 1
355
366
  elsif args.size <= 1
@@ -4,7 +4,7 @@ module Squared
4
4
  module Repo
5
5
  module Project
6
6
  class Git < Base
7
- include Common::Format
7
+ include Format
8
8
 
9
9
  REF = :git
10
10
  private_constant :REF
@@ -35,7 +35,7 @@ module Squared
35
35
  end
36
36
 
37
37
  def is_a?(val)
38
- if val.is_a?(::Pathname) || (val.is_a?(::String) && (val = Pathname.new(val)))
38
+ if (val = as_path(val))
39
39
  val.join('.git').directory?
40
40
  else
41
41
  super
@@ -516,7 +516,7 @@ module Squared
516
516
  return unless verbose?
517
517
 
518
518
  if size > 0
519
- args = styles[:banner]&.reject { |s| s.to_s.end_with?('!') } || []
519
+ args = theme[:banner]&.reject { |s| s.to_s.end_with?('!') } || []
520
520
  args << :bold if args.size <= 1
521
521
  puts print_footer "#{sub_style(size, *args)} #{size == 1 ? type.sub(/s$/, '') : type}"
522
522
  else
@@ -19,7 +19,7 @@ module Squared
19
19
  end
20
20
 
21
21
  def is_a?(val)
22
- if val.is_a?(::Pathname) || (val.is_a?(::String) && (val = Pathname.new(val)))
22
+ if (val = as_path(val))
23
23
  val.join('package.json').exist?
24
24
  else
25
25
  super
@@ -33,7 +33,7 @@ module Squared
33
33
  run: nil
34
34
  }.freeze
35
35
 
36
- def initialize(name, project, workspace, **kwargs)
36
+ def initialize(name, path, workspace, *, **kwargs)
37
37
  super
38
38
  initialize_script(REF)
39
39
  if (opts = env('BUILD', strict: true))
@@ -206,8 +206,7 @@ module Squared
206
206
  info cmd
207
207
  data = `#{cmd} --json --loglevel=error`
208
208
  Dir.chdir(pwd)
209
- doc = File.read(package)
210
- json = JSON.parse(doc)
209
+ json = JSON.parse(doc = package.read)
211
210
  pat = /^(\d+)(\.)(\d+)(\.)(\d+)$/
212
211
  dep1 = json['dependencies'] || {}
213
212
  dep2 = json['devDependencies'] || {}
@@ -451,11 +450,11 @@ module Squared
451
450
  elsif pnpm?
452
451
  if silent
453
452
  cmd << '--reporter=silent'
454
- else
455
- case level
456
- when 'debug', 'info', 'warn', 'error'
457
- cmd << "--loglevel=#{level}"
458
- end
453
+ level ||= 'error'
454
+ end
455
+ case level
456
+ when 'debug', 'info', 'warn', 'error'
457
+ cmd << "--loglevel=#{level}"
459
458
  end
460
459
  elsif silent
461
460
  cmd << '--loglevel=silent'
@@ -21,7 +21,7 @@ module Squared
21
21
  end
22
22
 
23
23
  def is_a?(val)
24
- if val.is_a?(::Pathname) || (val.is_a?(::String) && (val = Pathname.new(val)))
24
+ if (val = as_path(val))
25
25
  REQUIREMENTS.any? { |file| val.join(file).exist? }
26
26
  else
27
27
  super
@@ -29,7 +29,7 @@ module Squared
29
29
  end
30
30
  end
31
31
 
32
- def initialize(name, project, workspace, **kwargs)
32
+ def initialize(name, path, workspace, *, **kwargs)
33
33
  super
34
34
  initialize_build(REF, **kwargs)
35
35
  end
@@ -97,7 +97,7 @@ module Squared
97
97
 
98
98
  def outdated(*); end
99
99
 
100
- def install_type
100
+ def install_type(*)
101
101
  return @requirements if @requirements
102
102
 
103
103
  ret = REQUIREMENTS.index { |file| base_path(file).exist? }
@@ -18,7 +18,7 @@ module Squared
18
18
  end
19
19
 
20
20
  def is_a?(val)
21
- if val.is_a?(::Pathname) || (val.is_a?(::String) && (val = Pathname.new(val)))
21
+ if (val = as_path(val))
22
22
  [*GEMFILE, *::Rake::Application::DEFAULT_RAKEFILES, 'README.rdoc'].any? { |file| val.join(file).exist? }
23
23
  else
24
24
  super
@@ -33,7 +33,7 @@ module Squared
33
33
  rake: nil
34
34
  }.freeze
35
35
 
36
- def initialize(name, project, workspace, **kwargs)
36
+ def initialize(name, path, workspace, *, **kwargs)
37
37
  super
38
38
  initialize_build(REF, **kwargs)
39
39
  @version = env('BUILD', suffix: 'VERSION', strict: true) || kwargs.delete(:version)
@@ -51,7 +51,7 @@ module Squared
51
51
  break
52
52
  end
53
53
  rescue StandardError => e
54
- warn e
54
+ error e
55
55
  end
56
56
  end
57
57
 
@@ -213,11 +213,11 @@ module Squared
213
213
  end
214
214
  return false unless @autodetect
215
215
 
216
- error = ->(hint) { raise ArgumentError, message('failed to parse', hint: hint) }
216
+ quit = ->(hint) { raise ArgumentError, message('failed to parse', hint: hint) }
217
217
  begin
218
218
  out = `gem -C #{shell_quote(path)} list --local -d #{project}`
219
219
  data = /#{Regexp.escape(project)} \(([^)]+)\)/.match(out)
220
- error.('version') unless data
220
+ quit.('version') unless data
221
221
  ver = data[1].split(/\s*,\s*/)
222
222
  if @version
223
223
  ver.unshift(@version)
@@ -231,10 +231,10 @@ module Squared
231
231
  @version = v
232
232
  break
233
233
  end
234
- error.('path') unless data
234
+ quit.('path') unless data
235
235
  @gemdir = Pathname.new(data[1].strip).join(gempath.())
236
236
  rescue StandardError => e
237
- warn e
237
+ error e
238
238
  @version = nil
239
239
  @gemdir = nil
240
240
  @autodetect = false
@@ -3,7 +3,8 @@
3
3
  module Squared
4
4
  module Repo
5
5
  class Workspace
6
- include Common::Format
6
+ include Common
7
+ include Format
7
8
  include System
8
9
  include Task
9
10
  include ::Rake::DSL
@@ -51,10 +52,10 @@ module Squared
51
52
 
52
53
  @project_kind = []
53
54
 
54
- attr_reader :main, :root, :home, :series
55
- attr_accessor :manifest, :manifest_url, :exception, :styles, :pipe, :verbose
55
+ attr_reader :main, :root, :home, :series, :theme
56
+ attr_accessor :manifest, :manifest_url, :exception, :pipe, :verbose, :warning
56
57
 
57
- def initialize(main)
58
+ def initialize(main, *, common: true, **)
58
59
  @main = main.to_s
59
60
  @home = if (val = env('REPO_HOME'))
60
61
  home = Pathname.new(val)
@@ -90,7 +91,7 @@ module Squared
90
91
  end
91
92
  @root ||= @home.parent
92
93
  @series = TASK_NAME.dup
93
- @styles = {}
94
+ @theme = common ? __get__(:theme)[:workspace] : {}
94
95
  @project = {}
95
96
  @script = {
96
97
  group: {},
@@ -102,9 +103,12 @@ module Squared
102
103
  @exception = !env('PIPE_FAIL', ignore: '0').nil?
103
104
  @pipe = !env('PIPE_OUT', ignore: '0').nil?
104
105
  @verbose = !@pipe
106
+ @warning = !empty?(@root, init: false)
105
107
  end
106
108
 
107
109
  def build(**kwargs)
110
+ return unless enabled?
111
+
108
112
  default = kwargs[:default]
109
113
  parallel = env('REPO_SYNC', ignore: '0') ? [] : (kwargs[:parallel] || []).map!(&:to_sym)
110
114
 
@@ -140,9 +144,9 @@ module Squared
140
144
  end
141
145
  series.merge!(parent) if incl.uniq.size > 1
142
146
  series.merge!(group)
143
- series[:refresh].clear if series[:refresh].all? { |target| target.to_s.end_with?(':build') }
147
+ series[:refresh].clear if series[:refresh].all? { |target| target.end_with?(':build') }
144
148
 
145
- if manifest_url && (empty?(root) || @override)
149
+ if repo?
146
150
  branch = env('REPO_MANIFEST') || read_manifest
147
151
  target = branch || manifest
148
152
  stage = nil
@@ -250,27 +254,35 @@ module Squared
250
254
  yield self if block_given?
251
255
  end
252
256
 
253
- def repo(url, manifest = 'latest')
257
+ def repo(url, manifest = 'latest', run: nil, dev: nil, prod: nil)
254
258
  @manifest_url = url
255
259
  @manifest = manifest
256
- self
260
+ script = case (val = env('REPO_BUILD'))
261
+ when 'verbose'
262
+ run ? "#{run}:verbose" : nil
263
+ when 'silent'
264
+ @verbose = false
265
+ @warning = false
266
+ run
267
+ else
268
+ val || run
269
+ end
270
+ case env('REPO_WARN')
271
+ when '0'
272
+ @warning = false
273
+ when '1'
274
+ @warning = true
275
+ end
276
+ script ? run(script, dev: bool_match(env('REPO_DEV'), dev), prod: bool_match(env('REPO_DEV'), prod)) : self
257
277
  end
258
278
 
259
279
  def run(script, group: nil, ref: nil, **kwargs)
260
280
  if group || ref
261
281
  script_command :run, script, group, ref
262
282
  else
263
- @script[:build] = case (val = env('REPO_BUILD'))
264
- when 'verbose'
265
- "#{script}:verbose"
266
- when 'silent'
267
- @verbose = false
268
- script
269
- else
270
- val || script
271
- end
272
- @script[:dev] = bool_match(env('REPO_DEV'), kwargs[:dev])
273
- @script[:prod] = bool_match(env('REPO_PROD'), kwargs[:prod])
283
+ @script[:build] = script
284
+ @script[:dev] = kwargs[:dev]
285
+ @script[:prod] = kwargs[:prod]
274
286
  self
275
287
  end
276
288
  end
@@ -291,17 +303,17 @@ module Squared
291
303
  script_command :test, script, group, ref
292
304
  end
293
305
 
294
- def add(name, dir = nil, **kwargs)
295
- path = (dir || name).to_s
306
+ def add(name, path = nil, **kwargs)
307
+ path = root_path((path || name).to_s)
296
308
  ref = kwargs[:ref]
297
309
  project = if !ref.is_a?(::Class)
298
- Workspace.find(path: root_path(path), ref: ref)
310
+ Workspace.find(path: path, ref: ref)
299
311
  elsif ref < Project::Base
300
312
  ref
301
313
  end
302
314
  instance = (project || Project::Base).new(name, path, self, **kwargs)
303
315
  @project[n = name.to_sym] = instance
304
- get!(:project)[n] = instance
316
+ __get__(:project)[n] = instance unless kwargs[:private]
305
317
  self
306
318
  end
307
319
 
@@ -315,13 +327,19 @@ module Squared
315
327
  self
316
328
  end
317
329
 
318
- def style(name, *args)
319
- set = ->(k, v) { styles[k.to_sym] = check_style(v, empty: false) }
320
- if name.is_a?(Hash)
321
- name.each { |k, v| set.(k, v || args.flatten) }
322
- else
323
- set.(name, args.flatten)
330
+ def style(name, *args, target: nil, empty: false)
331
+ data = nil
332
+ if target
333
+ as_a(target).each_with_index do |val, i|
334
+ if i == 0
335
+ break unless (data = __get__(:theme)[val.to_sym])
336
+ else
337
+ data = data[val.to_sym] ||= {}
338
+ end
339
+ end
340
+ return unless data
324
341
  end
342
+ apply_style(data || theme, name, *args, empty: empty)
325
343
  self
326
344
  end
327
345
 
@@ -340,12 +358,12 @@ module Squared
340
358
  ret.empty? || as_a(ignore).any? { |val| ret == val.to_s } ? nil : ret
341
359
  end
342
360
 
343
- def read_manifest
361
+ def read_manifest(*)
344
362
  require 'rexml/document'
345
363
  file = root_path('.repo/manifest.xml')
346
364
  return unless file.exist?
347
365
 
348
- doc = REXML::Document.new(File.read(file))
366
+ doc = REXML::Document.new(file.read)
349
367
  doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
350
368
  end
351
369
 
@@ -382,13 +400,12 @@ module Squared
382
400
  "#<#{self.class}: #{main} => #{self}>"
383
401
  end
384
402
 
385
- def empty?(dir)
386
- return true if dir.empty? || dir.join('.repo').directory?
387
- return true if dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__
403
+ def enabled?
404
+ repo? || @project.any? { |_, proj| proj.enabled? }
405
+ end
388
406
 
389
- dir == root && !env('REPO_ROOT').nil? && root.children.none? do |path|
390
- path.directory? && !path.basename.to_s.start_with?('.') && path.to_s != home.to_s
391
- end
407
+ def repo?
408
+ !manifest_url.nil? && (empty?(root) || @override)
392
409
  end
393
410
 
394
411
  def multitask?
@@ -399,6 +416,15 @@ module Squared
399
416
  end
400
417
  end
401
418
 
419
+ def empty?(dir, init: true)
420
+ return true if dir.empty? || (init && dir.join('.repo').directory?)
421
+ return true if dir.children.size == 1 && dir.join(dir.children.first).to_s == __FILE__
422
+
423
+ dir == root && !env('REPO_ROOT').nil? && root.children.none? do |path|
424
+ path.directory? && !path.basename.to_s.start_with?('.') && path.to_s != home.to_s
425
+ end
426
+ end
427
+
402
428
  def task_defined?(obj, key)
403
429
  obj.is_a?(TASK_BASE[key])
404
430
  end
data/lib/squared/repo.rb CHANGED
@@ -9,7 +9,7 @@ module Squared
9
9
  project id
10
10
  else
11
11
  (id = Pathname.new(id).realdirpath.to_s) rescue nil if id.is_a?(::String)
12
- get!(:project).find { |_, val| val.path.to_s == id.to_s }
12
+ __get__(:project).find { |_, val| val.path.to_s == id.to_s }
13
13
  end
14
14
  end
15
15
  ret.size == 1 ? ret.first : ret
@@ -19,7 +19,7 @@ module Squared
19
19
  ret = project(name)
20
20
  return ret if ret&.path&.directory?
21
21
 
22
- raise NoMethodError, message('project is not initialized', name)
22
+ raise NoMethodError, "project is not initialized (#{name})"
23
23
  end
24
24
 
25
25
  def project?(name)
@@ -29,7 +29,7 @@ module Squared
29
29
  private
30
30
 
31
31
  def project(name)
32
- get!(:project)[name.to_sym]
32
+ __get__(:project)[name.to_sym]
33
33
  end
34
34
  end
35
35
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-01 00:00:00.000000000 Z
11
+ date: 2024-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake