Merge branch 'audit_build'
This commit is contained in:
27
build.cm
27
build.cm
@@ -464,7 +464,7 @@ Build.compile_file = function(pkg, file, target, opts) {
|
|||||||
|
|
||||||
// Compile
|
// Compile
|
||||||
log.shop('compiling ' + file)
|
log.shop('compiling ' + file)
|
||||||
log.console('Compiling ' + file)
|
log.build('Compiling ' + file)
|
||||||
err_path = '/tmp/cell_build_err_' + content_hash(setup.src_path) + '.log'
|
err_path = '/tmp/cell_build_err_' + content_hash(setup.src_path) + '.log'
|
||||||
full_cmd = setup.cmd_str + ' -o "' + obj_path + '" 2>"' + err_path + '"'
|
full_cmd = setup.cmd_str + ' -o "' + obj_path + '" 2>"' + err_path + '"'
|
||||||
ret = os.system(full_cmd)
|
ret = os.system(full_cmd)
|
||||||
@@ -603,6 +603,8 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
|||||||
var post_probe = null
|
var post_probe = null
|
||||||
var fallback_probe = null
|
var fallback_probe = null
|
||||||
var _fail_msg2 = null
|
var _fail_msg2 = null
|
||||||
|
var link_err_path = null
|
||||||
|
var link_err_text = null
|
||||||
|
|
||||||
if (probe && probe.fail) {
|
if (probe && probe.fail) {
|
||||||
_fail_msg2 = probe.fail_path ? text(fd.slurp(probe.fail_path)) : null
|
_fail_msg2 = probe.fail_path ? text(fd.slurp(probe.fail_path)) : null
|
||||||
@@ -697,9 +699,15 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
|||||||
cmd_str = text(cmd_parts, ' ')
|
cmd_str = text(cmd_parts, ' ')
|
||||||
if (_opts.verbose) log.build('[verbose] link: ' + cmd_str)
|
if (_opts.verbose) log.build('[verbose] link: ' + cmd_str)
|
||||||
log.shop('linking ' + file)
|
log.shop('linking ' + file)
|
||||||
log.console('Linking module ' + file + ' -> ' + fd.basename(dylib_path))
|
log.build('Linking module ' + file + ' -> ' + fd.basename(dylib_path))
|
||||||
ret = os.system(cmd_str)
|
link_err_path = '/tmp/cell_link_err_' + content_hash(file) + '.log'
|
||||||
|
ret = os.system(cmd_str + ' 2>"' + link_err_path + '"')
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
if (fd.is_file(link_err_path))
|
||||||
|
link_err_text = text(fd.slurp(link_err_path))
|
||||||
|
if (link_err_text)
|
||||||
|
log.error('Linking failed: ' + file + '\n' + link_err_text)
|
||||||
|
else
|
||||||
log.error('Linking failed: ' + file)
|
log.error('Linking failed: ' + file)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -745,6 +753,9 @@ Build.build_dynamic = function(pkg, target, buildtype, opts) {
|
|||||||
var _opts = opts || {}
|
var _opts = opts || {}
|
||||||
var c_files = pkg_tools.get_c_files(pkg, _target, true)
|
var c_files = pkg_tools.get_c_files(pkg, _target, true)
|
||||||
var results = []
|
var results = []
|
||||||
|
var total = length(c_files)
|
||||||
|
var done = 0
|
||||||
|
var failed = 0
|
||||||
|
|
||||||
// Pre-fetch cflags once to avoid repeated TOML reads
|
// Pre-fetch cflags once to avoid repeated TOML reads
|
||||||
var pkg_dir = shop.get_package_dir(pkg)
|
var pkg_dir = shop.get_package_dir(pkg)
|
||||||
@@ -760,14 +771,24 @@ Build.build_dynamic = function(pkg, target, buildtype, opts) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (total > 0)
|
||||||
|
os.print(' Building C modules ')
|
||||||
|
|
||||||
arrfor(c_files, function(file) {
|
arrfor(c_files, function(file) {
|
||||||
var sym_name = shop.c_symbol_for_file(pkg, file)
|
var sym_name = shop.c_symbol_for_file(pkg, file)
|
||||||
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
||||||
if (dylib) {
|
if (dylib) {
|
||||||
push(results, {file: file, symbol: sym_name, dylib: dylib})
|
push(results, {file: file, symbol: sym_name, dylib: dylib})
|
||||||
|
} else {
|
||||||
|
failed = failed + 1
|
||||||
}
|
}
|
||||||
|
done = done + 1
|
||||||
|
os.print('.')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (total > 0)
|
||||||
|
os.print(` ${text(done)}/${text(total)}${failed > 0 ? `, ${text(failed)} failed` : ''}\n`)
|
||||||
|
|
||||||
// Write manifest so runtime can find dylibs without the build module
|
// Write manifest so runtime can find dylibs without the build module
|
||||||
var mpath = manifest_path(pkg)
|
var mpath = manifest_path(pkg)
|
||||||
fd.slurpwrite(mpath, stone(blob(json.encode(results))))
|
fd.slurpwrite(mpath, stone(blob(json.encode(results))))
|
||||||
|
|||||||
@@ -9,13 +9,16 @@ Logging in ƿit is channel-based. Any `log.X(value)` call writes to channel `"X"
|
|||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
|
|
||||||
Three channels are conventional:
|
These channels are conventional:
|
||||||
|
|
||||||
| Channel | Usage |
|
| Channel | Usage |
|
||||||
|---------|-------|
|
|---------|-------|
|
||||||
| `log.console(msg)` | General output |
|
| `log.console(msg)` | General output |
|
||||||
| `log.error(msg)` | Errors and warnings |
|
| `log.error(msg)` | Errors |
|
||||||
|
| `log.warn(msg)` | Compiler diagnostics and warnings |
|
||||||
| `log.system(msg)` | Internal system messages |
|
| `log.system(msg)` | Internal system messages |
|
||||||
|
| `log.build(msg)` | Per-file compile/link output |
|
||||||
|
| `log.shop(msg)` | Package management internals |
|
||||||
|
|
||||||
Any name works. `log.debug(msg)` creates channel `"debug"`, `log.perf(msg)` creates `"perf"`, and so on.
|
Any name works. `log.debug(msg)` creates channel `"debug"`, `log.perf(msg)` creates `"perf"`, and so on.
|
||||||
|
|
||||||
@@ -29,16 +32,18 @@ Non-text values are JSON-encoded automatically.
|
|||||||
|
|
||||||
## Default Behavior
|
## Default Behavior
|
||||||
|
|
||||||
With no configuration, a default sink routes `console`, `error`, and `system` to the terminal in pretty format. The `error` channel includes a stack trace by default:
|
With no configuration, a default sink routes `console` and `error` to the terminal in clean format. The `error` channel includes a stack trace by default:
|
||||||
|
|
||||||
```
|
```
|
||||||
[a3f12] [console] server started on port 8080
|
server started on port 8080
|
||||||
[a3f12] [error] connection refused
|
error: connection refused
|
||||||
at handle_request (server.ce:42:3)
|
at handle_request (server.ce:42:3)
|
||||||
at main (main.ce:5:1)
|
at main (main.ce:5:1)
|
||||||
```
|
```
|
||||||
|
|
||||||
The format is `[actor_id] [channel] message`. Error stack traces are always on unless you explicitly configure a sink without them.
|
Clean format prints messages without actor ID or channel prefix. Error messages are prefixed with `error:`. Other formats (`pretty`, `bare`) include actor IDs and are available for debugging. Stack traces are always on for errors unless you explicitly configure a sink without them.
|
||||||
|
|
||||||
|
Channels like `warn`, `build`, and `shop` are not routed to the terminal by default. Enable them with `pit log enable <channel>`.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -67,7 +72,7 @@ exclude = ["console"]
|
|||||||
| Field | Values | Description |
|
| Field | Values | Description |
|
||||||
|-------|--------|-------------|
|
|-------|--------|-------------|
|
||||||
| `type` | `"console"`, `"file"` | Where output goes |
|
| `type` | `"console"`, `"file"` | Where output goes |
|
||||||
| `format` | `"pretty"`, `"bare"`, `"json"` | How output is formatted |
|
| `format` | `"clean"`, `"pretty"`, `"bare"`, `"json"` | How output is formatted |
|
||||||
| `channels` | array of names, or `["*"]` | Which channels this sink receives. Quote `'*'` on the CLI to prevent shell glob expansion. |
|
| `channels` | array of names, or `["*"]` | Which channels this sink receives. Quote `'*'` on the CLI to prevent shell glob expansion. |
|
||||||
| `exclude` | array of names | Channels to skip (useful with `"*"`) |
|
| `exclude` | array of names | Channels to skip (useful with `"*"`) |
|
||||||
| `stack` | array of channel names | Channels that capture a stack trace |
|
| `stack` | array of channel names | Channels that capture a stack trace |
|
||||||
@@ -75,6 +80,13 @@ exclude = ["console"]
|
|||||||
|
|
||||||
### Formats
|
### Formats
|
||||||
|
|
||||||
|
**clean** — CLI-friendly. No actor ID or channel prefix. Error channel messages are prefixed with `error:`. This is the default format.
|
||||||
|
|
||||||
|
```
|
||||||
|
server started on port 8080
|
||||||
|
error: connection refused
|
||||||
|
```
|
||||||
|
|
||||||
**pretty** — human-readable, one line per message. Includes actor ID, channel, source location, and message.
|
**pretty** — human-readable, one line per message. Includes actor ID, channel, source location, and message.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -158,7 +170,10 @@ The `pit log` command manages sinks and reads log files. See [CLI — pit log](/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
pit log list # show sinks
|
pit log list # show sinks
|
||||||
pit log add terminal console --format=bare --channels=console
|
pit log channels # list channels with enabled/disabled status
|
||||||
|
pit log enable warn # enable a channel on the terminal sink
|
||||||
|
pit log disable warn # disable a channel
|
||||||
|
pit log add terminal console --format=clean --channels=console
|
||||||
pit log add dump file .cell/logs/dump.jsonl '--channels=*' --exclude=console
|
pit log add dump file .cell/logs/dump.jsonl '--channels=*' --exclude=console
|
||||||
pit log add debug console --channels=error,debug --stack=error,debug
|
pit log add debug console --channels=error,debug --stack=error,debug
|
||||||
pit log remove terminal
|
pit log remove terminal
|
||||||
@@ -166,6 +181,16 @@ pit log read dump --lines=20 --channel=error
|
|||||||
pit log tail dump
|
pit log tail dump
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Channel toggling
|
||||||
|
|
||||||
|
The `enable` and `disable` commands modify the terminal sink's channel list without touching other sink configuration. This is the easiest way to opt in to extra output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pit log enable warn # see compiler warnings
|
||||||
|
pit log enable build # see per-file compile/link output
|
||||||
|
pit log disable warn # hide warnings again
|
||||||
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Development setup
|
### Development setup
|
||||||
|
|||||||
@@ -259,7 +259,6 @@ if (_native) {
|
|||||||
compile_native_cached(_te.name, core_path + '/' + _te.path)
|
compile_native_cached(_te.name, core_path + '/' + _te.path)
|
||||||
_ti = _ti + 1
|
_ti = _ti + 1
|
||||||
}
|
}
|
||||||
os.print("bootstrap: native cache seeded\n")
|
|
||||||
} else {
|
} else {
|
||||||
// Bytecode path: seed cache with everything engine needs
|
// Bytecode path: seed cache with everything engine needs
|
||||||
_targets = [
|
_targets = [
|
||||||
@@ -276,5 +275,4 @@ if (_native) {
|
|||||||
compile_and_cache(_te.name, core_path + '/' + _te.path)
|
compile_and_cache(_te.name, core_path + '/' + _te.path)
|
||||||
_ti = _ti + 1
|
_ti = _ti + 1
|
||||||
}
|
}
|
||||||
os.print("bootstrap: cache seeded\n")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ function analyze(src, filename) {
|
|||||||
_i = 0
|
_i = 0
|
||||||
while (_i < length(folded._diagnostics)) {
|
while (_i < length(folded._diagnostics)) {
|
||||||
e = folded._diagnostics[_i]
|
e = folded._diagnostics[_i]
|
||||||
os.print(`${filename}:${text(e.line)}:${text(e.col)}: ${e.severity}: ${e.message}\n`)
|
log.warn(`${filename}:${text(e.line)}:${text(e.col)}: ${e.severity}: ${e.message}`)
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
if (_wm) {
|
if (_wm) {
|
||||||
@@ -443,8 +443,12 @@ function run_ast_fn(name, ast, env, pkg) {
|
|||||||
_has_errors = false
|
_has_errors = false
|
||||||
while (_di < length(optimized._diagnostics)) {
|
while (_di < length(optimized._diagnostics)) {
|
||||||
_diag = optimized._diagnostics[_di]
|
_diag = optimized._diagnostics[_di]
|
||||||
os.print(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}\n`)
|
if (_diag.severity == "error") {
|
||||||
if (_diag.severity == "error") _has_errors = true
|
log.error(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}`)
|
||||||
|
_has_errors = true
|
||||||
|
} else {
|
||||||
|
log.warn(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}`)
|
||||||
|
}
|
||||||
_di = _di + 1
|
_di = _di + 1
|
||||||
}
|
}
|
||||||
if (_has_errors) disrupt
|
if (_has_errors) disrupt
|
||||||
@@ -506,8 +510,12 @@ function compile_user_blob(name, ast, pkg) {
|
|||||||
_has_errors = false
|
_has_errors = false
|
||||||
while (_di < length(optimized._diagnostics)) {
|
while (_di < length(optimized._diagnostics)) {
|
||||||
_diag = optimized._diagnostics[_di]
|
_diag = optimized._diagnostics[_di]
|
||||||
os.print(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}\n`)
|
if (_diag.severity == "error") {
|
||||||
if (_diag.severity == "error") _has_errors = true
|
log.error(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}`)
|
||||||
|
_has_errors = true
|
||||||
|
} else {
|
||||||
|
log.warn(`${_diag.file}:${text(_diag.line)}:${text(_diag.col)}: ${_diag.severity}: ${_diag.message}`)
|
||||||
|
}
|
||||||
_di = _di + 1
|
_di = _di + 1
|
||||||
}
|
}
|
||||||
if (_has_errors) disrupt
|
if (_has_errors) disrupt
|
||||||
@@ -920,9 +928,8 @@ function load_log_config() {
|
|||||||
sink: {
|
sink: {
|
||||||
terminal: {
|
terminal: {
|
||||||
type: "console",
|
type: "console",
|
||||||
format: "pretty",
|
format: "clean",
|
||||||
channels: ["*"],
|
channels: ["console", "error"],
|
||||||
exclude: ["system", "shop", "build"],
|
|
||||||
stack: ["error"]
|
stack: ["error"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -964,6 +971,25 @@ function bare_format(rec) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clean_format(rec) {
|
||||||
|
var ev = is_text(rec.event) ? rec.event : json.encode(rec.event, false)
|
||||||
|
var out = null
|
||||||
|
var i = 0
|
||||||
|
var fr = null
|
||||||
|
if (rec.channel == "error") {
|
||||||
|
out = `error: ${ev}\n`
|
||||||
|
} else {
|
||||||
|
out = `${ev}\n`
|
||||||
|
}
|
||||||
|
if (rec.stack && length(rec.stack) > 0) {
|
||||||
|
for (i = 0; i < length(rec.stack); i = i + 1) {
|
||||||
|
fr = rec.stack[i]
|
||||||
|
out = out + ` at ${fr.fn} (${fr.file}:${text(fr.line)}:${text(fr.col)})\n`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
function sink_excluded(sink, channel) {
|
function sink_excluded(sink, channel) {
|
||||||
var excluded = false
|
var excluded = false
|
||||||
if (!sink.exclude || length(sink.exclude) == 0) return false
|
if (!sink.exclude || length(sink.exclude) == 0) return false
|
||||||
@@ -981,6 +1007,8 @@ function dispatch_to_sink(sink, rec) {
|
|||||||
os.print(json.encode(rec, false) + "\n")
|
os.print(json.encode(rec, false) + "\n")
|
||||||
else if (sink.format == "bare")
|
else if (sink.format == "bare")
|
||||||
os.print(bare_format(rec))
|
os.print(bare_format(rec))
|
||||||
|
else if (sink.format == "clean")
|
||||||
|
os.print(clean_format(rec))
|
||||||
else
|
else
|
||||||
os.print(pretty_format(rec))
|
os.print(pretty_format(rec))
|
||||||
} else if (sink.type == "file") {
|
} else if (sink.type == "file") {
|
||||||
|
|||||||
@@ -1882,6 +1882,7 @@ Shop.sync_with_deps = function(pkg, opts) {
|
|||||||
if (visited[current]) continue
|
if (visited[current]) continue
|
||||||
visited[current] = true
|
visited[current] = true
|
||||||
|
|
||||||
|
log.console(' Fetching ' + current + '...')
|
||||||
Shop.sync(current, opts)
|
Shop.sync(current, opts)
|
||||||
|
|
||||||
_read_deps = function() {
|
_read_deps = function() {
|
||||||
@@ -2072,6 +2073,12 @@ Shop.build_package_scripts = function(package)
|
|||||||
_try()
|
_try()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (length(errors) > 0) {
|
||||||
|
log.console(' Compiling scripts (' + text(ok) + ' ok, ' + text(length(errors)) + ' errors)')
|
||||||
|
} else if (ok > 0) {
|
||||||
|
log.console(' Compiling scripts (' + text(ok) + ' ok)')
|
||||||
|
}
|
||||||
|
|
||||||
return {ok: ok, errors: errors, total: length(scripts)}
|
return {ok: ok, errors: errors, total: length(scripts)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
134
log.ce
134
log.ce
@@ -2,6 +2,9 @@
|
|||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// cell log list List configured sinks
|
// cell log list List configured sinks
|
||||||
|
// cell log channels List channels with status
|
||||||
|
// cell log enable <channel> Enable a channel on terminal
|
||||||
|
// cell log disable <channel> Disable a channel on terminal
|
||||||
// cell log add <name> console [opts] Add a console sink
|
// cell log add <name> console [opts] Add a console sink
|
||||||
// cell log add <name> file <path> [opts] Add a file sink
|
// cell log add <name> file <path> [opts] Add a file sink
|
||||||
// cell log remove <name> Remove a sink
|
// cell log remove <name> Remove a sink
|
||||||
@@ -46,6 +49,9 @@ function print_help() {
|
|||||||
log.console("")
|
log.console("")
|
||||||
log.console("Commands:")
|
log.console("Commands:")
|
||||||
log.console(" list List configured sinks")
|
log.console(" list List configured sinks")
|
||||||
|
log.console(" channels List channels with status")
|
||||||
|
log.console(" enable <channel> Enable a channel on terminal")
|
||||||
|
log.console(" disable <channel> Disable a channel on terminal")
|
||||||
log.console(" add <name> console [opts] Add a console sink")
|
log.console(" add <name> console [opts] Add a console sink")
|
||||||
log.console(" add <name> file <path> [opts] Add a file sink")
|
log.console(" add <name> file <path> [opts] Add a file sink")
|
||||||
log.console(" remove <name> Remove a sink")
|
log.console(" remove <name> Remove a sink")
|
||||||
@@ -328,6 +334,128 @@ function do_tail() {
|
|||||||
poll()
|
poll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var known_channels = ["console", "error", "warn", "system", "build", "shop", "compile", "test"]
|
||||||
|
|
||||||
|
function find_terminal_sink(config) {
|
||||||
|
var names = null
|
||||||
|
var found = null
|
||||||
|
if (!config || !config.sink) return null
|
||||||
|
names = array(config.sink)
|
||||||
|
if (config.sink.terminal) return config.sink.terminal
|
||||||
|
arrfor(names, function(n) {
|
||||||
|
if (!found && config.sink[n].type == "console")
|
||||||
|
found = config.sink[n]
|
||||||
|
})
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_enable() {
|
||||||
|
var channel = null
|
||||||
|
var config = null
|
||||||
|
var sink = null
|
||||||
|
var i = 0
|
||||||
|
var already = false
|
||||||
|
if (length(args) < 2) {
|
||||||
|
log.error("Usage: cell log enable <channel>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
channel = args[1]
|
||||||
|
config = load_config()
|
||||||
|
if (!config) config = {sink: {}}
|
||||||
|
if (!config.sink) config.sink = {}
|
||||||
|
sink = find_terminal_sink(config)
|
||||||
|
if (!sink) {
|
||||||
|
config.sink.terminal = {type: "console", format: "clean", channels: ["console", "error", channel], stack: ["error"]}
|
||||||
|
save_config(config)
|
||||||
|
log.console("Enabled channel: " + channel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
||||||
|
if (is_array(sink.exclude)) {
|
||||||
|
var new_exclude = []
|
||||||
|
arrfor(sink.exclude, function(ex) {
|
||||||
|
if (ex != channel) push(new_exclude, ex)
|
||||||
|
})
|
||||||
|
sink.exclude = new_exclude
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!is_array(sink.channels)) sink.channels = ["console", "error"]
|
||||||
|
arrfor(sink.channels, function(ch) {
|
||||||
|
if (ch == channel) already = true
|
||||||
|
})
|
||||||
|
if (!already) sink.channels[] = channel
|
||||||
|
}
|
||||||
|
save_config(config)
|
||||||
|
log.console("Enabled channel: " + channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_disable() {
|
||||||
|
var channel = null
|
||||||
|
var config = null
|
||||||
|
var sink = null
|
||||||
|
var i = 0
|
||||||
|
var new_channels = []
|
||||||
|
if (length(args) < 2) {
|
||||||
|
log.error("Usage: cell log disable <channel>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
channel = args[1]
|
||||||
|
config = load_config()
|
||||||
|
if (!config || !config.sink) {
|
||||||
|
log.error("No log configuration found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sink = find_terminal_sink(config)
|
||||||
|
if (!sink) {
|
||||||
|
log.error("No terminal sink found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
||||||
|
if (!is_array(sink.exclude)) sink.exclude = []
|
||||||
|
var already_excluded = false
|
||||||
|
arrfor(sink.exclude, function(ex) {
|
||||||
|
if (ex == channel) already_excluded = true
|
||||||
|
})
|
||||||
|
if (!already_excluded) sink.exclude[] = channel
|
||||||
|
} else {
|
||||||
|
if (is_array(sink.channels)) {
|
||||||
|
arrfor(sink.channels, function(ch) {
|
||||||
|
if (ch != channel) push(new_channels, ch)
|
||||||
|
})
|
||||||
|
sink.channels = new_channels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
save_config(config)
|
||||||
|
log.console("Disabled channel: " + channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_channels() {
|
||||||
|
var config = load_config()
|
||||||
|
var sink = null
|
||||||
|
var is_wildcard = false
|
||||||
|
var active = {}
|
||||||
|
if (config) sink = find_terminal_sink(config)
|
||||||
|
if (sink) {
|
||||||
|
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
||||||
|
is_wildcard = true
|
||||||
|
arrfor(known_channels, function(ch) { active[ch] = true })
|
||||||
|
if (is_array(sink.exclude)) {
|
||||||
|
arrfor(sink.exclude, function(ex) { active[ex] = false })
|
||||||
|
}
|
||||||
|
} else if (is_array(sink.channels)) {
|
||||||
|
arrfor(sink.channels, function(ch) { active[ch] = true })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
active.console = true
|
||||||
|
active.error = true
|
||||||
|
}
|
||||||
|
log.console("Channels:")
|
||||||
|
arrfor(known_channels, function(ch) {
|
||||||
|
var status = active[ch] ? "enabled" : "disabled"
|
||||||
|
log.console(" " + ch + ": " + status)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Main dispatch
|
// Main dispatch
|
||||||
if (length(args) == 0) {
|
if (length(args) == 0) {
|
||||||
print_help()
|
print_help()
|
||||||
@@ -335,6 +463,12 @@ if (length(args) == 0) {
|
|||||||
print_help()
|
print_help()
|
||||||
} else if (args[0] == 'list') {
|
} else if (args[0] == 'list') {
|
||||||
do_list()
|
do_list()
|
||||||
|
} else if (args[0] == 'channels') {
|
||||||
|
do_channels()
|
||||||
|
} else if (args[0] == 'enable') {
|
||||||
|
do_enable()
|
||||||
|
} else if (args[0] == 'disable') {
|
||||||
|
do_disable()
|
||||||
} else if (args[0] == 'add') {
|
} else if (args[0] == 'add') {
|
||||||
do_add()
|
do_add()
|
||||||
} else if (args[0] == 'remove') {
|
} else if (args[0] == 'remove') {
|
||||||
|
|||||||
@@ -3277,6 +3277,7 @@ JS_RaiseDisrupt (JSContext *ctx, const char *fmt, ...) {
|
|||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
vsnprintf (buf, sizeof (buf), fmt, ap);
|
vsnprintf (buf, sizeof (buf), fmt, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
if (ctx->log_callback)
|
||||||
JS_Log (ctx, "error", "%s", buf);
|
JS_Log (ctx, "error", "%s", buf);
|
||||||
ctx->current_exception = JS_TRUE;
|
ctx->current_exception = JS_TRUE;
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
|||||||
Reference in New Issue
Block a user