squared 0.4.7 → 0.4.9

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.
@@ -16,10 +16,10 @@ module Squared
16
16
  include Prompt
17
17
 
18
18
  def append(target, *args, delim: false, escape: false, quote: true)
19
- return if args.empty?
19
+ return if (ret = args.flatten).empty?
20
20
 
21
21
  target << '--' if delim && !target.include?('--')
22
- ret = args.flatten.map { |val| escape ? shell_escape(val, quote: quote) : shell_quote(val) }
22
+ ret.map! { |val| escape ? shell_escape(val, quote: quote) : shell_quote(val) } if escape || quote
23
23
  if target.is_a?(Set)
24
24
  target.merge(ret)
25
25
  else
@@ -35,18 +35,25 @@ module Squared
35
35
  kwargs[:hint] ||= 'unrecognized'
36
36
  append(target, opts, delim: true) if kwargs.delete(:append)
37
37
  warn log_message(Logger::WARN, opts.join(', '), pass: true, **kwargs)
38
- return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N', timeout: 30)
38
+ return if pass || confirm("Run? [#{sub_style(target, styles: styles)}] [y/N] ", 'N')
39
39
 
40
40
  raise_error 'user cancelled'
41
41
  end
42
42
 
43
+ def strip(val)
44
+ return [] unless val
45
+
46
+ val = shell_split(val) if val.is_a?(String)
47
+ val.map { |s| s.sub(/\A-([a-z\d])(.+)\z/mi, '\1=\2').sub(/\A--?/, '') }.reject(&:empty?)
48
+ end
49
+
43
50
  def arg?(target, *args, value: false)
44
51
  r, s = args.partition { |val| val.is_a?(Regexp) }
45
52
  unless s.empty?
46
53
  s.map! { |val| Regexp.escape(shell_option(val)) }
47
54
  r << /\A(?:#{s.join('|')})#{value ? '[ =].' : '(?: |=|\z)'}/
48
55
  end
49
- target.any? { |opt| r.any? { |val| opt.match?(val) } }
56
+ target.any? { |opt| r.any? { |val| opt&.match?(val) } }
50
57
  end
51
58
  end
52
59
 
@@ -66,7 +73,7 @@ module Squared
66
73
  parse(list, opts, **kwargs, &blk)
67
74
  end
68
75
 
69
- def parse(list, opts = extras, no: nil, single: nil, args: false, first: false, pass: ['='], &blk)
76
+ def parse(list, opts = extras, no: nil, single: nil, args: false, first: nil, &blk)
70
77
  @extras = []
71
78
  @values = []
72
79
  bare = []
@@ -79,8 +86,8 @@ module Squared
79
86
  i = []
80
87
  f = []
81
88
  si = []
82
- list.map do |val|
83
- x, y = val.split('|')
89
+ list.flat_map do |val|
90
+ x, y = val.split('|', 2)
84
91
  if y
85
92
  if (n = val.index('='))
86
93
  x += val[n..-1]
@@ -90,7 +97,6 @@ module Squared
90
97
  x
91
98
  end
92
99
  end
93
- .flatten
94
100
  .each do |val|
95
101
  if (n = val.index('='))
96
102
  flag = val[0, n]
@@ -117,6 +123,7 @@ module Squared
117
123
  else
118
124
  next
119
125
  end
126
+ m << flag if val[n + 2] == 'm'
120
127
  bare << flag if val.end_with?('?')
121
128
  else
122
129
  bare << val
@@ -124,6 +131,12 @@ module Squared
124
131
  end
125
132
  no = (no || []).map { |val| (n = val.index('=')) ? val[0, n] : val }
126
133
  bare.concat(no)
134
+ numtype = [
135
+ [i, /\A\d+\z/],
136
+ [f, /\A\d*(?:\.\d+)?\z/],
137
+ [si, /\A-?\d+\z/]
138
+ ].freeze
139
+ numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && pat.match?(v) } }
127
140
  skip = false
128
141
  opts.each do |opt|
129
142
  next @extras << opt if skip
@@ -138,17 +151,17 @@ module Squared
138
151
  if opt =~ /\A([^=]+)=(.+)\z/
139
152
  key = $1
140
153
  val = $2
141
- match = ->(flag, pat) { flag.include?(key) && pat.match?(val) }
154
+ merge = m.include?(key)
142
155
  if e.include?(key)
143
- target << shell_option(key, val)
156
+ target << shell_option(key, val, merge: merge)
144
157
  elsif q.include?(key)
145
- target << quote_option(key, val, double: qq.include?(key))
158
+ target << quote_option(key, val, double: qq.include?(key), merge: merge)
146
159
  elsif p.include?(key) && path
