squared 0.0.12 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d9e8c772c9f4d0ce5c54dbeb1b9583d2e477f155036faf34cfc547659c34ec4
4
- data.tar.gz: 87de412a78c0071eabd4b26713cbf84978a92fca6ea1a6dfe18653ddf22c90ee
3
+ metadata.gz: 5d5c87e8fd0e459e55e900839ba9f5f43e51ee1990d1fa103f9de264ae94c4e1
4
+ data.tar.gz: 1e38b9df0a7d3f2b48d6912b880d1c2d593dcf04a1942a01791b84ea8b9e023c
5
5
  SHA512:
6
- metadata.gz: '08475f426b15c41dab20fbead5d7c1ead70f5d80384e0a0772cbe7b101512a4402a1bb1231b2550f7da16aac2796f8411f6a6e3e570ae728d59b03f88fea5960'
7
- data.tar.gz: 5c0334640b20dda82641925cd94b41d76be4cd4e603355fef593a5cd69731ac926febab67f3ffa494267291ec9d89efba2f8a9ac4dde978ab2814a0f8a481a67
6
+ metadata.gz: f4b9df6f9d39a24bd1db9e056ab4b5864e36a6d5daf46403881845e3d1d725033b31a4c9d11274595a74c59dbf13ac77845e96a0c3e2f74c09317a3a1f123a62
7
+ data.tar.gz: fcd0370d7ba7b6b590c9fec4a411a302dde15c8124f832aa5ed1a1e58cef209481ac9d595a5d8d385fefce87a8dc0e53a9208b0da6916c00d3a3e8f853748813
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2024-12-7
4
+
5
+ ### Added
6
+
7
+ - Git command show was implemented.
8
+ - Projects can run arbitrarily ordered graphs.
9
+ - Repo can be installed from a nested directory without a Rakefile.
10
+ - Python interpreter can be set using ENV option PIP_PYTHON.
11
+ - Node workspaces can be copied by registry package name.
12
+
13
+ ### Changed
14
+
15
+ - Parallel tasks support using Regexp patterns.
16
+ - Project copy globs were renamed include and exclude.
17
+
18
+ ### Fixed
19
+
20
+ - Project workspaces did not detect for a valid directory.
21
+ - Git pull did not display colors for diff bar chart.
22
+ - Git commit did not fetch latest refs before submitting.
23
+
24
+ ## [0.0.12] - 2024-12-1
25
+
26
+ ### Added
27
+
28
+ - Changelog was created.
29
+
30
+ [0.1.0]: https://github.com/anpham6/squared/releases/tag/v0.1.0-ruby
31
+ [0.0.12]: https://github.com/anpham6/squared/releases/tag/v0.0.12-ruby
data/README.md CHANGED
@@ -129,10 +129,17 @@ REPO_ROOT=/tmp/123 NODE_INSTALL=pnpm repo:init
129
129
  ```sh
130
130
  # NODE_TAG=latest
131
131
  # RUBY_VERSION=2.4.0-3.3.0
132
+ # MANIFEST=nightly,staging,prod,android
132
133
  # BUILD={dev,prod}
133
134
  # DEV={0,1,local}
134
- # DOCS=1
135
+ # DOCS=any
136
+ # PIPE_FAIL={0,1}
135
137
  docker build -t squared --build-arg MANIFEST=prod --build-arg SQUARED=prod .
138
+ docker build -t node --build-arg NODE_TAG=20 --build-arg NODE_INSTALL=pnpm -f Dockerfile.slim . # no docs
139
+ # OR
140
+ # RUBY_TAG=latest
141
+ # NODE_VERSION=22.x
142
+ docker build -t ruby --build-arg RUBY_TAG=3.0 --build-arg NODE_VERSION=20.x --build-arg PIPE_FAIL=0 -f Dockerfile.ruby .
136
143
 
137
144
  # Express
138
145
  docker run -it --name express --rm -p 127.0.0.1:80:80 \
data/README.ruby.md CHANGED
@@ -20,6 +20,7 @@ gem install squared
20
20
 
21
21
  * [Repo](https://source.android.com/docs/setup/reference/repo)
22
22
  * Python 3.6
23
+ * Not compatible with Windows
23
24
 
24
25
  ```sh
