mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-28 09:02:12 +08:00
* feat(cli): add unified Commander CLI for QingLong 2.x * fix(cli): publish via npm and address security review feedback * ci(cli): package npm artifacts and remove evaluation collateral * test(cli): use a fixed shell fixture for log retention * refactor(cli): separate remote npm client from panel tools * feat(cli): cover active panel OpenAPI resources * docs(cli): unify authentication and skill guidance * refactor(cli): isolate internal commands and generate Commander help * refactor(cli): organize remote and internal modules by responsibility * ci(cli): publish verified npm archives from master * fix(cli): publish under the whyour npm scope * ci: use npm trusted publishing for both packages * docs: introduce the published CLI on the project homepage * fix(cli): preserve server log truncation and correct login hints * fix(cli): accept dashboard record request bodies * fix(cli): preserve stdin for local task execution * fix(cli): resolve task executables after changing directory * fix(cli): preserve shell function tasks and sanitize test failures * fix(cli): preserve shell hook state and resolve workdir after hooks * fix(cli): preserve cleanup across shared shell task timeouts * fix(cli): isolate shell control descriptors and reap timed-out descendants
39 lines
1.9 KiB
JavaScript
39 lines
1.9 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { sourceEnvironment } = require('../../dist/internal/runtime/context');
|
|
const { runProcess } = require('../../dist/internal/runtime/process');
|
|
|
|
test('environment transport preserves multiline values, empty values and exported functions', async () => {
|
|
const value = '中文\nsecond=line\r\n"quoted"\\literal';
|
|
const env = await sourceEnvironment({ PATH: process.env.PATH, VALUE: value }, [], [], {
|
|
command: 'export EMPTY=""; exported_fn() { printf "%s" "$VALUE"; }; export -f exported_fn; set -o pipefail; shopt -s nullglob; printf "user output"',
|
|
output: () => {},
|
|
});
|
|
assert.equal(env.VALUE, value);
|
|
assert.equal(env.EMPTY, '');
|
|
assert.ok(env.QL_CLI_SHELLOPTS.split(':').includes('pipefail'));
|
|
assert.ok(!env.QL_CLI_SHELLOPTS.split(':').includes('allexport'));
|
|
assert.ok(env.QL_CLI_BASHOPTS.split(':').includes('nullglob'));
|
|
assert.ok(!Object.keys(env).some(key => key.startsWith('__ql_')));
|
|
const child = await runProcess('bash', ['--noprofile', '--norc', '-c', 'exported_fn'], { env, capture: true });
|
|
assert.equal(child.code, 0);
|
|
assert.equal(child.stdout, value);
|
|
});
|
|
|
|
test('environment transport does not execute a Node runtime from user configuration', async () => {
|
|
const env = await sourceEnvironment({ PATH: process.env.PATH }, [], [], {
|
|
command: 'export NODE_OPTIONS="--this-option-does-not-exist"; export PATH="/nonexistent"',
|
|
});
|
|
assert.equal(env.NODE_OPTIONS, '--this-option-does-not-exist');
|
|
assert.equal(env.PATH, '/nonexistent');
|
|
});
|
|
|
|
for (const redirect of ['exec 3>/dev/null 9>/dev/null', 'exec 3>&-']) {
|
|
test(`environment transport survives user descriptors: ${redirect}`, async () => {
|
|
const env = await sourceEnvironment({ PATH: process.env.PATH }, [], [], {
|
|
command: `${redirect}; export FIXTURE_VALUE=present`,
|
|
});
|
|
assert.equal(env.FIXTURE_VALUE, 'present');
|
|
});
|
|
}
|