squared 0.9.1 → 0.9.2
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/CHANGELOG.md +44 -1
- data/README.md +8 -3
- data/exe/sqd +248 -84
- data/lib/squared/common/base.rb +2 -0
- data/lib/squared/common/format.rb +1 -1
- data/lib/squared/common/prompt.rb +26 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/project/base.rb +13 -11
- data/lib/squared/workspace/project/docker.rb +4 -4
- data/lib/squared/workspace/project/git.rb +4 -4
- data/lib/squared/workspace/project/node.rb +36 -23
- data/lib/squared/workspace/project/python.rb +6 -6
- data/lib/squared/workspace/project/ruby.rb +24 -26
- data/lib/squared/workspace/project/support/optionpartition.rb +8 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7bc8d196a7c5068373757f7bbb9ba037cafd30500875d924628690f57451b927
|
|
4
|
+
data.tar.gz: '00078ddc57f3f357cc9833a679c42d636936d0db91e75a327a07ba19dedd0165'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5b85d626962791e9da8355f82999b0ab8bcd1e63f88605c6a3dfecb8b5b515469373acb8f7d79eab4887b3b3f826e1d540133361b74e5c3e3160545215b3641
|
|
7
|
+
data.tar.gz: ee09108c1abea47c45ae2a931e01a9b1e42097dd597537796543321aaca03b9825d9942a26274c7fbca344f748b1d4b8765102dcd7b74f54489e7dc2115b5a97
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.2] - 2026-11-04
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- sqd: Option --no-gemfile for undoing bundle exec project wrapper.
|
|
8
|
+
- sqd: Option --commit for pushing files to remote branch.
|
|
9
|
+
- sqd: Option --mulitline for writing messages with newlines.
|
|
10
|
+
- sqd: Option --amend[-orig] for replacing current commit.
|
|
11
|
+
- sqd: Option --project can match common subtasks.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Logger warn statements from project misconfiguration were downgraded.
|
|
16
|
+
- sqd: Task creation from joins are validated before consuming arguments.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- sqd: Option --project did not support multiple patterns.
|
|
21
|
+
|
|
22
|
+
## [0.8.8]
|
|
23
|
+
|
|
24
|
+
- See `0.7.15`.
|
|
25
|
+
|
|
26
|
+
## [0.7.15]
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Git command commit action pathspec was implemented.
|
|
31
|
+
- Common base argument TAB for column alignment was created.
|
|
32
|
+
- Node command package action deny can modify currently approved scripts.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Node command package action [approve|deny] uses install-scripts ls.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Bundle exec wrapper as a Hash did not support using alternate Gemfile.
|
|
41
|
+
- Common base ARG data objects were not frozen with __freeze__.
|
|
42
|
+
|
|
3
43
|
## [0.9.1] - 2026-10-22
|
|
4
44
|
|
|
5
45
|
### Added
|
|
@@ -99,7 +139,7 @@
|
|
|
99
139
|
|
|
100
140
|
- OptionPartition did not parse quoted option values.
|
|
101
141
|
|
|
102
|
-
## [0.6.20]
|
|
142
|
+
## [0.6.20]
|
|
103
143
|
|
|
104
144
|
### Added
|
|
105
145
|
|
|
@@ -2234,8 +2274,10 @@
|
|
|
2234
2274
|
|
|
2235
2275
|
- Changelog was created.
|
|
2236
2276
|
|
|
2277
|
+
[0.9.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.9.2
|
|
2237
2278
|
[0.9.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.9.1
|
|
2238
2279
|
[0.9.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.9.0
|
|
2280
|
+
[0.8.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.8
|
|
2239
2281
|
[0.8.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.7
|
|
2240
2282
|
[0.8.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.6
|
|
2241
2283
|
[0.8.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.5
|
|
@@ -2244,6 +2286,7 @@
|
|
|
2244
2286
|
[0.8.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.2
|
|
2245
2287
|
[0.8.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.1
|
|
2246
2288
|
[0.8.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.8.0
|
|
2289
|
+
[0.7.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.15
|
|
2247
2290
|
[0.7.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.14
|
|
2248
2291
|
[0.7.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.13
|
|
2249
2292
|
[0.7.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.12
|
data/README.md
CHANGED
|
@@ -32,7 +32,7 @@ gem install squared
|
|
|
32
32
|
There is an additional program wrapper for ``rake`` to be used when running batch commands and to enable global settings more easily.
|
|
33
33
|
|
|
34
34
|
```xml
|
|
35
|
-
Usage: sqd [options] [rake options] [global...] [:targets...] -- [rake targets...]
|
|
35
|
+
Usage: sqd [options] [rake options] [pathspec...] -- [global...] [:targets...] -- [rake targets...]
|
|
36
36
|
|
|
37
37
|
-R, --ref STR,STR Run global commands by class reference
|
|
38
38
|
-G, --group STR,STR Run global commands by project group
|
|
@@ -49,14 +49,19 @@ Usage: sqd [options] [rake options] [global...] [:targets...] -- [rake targets..
|
|
|
49
49
|
-y, --yes [STR,STR] Enable auto-approve through ENV by application
|
|
50
50
|
-d, --dry-run Run commands without any modifying actions
|
|
51
51
|
|
|
52
|
-
-S, --select PAGE[:CHOICE] Prompt menu selection pagination display (e.g.
|
|
52
|
+
-S, --select PAGE[:CHOICE] Prompt menu selection pagination display (e.g. 20:60)
|
|
53
|
+
-M, --multiline STR Use advanced editor with custom message terminator (e.g. EOF)
|
|
53
54
|
|
|
54
|
-
-g, --gemfile
|
|
55
|
+
-g, --[no-]gemfile Execute commands using bundle exec and nearest Gemfile
|
|
55
56
|
-p, --pipe 0|1|2 Set file descriptor for communication
|
|
56
57
|
-o, --pipe-out FILE Write command data stream to a file
|
|
57
58
|
--fail 0..4 Set application exception level
|
|
58
59
|
--log-level SEVERITY Set logger and exception state (debug, info, warn, error, fatal)
|
|
59
60
|
|
|
61
|
+
-c, --commit Push files remotely on active branch from current directory
|
|
62
|
+
--amend Replace the tip of the active branch remotely with a force push
|
|
63
|
+
--amend-orig Perform an amend commit without changing the message
|
|
64
|
+
|
|
60
65
|
--[no-]banner Display executing command attributes
|
|
61
66
|
-x, --[no-]color Use enhanced styling for terminal output
|
|
62
67
|
-X, --plain Disable banner and styling for all commands
|
data/exe/sqd
CHANGED
|
@@ -1,43 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
$:.unshift(File.expand_path('../lib', __dir__)) if File.exist?(File.expand_path('../squared.gemspec', __dir__))
|
|
5
|
-
|
|
6
4
|
require 'squared'
|
|
7
5
|
require 'rake'
|
|
8
6
|
require 'optparse'
|
|
9
7
|
|
|
10
8
|
class SqdParser < OptionParser
|
|
11
|
-
include Squared
|
|
9
|
+
include Squared
|
|
10
|
+
include Common::Format
|
|
12
11
|
include Utils
|
|
13
12
|
|
|
13
|
+
OPT_DASH = /^--?[^-]/.freeze
|
|
14
|
+
|
|
14
15
|
attr_reader :options, :global
|
|
16
|
+
attr_accessor :argv
|
|
15
17
|
|
|
16
18
|
def initialize(*)
|
|
17
|
-
super
|
|
18
19
|
@options = { 'project-args': [], 'project-env': [] }
|
|
19
20
|
@global = []
|
|
21
|
+
@argv = ARGV.dup
|
|
22
|
+
super
|
|
20
23
|
@program_name = 'squared'
|
|
21
24
|
@raise_unknown = false
|
|
22
25
|
@require_exact = true
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def parse_global(list, assert:)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
ARGV.each_with_index do |val, index|
|
|
29
|
+
error_exit "cannot be used with --#{assert}" if options.key?(assert)
|
|
30
|
+
each_with_index do |val, index|
|
|
29
31
|
if val == '--'
|
|
30
32
|
separator!(index: index)
|
|
31
33
|
break
|
|
32
34
|
end
|
|
33
|
-
|
|
35
|
+
found = list.map { |name| "#{val}:#{name}" }.select { |name| tasks.include?(name) }
|
|
36
|
+
next if found.empty?
|
|
34
37
|
|
|
35
|
-
global.concat(
|
|
38
|
+
global.concat(found)
|
|
36
39
|
ARGV[index] = ''
|
|
37
40
|
end
|
|
38
41
|
end
|
|
39
42
|
|
|
40
|
-
def parse_common(list,
|
|
43
|
+
def parse_common(list, arg:)
|
|
41
44
|
if list && !list.include?('*')
|
|
42
45
|
session[arg].merge!(list.to_h { |key| [key, 'true'] })
|
|
43
46
|
else
|
|
@@ -45,7 +48,7 @@ class SqdParser < OptionParser
|
|
|
45
48
|
end
|
|
46
49
|
end
|
|
47
50
|
|
|
48
|
-
def parse_series(list,
|
|
51
|
+
def parse_series(list, flag:)
|
|
49
52
|
pattern, parallel = list.partition do |val|
|
|
50
53
|
next false if val.match?(%r{^[\w~`!@#%&\-=:;"'<>/]+$})
|
|
51
54
|
|
|
@@ -58,18 +61,146 @@ class SqdParser < OptionParser
|
|
|
58
61
|
(session[:APP][:"build_parallel#{s}"] ||= []).concat(parallel) unless parallel.empty?
|
|
59
62
|
end
|
|
60
63
|
|
|
61
|
-
def
|
|
64
|
+
def parse_range(val, max:, arg:, min: 0)
|
|
65
|
+
error_exit('out of range', hint: val) unless val.between?(min, max)
|
|
66
|
+
session[arg] = val
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def parse_rakefile
|
|
70
|
+
OptionParser.new do |opts|
|
|
71
|
+
opts.raise_unknown = false
|
|
72
|
+
opts.on('--rakefile', '-f [FILENAME]', '') do |val|
|
|
73
|
+
return val || ''
|
|
74
|
+
end
|
|
75
|
+
end.parse(ARGV.dup)
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def option_select(val)
|
|
80
|
+
page, choice = val.split(/\D/, 2).map(&:to_i)
|
|
81
|
+
error_exit('not an integer', hint: val) if choice.nil? ? page == 0 : choice == 0
|
|
82
|
+
session[:PAGE] = page if page > 0
|
|
83
|
+
session[:CHOICE] = choice if choice.to_i > 0
|
|
84
|
+
ENV['SELECT'] = "#{page}:#{choice}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def option_multiline(val)
|
|
88
|
+
Common::Prompt.multiline = val
|
|
89
|
+
rescue NotImplementedError => e
|
|
90
|
+
warn log_warn(e, hint: argv.find { |val| multilineopts.include?(val) })
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def option_gemfile(val)
|
|
94
|
+
require 'pathname'
|
|
95
|
+
session[:APP][:ruby_gemfile] = val
|
|
96
|
+
return unless val
|
|
97
|
+
return if ENV['RUBYOPT']&.match?(/(^|\b)-r.+#{File::SEPARATOR}bundler#{File::SEPARATOR}setup\b/)
|
|
98
|
+
|
|
99
|
+
gemfile = Pathname.pwd.ascend { |path| break path if path.join('Gemfile').file? } || ENV['BUNDLE_GEMFILE']
|
|
100
|
+
return unless gemfile && (argv.delete('--gemfile') || argv.delete('-g'))
|
|
101
|
+
|
|
102
|
+
argv.unshift('sqd')
|
|
103
|
+
if gemfile.is_a?(String)
|
|
104
|
+
gemfile = Common::Shell.shell_escape(Pathname.new(gemfile).relative_path_from(Dir.pwd), quote: true)
|
|
105
|
+
argv.unshift("--gemfile=#{gemfile}")
|
|
106
|
+
gemfile = Dir.pwd
|
|
107
|
+
end
|
|
108
|
+
ENV['BUNDLE_GEMFILE'] = nil
|
|
109
|
+
exec(Common::Shell.shell_bin('bundle'), 'exec', *argv, chdir: gemfile)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def option_loglevel(val)
|
|
113
|
+
require 'logger'
|
|
114
|
+
severity = case val
|
|
115
|
+
when :debug then Logger::DEBUG
|
|
116
|
+
when :info then Logger::INFO
|
|
117
|
+
when :warn then Logger::WARN
|
|
118
|
+
when :error then Logger::ERROR
|
|
119
|
+
when :fatal then Logger::FATAL
|
|
120
|
+
else
|
|
121
|
+
val.to_i
|
|
122
|
+
end
|
|
123
|
+
session[:LEVEL] = severity
|
|
124
|
+
ENV['LOG_LEVEL'] = severity.to_s
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def option_commit(*opts, flag:)
|
|
128
|
+
require 'squared/workspace'
|
|
129
|
+
c = argv.index { |val| opts.include?(val) } || error_exit('option was not found', hint: opts.last)
|
|
130
|
+
check_exclusive('-c', '--commit', '--amend', '--amend-orig', flag: argv[c])
|
|
131
|
+
first = lambda do
|
|
132
|
+
if ARGV.empty?
|
|
133
|
+
m = argv.index { |val| multilineopts.include?(val) }
|
|
134
|
+
t = argv.index { |val| !val.match?(OPT_DASH) } || -1
|
|
135
|
+
return true if c == 0 || (m == 0 && c == 2) || t > c
|
|
136
|
+
end
|
|
137
|
+
!rakefile?
|
|
138
|
+
end
|
|
139
|
+
refs = []
|
|
140
|
+
found = argv[c.succ]
|
|
141
|
+
j = -1
|
|
142
|
+
each_with_index do |pat, i|
|
|
143
|
+
found = nil if pat == found
|
|
144
|
+
if i == j
|
|
145
|
+
ARGV[i.pred] = ''
|
|
146
|
+
ARGV[i] = ''
|
|
147
|
+
option_multiline pat
|
|
148
|
+
next
|
|
149
|
+
end
|
|
150
|
+
next if found
|
|
151
|
+
|
|
152
|
+
case pat
|
|
153
|
+
when '--'
|
|
154
|
+
ARGV[i] = ''
|
|
155
|
+
break
|
|
156
|
+
when *multilineopts
|
|
157
|
+
j = i.succ
|
|
158
|
+
next
|
|
159
|
+
when OPT_DASH
|
|
160
|
+
next if refs.empty? || Dir[pat].empty?
|
|
161
|
+
else
|
|
162
|
+
next if refs.empty? && Dir[pat].empty?
|
|
163
|
+
end
|
|
164
|
+
refs << pat
|
|
165
|
+
ARGV[i] = ''
|
|
166
|
+
end
|
|
167
|
+
if refs.empty?
|
|
168
|
+
if !`git status -s --ignore-submodules=all --ignored=no`.empty?
|
|
169
|
+
refs << '*'
|
|
170
|
+
elsif first.call
|
|
171
|
+
warn 'No files to commit.'
|
|
172
|
+
exit 1
|
|
173
|
+
else
|
|
174
|
+
return
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
Workspace::Application
|
|
178
|
+
.new
|
|
179
|
+
.add(File.basename(Dir.pwd), ref: :git) { commit(flag, refs: refs.uniq, pass: nil) }
|
|
180
|
+
exit if first.call
|
|
181
|
+
self.argv = ARGV.dup
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def option_verbose
|
|
185
|
+
unless session[:VERBOSE]
|
|
186
|
+
session[:VERBOSE] = $VERBOSE ? 1 : 0
|
|
187
|
+
global.unshift('--verbose')
|
|
188
|
+
end
|
|
189
|
+
ENV['VERBOSE'] = (session[:VERBOSE] += 1).to_s
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def banner_set(val)
|
|
62
193
|
session[:BANNER] = val
|
|
63
194
|
ENV['BANNER'] = val ? 'true' : 'false'
|
|
64
195
|
end
|
|
65
196
|
|
|
66
|
-
def color_set(val
|
|
197
|
+
def color_set(val)
|
|
67
198
|
if (session[:COLOR] = val)
|
|
68
199
|
enable_aixterm
|
|
69
200
|
enable_drawing
|
|
70
201
|
else
|
|
71
202
|
enable_drawing false
|
|
72
|
-
|
|
203
|
+
Common.const_get(:VAR)[:colors].freeze
|
|
73
204
|
end
|
|
74
205
|
ENV['NO_COLOR'] = val ? nil : '1'
|
|
75
206
|
ENV['FORCE_COLOR'] = val ? '2' : '0'
|
|
@@ -86,57 +217,111 @@ class SqdParser < OptionParser
|
|
|
86
217
|
rescue RegexpError
|
|
87
218
|
false
|
|
88
219
|
end
|
|
220
|
+
subtasks = []
|
|
89
221
|
pattern.each do |val|
|
|
90
222
|
val = if val == '*'
|
|
91
223
|
'[^:]+'
|
|
92
224
|
else
|
|
93
225
|
val.sub(/^\*/, '.*')
|
|
94
226
|
.sub(/(?<!\.)\*$/, '.*')
|
|
95
|
-
.gsub(
|
|
227
|
+
.gsub(/(?<!\\)\.([*+])(?!\?)/, '[^:]\1?')
|
|
96
228
|
end
|
|
97
|
-
|
|
229
|
+
pat = /^(#{val.chomp(':')}):/
|
|
230
|
+
tasks.each do |task|
|
|
231
|
+
next unless task =~ pat
|
|
232
|
+
|
|
233
|
+
subtasks << $1
|
|
234
|
+
name = task.split(':', 2).first
|
|
235
|
+
project << name unless project.include?(name)
|
|
236
|
+
end
|
|
98
237
|
end
|
|
99
238
|
exit 1 if project.empty? && !pattern.empty?
|
|
100
|
-
|
|
239
|
+
subtasks.uniq!
|
|
101
240
|
options[:'project-env'].each do |val|
|
|
102
241
|
n = val.index('=')
|
|
103
|
-
key = val[...n]
|
|
104
|
-
val = val[n.succ
|
|
242
|
+
key = val[0...n]
|
|
243
|
+
val = val[n.succ..-1].stripquote
|
|
105
244
|
project.each { |name| ENV["#{key}_#{env_key(name.split(':').first)}"] = val }
|
|
106
245
|
end
|
|
107
|
-
|
|
246
|
+
each_with_index do |val, index|
|
|
108
247
|
if val == '--'
|
|
109
248
|
separator!(index: index)
|
|
110
249
|
break
|
|
111
250
|
end
|
|
112
251
|
next unless val.start_with?(':')
|
|
113
252
|
|
|
114
|
-
|
|
115
|
-
|
|
253
|
+
found = subtasks.map { |name| "#{name}#{val}" }.select { |name| tasks.include?(name) }
|
|
254
|
+
if (args = options[:'project-args'].shift)
|
|
255
|
+
found.map! { |name| "#{name}[#{args}]" }
|
|
256
|
+
end
|
|
257
|
+
global.concat(found)
|
|
116
258
|
ARGV[index] = ''
|
|
117
259
|
end
|
|
118
260
|
end
|
|
119
|
-
ARGV.reject!(&:empty?)
|
|
120
261
|
Rake.application.run(global.concat(ARGV))
|
|
121
262
|
end
|
|
122
263
|
|
|
264
|
+
def tasks
|
|
265
|
+
@tasks ||= Rake.with_application do |rake|
|
|
266
|
+
if (rakefile = parse_rakefile)
|
|
267
|
+
rakefiles = rake.instance_variable_get(:@rakefiles)
|
|
268
|
+
rakefiles.clear
|
|
269
|
+
rakefiles << rakefile
|
|
270
|
+
end
|
|
271
|
+
rake.raw_load_rakefile
|
|
272
|
+
end.tasks.map(&:name)
|
|
273
|
+
end
|
|
274
|
+
|
|
123
275
|
def separator!(index:)
|
|
124
276
|
ARGV[index] = '' if ARGV.grep('--').size > 1
|
|
125
277
|
end
|
|
126
278
|
|
|
127
|
-
def
|
|
279
|
+
def check_exclusive(*args, flag:)
|
|
280
|
+
args.delete(flag)
|
|
281
|
+
return unless (n = index(*args))
|
|
282
|
+
|
|
283
|
+
error_exit "cannot be used with #{argv[n]}"
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def error_exit(*val, hint: nil)
|
|
128
287
|
raise OptionParser::InvalidArgument, message(*val, hint: hint), caller(1)
|
|
129
288
|
end
|
|
289
|
+
|
|
290
|
+
def session
|
|
291
|
+
Common::ARG
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def multilineopts
|
|
295
|
+
%w[-M --multiline]
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def each_with_index(&blk)
|
|
299
|
+
ARGV.each_with_index(&blk)
|
|
300
|
+
ARGV.reject!(&:empty?)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def index(*args)
|
|
304
|
+
argv.each_with_index do |val, i|
|
|
305
|
+
return i if args.any? { |s| val == s || (s.start_with?('--') && val.start_with?("#{s}=")) }
|
|
306
|
+
end
|
|
307
|
+
nil
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def warn(*args)
|
|
311
|
+
$stderr.puts(*args)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def rakefile?
|
|
315
|
+
Rake.application.find_rakefile_location || parse_rakefile ? true : false
|
|
316
|
+
end
|
|
130
317
|
end
|
|
131
318
|
|
|
132
319
|
SqdParser.new do |sqd|
|
|
133
|
-
|
|
134
|
-
argv = ARGV.dup
|
|
135
|
-
sqd.banner = 'Usage: sqd [options] [rake options] [global...] [:targets...] -- [rake targets...]'
|
|
320
|
+
sqd.banner = 'Usage: sqd [options] [rake options] [pathspec...] -- [global...] [:targets...] -- [rake targets...]'
|
|
136
321
|
sqd.separator ''
|
|
137
322
|
sqd.on('-R', '--ref STR,STR', Array, 'Run global commands by class reference') do |val|
|
|
138
323
|
sqd.parse_global(val, assert: :group)
|
|
139
|
-
session[:APP][:series_ref_min] = 1
|
|
324
|
+
sqd.session[:APP][:series_ref_min] = 1
|
|
140
325
|
end
|
|
141
326
|
sqd.on('-G', '--group STR,STR', Array, 'Run global commands by project group') do |val|
|
|
142
327
|
sqd.parse_global(val, assert: :ref)
|
|
@@ -147,105 +332,84 @@ SqdParser.new do |sqd|
|
|
|
147
332
|
sqd.options[:'project-args'] << val
|
|
148
333
|
end
|
|
149
334
|
sqd.on('-e', '--project-env KEY=STR', 'Provide command ENV variables for :targets (multiple)') do |val|
|
|
150
|
-
sqd.error_exit('missing value', "#{val}=") unless val.include?('=')
|
|
335
|
+
sqd.error_exit('missing value', hint: "#{val}=") unless val.include?('=')
|
|
151
336
|
sqd.options[:'project-env'] << val
|
|
152
337
|
end
|
|
153
338
|
sqd.separator ''
|
|
154
339
|
sqd.on('-s', '--[no-]strict', 'Do not run commands with invalid arguments') do |val|
|
|
155
|
-
session[:STRICT] = val
|
|
340
|
+
sqd.session[:STRICT] = val
|
|
156
341
|
ENV['STRICT'] = val ? 'true' : 'false'
|
|
157
342
|
end
|
|
158
343
|
sqd.on('--update', 'Use update strategy for applicable commands') do
|
|
159
344
|
ENV['UPDATE'] = 'true'
|
|
160
345
|
end
|
|
161
346
|
sqd.on('-u', '--parallel STR,PAT', Array, 'Run standard tasks with multi-task threads') do |val|
|
|
162
|
-
sqd.parse_series(val,
|
|
347
|
+
sqd.parse_series(val, flag: :parallel)
|
|
163
348
|
end
|
|
164
349
|
sqd.on('-U', '--sync STR,PAT', Array, 'Run parallel tasks in a series sequentially') do |val|
|
|
165
|
-
sqd.parse_series(val,
|
|
350
|
+
sqd.parse_series(val, flag: :sync)
|
|
166
351
|
end
|
|
167
352
|
sqd.on('-F', '--force [STR,STR]', Array, 'Enable force through ENV by application') do |val|
|
|
168
|
-
sqd.parse_common(val,
|
|
353
|
+
sqd.parse_common(val, arg: :FORCE)
|
|
169
354
|
end
|
|
170
355
|
sqd.on('-y', '--yes [STR,STR]', Array, 'Enable auto-approve through ENV by application') do |val|
|
|
171
|
-
sqd.parse_common(val,
|
|
356
|
+
sqd.parse_common(val, arg: :YES)
|
|
172
357
|
end
|
|
173
358
|
sqd.on('-d', '--dry-run', 'Run commands without any modifying actions') do
|
|
174
359
|
ENV['DRY_RUN'] = 'true'
|
|
175
360
|
end
|
|
176
361
|
sqd.separator ''
|
|
177
|
-
sqd.on('-S', '--select PAGE[:CHOICE]', 'Prompt menu selection pagination display (e.g.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
ENV['SELECT'] = "#{page}:#{choice}"
|
|
362
|
+
sqd.on('-S', '--select PAGE[:CHOICE]', 'Prompt menu selection pagination display (e.g. 20:60)') do |val|
|
|
363
|
+
sqd.option_select(val)
|
|
364
|
+
end
|
|
365
|
+
sqd.on('-M', '--multiline STR', 'Use advanced editor with custom message terminator (e.g. EOF)') do |val|
|
|
366
|
+
sqd.option_multiline(val)
|
|
183
367
|
end
|
|
184
368
|
sqd.separator ''
|
|
185
|
-
sqd.on('-g', '--gemfile', 'Execute commands using bundle exec and nearest Gemfile') do
|
|
186
|
-
|
|
187
|
-
next if ENV['RUBYOPT']&.match?(/(^|\b)-r.+#{File::SEPARATOR}bundler#{File::SEPARATOR}setup\b/)
|
|
188
|
-
|
|
189
|
-
gemfile = Pathname.pwd.ascend { |path| break path if path.join('Gemfile').file? } || ENV['BUNDLE_GEMFILE']
|
|
190
|
-
next unless gemfile && (argv.delete('--gemfile') || argv.delete('-g'))
|
|
191
|
-
|
|
192
|
-
include Squared::Common
|
|
193
|
-
include Shell
|
|
194
|
-
|
|
195
|
-
argv.unshift('sqd')
|
|
196
|
-
if gemfile.is_a?(String)
|
|
197
|
-
argv.unshift("--gemfile=#{shell_escape(Pathname.new(gemfile).relative_path_from(Dir.pwd), quote: true)}")
|
|
198
|
-
gemfile = Dir.pwd
|
|
199
|
-
end
|
|
200
|
-
ENV['BUNDLE_GEMFILE'] = nil
|
|
201
|
-
exec(shell_bin('bundle'), 'exec', *argv, chdir: gemfile)
|
|
369
|
+
sqd.on('-g', '--[no-]gemfile', 'Execute commands using bundle exec and nearest Gemfile') do |val|
|
|
370
|
+
sqd.option_gemfile(val)
|
|
202
371
|
end
|
|
203
372
|
sqd.on('-p', '--pipe 0|1|2', Integer, 'Set file descriptor for communication') do |val|
|
|
204
|
-
sqd.
|
|
205
|
-
session[:PIPE] = val
|
|
373
|
+
sqd.parse_range(val, max: 2, arg: :PIPE)
|
|
206
374
|
end
|
|
207
375
|
sqd.on('-o', '--pipe-out FILE', 'Write command data stream to a file') do |val|
|
|
208
|
-
sqd.error_exit("missing an explicit \".#{File::SEPARATOR}\"", val) unless val.include?(File::SEPARATOR)
|
|
209
|
-
session[:OUT] = val
|
|
376
|
+
sqd.error_exit("missing an explicit \".#{File::SEPARATOR}\"", hint: val) unless val.include?(File::SEPARATOR)
|
|
377
|
+
sqd.session[:OUT] = val
|
|
210
378
|
end
|
|
211
379
|
sqd.on('--fail 0..4', Integer, 'Set application exception level') do |val|
|
|
212
|
-
sqd.
|
|
213
|
-
session[:FAIL] = val
|
|
380
|
+
sqd.parse_range(val, max: 4, arg: :FAIL)
|
|
214
381
|
end
|
|
215
382
|
%i[debug info warn error fatal].then do |state|
|
|
216
383
|
values = state + (0..4).map(&:to_s)
|
|
217
384
|
sqd.on('--log-level SEVERITY', values, "Set logger and exception state (#{state.join(', ')})") do |val|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
385
|
+
sqd.option_loglevel(val)
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
if Pathname.pwd.join('.git').directory?
|
|
389
|
+
sqd.separator ''
|
|
390
|
+
sqd.on('-c', '--commit', 'Push files remotely on active branch from current directory') do
|
|
391
|
+
sqd.option_commit('-c', '--commit', flag: :pathspec)
|
|
392
|
+
end
|
|
393
|
+
sqd.on('--amend', 'Replace the tip of the active branch remotely with a force push') do
|
|
394
|
+
sqd.option_commit('--amend', flag: :amend)
|
|
395
|
+
end
|
|
396
|
+
sqd.on('--amend-orig', 'Perform an amend commit without changing the message') do
|
|
397
|
+
sqd.option_commit('--amend-orig', flag: :'amend-orig')
|
|
230
398
|
end
|
|
231
399
|
end
|
|
232
400
|
sqd.separator ''
|
|
233
401
|
sqd.on('--[no-]banner', 'Display executing command attributes') do |val|
|
|
234
|
-
sqd.banner_set(val
|
|
402
|
+
sqd.banner_set(val)
|
|
235
403
|
end
|
|
236
404
|
sqd.on('-x', '--[no-]color', 'Use enhanced styling for terminal output') do |val|
|
|
237
|
-
sqd.color_set(val
|
|
405
|
+
sqd.color_set(val)
|
|
238
406
|
end
|
|
239
407
|
sqd.on('-X', '--plain', 'Disable banner and styling for all commands') do
|
|
240
|
-
sqd.banner_set(false
|
|
241
|
-
sqd.color_set(false
|
|
408
|
+
sqd.banner_set(false)
|
|
409
|
+
sqd.color_set(false)
|
|
242
410
|
end
|
|
243
411
|
sqd.on('-v', '--verbose', 'Increase output verbosity (multiple)') do
|
|
244
|
-
|
|
245
|
-
session[:VERBOSE] = $VERBOSE ? 1 : 0
|
|
246
|
-
sqd.global.unshift('--verbose')
|
|
247
|
-
end
|
|
248
|
-
ENV['VERBOSE'] = (session[:VERBOSE] += 1).to_s
|
|
412
|
+
sqd.option_verbose
|
|
249
413
|
end
|
|
250
414
|
sqd.on('--version', 'Print the current version') do
|
|
251
415
|
puts Squared::VERSION
|
data/lib/squared/common/base.rb
CHANGED
|
@@ -17,6 +17,7 @@ module Squared
|
|
|
17
17
|
BANNER: true,
|
|
18
18
|
PAGE: 20,
|
|
19
19
|
CHOICE: 100,
|
|
20
|
+
TAB: 4,
|
|
20
21
|
QUOTE: "'",
|
|
21
22
|
SPACE: ' => ',
|
|
22
23
|
SUCCESS: 'Success',
|
|
@@ -105,6 +106,7 @@ module Squared
|
|
|
105
106
|
|
|
106
107
|
def __freeze__
|
|
107
108
|
PATH.freeze
|
|
109
|
+
ARG.each_value { |val| val.freeze if val.is_a?(::Hash) || val.is_a?(::Array) }
|
|
108
110
|
ARG.freeze
|
|
109
111
|
VAR.each_value(&:freeze)
|
|
110
112
|
VAR[:theme].each_value { |val| val.freeze.each_value(&:freeze) }
|
|
@@ -5,12 +5,30 @@ require 'timeout'
|
|
|
5
5
|
module Squared
|
|
6
6
|
module Common
|
|
7
7
|
module Prompt
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
class << self
|
|
9
|
+
def reline
|
|
10
|
+
require 'reline'
|
|
11
|
+
Reline
|
|
12
|
+
rescue LoadError
|
|
13
|
+
require 'readline'
|
|
14
|
+
Readline
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def multiline=(val)
|
|
18
|
+
raise NotImplementedError, 'multiline is available only with reline' unless multiline?
|
|
19
|
+
|
|
20
|
+
@multiline = case val
|
|
21
|
+
when '', '0', 'false' then nil
|
|
22
|
+
else
|
|
23
|
+
val.split(',').map(&:strip)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def multiline?
|
|
28
|
+
reline.respond_to?(:readmultiline)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
attr_reader :multiline
|
|
14
32
|
end
|
|
15
33
|
|
|
16
34
|
module_function
|
|
@@ -169,8 +187,8 @@ module Squared
|
|
|
169
187
|
end
|
|
170
188
|
end
|
|
171
189
|
|
|
172
|
-
def readline(msg, history = false, force: nil, multiline:
|
|
173
|
-
multiline = nil unless Prompt.
|
|
190
|
+
def readline(msg, history = false, force: nil, multiline: Prompt.multiline, &blk)
|
|
191
|
+
multiline = nil unless Prompt.multiline?
|
|
174
192
|
read = lambda do
|
|
175
193
|
if !multiline
|
|
176
194
|
Prompt.reline.readline(msg, history)
|
data/lib/squared/version.rb
CHANGED
|
@@ -607,10 +607,10 @@ module Squared
|
|
|
607
607
|
@clean.each do |val|
|
|
608
608
|
src = basepath(val = val.to_s)
|
|
609
609
|
if src.directory? && val.match?(%r{[\\/]\z})
|
|
610
|
-
log&.
|
|
610
|
+
log&.info "rm -rf #{src}"
|
|
611
611
|
rm_rf(src, verbose: !silent?)
|
|
612
612
|
else
|
|
613
|
-
log&.
|
|
613
|
+
log&.info "rm #{src}"
|
|
614
614
|
(val.include?('*') ? Dir[src] : [src]).each do |file|
|
|
615
615
|
next unless File.file?(file)
|
|
616
616
|
|
|
@@ -864,7 +864,7 @@ module Squared
|
|
|
864
864
|
instance_variable_set :"@#{key}", [blk]
|
|
865
865
|
end
|
|
866
866
|
else
|
|
867
|
-
log&.
|
|
867
|
+
log&.debug "series: @#{key}".subhint('invalid')
|
|
868
868
|
end
|
|
869
869
|
self
|
|
870
870
|
end
|
|
@@ -876,7 +876,7 @@ module Squared
|
|
|
876
876
|
return
|
|
877
877
|
end
|
|
878
878
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
|
879
|
-
if interactive && sync && !(@session && option('y'))
|
|
879
|
+
if interactive && sync && !(@session && option('y', 'yes'))
|
|
880
880
|
print_item(series: true)
|
|
881
881
|
msg, y, h = case interactive
|
|
882
882
|
when Array
|
|
@@ -1019,7 +1019,7 @@ module Squared
|
|
|
1019
1019
|
instance_variable_set(:"@#{key}", val)
|
|
1020
1020
|
end
|
|
1021
1021
|
else
|
|
1022
|
-
log&.
|
|
1022
|
+
log&.debug "variable_set: @#{key}".subhint('private')
|
|
1023
1023
|
end
|
|
1024
1024
|
self
|
|
1025
1025
|
end
|
|
@@ -1701,7 +1701,7 @@ module Squared
|
|
|
1701
1701
|
ret = case key.downcase
|
|
1702
1702
|
when 'force'
|
|
1703
1703
|
getarg.call(:FORCE)
|
|
1704
|
-
when 'y'
|
|
1704
|
+
when 'y', 'yes'
|
|
1705
1705
|
getarg.call(:YES)
|
|
1706
1706
|
end
|
|
1707
1707
|
return yield(ret) if !ret.nil? && block_given?
|
|
@@ -2161,7 +2161,7 @@ module Squared
|
|
|
2161
2161
|
end
|
|
2162
2162
|
|
|
2163
2163
|
def confirm_basic(msg, hint, accept = 'Y', style: :inline, target: @session, prefix: target&.first, **kwargs)
|
|
2164
|
-
return true if option('y', prefix: prefix)
|
|
2164
|
+
return true if option('y', 'yes', prefix: prefix)
|
|
2165
2165
|
|
|
2166
2166
|
confirm("#{msg} [#{sub_style(hint.to_s, style.is_a?(Symbol) ? theme[style] : style)}]", accept, **kwargs)
|
|
2167
2167
|
end
|
|
@@ -2726,10 +2726,12 @@ module Squared
|
|
|
2726
2726
|
end
|
|
2727
2727
|
|
|
2728
2728
|
def checkdir?(val)
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2729
|
+
if val.directory? && !val.empty?
|
|
2730
|
+
true
|
|
2731
|
+
else
|
|
2732
|
+
log&.warn "directory \"#{val}\"".subhint(val.directory? ? 'empty' : 'missing')
|
|
2733
|
+
false
|
|
2734
|
+
end
|
|
2733
2735
|
end
|
|
2734
2736
|
|
|
2735
2737
|
def printfirst?
|
|
@@ -422,7 +422,7 @@ module Squared
|
|
|
422
422
|
def clean(*, sync: invoked_sync?('clean'), **)
|
|
423
423
|
if runnable?(@clean)
|
|
424
424
|
super
|
|
425
|
-
elsif sync || option('y', prefix: 'docker')
|
|
425
|
+
elsif sync || option('y', 'yes', prefix: 'docker')
|
|
426
426
|
image :rm
|
|
427
427
|
end
|
|
428
428
|
end
|
|
@@ -731,7 +731,7 @@ module Squared
|
|
|
731
731
|
return
|
|
732
732
|
end
|
|
733
733
|
op << id
|
|
734
|
-
if option('y')
|
|
734
|
+
if option('y', 'yes')
|
|
735
735
|
exception = false
|
|
736
736
|
banner = false
|
|
737
737
|
end
|
|
@@ -966,7 +966,7 @@ module Squared
|
|
|
966
966
|
pwd_set(from: from) do
|
|
967
967
|
index = 1
|
|
968
968
|
all = option('all', prefix: 'docker')
|
|
969
|
-
y = from == :'image:rm' && option('y', prefix: 'docker')
|
|
969
|
+
y = from == :'image:rm' && option('y', 'yes', prefix: 'docker')
|
|
970
970
|
filter = env('DOCKER_FILTER', filter).to_s
|
|
971
971
|
pat = if OptionPartition.pattern?(filter)
|
|
972
972
|
Regexp.new(filter)
|
|
@@ -1013,7 +1013,7 @@ module Squared
|
|
|
1013
1013
|
end
|
|
1014
1014
|
pad = cols.map(&:size).max
|
|
1015
1015
|
cols.each { |key| puts "#{g + f} #{key.rjust(pad)}: #{Array(data[key]).join(', ')}" }
|
|
1016
|
-
w = 9 + flag.to_s.size +
|
|
1016
|
+
w = 9 + flag.to_s.size + ARG[:TAB] + ee.size
|
|
1017
1017
|
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), theme[:inline])
|
|
1018
1018
|
index += 1
|
|
1019
1019
|
next unless confirm("#{h + b}?", no ? 'N' : 'Y')
|
|
@@ -363,7 +363,7 @@ module Squared
|
|
|
363
363
|
subtasks({
|
|
364
364
|
'branch' => %i[create track delete move copy list all current].freeze,
|
|
365
365
|
'checkout' => %i[commit branch track detach path].freeze,
|
|
366
|
-
'commit' => %i[head add all amend amend-orig fixup].freeze,
|
|
366
|
+
'commit' => %i[head add all pathspec amend amend-orig fixup].freeze,
|
|
367
367
|
'clone' => %i[branch tag].freeze,
|
|
368
368
|
'diff' => %i[head branch files view between contain].freeze,
|
|
369
369
|
'range-diff' => %i[view between contain].freeze,
|
|
@@ -530,7 +530,7 @@ module Squared
|
|
|
530
530
|
if flag == :add
|
|
531
531
|
opts = param_guard(action, flag, args: args.to_a)
|
|
532
532
|
elsif (refs = args.to_a).empty?
|
|
533
|
-
refs = readline('Enter
|
|
533
|
+
refs = readline('Enter glob patterns', force: true).shellsplit
|
|
534
534
|
end
|
|
535
535
|
end
|
|
536
536
|
commit(flag, opts, refs: refs, ref: ref, squash: squash, pick: pick)
|
|
@@ -1773,7 +1773,7 @@ module Squared
|
|
|
1773
1773
|
pathspec = false if pick == 'reword'
|
|
1774
1774
|
end
|
|
1775
1775
|
if pathspec.nil?
|
|
1776
|
-
pathspec = if (flag == :fixup || amend) && refs.size == 1 && refs.first == '*'
|
|
1776
|
+
pathspec = if (flag == :pathspec || flag == :fixup || amend) && refs.size == 1 && refs.first == '*'
|
|
1777
1777
|
'--all'
|
|
1778
1778
|
elsif (refs = projectmap(refs)).empty?
|
|
1779
1779
|
raise 'no qualified pathspec'
|
|
@@ -1847,7 +1847,7 @@ module Squared
|
|
|
1847
1847
|
elsif stdout?
|
|
1848
1848
|
puts log_message('nothing to commit', subject: name, hint: flag)
|
|
1849
1849
|
end
|
|
1850
|
-
exit 1
|
|
1850
|
+
exit 1 unless pass.nil?
|
|
1851
1851
|
end
|
|
1852
1852
|
end
|
|
1853
1853
|
|
|
@@ -11,7 +11,7 @@ module Squared
|
|
|
11
11
|
install_a: %w[audit=! bin-links=! engine-strict=!? foreground-scripts=!? fund=! ignore-scripts=!?
|
|
12
12
|
install-links=!? package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
|
|
13
13
|
install_b: %w[no-save B|save-bundle D|save-dev O|save-optional save-peer P|save-prod g|global=!?
|
|
14
|
-
S|save=!?].freeze,
|
|
14
|
+
min-release-age=i min-release-age-exclude=q S|save=!?].freeze,
|
|
15
15
|
install_c: %w[allow-directory=b? allow-file=b? allow-git=b? allow-remote=b?].freeze,
|
|
16
16
|
run: %w[foreground-scripts=!? if-present=!? ignore-scripts=!? script-shell=p].freeze,
|
|
17
17
|
exec: %w[c|call=q package=b].freeze,
|
|
@@ -230,7 +230,7 @@ module Squared
|
|
|
230
230
|
elsif exception?
|
|
231
231
|
indexerror n, list
|
|
232
232
|
else
|
|
233
|
-
log.
|
|
233
|
+
log.debug "run script #{n} of #{list.size}".subhint('out of range')
|
|
234
234
|
next
|
|
235
235
|
end
|
|
236
236
|
else
|
|
@@ -330,26 +330,39 @@ module Squared
|
|
|
330
330
|
when 'package'
|
|
331
331
|
case flag
|
|
332
332
|
when :approve, :deny
|
|
333
|
-
format_desc
|
|
333
|
+
format_desc(action, flag, 'opts*', before: flag == :approve ? 'name*|:' : 'name*|:|::')
|
|
334
334
|
task flag do |_, args|
|
|
335
335
|
args = args.to_a
|
|
336
|
-
if choice!(args)
|
|
336
|
+
if choice!(args) || (flag == :deny && (all = choice!(args, char: '::')))
|
|
337
|
+
list = []
|
|
338
|
+
pad = 0
|
|
339
|
+
size = ->(s) { pad = [pad, s.size].max }
|
|
337
340
|
pwd_set do
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
341
|
+
json = JSON.parse(`#{npm_output('install-scripts ls --json')}`)
|
|
342
|
+
json&.fetch('allowScripts', [])&.each do |data|
|
|
343
|
+
line = data['changes']&.find { |item| item['change'] == 'pending' }
|
|
344
|
+
next unless line && line['key'] =~ /^(.+)@([^@]+)$/
|
|
345
|
+
|
|
346
|
+
size.call($1)
|
|
347
|
+
list << [$1, $2]
|
|
348
|
+
end
|
|
349
|
+
if all
|
|
350
|
+
current = read_package 'allowScripts'
|
|
351
|
+
current&.each_pair do |key, val|
|
|
352
|
+
next unless val
|
|
353
|
+
|
|
354
|
+
md = key.match(/^(.+?)(?:@([^@]+))?$/)
|
|
355
|
+
size.call(md[1])
|
|
356
|
+
list << [md[1], sub_style(md[2] || 'any', theme[:inline])]
|
|
357
|
+
end
|
|
350
358
|
end
|
|
351
|
-
args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
|
|
352
359
|
end
|
|
360
|
+
if list.empty?
|
|
361
|
+
puts log_message('no packages to review', subject: name, hint: "#{flag}-scripts")
|
|
362
|
+
exit
|
|
363
|
+
end
|
|
364
|
+
list.map! { |name, ver| name.ljust(pad + ARG[:TAB]) + ver }
|
|
365
|
+
args.concat(choice_index('Select packages', list, multiple: true, column: /^(\S+)/))
|
|
353
366
|
end
|
|
354
367
|
package flag, args
|
|
355
368
|
end
|
|
@@ -885,9 +898,9 @@ module Squared
|
|
|
885
898
|
end
|
|
886
899
|
print_item banner unless sync
|
|
887
900
|
if !found.empty?
|
|
888
|
-
col1 = width.call(found, 0) +
|
|
889
|
-
col2 = width.call(found, 1) +
|
|
890
|
-
col3 = pad.call(found, found.size).size + 2 + col1 + col2 + width.call(found, 2)
|
|
901
|
+
col1 = width.call(found, 0) + ARG[:TAB]
|
|
902
|
+
col2 = width.call(found, 1) + ARG[:TAB]
|
|
903
|
+
col3 = pad.call(found, found.size).size + (ARG[:TAB] / 2) + col1 + col2 + width.call(found, 2)
|
|
891
904
|
packages = []
|
|
892
905
|
pat = ->(a) { /("#{Regexp.escape(a[0])}"\s*:\s*)"([~^])#{'?' if a[4]}#{Regexp.escape(a[1])}"/ }
|
|
893
906
|
edit = lambda do |a, pkg, mod|
|
|
@@ -983,9 +996,9 @@ module Squared
|
|
|
983
996
|
end
|
|
984
997
|
end
|
|
985
998
|
elsif !avail.empty?
|
|
986
|
-
col1 = width.call(avail, 0) +
|
|
999
|
+
col1 = width.call(avail, 0) + ARG[:TAB]
|
|
987
1000
|
col2 = width.call(avail, 1)
|
|
988
|
-
col3 = width.call(avail, 2) +
|
|
1001
|
+
col3 = width.call(avail, 2) + ARG[:TAB]
|
|
989
1002
|
avail.each_with_index do |item, i|
|
|
990
1003
|
a, b, c, d = item
|
|
991
1004
|
a = a.ljust(col1)
|
|
@@ -1381,7 +1394,7 @@ module Squared
|
|
|
1381
1394
|
op.exist?(add: true)
|
|
1382
1395
|
end
|
|
1383
1396
|
end
|
|
1384
|
-
op.append(flags,
|
|
1397
|
+
op.append(flags, context: kwargs)
|
|
1385
1398
|
.clear
|
|
1386
1399
|
print_run(op, banner, **kwargs)
|
|
1387
1400
|
start = time_epoch if kwargs.fetch(:verbose, verbose? && !stdin?)
|
|
@@ -221,7 +221,7 @@ module Squared
|
|
|
221
221
|
indexerror n, list
|
|
222
222
|
else
|
|
223
223
|
found |= 2
|
|
224
|
-
log.
|
|
224
|
+
log.debug "run script #{n} of #{list.size}".subhint('out of range')
|
|
225
225
|
end
|
|
226
226
|
else
|
|
227
227
|
case (i > 1 && poetry? ? 0 : i)
|
|
@@ -235,7 +235,7 @@ module Squared
|
|
|
235
235
|
raise message('script', val) if exception?
|
|
236
236
|
|
|
237
237
|
found |= 2
|
|
238
|
-
log.
|
|
238
|
+
log.debug "run script \"#{val}\"".subhint('not indexed')
|
|
239
239
|
end
|
|
240
240
|
end
|
|
241
241
|
end
|
|
@@ -253,7 +253,7 @@ module Squared
|
|
|
253
253
|
task action do |_, args|
|
|
254
254
|
args = args.to_a
|
|
255
255
|
cmd = if (i = args.delete(':')) && !windows?
|
|
256
|
-
readline('Enter script', force: true, multiline: %w[## ;])
|
|
256
|
+
readline('Enter script', force: true, multiline: Prompt.multiline || %w[## ;])
|
|
257
257
|
elsif i || args.empty?
|
|
258
258
|
readline('Enter command', force: true)
|
|
259
259
|
else
|
|
@@ -803,7 +803,7 @@ module Squared
|
|
|
803
803
|
op.clear
|
|
804
804
|
else
|
|
805
805
|
op.exist?(add: true, first: true) unless op.arg?('m')
|
|
806
|
-
op.append(
|
|
806
|
+
op.append(context: kwargs)
|
|
807
807
|
end
|
|
808
808
|
end
|
|
809
809
|
var = kwargs[:env]
|
|
@@ -914,7 +914,7 @@ module Squared
|
|
|
914
914
|
when :install, :uninstall
|
|
915
915
|
raise ArgumentError, message('no tags listed', hint: flag) if op.empty?
|
|
916
916
|
end
|
|
917
|
-
op << '-y' if option('y')
|
|
917
|
+
op << '-y' if option('y', 'yes')
|
|
918
918
|
op.append
|
|
919
919
|
print_run(op, banner, **kwargs)
|
|
920
920
|
run(sync: sync, banner: banner, exception: exception?(**kwargs), from: symjoin('py', flag))
|
|
@@ -952,7 +952,7 @@ module Squared
|
|
|
952
952
|
@dependindex = index
|
|
953
953
|
@dependfile = val
|
|
954
954
|
else
|
|
955
|
-
log.
|
|
955
|
+
log.debug "variable_set: @dependfile=#{val}".subhint('not supported')
|
|
956
956
|
end
|
|
957
957
|
end
|
|
958
958
|
when :venv
|
|
@@ -304,7 +304,7 @@ module Squared
|
|
|
304
304
|
elsif exception?
|
|
305
305
|
indexerror n, tasks
|
|
306
306
|
else
|
|
307
|
-
log.
|
|
307
|
+
log.debug "rake task #{n} of #{tasks.size}".subhint('out of range')
|
|
308
308
|
opts.clear
|
|
309
309
|
next
|
|
310
310
|
end
|
|
@@ -572,10 +572,10 @@ module Squared
|
|
|
572
572
|
when ';', /^#+$/
|
|
573
573
|
args.shift
|
|
574
574
|
else
|
|
575
|
-
%w[## ;]
|
|
575
|
+
Prompt.multiline || %w[## ;]
|
|
576
576
|
end
|
|
577
577
|
unless (command = ENV['RUBY_E'])
|
|
578
|
-
command = if Prompt.
|
|
578
|
+
command = if Prompt.multiline?
|
|
579
579
|
require 'ripper'
|
|
580
580
|
readline('ruby>', force: true, multiline: multiline) do |code|
|
|
581
581
|
next if code.strip.empty? || !Ripper.sexp(code)
|
|
@@ -956,7 +956,7 @@ module Squared
|
|
|
956
956
|
end
|
|
957
957
|
s = '%2d. %s' % [start, line]
|
|
958
958
|
if ia
|
|
959
|
-
unless confirm_semver(s.ljust(col +
|
|
959
|
+
unless confirm_semver(s.ljust(col + ARG[:TAB] + line.size - n), type)
|
|
960
960
|
start += 1
|
|
961
961
|
next
|
|
962
962
|
end
|
|
@@ -1049,7 +1049,7 @@ module Squared
|
|
|
1049
1049
|
if op.arg?('e')
|
|
1050
1050
|
op.clear
|
|
1051
1051
|
else
|
|
1052
|
-
op.append(delim: true,
|
|
1052
|
+
op.append(delim: true, context: kwargs)
|
|
1053
1053
|
end
|
|
1054
1054
|
end
|
|
1055
1055
|
print_run(op, banner, **kwargs) unless flag || op.stdout
|
|
@@ -1394,10 +1394,10 @@ module Squared
|
|
|
1394
1394
|
end
|
|
1395
1395
|
if flag == :install
|
|
1396
1396
|
op.append_any(escape: true)
|
|
1397
|
+
op.delim << post if post
|
|
1397
1398
|
else
|
|
1398
1399
|
op.append(escape: true)
|
|
1399
1400
|
end
|
|
1400
|
-
op.delim << post if post
|
|
1401
1401
|
when :check, :cleanup, :contents, :fetch, :list, :lock, :rdoc
|
|
1402
1402
|
op.append
|
|
1403
1403
|
when :dependency, :info, :search
|
|
@@ -1630,7 +1630,7 @@ module Squared
|
|
|
1630
1630
|
case flag
|
|
1631
1631
|
when :prototype
|
|
1632
1632
|
sig = args.shift
|
|
1633
|
-
y = option('y', ignore: false)
|
|
1633
|
+
y = option('y', 'yes', ignore: false)
|
|
1634
1634
|
i = 1
|
|
1635
1635
|
args.map { |val| basepath(val).relative_path_from(path) }.each do |file|
|
|
1636
1636
|
dir = basepath sig, file.dirname
|
|
@@ -1769,7 +1769,7 @@ module Squared
|
|
|
1769
1769
|
end
|
|
1770
1770
|
|
|
1771
1771
|
def gemname
|
|
1772
|
-
@gemname ||=
|
|
1772
|
+
@gemname ||= gemspec&.name || project
|
|
1773
1773
|
end
|
|
1774
1774
|
|
|
1775
1775
|
def project
|
|
@@ -1922,24 +1922,22 @@ module Squared
|
|
|
1922
1922
|
end
|
|
1923
1923
|
|
|
1924
1924
|
def bundle_args(*args)
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
end
|
|
1940
|
-
args.unshift('bundle', 'exec')
|
|
1925
|
+
gemfile = ARG[:APP][:ruby_gemfile]
|
|
1926
|
+
val = gemfile.is_a?(Hash) ? gemfile : @bundle[:exec]
|
|
1927
|
+
return args unless gemfile || (val && gemfile != false)
|
|
1928
|
+
|
|
1929
|
+
app = args.first
|
|
1930
|
+
if val.is_a?(Hash)
|
|
1931
|
+
val = val[app.to_s] || val[app.to_sym]
|
|
1932
|
+
elsif app == 'ruby' && !gemfile
|
|
1933
|
+
return args
|
|
1934
|
+
end
|
|
1935
|
+
case val
|
|
1936
|
+
when String, Pathname
|
|
1937
|
+
val = basepath!(val, type: 'f')
|
|
1938
|
+
args.unshift("--gemfile=#{shell_escape(val.relative_path_from(path), quote: true)}") if val
|
|
1941
1939
|
end
|
|
1942
|
-
args
|
|
1940
|
+
val ? args.unshift('bundle', 'exec') : args
|
|
1943
1941
|
end
|
|
1944
1942
|
|
|
1945
1943
|
def bundle_load
|
|
@@ -2133,7 +2131,7 @@ module Squared
|
|
|
2133
2131
|
def serve?
|
|
2134
2132
|
!Gem::Specification.find_by_name('webrick').nil?
|
|
2135
2133
|
rescue Gem::MissingSpecError => e
|
|
2136
|
-
log.
|
|
2134
|
+
log.debug e if @serve
|
|
2137
2135
|
false
|
|
2138
2136
|
end
|
|
2139
2137
|
end
|
|
@@ -58,10 +58,10 @@ module Squared
|
|
|
58
58
|
ret.map! do |val|
|
|
59
59
|
next val if opt?(val)
|
|
60
60
|
|
|
61
|
-
if
|
|
62
|
-
shell_escape(val, quote: quote, double: double)
|
|
63
|
-
elsif quote || pa
|
|
61
|
+
if (quote && !escape) || val.is_a?(Pathname)
|
|
64
62
|
shell_quote(val, double: double, **kwargs)
|
|
63
|
+
elsif escape
|
|
64
|
+
shell_escape(val, quote: quote, double: double)
|
|
65
65
|
else
|
|
66
66
|
val
|
|
67
67
|
end
|
|
@@ -487,7 +487,11 @@ module Squared
|
|
|
487
487
|
self
|
|
488
488
|
end
|
|
489
489
|
|
|
490
|
-
def append(*args, clear: false, preserve: '"', **kwargs, &blk)
|
|
490
|
+
def append(*args, clear: false, preserve: '"', context: nil, **kwargs, &blk)
|
|
491
|
+
if context
|
|
492
|
+
kwargs[:escape] = context.fetch(:escape, false) unless kwargs.key?(:escape)
|
|
493
|
+
kwargs[:quote] = context.fetch(:quote, false) unless kwargs.key?(:quote)
|
|
494
|
+
end
|
|
491
495
|
args = clear ? extras.dup.tap { extras.clear } : extras if args.empty?
|
|
492
496
|
pass = kwargs[:pass] ||= []
|
|
493
497
|
OptionPartition.append(target, *args, preserve: preserve, **kwargs, &blk)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: squared
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- An Pham
|
|
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
142
142
|
- !ruby/object:Gem::Version
|
|
143
143
|
version: '0'
|
|
144
144
|
requirements: []
|
|
145
|
-
rubygems_version: 4.0.
|
|
145
|
+
rubygems_version: 4.0.20
|
|
146
146
|
specification_version: 4
|
|
147
147
|
summary: Rake task generator for managing multi-language workspaces.
|
|
148
148
|
test_files: []
|