25
26
  mkdir -p ~/.bin
@@ -30,7 +31,7 @@ chmod a+rx ~/.bin/repo
30
31
 
31
32
  ## Example - Rakefile
32
33
 
33
- Projects from any accessible folder can be added either relative to `REPO_ROOT` or absolutely. The same Rakefile can also manage other similarly cloned repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
34
+ Projects from any accessible folder can be added relative to the parent directory (e.g. *REPO_ROOT*) or absolutely. The same Rakefile can also manage other similarly cloned `Repo` repositories remotely by setting the `REPO_ROOT` environment variable to the location. Missing projects will simply be excluded from the task runner.
34
35
 
35
36
  ```ruby
36
37
  require "squared"
@@ -45,7 +46,7 @@ require "squared/app" # All workspace related modules
45
46
 
46
47
  # NODE_ENV = production
47
48
  # REPO_ROOT = /workspaces
48
- # REPO_HOME = /workspaces/squared (Dir.pwd)
49
+ # REPO_HOME = /workspaces/squared
49
50
  # rake = /workspaces/squared/Rakefile
50
51
  # pathname = /workspaces/pathname
51
52
  # optparse = /workspaces/optparse
@@ -88,7 +89,7 @@ Workspace::Application
88
89
  variable_set :clean, ["build/sqd/"]
89
90
  end
90
91
  .style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
91
- .build(default: "status", parallel: ["pull", "fetch", "rebase", "copy", "clean", "outdated:ruby"]) do |workspace|
92
+ .build(default: "build", parallel: ["pull", "fetch", "rebase", "copy", "clean", /^outdated:/]) do |workspace|
92
93
  workspace
93
94
  .enable_aixterm
94
95
  .style({
@@ -130,12 +131,13 @@ Workspace::Application
130
131
  ```ruby
131
132
  Workspace::Application
132
133
  .new(main: "squared")
134
+ .graph(["depend"], ref: :git) # Optional
133
135
  .with(:python) do
134
136
  add("android-docs", "android")
135
137
  add("chrome-docs", "chrome", graph: "android")
136
138
  end
137
139
  .with(:node) do
138
- graph(["build", "copy"]) # Optional
140
+ graph(["build", "copy"]) # Overrides "git"
139
141
  add("e-mc", "emc")
140
142
  add("pi-r", "pir", graph: "emc")
141
143
  add("squared-express", "express", graph: "pir")
@@ -15,7 +15,7 @@ module Squared
15
15
  def_delegators :@data, :+, :each, :each_with_index, :entries, :to_a, :include?
16
16
 
17
17
  def initialize(data = [])
18
- @data = ::Set.new(data)
18
+ @data = Set.new(data)
19
19
  end
20
20
 
21
21
  def add(val)
@@ -29,7 +29,7 @@ module Squared
29
29
  alias inspect to_s
30
30
  end
31
31
 
32
- class JoinSet < ::Set
32
+ class JoinSet < Set
33
33
  def self.to_s
34
34
  super.match(/[^:]+$/)[0]
35
35
  end
@@ -94,7 +94,7 @@ module Squared
94
94
  ret = wrap.(ret, code) unless code.empty?
95
95
  return ret unless data
96
96
 
97
- out = +''
97
+ out = ''.dup
98
98
  data.to_a.each_with_index do |group, i|
99
99
  next if i == 0
100
100
 
@@ -20,17 +20,21 @@ module Squared
20
20
  end
21
21
  end
22
22
 
23
- def copy_d(src, dest, glob: ['**/*'], create: false, verbose: true)
23
+ def copy_d(src, dest, glob: ['**/*'], pass: nil, create: false, verbose: true)
24
24
  src = ::Pathname.new(src)
25
25
  dest = ::Pathname.new(dest)
