squared 0.1.11 → 0.2.0

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.
data/README.ruby.md ADDED
@@ -0,0 +1,384 @@
1
+ # squared 0.2
2
+
3
+ * [source](https://github.com/anpham6/squared)
4
+ * [manifest](https://github.com/anpham6/squared-repo)
5
+ * [docs](https://squared.readthedocs.io)
6
+
7
+ ## Version Compatibility
8
+
9
+ | Date | squared | Min | Max |
10
+ | :--------: | ------: | -----: | -----: |
11
+ | 2024-12-07 | 0.1.0 | 2.4.0 | 3.3.6 |
12
+ | 2025-01-07 | 0.2.0 | 2.4.0 | 3.4.0 |
13
+
14
+ The range chart indicates the latest Ruby tested against at the time of release.
15
+
16
+ ## Installation
17
+
18
+ ```sh
19
+ gem install squared
20
+ ```
21
+
22
+ ### Optional
23
+
24
+ * [Repo](https://source.android.com/docs/setup/reference/repo)
25
+ * Python 3.6
26
+ * Not compatible with Windows
27
+
28
+ ```sh
29
+ mkdir -p ~/.bin
30
+ PATH="${HOME}/.bin:${PATH}"
31
+ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
32
+ chmod a+rx ~/.bin/repo
33
+ ```
34
+
35
+ ## Example - Rakefile
36
+
37
+ 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.
38
+
39
+ ```ruby
40
+ require "squared"
41
+
42
+ require "squared/workspace"
43
+ require "squared/workspace/repo" # Optional
44
+ require "squared/workspace/project/node" #
45
+ require "squared/workspace/project/python" #
46
+ require "squared/workspace/project/ruby" #
47
+ # OR
48
+ require "squared/app" # All workspace related modules
49
+
50
+ # NODE_ENV = production
51
+
52
+ # REPO_ROOT = /workspaces #
53
+ # REPO_HOME = /workspaces/squared # Dir.pwd
54
+ # rake = /workspaces/squared/Rakefile # main?
55
+ # OR
56
+ # REPO_ROOT = /workspaces # Dir.pwd
57
+ # rake = /workspaces/Rakefile #
58
+ # REPO_HOME = /workspaces/squared # main: "squared"
59
+
60
+ # pathname = /workspaces/pathname
61
+ # optparse = /workspaces/optparse
62
+ # log = /workspaces/logger
63
+ # emc = /workspaces/e-mc
64
+ # pir = /workspaces/pi-r
65
+ # squared = /workspaces/squared
66
+ # cli = /workspaces/squared/publish/sqd-cli
67
+ # sqd-serve = /workspaces/squared/publish/sqd-serve
68
+ # sqd = /workspaces/squared/sqd
69
+
70
+ Workspace::Application
71
+ .new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
72
+ .banner("group", "project", styles: ["yellow", "black"], border: "bold") # name | project | path | ref | group? | parent? | version?
73
+ .repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "build:prod"], ref: :node) # Repo (optional)
74
+ .run("rake install", ref: :ruby)
75
+ .depend(false, group: "default")
76
+ .clean("rake clean", group: "default")
77
+ .clean(["build/"], group: "app")
78
+ .log({ file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app")
79
+ .add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", env: { # Ruby (with C extensions)
80
+ "CFLAGS" => "-fPIC -O1"
81
+ })
82
+ .add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
83
+ .add("logger", copy: { from: "lib", glob: "**/*.rb", into: "~/.rvm/gems/ruby-3.4.0/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
84
+ .add("e-mc", "emc", copy: { from: "publish", scope: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
85
+ .add("pi-r", "pir", copy: { from: "publish", scope: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
86
+ .add("squared", script: ["build:stage1", "build:stage2"], group: "app") do # Copy target (main)
87
+ add("publish/sqd-cli", "cli", exclude: [:git]) # rake cli:build
88
+ add("publish/sqd-serve") # rake sqd-serve:build
89
+ add("publish/sqd-admin", group: "sqd", exclude: [:base])
90
+ # OR
91
+ with(exclude: [:base]) { add("publish/*", "packages") } # rake packages:sqd-serve:build
92
+ # OR
93
+ add(["publish/sqd-cli", "publish/sqd-serve", "publish/sqd-admin"], true, exclude: [:base]) # rake squared:sqd-serve:build
94
+ end
95
+ .add("squared/sqd", exclude: :git, pass: [:node, 'checkout', 'bump']) do # Skip initialize(:node) + squared:checkout:* + squared:bump:*
96
+ variable_set :script, "build:sqd" # Override detection
97
+ variable_set :depend, false
98
+ variable_set :clean, ["build/sqd/"]
99
+ end
100
+ .style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
101
+ .build(default: "build", parallel: ["pull", "fetch", "rebase", "copy", "clean", /^outdated:/]) do |workspace|
102
+ workspace
103
+ .enable_aixterm
104
+ .style({
105
+ banner: ["bright_cyan", "bold", "bright_black!"],
106
+ border: "bright_white"
107
+ })
108
+ end
109
+
110
+ # default = /workspaces/ruby/*
111
+ # pathname = /workspaces/ruby/pathname
112
+ # optparse = /workspaces/ruby/optparse
113
+ # logger = /workspaces/ruby/logger
114
+ # android = /workspaces/android-docs
115
+ # chrome = /workspaces/chrome-docs
116
+
117
+ Workspace::Application
118
+ .new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
119
+ .group("ruby", "default", run: "rake build", copy: "rake install", clean: "rake clean", ref: :ruby, override: {
120
+ pathname: {
121
+ run: "rake compile" # rake rb:pathname:build
122
+ }
123
+ })
124
+ .with(:python) do # ref=Symbol | group=String
125
+ banner([:name, ": ", :version], "path") # chrome-docs: 0.1.0 | /workspaces/chrome-docs
126
+ doc("make html") # rake rb:doc:python
127
+ run(false) # rake rb:build:python (disabled)
128
+ exclude(%i[base git]) # Project::Git.ref (superclass)
129
+ add("android-docs", "android") # rake rb:android:doc
130
+ add("chrome-docs", "chrome") # rake rb:chrome:doc
131
+ end
132
+ .style("inline", "bold")
133
+ .build
134
+ ```
135
+
136
+ **NOTE**: The use of "**ref**" (class name) is only necessary when initializing an empty directory (e.g. *rake repo:init*).
137
+
138
+ ### Clone
139
+
140
+ The task is only active when the project directory is empty or does not exist.
141
+
142
+ ```ruby
143
+ Workspace::Application
144
+ .new(main: "squared")
145
+ .git(
146
+ "emc": "https://github.com/anpham6/e-mc", # rake emc:clone
147
+ "pir": { # rake pir:clone
148
+ uri: "https://github.com/anpham6/pi-r", #
149
+ options: { #
150
+ "origin": "github", # --origin='github'
151
+ "recurse-submodules": false, # --no-recurse-submodules
152
+ "shallow-exclude": ["v0.0.1", "v0.0.2"] # --shallow-exclude='v0.0.1' --shallow-exclude='v0.0.2'
153
+ }
154
+ }
155
+ )
156
+ .git("squared", "/path/to/squared", options: { local: true }) # Relative paths resolve from workspace root
157
+ .git(
158
+ {
159
+ emc: { uri: "e-mc", options: { "depth": 2 } }, # https://github.com/anpham6/e-mc
160
+ pir: "pi-r" # Maps task alias to repository folder
161
+ },
162
+ base: "https://github.com/anpham6", # Required
163
+ repo: ["squared", "android-docs", "chrome-docs"], # https://github.com/anpham6/squared
164
+ options: { # Only "repo"
165
+ "depth": 1,
166
+ "quiet": true
167
+ }
168
+ )
169
+ .with(:node) do # rake clone:node
170
+ add("e-mc", "emc") # https://github.com/anpham6/e-mc
171
+ add("pi-r", "pir") # https://github.com/anpham6/pi-r
172
+ add("squared") # https://github.com/anpham6/squared
173
+ end
174
+ .with(:python) do # rake clone:python
175
+ add("android-docs")
176
+ add("chrome-docs")
177
+ end
178
+ .git("https://github.com/anpham6") # Uses already defined root projects
179
+ .git("https://github.com/anpham6", ["emc", "pir"]) # Targets any defined project
180
+ .build(parallel: ["clone"]) # rake clone + rake clone:sync
181
+ ```
182
+
183
+ ### Graph
184
+
185
+ ```ruby
186
+ Workspace::Application
187
+ .new(main: "squared")
188
+ .graph(["depend"], ref: :git) # Optional
189
+ .with(:python) do
190
+ add("android-docs", "android")
191
+ add("chrome-docs", "chrome", graph: "android")
192
+ end
193
+ .with(:node) do
194
+ graph(["build", "copy"], on: { # Overrides "git"
195
+ first: proc { puts "1" },
196
+ last: proc { puts "2" }
197
+ })
198
+ add("e-mc", "emc") do
199
+ first("build", "emc:clean", "emc:depend") # rake emc:clean; rake emc:depend; rake emc:build; puts "123";
200
+ last("build", out: "123") { |out: nil| puts out } #
201
+ error("build") { |err: nil| log.debug err } #
202
+ end
203
+ add("pi-r", "pir", graph: "emc", first: {
204
+ build: proc { puts self.name } # puts "pir"
205
+ })
206
+ add("squared-express", "express", graph: "pir")
207
+ add("squared", graph: ["chrome", "express"]) do
208
+ first("git:ls-files") { puts path }
209
+ last("git:ls-files") { puts workspace.root }
210
+ end
211
+ end
212
+ .with(:ruby) do
213
+ add("pathname")
214
+ add("fileutils", graph: "pathname")
215
+ add("optparse")
216
+ add("rake", graph: ["fileutils", "optparse"])
217
+ banner(command: false) # Always hide banner
218
+ end
219
+ .build
220
+ ```
221
+
222
+ ```sh
223
+ rake pir:graph # emc + pir
224
+ rake express:graph # emc + pir + express
225
+ rake chrome:graph # android + chrome
226
+ rake graph:python # same
227
+ rake squared:graph # android + chrome + emc + pir + express + squared
228
+ rake graph:node # same
229
+ rake rake:graph # pathname + fileutils + optparse + rake
230
+ rake graph:ruby # same
231
+ rake graph # graph:node + graph:ruby
232
+ ```
233
+
234
+ ### Batch
235
+
236
+ ```ruby
237
+ Workspace::Series.batch(:ruby, :node, {
238
+ stage: %i[graph test],
239
+ reset: %i[stash pull]
240
+ })
241
+ ```
242
+
243
+ ### Rename
244
+
245
+ ```ruby
246
+ Workspace::Series.rename("depend", "install")
247
+ ```
248
+
249
+ ## Usage
250
+
251
+ ```sh
252
+ rake -T # List tasks
253
+ rake # rake status (usually "build")
254
+
255
+ # GIT_OPTIONS=rebase
256
+ rake pull # All except "default" + "app"
257
+ rake pull:ruby # pathname + optparse + logger
258
+ rake pull:default # pathname + optparse
259
+ rake pull:app # squared
260
+ rake pull:node # emc + pir + squared
261
+
262
+ rake build # All except "android"
263
+ rake doc # optparse + android
264
+ rake depend # All except "default"
265
+
266
+ rake build:ruby # rake compile + rake install + rake install
267
+
268
+ rake clean # All except "default" + "app"
269
+ rake clean:ruby # rake clean + rake clean + ["tmp/"]
270
+ rake clean:default # rake clean + rake clean + skip
271
+ rake clean:app # none + skip + ["build/"]
272
+ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
273
+
274
+ rake squared:run[#] # List scripts (node)
275
+ rake squared:rake[#] # List tasks (ruby)
276
+ ```
277
+
278
+ ```sh
279
+ rake build:app # squared + cli + sqd-serve
280
+ rake squared:build:workspace # cli + sqd-serve
281
+ rake pull:sqd # sqd-admin
282
+ rake squared:pull:workspace # sqd-serve + sqd-admin
283
+ rake squared:outdated:workspace # cli + sqd-serve + sqd-admin
284
+ ```
285
+
286
+ ## Methods
287
+
288
+ Task:
289
+
290
+ * run
291
+ * depend
292
+ * graph
293
+ * test
294
+ * doc
295
+ * clean
296
+
297
+ Non-task:
298
+
299
+ * log
300
+ * exclude
301
+
302
+ ## Styles
303
+
304
+ * banner
305
+ * border
306
+ * header
307
+ * active
308
+ * inline
309
+ * current
310
+ * major
311
+ * red
312
+ * yellow
313
+ * green
314
+
315
+ ## Environment
316
+
317
+ ### Path
318
+
319
+ All project executable programs can have their binary path set to a non-global alias.
320
+
321
+ ```ruby
322
+ Common::PATH.merge!({
323
+ GIT: '/usr/bin/git',
324
+ GEM: '~/.rvm/rubies/ruby-3.4.0/bin/gem',
325
+ BUNDLE: '~/.rvm/gems/ruby-3.4.0/bin/bundle',
326
+ RAKE: '~/.rvm/gems/ruby-3.4.0/bin/rake',
327
+ NPM: '/opt/node/v22.0.0/bin/npm',
328
+ PYTHON: "#{ENV['PYTHONPATH']}/bin/python"
329
+ })
330
+ ```
331
+
332
+ ### Build
333
+
334
+ ```ruby
335
+ # :env :run :opts
336
+ # LD_LIBRARY_PATH="path/to/lib" CFLAGS="-Wall" gcc a.c -o a.o -c
337
+ BUILD_${NAME} # gcc a.c -o a.o
338
+ BUILD_OPTS_${NAME} # -c
339
+ BUILD_ENV_${NAME} # {"LD_LIBRARY_PATH":"path/to/lib","CFLAGS":"-Wall"} (hash/json)
340
+
341
+ # :env :opts :script
342
+ # NODE_ENV="production" NO_COLOR="1" npm run --loglevel=error --workspaces=false build:dev
343
+ BUILD_${NAME} # build:dev
344
+ BUILD_OPTS_${NAME} # --loglevel=error --workspaces=false
345
+ BUILD_ENV_${NAME} # {"NODE_ENV":"production","NO_COLOR":"1"} (hash/json)
346
+ BUILD_DEV_${NAME} # pattern,0,1 (:dev)
347
+ BUILD_PROD_${NAME} # pattern,0,1 (:prod)
348
+
349
+ BUILD_${NAME}=0 # skip project
350
+ ```
351
+
352
+ These options also support the project specific suffix `${NAME}`. (e.g. LOG_FILE_SQUARED)
353
+
354
+ ### Logger
355
+
356
+ ```ruby
357
+ LOG_FILE # %Y-%m-%d.log
358
+ # OR
359
+ LOG_AUTO # year,y,month,m,day,d,1
360
+ # Optional
361
+ LOG_DIR # exist?
362
+ LOG_LEVEL # See gem "logger"
363
+ LOG_COLUMNS # terminal width (default: 80)
364
+ ```
365
+
366
+ ### Repo
367
+
368
+ ```ruby
369
+ REPO_ROOT # parent dir
370
+ REPO_HOME # project dir (main)
371
+ REPO_BUILD # run,script
372
+ REPO_GROUP # string
373
+ REPO_REF # e.g. ruby,node
374
+ REPO_DEV # pattern,0,1
375
+ REPO_PROD # pattern,0,1
376
+ REPO_WARN # 0,1
377
+ REPO_SYNC # 0,1
378
+ REPO_MANIFEST # e.g. latest,nightly,prod
379
+ REPO_TIMEOUT # confirm dialog (seconds)
380
+ ```
381
+
382
+ ## LICENSE
383
+
384
+ BSD 3-Clause
data/lib/squared/app.rb CHANGED
@@ -6,5 +6,3 @@ require_relative 'workspace/project/node'
6
6
  require_relative 'workspace/project/python'
7
7
  require_relative 'workspace/project/ruby'
8
8
  require_relative 'config'
9
-
10
- Common = Squared::Common
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Squared
4
4
  module Common
5
+ PATH = {}
5
6
  ARG = {
6
7
  PIPE: 1,
7
8
  OUT: nil,
@@ -11,6 +12,7 @@ module Squared
11
12
  BANNER: true,
12
13
  SPACE: ' => ',
13
14
  GRAPH: ['│', '─', '├', '└', '┬'],
15
+ VIEW: 'view',
14
16
  COLOR: ENV.fetch('NO_COLOR', '').empty?
15
17
  }
16
18
  VAR = {
@@ -35,30 +37,31 @@ module Squared
35
37
  },
36
38
  theme: {
37
39
  workspace: {
38
- header: %i[bold],
39
- active: %i[bold],
40
- inline: %i[bold],
41
- major: %i[bold]
40
+ header: [:bold],
41
+ active: [:bold],
42
+ inline: [:bold],
43
+ current: nil,
44
+ major: [:bold]
42
45
  },
43
46
  project: {},
44
47
  viewer: {
45
- banner: %i[blue bold],
46
- key: %i[bold],
47
- value: %i[green],
48
- string: %i[yellow],
48
+ banner: [:bold],
49
+ border: [:blue],
50
+ key: nil,
51
+ value: [:green],
52
+ string: [:yellow],
49
53
  hash: %i[green black!],
50
54
  array: %i[blue black!],
51
- number: %i[magenta],
52
- boolean: %i[magenta],
55
+ number: [:magenta],
53
56
  undefined: %i[red italic]
54
57
  },
55
58
  logger: {
56
- unknown: %i[cyan],
59
+ unknown: [:cyan],
57
60
  fatal: %i[white bold red!],
58
61
  error: %i[red bold],
59
62
  warn: %i[yellow bold],
60
- info: %i[blue],
61
- debug: %i[green]
63
+ info: [:blue],
64
+ debug: [:green]
62
65
  }
63
66
  }
64
67
  }.compare_by_identity
@@ -77,29 +80,29 @@ module Squared
77
80
  end
78
81
 
79
82
  def __freeze__
83
+ PATH.freeze
80
84
  ARG.freeze
81
85
  VAR.each_value(&:freeze)
82
- VAR[:theme].each_value { |val| val.freeze.each_value(&:freeze) }
86
+ VAR[:theme].each_value(&:freeze)
83
87
  VAR.freeze
84
88
  end
85
89
 
86
90
  module_function
87
91
 
88
- def as_a(obj, meth = nil, flat: nil, compact: false)
92
+ def as_a(obj, meth = nil, flat: nil, compact: false, &blk)
89
93
  return [] if obj.nil?
90
94
 
91
95
  unless obj.is_a?(::Array)
92
- obj = if obj.respond_to?(:to_ary)
93
- obj.to_ary
94
- elsif obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
96
+ obj = if obj.respond_to?(:to_a) && !obj.is_a?(::Hash) && (val = obj.to_a).is_a?(::Array)
95
97
  val
96
98
  else
97
99
  [obj]
98
100
  end
99
101
  end
100
- obj = flat.is_a?(::Numeric) ? obj.flatten(flat) : obj.flatten if flat
102
+ obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
101
103
  obj = obj.compact if compact
102
- meth ? obj.map(&meth) : obj
104
+ obj = obj.map(&meth) if meth
105
+ block_given? ? obj.select(&blk) : obj
103
106
  end
104
107
  end
105
108
  end
@@ -34,11 +34,28 @@ module Squared
34
34
  super.match(/[^:]+\z/)[0]
35
35
  end
36
36
 
37
+ attr_reader :delim
38
+
37
39
  def initialize(data = [], delim: ' ')
38
40
  super(data.compact)
39
41
  @delim = delim
40
42
  end
41
43
 
44
+ def pass(&blk)
45
+ ret = to_a.map!(&:to_s).reject(&:empty?)
46
+ block_given? ? ret.reject(&blk) : ret
47
+ end
48
+
49
+ def temp(*args, &blk)
50
+ args.compact!
51
+ ret = pass(&blk)
52
+ unless args.empty?
53
+ ret += args
54
+ ret = Set.new(ret).to_a
55
+ end
56
+ ret.join(@delim)
57
+ end
58
+
42
59
  def done
43
60
  ret = to_s
44
61
  clear
@@ -46,7 +63,7 @@ module Squared
46
63
  end
47
64
 
48
65
  def to_s
49
- to_a.map!(&:to_s).reject(&:empty?).join(@delim)
66
+ pass.join(@delim)
50
67
  end
51
68
  end
52
69
  end
@@ -53,7 +53,7 @@ module Squared
53
53
  end
54
54
  wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
55
55
  code = []
56
- args.concat(as_a(styles)).flatten.each_with_index do |type, i|
56
+ args.concat(as_a(styles)).each_with_index do |type, i|
57
57
  next unless type
58
58
 
59
59
  if index == -1
@@ -114,7 +114,7 @@ module Squared
114
114
  if !val.is_a?(::Numeric)
115
115
  val = val.to_sym
116
116
  ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
117
- elsif val.between?(0, 256)
117
+ elsif val >= 0 && val <= 256
118
118
  ret << val
119
119
  elsif val < 0 && (b = val.to_s.split('.')[1])
120
120
  b = b[0..2]
@@ -127,26 +127,26 @@ module Squared
127
127
  def apply_style(data, key, args, empty: true)
128
128
  return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
129
129
 
130
- set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
130
+ set = ->(k, v) { data[k] = check_style(v, empty: empty) }
131
131
  if key.is_a?(::Hash)
132
132
  key.each { |k, v| set.(k, v || args) }
133
133
  else
134
- set.(key, args)
134
+ set.(key.to_sym, args)
135
135
  end
136
136
  end
137
137
 
138
138
  def log_sym(level)
139
139
  if level.is_a?(::Numeric)
140
140
  case level
141
- when ::Logger::DEBUG
141
+ when Logger::DEBUG
142
142
  :debug
143
- when ::Logger::INFO
143
+ when Logger::INFO
144
144
  :info
145
- when ::Logger::WARN
145
+ when Logger::WARN
146
146
  :warn
147
- when ::Logger::ERROR
147
+ when Logger::ERROR
148
148
  :error
149
- when ::Logger::FATAL
149
+ when Logger::FATAL
150
150
  :fatal
151
151
  else
152
152
  :unknown
@@ -171,20 +171,24 @@ module Squared
171
171
  if args.size > 1
172
172
  title = log_title(level, color: false)
173
173
  sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
174
- emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub, pipe: -1)
174
+ emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
175
175
  else
176
176
  msg = [log_title(level, color: color)]
177
- msg << (color ? sub_style(subject, :underline) : subject) if subject
178
- msg << args.shift if msg.size == 1
177
+ if subject
178
+ msg << (color ? sub_style(subject, :underline) : subject)
179
+ else
180
+ msg += args
181
+ args.clear
182
+ end
179
183
  message(msg.join(' '), *args, hint: hint)
180
184
  end
181
185
  end
182
186
 
183
187
  def puts_oe(*args, pipe: 1)
184
- if pipe.is_a?(::Pathname)
188
+ if pipe.is_a?(Pathname)
185
189
  begin
186
- ::File.open(pipe, 'a') do |f|
187
- br = ::File::SEPARATOR == '\\' ? "\r\n" : "\n"
190
+ File.open(pipe, 'a') do |f|
191
+ br = File::SEPARATOR == '\\' ? "\r\n" : "\n"
188
192
  args.flatten.each { |val| f.write("#{strip_style(val.chomp)}#{br}") }
189
193
  end
190
194
  return
@@ -257,8 +261,6 @@ module Squared
257
261
  yield out
258
262
  elsif pipe
259
263
  case pipe
260
- when -1
261
- return out
262
264
  when 0
263
265
  pipe = $stdin
264
266
  when 2
@@ -276,12 +278,8 @@ module Squared
276
278
  val.gsub(/\x1B\[(\d+;?)+m/, '')
277
279
  end
278
280
 
279
- def stripext(val)
280
- File.basename(val, File.extname(val))
281
- end
282
-
283
281
  def raise_error(*args, hint: nil, kind: ArgumentError)
284
- raise kind, message(*args, hint: hint, empty: true)
282
+ raise kind, message(*args, hint: hint, empty: true), caller_locations(1)
285
283
  end
286
284
  end
287
285
  end
@@ -21,7 +21,7 @@ module Squared
21
21
  return false
22
22
  end
23
23
  attempts -= 1
24
- exit 1 unless attempts > 0
24
+ exit 1 unless attempts >= 0
25
25
  end
26
26
  rescue Interrupt
27
27
  puts