147
- target << quote_option(key, path.join(val))
148
- elsif m.include?(key)
160
+ target << quote_option(key, path + val, merge: merge)
161
+ elsif b.include?(key) || numcheck.call(key, val)
162
+ target << basic_option(key, val, merge: merge)
163
+ elsif merge
149
164
  target << basic_option(key, val, merge: true)
150
- elsif b.include?(key) || match.(i, /^\d+$/) || match.(f, /^\d*(?:\.\d+)?$/) || match.(si, /^-?\d+$/)
151
- target << basic_option(key, val)
152
165
  else
153
166
  @extras << opt
154
167
  end
@@ -157,10 +170,10 @@ module Squared
157
170
  @extras << opt
158
171
  skip = true if args
159
172
  end
160
- skip = true if first && pass.none? { |s| opt.include?(s) }
173
+ skip = true if first&.any? { |s| s.is_a?(Regexp) ? opt.match?(s) : !opt.include?(s) }
161
174
  end
162
175
  end
163
- @values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/
176
+ @values = @values.empty? ? /\A\s+\z/ : /\A(#{@values.join('|')})=(.+)\z/m
164
177
  @extras.each_with_index(&blk) if block_given?
165
178
  self
166
179
  end
@@ -179,9 +192,14 @@ module Squared
179
192
  self
180
193
  end
181
194
 
182
- def clear(opts = nil, **kwargs)
183
- opts ||= (kwargs[:errors] ? errors : extras)
195
+ def clear(opts = nil, errors: false, **kwargs)
184
196
  styles = project.theme[:inline] if project
197
+ if !opts
198
+ opts = errors ? @errors : @extras
199
+ elsif errors
200
+ OptionPartition.clear(target, @errors, styles: styles, **kwargs)
201
+ @errors.clear
202
+ end
185
203
  OptionPartition.clear(target, opts.reject { |val| found.include?(val) }, styles: styles, **kwargs)
186
204
  opts.clear
187
205
  self
@@ -3,12 +3,10 @@
3
3
  module Squared
4
4
  module Workspace
5
5
  module Repo
6
- include Common::Format
7
-
8
6
  class << self
9
7
  def read_manifest(path)
10
8
  require 'rexml/document'
11
- return unless (file = path.join('.repo/manifest.xml')).exist?
9
+ return unless (file = path + '.repo/manifest.xml').exist?
12
10
 
13
11
  doc = REXML::Document.new(file.read)
14
12
  doc.elements['manifest/include'].attributes['name']&.sub('.xml', '')
@@ -41,12 +39,12 @@ module Squared
41
39
  raise_error("path does not exist: #{val}", hint: 'REPO_ROOT') unless repo_confirm
42
40
  end
43
41
  @root.join(main).realdirpath
44
- elsif repo_install?(parent: true) && (!@home.exist? || @root.join(main) == @home)
42
+ elsif repo_install?(parent: true) && (!@home.exist? || @root + main == @home)
45
43
  @home
46
44
  elsif repo_install?(@home)
47
- @home.join(main)
45
+ @home + main
48
46
  else
49
- (path = pwd) == @home || !repo_install?(path) ? @home : path.join(main)
47
+ (path = pwd) == @home || !repo_install?(path) ? @home : path + main
50
48
  end
51
49
  @root = @home.parent
52
50
  @manifest_url = url
@@ -149,9 +147,9 @@ module Squared
149
147
  end
150
148
  end
151
149
 
152
- desc.('all[{0}]')
150
+ desc.call('all[{0}]')
153
151
  task 'all', [:opts] do |_, args|
154
- parse_opts.(args)
152
+ parse_opts.call(args)
155
153
  stage ||= 'all'
156
154
  repo['sync'].invoke
157
155
  next if env('REPO_DRYRUN', equals: '2')
@@ -174,21 +172,21 @@ module Squared
174
172
  end
175
173
  end
176
174
 
177
- desc.("init[manifest?=#{target},{0}]", target)
175
+ desc.call("init[manifest?=#{target},{0}]", target)
178
176
  task 'init', [:manifest, :opts] do |_, args|
179
- parse_opts.(args)
177
+ parse_opts.call(args)
180
178
  stage = 'init'
181
179
  puts if newline
182
180
  system("repo init -u #{env('REPO_URL') || manifest_url} -m #{args.manifest || target}.xml", chdir: root)
183
181
  repo['all'].invoke
184
182
  end
185
183
 
186
- desc.('sync[{0}]')
184
+ desc.call('sync[{0}]')
187
185
  task 'sync', [:opts] do |_, args|
188
186
  unless branch || stage == 'init'
189
187
  raise_error('repo not initialized', hint: task_name('repo:init'), kind: LoadError)
190
188
  end
191
- parse_opts.(args)
189
+ parse_opts.call(args)
192
190
  cmd << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}"