26
- raise "#{dest} (not found)" if !create && !dest.exist?
26
+ raise "#{dest} (not found)" if !create && !dest.parent.exist?
27
27
 
28
28
  subdir = []
29
29
  files = 0
30
30
  dest.mkpath if create
31
+ if pass
32
+ exclude = []
33
+ (pass.is_a?(::Array) ? pass : [pass]).each { |val| exclude += ::Dir.glob(src.join(val)) }
34
+ end
31
35
  (glob.is_a?(::Array) ? glob : [glob]).each do |val|
32
36
  ::Dir.glob(src.join(val)) do |path|
33
- next if (path = ::Pathname.new(path)).directory?
37
+ next if exclude&.include?(path) || (path = ::Pathname.new(path)).directory?
34
38
 
35
39
  target = dest.join(path.relative_path_from(src))
36
40
  dir = target.dirname
@@ -27,8 +27,12 @@ module Squared
27
27
  end
28
28
  end
29
29
 
30
- def task_invoked?(name)
31
- ::Rake::Task.tasks.any? { |obj| obj.already_invoked && obj.name == name }
30
+ def task_invoked?(*args)
31
+ ::Rake::Task.tasks.any? do |obj|
32
+ next unless obj.already_invoked
33
+
34
+ args.any? { |val| val.is_a?(::Regexp) ? val.match?(obj.name) : val == obj.name }
35
+ end
32
36
  end
33
37
 
34
38
  def env(key, default = nil, suffix: @envname, equals: nil, ignore: nil)
@@ -9,7 +9,7 @@ module Squared
9
9
  class Viewer
10
10
  include Common::Format
11
11
  include Utils
12
- include ::Rake::DSL
12
+ include Rake::DSL
13
13
 
14
14
  def self.to_s
15
15
  super.match(/[^:]+$/)[0]
@@ -51,7 +51,7 @@ module Squared
51
51
  ['path not found', realpath]
52
52
  else
53
53
  @required = true
54
- project ? [project, 'not found'] : %w[name missing]
54
+ project ? [project, 'not found'] : ['name', 'missing']
55
55
  end
56
56
  warn log_message(:warn, msg, subject: self.class, hint: hint)
57
57
  end
@@ -63,18 +63,18 @@ module Squared
63
63
  view = @command && @command != name ? @command : 'view'
64
64
  params = ->(args) { exist? ? [realpath, [args.keys] + args.extras] : [args.keys, args.extras] }
65
65
  namespace view do
66
- if @mime['json'] && (exist? || !::Rake::Task.task_defined?("#{ns}:#{view}:json"))
66
+ if @mime['json'] && (exist? || !Rake::Task.task_defined?("#{ns}:#{view}:json"))
67
67
  desc format_desc(view, 'json')
68
68
  task 'json', [:keys] do |_, args|
69
69
  read_keys(JSON, 'json', *params.(args))
70
70
  end
71
71
  end
72
72
 
73
- if @mime['yaml'] && (exist? || !::Rake::Task.task_defined?("#{ns}:#{view}:yaml"))
73
+ if @mime['yaml'] && (exist? || !Rake::Task.task_defined?("#{ns}:#{view}:yaml"))
74
74
  desc format_desc(view, 'yaml', 'yml')
75
75
  task 'yaml', [:keys] do |_, args|
76
76
  require 'yaml'
77
- read_keys(YAML, 'yaml', *params.(args), ext: %w[yml yaml])
77
+ read_keys(YAML, 'yaml', *params.(args), ext: ['yml', 'yaml'])
78
78
  end
79
79
  end
80
80
  end
@@ -120,7 +120,7 @@ module Squared
120
120
  def also(path, type = nil, name: nil, gem: nil, parse: nil, opts: {})
121
121
  return self if @mime.frozen? || !(file = basepath(path)).exist?
122
122
 
123
- ext = mime_type(file)
123
+ ext = mimetype(file)
124
124
  type = type&.to_s || ext
125
125
  unless parse
126
126
  case type
@@ -140,6 +140,12 @@ module Squared
140
140
  self
141
141
  end
