From 9123c2bcb84a777384af659b71af33696e5195f4 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Sun, 7 Sep 2025 14:52:17 +0300 Subject: [PATCH] refactor: simplify console management and apply fixes - Replace ConsoleFactory with global state and functions - Fix container state check to use `result.output` - Reformat `osal.exec` calls and map literals - Streamline environment variable parsing - Remove redundant blank lines and trailing characters --- lib/builder/executor_crun.v | 60 ++++++++++++++++++++----------------- lib/ui/console/factory.v | 47 +++++++++++++---------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/lib/builder/executor_crun.v b/lib/builder/executor_crun.v index 7e3c1c68..91e7ad7b 100644 --- a/lib/builder/executor_crun.v +++ b/lib/builder/executor_crun.v @@ -22,9 +22,9 @@ fn (mut executor ExecutorCrun) init() ! { result := osal.exec(cmd: 'crun state ${executor.container_id}', stdout: false) or { return error('Container ${executor.container_id} not found or not accessible') } - + // Parse state to ensure container is running - if !result.contains('"status":"running"') { + if !result.output.contains('"status":"running"') { return error('Container ${executor.container_id} is not running') } } @@ -42,32 +42,32 @@ pub fn (mut executor ExecutorCrun) exec(args_ ExecArgs) !string { if executor.debug { console.print_debug('execute in container ${executor.container_id}: ${args.cmd}') } - + mut cmd := 'crun exec ${executor.container_id} ${args.cmd}' if args.cmd.contains('\n') { // For multiline commands, write to temp file first temp_script := '/tmp/crun_script_${rand.uuid_v4()}.sh' script_content := texttools.dedent(args.cmd) os.write_file(temp_script, script_content)! - + // Copy script into container and execute executor.file_write('/tmp/exec_script.sh', script_content)! cmd = 'crun exec ${executor.container_id} bash /tmp/exec_script.sh' } - + res := osal.exec(cmd: cmd, stdout: args.stdout, debug: executor.debug)! return res.output } pub fn (mut executor ExecutorCrun) exec_interactive(args_ ExecArgs) ! { mut args := args_ - + if args.cmd.contains('\n') { args.cmd = texttools.dedent(args.cmd) executor.file_write('/tmp/interactive_script.sh', args.cmd)! args.cmd = 'bash /tmp/interactive_script.sh' } - + cmd := 'crun exec -t ${executor.container_id} ${args.cmd}' console.print_debug(cmd) osal.execute_interactive(cmd)! @@ -77,12 +77,12 @@ pub fn (mut executor ExecutorCrun) file_write(path string, text string) ! { if executor.debug { console.print_debug('Container ${executor.container_id} file write: ${path}') } - + // Write to temp file first, then copy into container temp_file := '/tmp/crun_file_${rand.uuid_v4()}' os.write_file(temp_file, text)! defer { os.rm(temp_file) or {} } - + // Use crun exec to copy file content cmd := 'cat ${temp_file} | crun exec -i ${executor.container_id} tee ${path} > /dev/null' osal.exec(cmd: cmd, stdout: false)! @@ -92,7 +92,7 @@ pub fn (mut executor ExecutorCrun) file_read(path string) !string { if executor.debug { console.print_debug('Container ${executor.container_id} file read: ${path}') } - + return executor.exec(cmd: 'cat ${path}', stdout: false) } @@ -100,7 +100,7 @@ pub fn (mut executor ExecutorCrun) file_exists(path string) bool { if executor.debug { console.print_debug('Container ${executor.container_id} file exists: ${path}') } - + output := executor.exec(cmd: 'test -f ${path} && echo found || echo not found', stdout: false) or { return false } @@ -117,18 +117,21 @@ pub fn (mut executor ExecutorCrun) delete(path string) ! { pub fn (mut executor ExecutorCrun) upload(args SyncArgs) ! { // For container uploads, we need to copy files from host to container // Use crun exec with tar for efficient transfer - + mut src_path := pathlib.get(args.source) if !src_path.exists() { return error('Source path ${args.source} does not exist') } - + if src_path.is_dir() { // For directories, use tar to transfer temp_tar := '/tmp/crun_upload_${rand.uuid_v4()}.tar' - osal.exec(cmd: 'tar -cf ${temp_tar} -C ${src_path.path_dir()} ${src_path.name()}', stdout: false)! + osal.exec( + cmd: 'tar -cf ${temp_tar} -C ${src_path.path_dir()} ${src_path.name()}' + stdout: false + )! defer { os.rm(temp_tar) or {} } - + // Extract in container cmd := 'cat ${temp_tar} | crun exec -i ${executor.container_id} tar -xf - -C ${args.dest}' osal.exec(cmd: cmd, stdout: args.stdout)! @@ -146,9 +149,12 @@ pub fn (mut executor ExecutorCrun) download(args SyncArgs) ! { cmd := 'crun exec ${executor.container_id} tar -cf - -C ${args.source} . > ${temp_tar}' osal.exec(cmd: cmd, stdout: false)! defer { os.rm(temp_tar) or {} } - + // Extract on host - osal.exec(cmd: 'mkdir -p ${args.dest} && tar -xf ${temp_tar} -C ${args.dest}', stdout: args.stdout)! + osal.exec( + cmd: 'mkdir -p ${args.dest} && tar -xf ${temp_tar} -C ${args.dest}' + stdout: args.stdout + )! } else { // For single files content := executor.file_read(args.source)! @@ -157,16 +163,16 @@ pub fn (mut executor ExecutorCrun) download(args SyncArgs) ! { } pub fn (mut executor ExecutorCrun) environ_get() !map[string]string { - env := executor.exec(cmd: 'env', stdout: false) or { - return error('Cannot get environment from container ${executor.container_id}') + env := executor.exec(cmd: 'env', stdout: false) or { + return error('Cannot get environment from container ${executor.container_id}') } - + mut res := map[string]string{} for line in env.split('\n') { if line.contains('=') { - parts := line.split_once('=') or { continue } - key := parts[0].trim(' ') - val := parts[1].trim(' ') + mut key, mut val := line.split_once('=') or { continue } + key = key.trim(' ') + val = val.trim(' ') res[key] = val } } @@ -175,9 +181,9 @@ pub fn (mut executor ExecutorCrun) environ_get() !map[string]string { pub fn (mut executor ExecutorCrun) info() map[string]string { return { - 'category': 'crun' + 'category': 'crun' 'container_id': executor.container_id - 'runtime': 'crun' + 'runtime': 'crun' } } @@ -193,7 +199,7 @@ pub fn (mut executor ExecutorCrun) list(path string) ![]string { if !executor.dir_exists(path) { return error('Directory ${path} does not exist in container') } - + output := executor.exec(cmd: 'ls ${path}', stdout: false)! mut res := []string{} for line in output.split('\n') { @@ -210,4 +216,4 @@ pub fn (mut executor ExecutorCrun) dir_exists(path string) bool { return false } return output.trim_space() == 'found' -} \ No newline at end of file +} diff --git a/lib/ui/console/factory.v b/lib/ui/console/factory.v index 9b7f16e4..29d7e40c 100644 --- a/lib/ui/console/factory.v +++ b/lib/ui/console/factory.v @@ -2,29 +2,21 @@ module console import freeflowuniverse.herolib.core.texttools -pub struct ConsoleFactory { -pub mut: +__global ( consoles map[string]&UIConsole silent bool +) + +pub fn silent_set() { + silent = true } -pub fn new_console_factory() &ConsoleFactory { - return &ConsoleFactory{ - consoles: map[string]&UIConsole{} - silent: false - } +pub fn silent_unset() { + silent = false } -pub fn (mut cf ConsoleFactory) silent_set() { - cf.silent = true -} - -pub fn (mut cf ConsoleFactory) silent_unset() { - cf.silent = false -} - -pub fn (cf ConsoleFactory) silent_get() bool { - return cf.silent +pub fn silent_get() bool { + return silent } pub struct UIConsole { @@ -56,14 +48,17 @@ pub fn (mut c UIConsole) status() string { return out.trim_space() } -pub fn (mut cf ConsoleFactory) new_console() &UIConsole { - mut c := UIConsole{} - cf.consoles['main'] = &c - return &c +pub fn new() UIConsole { + return UIConsole{} } -pub fn (cf ConsoleFactory) get_console() &UIConsole { - return cf.consoles['main'] or { panic('bug') } +fn init() { + mut c := UIConsole{} + consoles['main'] = &c +} + +fn get() &UIConsole { + return consoles['main'] or { panic('bug') } } pub fn trim(c_ string) string { @@ -72,12 +67,12 @@ pub fn trim(c_ string) string { } // line feed -pub fn (mut cf ConsoleFactory) lf() { - mut c := cf.get_console() +pub fn lf() { + mut c := get() if c.prev_lf { return } - if !cf.silent_get() { + if !silent_get() { print('\n') } c.prev_lf = true