squared 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90258e1d46b51b15fcb414cddf85407968d227b5032797e76ead83befa5d302b
4
- data.tar.gz: a01b153f7c26b7f15a24cc66a159e47e42bc117e7b0810d7146c6ca3766f3cd0
3
+ metadata.gz: 71eae17e75e9ebe9a4fbe250f49da6397b169f06ac85c7f77170b9fc575bd63e
4
+ data.tar.gz: f68b5c36da52802d0b952c54a406d6d6bde3085308c465c2f058c8c944dce894
5
5
  SHA512:
6
- metadata.gz: 484c0af12a637957f3ed9ddc43b6f08bee1f3dbcba50a2acdfdd0dcb7bb929b83b64d40fd8bbf17ceddc5d8177a27773e4193198cbc80f2991651bf55366b2c8
7
- data.tar.gz: a9617a969c41e971235b98bc730fd440f6c913a2ce21b9e8acb1907ae170ac72da1bb5d72df8650c1833827599fb0d95ab4aae19e5c75249dac07c0096efe077
6
+ metadata.gz: 515aa7c65dd969fb9dd165a38716695a6c08ccbf0597ef3d7936bcd70750c2c54f661fc44e9dc303d34b8d99947d27939039654ca5ffd43afcf33f917deb2866
7
+ data.tar.gz: cfe3827d03d56619de9d3c60a4df2b249ff1f802bc9a6be407b96c5db95fb14faf6b3719e657c83dc046287d62272f1cf2e676fdad67da345abc93675e511474
data/README.md CHANGED
@@ -16,9 +16,6 @@
16
16
  * [E-mc](https://github.com/anpham6/e-mc#readme)
17
17
  * [Pi-r](https://github.com/anpham6/pi-r#readme)
18
18
 
19
- > [!NOTE]
20
- > `squared-express` originally was intended to be used as a HTTP/1.1 insecure development server for Android projects. `E-mc` was created a few years later to produce static outputs for any kind of development accessible through a simple REST API. Gradually any new development that calls the REST API will use [NGINX Unit](https://unit.nginx.org) as the *production* application runtime to efficiently serve static assets. Middleware and application code can be conducted in the same manner with Express and other programming frameworks (e.g. Ruby). Maintanence updates with subsequent `E-mc` releases supporting legacy development environments will be tested only against `Express 4.19` although most existing applications can be upgraded without any problems. Upgrading to `Express 5` is not recommended as it offers no new noticeable features (e.g. HTTP/2) and possibly compatibility issues with template libraries.
21
-
22
19
  ## Installation
23
20
 
24
21
  * NodeJS 16 LTS
@@ -113,14 +110,13 @@ cd workspaces # REPO_ROOT
113
110
 
114
111
  wget https://raw.githubusercontent.com/anpham6/squared/master/Rakefile
115
112
 
116
- # REPO_DOCS=1 (venv)
117
113
  rake -T # List tasks
118
114
 
119
115
  # REPO_BUILD={dev,prod}
120
116
  # PIPE_FAIL=1
121
117
  rake repo:init # nightly
122
- # OR
123
- rake repo:init[latest] # 0.11.x
118
+ rake repo:init[latest] # squared
119
+ rake repo:init[0.11.x] # e-mc
124
120
  # OR
125
121
  REPO_ROOT=/tmp/123 NODE_INSTALL=pnpm repo:init
126
122
  ```
data/README.ruby.md CHANGED
@@ -4,9 +4,17 @@
4
4
  * [manifest](https://github.com/anpham6/squared-repo)
5
5
  * [docs](https://squared.readthedocs.io)
6
6
 
7
- ## Prerequisites
7
+ ## Version Compatibility
8
8
 
9
- * Ruby 2.4
9
+ | Date | squared | Ruby 2 | Ruby 3 |
10
+ | :------: | ------: | -----: | -----: |
11
+ | 12-07-24 | 0.1.0 | 2.4.0 | 3.0.0 |
12
+
13
+ ## Installation
14
+
15
+ ```sh
16
+ gem install squared
17
+ ```
10
18
 
11
19
  ### Optional
12
20
 
@@ -20,12 +28,6 @@ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
20
28
  chmod a+rx ~/.bin/repo
21
29
  ```
22
30
 
23
- ## Installation
24
-
25
- ```sh
26
- gem install squared
27
- ```
28
-
29
31
  ## Example - Rakefile
30
32
 
31
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.
@@ -36,24 +38,44 @@ require "squared/workspace/repo" # Repo (optional)
36
38
 
37
39
  # NODE_ENV = production
38
40
  # REPO_ROOT = /workspaces
39
- # REPO_HOME = /workspaces/squared
41
+ # REPO_HOME = /workspaces/squared (Dir.pwd)
40
42
  # rake = /workspaces/squared/Rakefile
43
+ # pathname = /workspaces/pathname
44
+ # optparse = /workspaces/optparse
45
+ # log = /workspaces/logger
46
+ # emc = /workspaces/e-mc
47
+ # pir = /workspaces/pi-r
48
+ # squared = /workspaces/squared
49
+ # cli = /workspaces/squared/publish/sqd-cli
50
+ # sqd-serve = /workspaces/squared/publish/sqd-serve
51
+ # sqd = /workspaces/squared/sqd
41
52
 
42
53
  Workspace::Application
43
- .new(main: "squared") # Dir.pwd? (main? is implicitly basename)
54
+ .new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
44
55
  .banner("group", "project", styles: %i[yellow black], border: "bold") # name | project | path | ref | group?
45
- .repo("https://github.com/anpham6/squared-repo", "nightly", run: "build", ref: :node) # Repo (optional)
56
+ .repo("https://github.com/anpham6/squared-repo", "nightly", script: ["build:dev", "build:prod"], ref: :node) # Repo (optional)
46
57
  .run("rake install", ref: :ruby)
47
58
  .depend(false, group: "default")
48
59
  .clean("rake clean", group: "default")
49
60
  .clean(["build/"], group: "app")
50
- .add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", ref: :ruby) # Ruby (with C extensions)
61
+ .log({ file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app")
62
+ .add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", env: { # Ruby (with C extensions)
63
+ "CFLAGS" => "-fPIC -O1"
64
+ })
51
65
  .add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
52
66
  .add("logger", copy: { from: "lib", glob: "**/*.rb", gemdir: "~/.rvm/gems/ruby-3.3.5/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
53
- .add("emc", "e-mc", copy: { from: "publish", into: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
54
- .add("pir", "pi-r", copy: { from: "publish", into: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
55
- .add("squared", log: { file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app") # Copy target (main)
56
- .add("sqd", "squared/sqd", script: ["build:sqd", "prod:sqd"], depend: false, clean: ["build/sqd/"], exclude: :git) # NPM workspaces
67
+ .add("e-mc", "emc", copy: { from: "publish", into: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
68
+ .add("pi-r", "pir", copy: { from: "publish", into: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
69
+ .add("squared", script: ["build:stage1", "build:stage2"], group: "app") do # Copy target (main)
70
+ add("publish/sqd-cli", "cli", exclude: [:git])
71
+ add("publish/sqd-serve")
72
+ add("publish/sqd-admin", group: "sqd", exclude: [:base])
73
+ end
74
+ .add("squared/sqd", exclude: [:git]) do
75
+ variable_set :script, "build:sqd" # Override detection
76
+ variable_set :depend, false
77
+ variable_set :clean, ["build/sqd/"]
78
+ end
57
79
  .style("banner", 255.255) # 256 colors (fg | fg.bg | -0.bg)
58
80
  .build(default: "status", parallel: ["pull", "fetch", "rebase", "copy", "clean"]) do |workspace|
59
81
  workspace
@@ -63,16 +85,17 @@ Workspace::Application
63
85
  border: "bright_white"
64
86
  })
65
87
  end
66
- # pathname = /workspaces/pathname
67
- # optparse = /workspaces/optparse
68
- # log = /workspaces/logger
69
- # emc = /workspaces/e-mc
70
- # pir = /workspaces/pi-r
71
- # squared = /workspaces/squared
88
+
89
+ # default = /workspaces/ruby/*
90
+ # pathname = /workspaces/ruby/pathname
91
+ # optparse = /workspaces/ruby/optparse
92
+ # logger = /workspaces/ruby/logger
93
+ # android = /workspaces/android-docs
94
+ # chrome = /workspaces/chrome-docs
72
95
 
73
96
  Workspace::Application
74
- .new(ENV["SQUARED_DIR"], prefix: "rb", common: false) # Local styles
75
- .group("default", "ruby/", run: "rake build", copy: "rake install", clean: "rake clean", ref: :ruby, override: {
97
+ .new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
98
+ .group("ruby", "default", run: "rake build", copy: "rake install", clean: "rake clean", ref: :ruby, override: {
76
99
  pathname: {
77
100
  run: "rake compile" # rake rb:pathname:build
78
101
  }
@@ -82,17 +105,11 @@ Workspace::Application
82
105
  doc("make html") # rake rb:doc:python
83
106
  run(false) # rake rb:build:python (disabled)
84
107
  exclude(%i[base git]) # Project::Git.ref (superclass)
85
- add("android", "android-docs") # rake rb:android:doc
86
- add("chrome", "chrome-docs") # rake rb:chrome:doc
108
+ add("android-docs", "android") # rake rb:android:doc
109
+ add("chrome-docs", "chrome") # rake rb:chrome:doc
87
110
  end #
88
111
  .style("inline", "bold")
89
112
  .build
90
- # default = /workspaces/ruby/*
91
- # pathname = /workspaces/ruby/pathname
92
- # optparse = /workspaces/ruby/optparse
93
- # logger = /workspaces/ruby/logger
94
- # android = /workspaces/android-docs
95
- # chrome = /workspaces/chrome-docs
96
113
  ```
97
114
 
98
115
  **NOTE**: The use of "**ref**" (class name) is only necessary when running `repo:init` for the first time into an empty directory.
@@ -123,7 +140,16 @@ rake clean:app # none + skip + ["build/"]
123
140
  rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
124
141
  ```
125
142
 
126
- ## Commands
143
+ ```sh
144
+ rake build:app # squared + cli + sqd-serve
145
+ rake squared:build:workspace # cli + sqd-serve
146
+ rake pull:sqd # sqd-admin
147
+ rake squared:pull:workspace # sqd-serve + sqd-admin
148
+ ```
149
+
150
+ ## Methods
151
+
152
+ Task:
127
153
 
128
154
  * run
129
155
  * depend
@@ -131,6 +157,11 @@ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
131
157
  * doc
132
158
  * clean
133
159
 
160
+ Non-task:
161
+
162
+ * log
163
+ * exclude
164
+
134
165
  ## Styles
135
166
 
136
167
  * banner
@@ -139,6 +170,54 @@ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
139
170
  * active
140
171
  * inline
141
172
  * major
173
+ * red
174
+ * yellow
175
+ * green
176
+
177
+ ## Environment
178
+
179
+ ### Build
180
+
181
+ ```ruby
182
+ # LD_LIBRARY_PATH="path/to/lib" CFLAGS="-Wall" gcc a.c -o a.o -c
183
+ BUILD_${NAME} # gcc a.c -o a.o
184
+ BUILD_${NAME}_OPTS # -c
185
+ BUILD_${NAME}_ENV # {"LD_LIBRARY_PATH":"path/to/lib","CFLAGS":"-Wall"} (json)
186
+
187
+ # Scripts
188
+ BUILD_${NAME}_DEV # pattern,0,1
189
+ BUILD_${NAME}_PROD # pattern,0,1
190
+ ```
191
+
192
+ These options also support the project specific suffix `${NAME}`. (e.g. LOG_FILE_SQUARED)
193
+
194
+ ### Logger
195
+
196
+ ```ruby
197
+ LOG_FILE # %Y-%m-%d.log
198
+ # OR
199
+ LOG_AUTO # year,y,month,m,day,d,1
200
+ # Optional
201
+ LOG_DIR # exist?
202
+ LOG_LEVEL # See gem "logger"
203
+ LOG_COLUMNS # terminal width (default: 80)
204
+ ```
205
+
206
+ ### Repo
207
+
208
+ ```ruby
209
+ REPO_ROOT # parent dir
210
+ REPO_HOME # project dir (main)
211
+ REPO_BUILD # run,script
212
+ REPO_GROUP # string
213
+ REPO_REF # e.g. ruby,node
214
+ REPO_DEV # pattern,0,1
215
+ REPO_PROD # pattern,0,1
216
+ REPO_WARN # 0,1
217
+ REPO_SYNC # 0,1
218
+ REPO_MANIFEST # e.g. latest,nightly,prod
219
+ REPO_TIMEOUT # confirm dialog (seconds)
220
+ ```
142
221
 
143
222
  ## LICENSE
144
223
 
@@ -2,6 +2,11 @@
2
2
 
3
3
  module Squared
4
4
  module Common
5
+ KEY = {
6
+ PIPE: 1,
7
+ FAIL: false,
8
+ COMMON: true
9
+ }
5
10
  VAR = {
6
11
  project: {},
7
12
  colors: {
@@ -86,11 +91,14 @@ module Squared
86
91
  def as_a(obj, meth = nil, flat: nil, compact: false)
87
92
  return [] if obj.nil?
88
93
 
89
- if !obj.is_a?(::Array)
90
- obj = [obj]
91
- elsif flat
92
- obj = obj.flatten(flat == true ? nil : flat)
94
+ unless obj.is_a?(::Array)
95
+ obj = if !obj.is_a?(::Hash) && obj.respond_to?(:to_a) && (val = obj.to_a).is_a?(::Array)
96
+ val
97
+ else
98
+ [obj]
99
+ end
93
100
  end
101
+ obj = obj.flatten(flat.is_a?(::Numeric) ? flat : nil) if flat
94
102
  obj = obj.map(&meth) if meth
95
103
  compact ? obj.compact : obj
96
104
  end
@@ -61,7 +61,7 @@ module Squared
61
61
  else
62
62
  s = ret
63
63
  end
64
- if type.is_a?(Numeric)
64
+ if type.is_a?(::Numeric)
65
65
  f, b = type.to_s.split('.')
66
66
  s = wrap.(s, ['38', '5', f]) if f[0] != '-' && f.to_i <= 255
67
67
  if b
@@ -77,7 +77,7 @@ module Squared
77
77
  code << c
78
78
  end
79
79
  else
80
- next unless (n = TEXT_STYLE.index { |style| style == t })
80
+ next unless (n = TEXT_STYLE.index(t))
81
81
 
82
82
  s = "\x1B[#{n + 1}m#{s}\x1B[#{n == 0 ? 22 : n + 21}m"
83
83
  end
@@ -110,7 +110,7 @@ module Squared
110
110
  ret = []
111
111
  colors = __get__(:colors)
112
112
  as_a(args, flat: true, compact: true).each do |val|
113
- if !val.is_a?(Numeric)
113
+ if !val.is_a?(::Numeric)
114
114
  val = val.to_sym
115
115
  ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
116
116
  elsif val >= 0 && val <= 256
@@ -124,38 +124,40 @@ module Squared
124
124
  end
125
125
 
126
126
  def apply_style(data, key, *args, empty: true)
127
- data = __get__(:theme)[data] if data.is_a?(Symbol)
128
- return unless data
127
+ return if data.is_a?(::Symbol) && (data = __get__(:theme)[data]).nil?
129
128
 
130
- set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
131
- if key.is_a?(Hash)
132
- key.each { |k, v| set.(k, v || args.flatten) }
129
+ set = ->(k, v) { data[k] = check_style(v, empty: empty) }
130
+ if key.is_a?(::Hash)
131
+ key.each { |k, v| set.(k, v || args) }
133
132
  else
134
- set.(key, args.flatten)
133
+ set.(key.to_sym, args)
134
+ end
135
+ end
136
+
137
+ def log_sym(level)
138
+ if level.is_a?(::Numeric)
139
+ case level
140
+ when Logger::DEBUG
141
+ :debug
142
+ when Logger::INFO
143
+ :info
144
+ when Logger::WARN
145
+ :warn
146
+ when Logger::ERROR
147
+ :error
148
+ when Logger::FATAL
149
+ :fatal
150
+ else
151
+ :unknown
152
+ end
153
+ else
154
+ level.to_s.downcase.to_sym
135
155
  end
136
156
  end
137
157
 
138
158
  def log_title(level, color: true)
139
- level = if level.is_a?(::Numeric)
140
- case level
141
- when Logger::DEBUG
142
- :debug
143
- when Logger::INFO
144
- :info
145
- when Logger::WARN
146
- :warn
147
- when Logger::ERROR
148
- :error
149
- when Logger::FATAL
150
- :fatal
151
- else
152
- :unknown
153
- end
154
- else
155
- level.to_s.downcase.to_sym
156
- end
157
159
  theme = __get__(:theme)[:logger]
158
- styles = theme[level] || theme[level = :unknown]
160
+ styles = theme[level = log_sym(level)] || theme[level = :unknown]
159
161
  case (ret = +level.to_s.upcase)
160
162
  when 'WARN', 'ERROR', 'FATAL'
161
163
  ret += '!'
@@ -164,9 +166,21 @@ module Squared
164
166
  end
165
167
 
166
168
  def log_message(level, *args, subject: nil, hint: nil, color: true)
167
- msg = [log_title(level, color: color)]
168
- msg << (color ? sub_style(subject, :underline) : subject) if subject
169
- message(msg.join(' '), *args, hint: hint)
169
+ args = args.map(&:to_s)
170
+ if args.size > 1
171
+ title = log_title(level, color: false)
172
+ sub = { pat: /^(#{title})(.+)$/, styles: __get__(:theme)[:logger][log_sym(level)] } if color
173
+ emphasize(args, title: title + (subject ? " #{subject}" : ''), sub: sub)
174
+ else
175
+ msg = [log_title(level, color: color)]
176
+ if subject
177
+ msg << (color ? sub_style(subject, :underline) : subject)
178
+ else
179
+ msg += args
180
+ args.clear
181
+ end
182
+ message(msg.join(' '), *args, hint: hint)
183
+ end
170
184
  end
171
185
 
172
186
  def raise_error(*args, hint: nil, kind: ArgumentError)
@@ -11,16 +11,29 @@ module Squared
11
11
  def shell_escape(val, quote: false)
12
12
  return Shellwords.escape(val) unless ::Rake::Win32.windows?
13
13
 
14
- quote ? shell_quote(val, force: false) : val
14
+ quote ? shell_quote(opt, force: false) : opt
15
15
  end
16
16
 
17
17
  def shell_quote(val, force: true)
18
18
  ret = val.to_s.strip
19
- return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|=)(["']).+\1$/m
19
+ return ret if (!force && !ret.include?(' ')) || ret =~ /(?:^|\S=|[^=]\s+)(["']).+\1$/m
20
20
 
21
21
  ::Rake::Win32.windows? ? "\"#{double_quote(ret)}\"" : "'#{single_quote(ret)}'"
22
22
  end
23
23
 
24
+ def shell_split(val, quote: false, join: false)
25
+ ret = Shellwords.split(val).map do |opt|
26
+ if (data = /^(--?[^= ]+)(=|\s+)?(["'])?(.+?)\3?$/m.match(opt))
27
+ next opt unless data[2] && !data[3]
28
+
29
+ data[1] + data[2] + shell_quote(data[4], force: !::Rake::Win32.windows?)
30
+ else
31
+ shell_escape(opt, quote: quote)
32
+ end
33
+ end
34
+ join ? ret.join(' ') : ret
35
+ end
36
+
24
37
  def fill_option(val)
25
38
  return "-#{val}" if val.size == 1 || val =~ /^[a-z]\d+$/i
26
39
 
@@ -37,11 +50,7 @@ module Squared
37
50
  end
38
51
 
39
52
  def split_escape(val, char: ',')
40
- val.split(/\s*(?<!\\)#{char}\s*/)
41
- end
42
-
43
- def sanitize_args(*opts)
44
- opts.map { |val| val.include?(' ') ? shell_quote(val) : shell_escape(val) }.join(' ')
53
+ val.split(/\s*(?<!\\)#{char}\s*/o)
45
54
  end
46
55
  end
47
56
  end
@@ -20,11 +20,11 @@ module Squared
20
20
  end
21
21
  end
22
22
 
23
- def confirm(msg, agree: 'Y', cancel: 'N', default: nil, attempts: 5, timeout: 15)
23
+ def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 5, timeout: 15)
24
24
  require 'readline'
25
25
  require 'timeout'
26
- agree = /^#{agree}$/i if agree.is_a?(String)
27
- cancel = /^#{cancel}$/i if cancel.is_a?(String)
26
+ agree = /^#{agree}$/i if agree.is_a?(::String)
27
+ cancel = /^#{cancel}$/i if cancel.is_a?(::String)
28
28
  Timeout.timeout(timeout) do
29
29
  begin
30
30
  while (ch = Readline.readline(msg, true))
@@ -64,7 +64,7 @@ module Squared
64
64
 
65
65
  target = dest.join(ent.relative_path_from(src))
66
66
  dir = target.dirname
67
- if !subdir.include?(dir.to_s)
67
+ unless subdir.include?(dir.to_s)
68
68
  dir.mkpath
69
69
  subdir << dir.to_s
70
70
  end
@@ -76,7 +76,7 @@ module Squared
76
76
  end
77
77
 
78
78
  def copy_f(src, dest, overwrite: true, verbose: false)
79
- if !overwrite
79
+ unless overwrite
80
80
  path = Pathname.new(dest)
81
81
  if path.directory?
82
82
  src = [src] unless src.is_a?(::Array)
@@ -17,7 +17,7 @@ module Squared
17
17
  end
18
18
 
19
19
  def invoked?(name)
20
- ::Rake::Task.tasks.any? { |item| item.already_invoked && item.name == name.to_s }
20
+ ::Rake::Task.tasks.any? { |obj| obj.already_invoked && obj.name == name.to_s }
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Squared
4
+ module Common
5
+ module Utils
6
+ module_function
7
+
8
+ def env_value(key, suffix: nil)
9
+ if suffix
10
+ ret = ENV["#{key}_#{suffix}"]
11
+ return ret unless ret.nil?
12
+ end
13
+ ENV.fetch(key, '')
14
+ end
15
+
16
+ def env_bool(key, default = false, suffix: nil)
17
+ return default if key.nil?
18
+
19
+ if key.is_a?(::String)
20
+ case env_value(key, suffix: suffix)
21
+ when ''
22
+ default
23
+ when '0', 'false'
24
+ false
25
+ else
26
+ true
27
+ end
28
+ else
29
+ key
30
+ end
31
+ end
32
+
33
+ def env_pipe(key, default = 1, suffix: nil)
34
+ if key.is_a?(::String)
35
+ case (ret = env_value(key, suffix: suffix))
36
+ when '0', '1', '2'
37
+ ret.to_i
38
+ else
39
+ default
40
+ end
41
+ else
42
+ key.is_a?(::Numeric) && key >= 0 && key <= 2 ? key : default
43
+ end
44
+ end
45
+
46
+ def env_match(key, default = nil, suffix: nil, options: 0, timeout: nil)
47
+ case (ret = env_value(key, suffix: suffix))
48
+ when ''
49
+ default
50
+ when '0'
51
+ false
52
+ when '1'
53
+ true
54
+ else
55
+ Regexp.new(ret, options, timeout: timeout)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -9,3 +9,4 @@ require_relative 'common/format'
9
9
  require_relative 'common/shell'
10
10
  require_relative 'common/system'
11
11
  require_relative 'common/task'
12
+ require_relative 'common/utils'
@@ -9,6 +9,7 @@ module Squared
9
9
  class Viewer
10
10
  include Common
11
11
  include Format
12
+ include Utils
12
13
  include ::Rake::DSL
13
14
 
14
15
  class << self
@@ -18,8 +19,11 @@ module Squared
18
19
  end
19
20
 
20
21
  attr_reader :main, :name, :project, :theme
22
+ attr_accessor :pipe
21
23
 
22
- def initialize(main, name = nil, project: nil, prefix: nil, dump: nil, opts: {}, auto: true, common: true)
24
+ def initialize(main, name = nil,
25
+ project: nil, prefix: nil, dump: nil, opts: {}, auto: true,
26
+ common: Common::KEY[:COMMON], pipe: Common::KEY[:PIPE], **)
23
27
  if project
24
28
  main = @project.base_path(main).to_s if (@project = __get__(:project)[project.to_sym])
25
29
  @required = true
@@ -30,6 +34,7 @@ module Squared
30
34
  @dump = dump
31
35
  @mime = {}
32
36
  @theme = common ? __get__(:theme)[:viewer] : {}
37
+ @pipe = env_pipe(pipe, @project ? @project.pipe : 1)
33
38
  if exist?
34
39
  @main = main.chomp(@ext)
35
40
  @name = @main unless @name || @required
@@ -106,7 +111,8 @@ module Squared
106
111
  end
107
112
  end
108
113
  end
109
- rescue LoadError, NameError
114
+ rescue LoadError, NameError => e
115
+ project&.log&.warn e
110
116
  self
111
117
  else
112
118
  @mime[type] = opts
@@ -122,7 +128,7 @@ module Squared
122
128
 
123
129
  ext = mime_type(file)
124
130
  type = type&.to_s || ext
125
- if !parse
131
+ unless parse
126
132
  case type
127
133
  when 'json'
128
134
  parse = 'JSON'
@@ -190,7 +196,7 @@ module Squared
190
196
  .realpath
191
197
  .to_s
192
198
  .sub(Regexp.new("^#{Regexp.escape(File.join(Dir.pwd, ''))}"), '')
193
- sub = if !pipe?
199
+ sub = unless stdin?
194
200
  [
195
201
  { pat: /^((?:[^:]|(?<! ):(?! ))+)$/, styles: theme[:banner] },
196
202
  { pat: /^(.*?)(<[^>]+>)(.+)$/m, styles: theme[:undefined], index: 2 },
@@ -202,7 +208,7 @@ module Squared
202
208
  { pat: /^(.+ : (?!undefined))([^"\[{].*)$/m, styles: theme[:value], index: 2 }
203
209
  ]
204
210
  end
205
- emphasize(lines, title: title, sub: sub)
211
+ emphasize(lines, title: title, sub: sub, pipe: pipe == 2 ? $stderr : nil)
206
212
  end
207
213
 
208
214
  def print_keys(type, data, keys, file: nil)
@@ -233,13 +239,13 @@ module Squared
233
239
  $2 ? ".#{s}" : "#{s}."
234
240
  end
235
241
  end
236
- out << [key, pipe? ? JSON.dump(nil) : 'undefined']
242
+ out << [key, stdin? ? JSON.dump(nil) : 'undefined']
237
243
  else
238
- out << [key, @dump == 'json' || pipe? ? JSON.dump(val) : val.inspect]
244
+ out << [key, @dump == 'json' || stdin? ? JSON.dump(val) : val.inspect]
239
245
  end
240
246
  pad = [pad, key.size].max
241
247
  end
242
- if pipe?
248
+ if stdin?
243
249
  puts out.map(&:last).join("\n")
244
250
  else
245
251
  out.map { |item| "#{item[0].ljust(pad)} : #{item[1]}" }
@@ -279,16 +285,13 @@ module Squared
279
285
  !@ext.empty? && (!@required || !project.nil?)
280
286
  end
281
287
 
282
- def pipe?
283
- return project.workspace.pipe if project
284
-
285
- val = ENV['PIPE_OUT']
286
- !val.nil? && !val.empty? && val != '0'
287
- end
288
-
289
288
  def warning?
290
289
  project ? project.workspace.warning : true
291
290
  end
291
+
292
+ def stdin?
293
+ pipe == 0
294
+ end
292
295
  end
293
296
  end
294
297
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.10'
5
5
  end