142
142
 
143
+ def enabled?
144
+ return File.exist?(realpath) if exist?
145
+
146
+ !@required || !!project&.enabled?
147
+ end
148
+
143
149
  def extensions
144
150
  exist? ? [@ext.sub('.', '')] : @mime.keys
145
151
  end
@@ -154,12 +160,6 @@ module Squared
154
160
  "#<#{self.class}: #{name} => #{exist? ? realpath : "#{main} {#{extensions.join(', ')}}"}>"
155
161
  end
156
162
 
157
- def enabled?
158
- return File.exist?(realpath) if exist?
159
-
160
- !@required || !!project&.enabled?
161
- end
162
-
163
163
  private
164
164
 
165
165
  def puts(*args)
@@ -167,7 +167,7 @@ module Squared
167
167
  end
168
168
 
169
169
  def read_keys(reader, type, file, keys, ext: [type])
170
- if file && (mime = mime_type(file)) && basepath(file).exist?
170
+ if file && (mime = mimetype(file)) && basepath(file).exist?
171
171
  raise_error(file, mime, hint: 'invalid') unless ext.include?(mime)
172
172
  else
173
173
  if ext.include?(mime)
@@ -227,7 +227,7 @@ module Squared
227
227
  if val.nil?
228
228
  val = data
229
229
  items.each do |name|
230
- raise name unless val.is_a?(::Hash) && val.key?(name)
230
+ raise name unless val.is_a?(Hash) && val.key?(name)
231
231
 
232
232
  val = val[name]
233
233
  end
@@ -256,15 +256,28 @@ module Squared
256
256
  end
257
257
  end
258
258
 
259
- def basepath(file)
260
- project ? project.basepath(file) : Pathname.new(file).realdirpath
261
- end
262
-
263
259
  def task_name(val)
264
260
  @prefix ? "#{@prefix}:#{val}" : val.to_s
265
261
  end
266
262
 
267
- def mime_type(file)
263
+ def format_desc(command, *ext, exist: exist?)
264
+ val = "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
265
+ message(@prefix, *name.split(':'), command, val, empty: true)
266
+ end
267
+
268
+ def exist?
269
+ !@ext.empty? && (!@required || !project.nil?)
270
+ end
271
+
272
+ def warning?
273
+ project ? project.workspace.warning : true
274
+ end
275
+
276
+ def stdin?
277
+ pipe == 0
278
+ end
279
+
280
+ def mimetype(file)
268
281
  case (ret = File.extname(file).sub('.', '').downcase)
269
282
  when 'yml'
270
283
  'yaml'
@@ -277,25 +290,12 @@ module Squared
277
290
  end
278
291
  end
279
292
 
280
- def format_desc(command, *ext, exist: exist?)
281
- val = "#{ext.first}[#{exist ? '' : "file?=#{File.basename(main)}.#{ext.last},"}keys+]"
282
- message(@prefix, *name.split(':'), command, val, empty: true)
283
- end
284
-
285
293
  def realpath
286
294
  basepath(file = main + @ext).to_s rescue file
287
295
  end
288
296
 
289
- def exist?
290
- !@ext.empty? && (!@required || !project.nil?)
291
- end
292
-
293
- def warning?
294
- project ? project.workspace.warning : true
295
- end
296
-
297
- def stdin?
298
- pipe == 0
297
+ def basepath(file)
298
+ project ? project.basepath(file) : Pathname.new(file).realdirpath
299
299
  end
300
300
  end
301
301
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.0.12'
4
+ VERSION = '0.1.0'
5
5
  end
@@ -5,7 +5,7 @@ module Squared
5
5
  class Application
6
6
  include Common::Format
7
7
  include Utils
8
- include ::Rake::DSL
8
+ include Rake::DSL
9
9
 