193
191
  cmd << '--fail-fast' if failfast
194
192
  puts if newline && stage != 'init'
@@ -71,11 +71,12 @@ module Squared
71
71
  def_delegators :@data, :[], :each, :each_key, :keys, :fetch, :to_a, :to_s, :inspect, :merge!, :key?
72
72
  def_delegators :@workspace, :task_desc, :task_name, :task_namespace, :task_join, :format_desc
73
73
 
74
- def initialize(workspace)
74
+ def initialize(workspace, exclude: [])
75
75
  @workspace = workspace
76
76
  @sync = []
77
77
  @multiple = []
78
78
  @parallel = []
79
+ @exclude = exclude.freeze
79
80
  @session = {
80
81
  group: {},
81
82
  parent: {},
@@ -89,7 +90,7 @@ module Squared
89
90
  group, parent, id = @session.values
90
91
  ws = proj.workspace
91
92
  @data.each do |key, items|
92
- next if (tasks = ws.task_resolve(proj, key)).empty?
93
+ next if exclude?(key) || (tasks = ws.task_resolve(proj, key)).empty?
93
94
 
94
95
  if (g = proj.group)
95
96
  id << g
@@ -113,13 +114,13 @@ module Squared
113
114
  @data.merge!(@session[:parent]) if @session[:id].uniq.size > 1
114
115
  @data.merge!(@session[:group])
115
116
  @data.each do |key, items|
116
- next if items.empty? || @workspace.task_exclude?(t = name_get(key))
117
+ next if exclude?(key, true) || @workspace.task_exclude?(t = name_get(key))
117
118
 
118
- key = task_name(t)
119
+ key = task_name t
119
120
  val = format_desc(key, out: true)
120
121
  if items.size > 1
121
122
  @multiple << key
122
- if parallel.include?(t) || pattern.any? { |pat| t.match?(pat) } || subcheck.(t)
123
+ if parallel.include?(t) || pattern.any? { |pat| t.match?(pat) } || subcheck.call(t)
123
124
  task_desc("#{val} (thread)", name: key)
124
125
  multitask key => items
125
126
  @parallel << key
@@ -167,14 +168,13 @@ module Squared
167
168
  return false unless (items = TASK_EXTEND[key]) && !(items = items.select { |kind| obj.is_a?(kind) }).empty?
168
169
 
169
170
  meth = :"#{key}?"
170
- allref = obj.allref.to_a
171
171
  ret = false
172
172
  items.each do |kind|
173
173
  if kind.instance_methods.include?(meth)
174
174
  out = obj.__send__(meth)
175
175
  return true if out == 1
176
176
  return out if obj.ref?(kind.ref)
177
- elsif allref.include?(kind.ref)
177
+ elsif obj.ref?(kind.ref)
178
178
  ret = true
179
179
  end
180
180
  end
@@ -199,6 +199,10 @@ module Squared
199
199
  already_invoked?(parallel, val)
200
200
  end
201
201
 
202
+ def exclude?(key, empty = false)
203
+ @exclude.include?(key) || (empty && @data[key].empty?)
204
+ end
205
+
202
206
  private
203
207
 
204
208
  def already_invoked?(list, val)
@@ -10,15 +10,14 @@ module Squared
10
10
  if id.is_a?(Symbol)
11
11
  project id
12
12
  else
13
- id = dirpath(id) if id.is_a?(String)
14
- __get__(:project).find { |_, val| val.path.to_s == id.to_s }
13
+ __get__(:project).find { |_, val| File.expand_path(val.path) == File.expand_path(id) }
15
14
  end
16
15
  end
17
16
  ret.size == 1 ? ret.first : ret
18
17
  end
19
18
 
20
19
  def expect(name)
21
- ret = project(name)
20
+ ret = project name
22
21
  return ret if ret&.path&.directory?
23
22
 
24
23
  raise NoMethodError, "project is not initialized (#{name})"
@@ -33,12 +32,6 @@ module Squared
33
32
  def project(name)
34
33
  __get__(:project)[name.to_s]
35
34
  end
36
-
37
- def dirpath(val, absolute: true)
38
- Pathname.new(val).realdirpath
39
- rescue StandardError
40
- absolute ? Pathname.pwd.join(val) : Pathname.new(val)
41
- end
42
35
  end
43
36
  end
44
37
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-04-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  requirements: []
126
- rubygems_version: 3.6.8
126
+ rubygems_version: 3.6.2
127
127
  specification_version: 4
128
128
  summary: Rake task generator for managing multi-language workspaces.
129
129
  test_files: []