squared 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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