10
10
  SCRIPT_OBJ = {
11
11
  run: nil,
@@ -71,12 +71,12 @@ module Squared
71
71
  @extensions = []
72
72
  @pipe = env_pipe(pipe, (ARG[:OUT] && env(ARG[:OUT])) || 1, root: @home)
73
73
  @exception = env_bool(exception)
74
- @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(::String) ? @pipe != 0 : verbose)
74
+ @verbose = env_bool(verbose, verbose.nil? || verbose.is_a?(String) ? @pipe != 0 : verbose)
75
75
  @warning = @verbose != false
76
76
  @closed = false
77
77
  if common
78
78
  @theme = __get__(:theme)[:workspace]
79
- ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(::Pathname)
79
+ ARG[:COLOR] = false if @pipe == 0 || @pipe.is_a?(Pathname)
80
80
  else
81
81
  @theme = {}
82
82
  end
@@ -95,7 +95,7 @@ module Squared
95
95
 
96
96
  def initialize_session
97
97
  @envname = @main.gsub(/[^\w]+/, '_').upcase.freeze
98
- return unless @pipe.is_a?(::Pathname)
98
+ return unless @pipe.is_a?(Pathname)
99
99
 
100
100
  bord = '#' * Project.line_width
101
101
  puts bord, format('Session started on %s by %s', Time.now.to_s, @main), bord
@@ -104,7 +104,13 @@ module Squared
104
104
  def build(parallel: [], **kwargs)
105
105
  return self unless enabled? && !@closed
106
106
 
107
- kwargs[:parallel] = parallel.map(&:to_s)
107
+ if kwargs[:pattern].is_a?(Array)
108
+ kwargs[:parallel] = parallel.map(&:to_s)
109
+ else
110
+ kwargs[:pattern] = []
111
+ kwargs[:parallel] = parallel.reject { |val| val.is_a?(Regexp) && (kwargs[:pattern] << val) }
112
+ .map(&:to_s)
113
+ end
108
114
  @project.each_value do |proj|
109
115
  next unless proj.enabled?
110
116
 
@@ -131,9 +137,9 @@ module Squared
131
137
  kind = val.first
132
138
  val = kind if val.size == 1
133
139
  case kind
134
- when ::String
140
+ when String
135
141
  @group = val
136
- when ::Symbol
142
+ when Symbol
137
143
  @ref = val
138
144
  else
139
145
  raise_error('group{Symbol} | ref{String}', hint: 'missing') if block_given?
@@ -182,14 +188,14 @@ module Squared
182
188
  def banner(*args, command: true, styles: nil, border: nil, group: @group, ref: @ref)
183
189
  data = { command: command, order: [], styles: check_style(styles, empty: false), border: check_style(border) }
184
190
  args.each do |meth|
185
- if meth.is_a?(::Array)
191
+ if meth.is_a?(Array)
186
192
  found = false
187
193
  meth = meth.select do |val|
188
194
  case val
189
- when ::Symbol
195
+ when Symbol
190
196
  found = true
191
197
  Application.attr_banner.include?(val)
192
- when ::String
198
+ when String
193
199
  true
194
200
  else
195
201
  false
@@ -227,10 +233,10 @@ module Squared
227
233
  ref = if kwargs.key?(:ref)
228
234
  kwargs = kwargs.dup unless @withargs
229
235
  kwargs.delete(:ref)
230
- elsif @ref.is_a?(::Symbol)
236
+ elsif @ref.is_a?(Symbol)
231
237
  @ref
232
238
  end
233
- if @group.is_a?(::String) && !kwargs.key?(:group)
239
+ if @group.is_a?(String) && !kwargs.key?(:group)
234
240
  kwargs = kwargs.dup unless @withargs
235
241
  kwargs[:group] = @group
236
242
  end
@@ -242,7 +248,7 @@ module Squared
242
248
  index += 1
243
249
  name = "#{project}-#{index}"
244
250
  end
245
- proj = ((if !ref.is_a?(::Class)
251
+ proj = ((if !ref.is_a?(Class)
246
252
  Application.find(ref, path: path)
247
253
  elsif ref < Project::Base
248
254
  ref
@@ -359,18 +365,33 @@ module Squared
359
365
  ret
360
366
  end
361
367
 
368
+ def task_sync(key)
369
+ key = task_name(key)
370
+ task_defined?(ret = task_join(key, 'sync')) ? ret : key
371
+ end
372
+
362
373
  def script_find(*args)
363
374
  args.reverse_each do |val|
364
- next unless val && (ret = val.is_a?(::Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
375
+ next unless val && (ret = val.is_a?(Symbol) ? @script[:ref!][val] : @script[:group!][val.to_sym])
365
376
 
366
377
  return ret
367
378
  end
368
379
  @script[:ref!][:_] || SCRIPT_OBJ
369
380
  end
370
381
 
371
- def script_get(group: nil, ref: nil)
382
+ def script_get(*args, group: nil, ref: nil)
372
383
  if group
373
384
  @script[:group][group.to_sym]
385
+ elsif ref.is_a?(Array)
386
+ ref = ref.each
387
+ end
388
+ if ref.instance_of?(Enumerator)
389
+ ref.each do |key|
390
+ next unless (ret = @script[:ref][key])
391
+
392
+ return ret if args.empty? || args.any? { |val| ret.key?(val) }
393
+ end
394
+ nil
374
395
  elsif ref
375
396
  @script[:ref][ref]
376
397
  end
@@ -384,14 +405,6 @@ module Squared
384
405
  @banner[:ref][:_]
385
406
  end
386
407
 
387
- def to_s
388
- (home? ? home : root).to_s
389
- end
390
-
391
- def inspect
392
- "#<#{self.class}: #{main} => #{self}>"
393
- end
394
-
395
408
  def enabled?
396
409
  !@extensions.empty? || @project.values.any?(&:enabled?)
397
410
  end
@@ -409,7 +422,7 @@ module Squared
409
422
  end
410
423
 
411
424
  def task_defined?(*key)
412
- ::Rake::Task.task_defined?(key.size == 1 ? key.first : task_join(*key))
425
+ Rake::Task.task_defined?(key.size == 1 ? key.first : task_join(*key))
413
426
  end
414
427
 
415
428
  def dev?(**kwargs)
@@ -432,6 +445,10 @@ module Squared
432
445
  home.join(*args)
433
446
  end
434
447
 
448
+ def pwd
449
+ Pathname.new(Rake.application.original_dir)
450
+ end
451
+
435
452
  def baseref
436
453
  Application.baseref
437
454
  end
@@ -440,14 +457,22 @@ module Squared
440
457
  { exception: exception, warning: warning }
441
458
  end
442
459
 
460
+ def to_s
461
+ (home? ? home : root).to_s
462
+ end
463
+
464
+ def inspect
465
+ "#<#{self.class}: #{main} => #{self}>"
466
+ end
467
+
443
468
  public :task_join
444
469
 
445
470
  private
446
471
 
447
472
  def __build__(default: nil, **)
448
- if default && task_defined?(t = task_name(default)) && !task_defined?(n = ::Rake.application.default_task_name)
449
- task n => t
450
- end
473
+ return unless default && task_defined?(out = task_name(default))
474
+
475
+ task Rake.application.default_task_name => out
451
476
  end
452
477
 
453
478
  def puts(*args)
@@ -477,10 +502,6 @@ module Squared
477
502
  end
478
503
  end
479
504
 
480
- def script_obj
481
- SCRIPT_OBJ.dup
482
- end
483
-
484
505
  def script?(state, target: nil, pat: nil, group: nil, ref: baseref, global: false)
485
506
  data = script_find(ref, group)
486
507
  if global
@@ -489,7 +510,11 @@ module Squared
489
510
  end
490
511
  return false if state == :prod && data[:dev] == true && data[:global]
491
512
 
492
- target && pat.is_a?(::Regexp) ? as_a(target).any? { |val| pat.match?(val) } : pat == true
513
+ target && pat.is_a?(Regexp) ? as_a(target).any? { |val| pat.match?(val) } : pat == true
514
+ end
515
+
516
+ def scriptobj
517
+ SCRIPT_OBJ.dup
493
518
  end
494
519
  end
495
520
  end