v: run code from stdin `echo println(2+2) | v run -`, with no repl limits (#6884)
parent
55a7c907ad
commit
159932d59b
|
@ -1,8 +1,11 @@
|
||||||
Usage: v [build flags] run <file.v|directory> [arguments...]
|
Usage: v [build flags] run <file.v|directory|-> [arguments...]
|
||||||
|
|
||||||
This command is equivalent to running `v build` and running the compiled executable.
|
This command is equivalent to running `v build` and running the compiled executable.
|
||||||
The executable is passed the arguments as provided in [arguments...].
|
The executable is passed the arguments as provided in [arguments...].
|
||||||
|
|
||||||
|
If the target is '-', it means that the V source code to build comes from stdin.
|
||||||
|
If the '-o' option is not specified, and the target is '-', a temporary base name for the executable will be used.
|
||||||
|
|
||||||
The exit status of run will be:
|
The exit status of run will be:
|
||||||
* `1` if the compilation failed.
|
* `1` if the compilation failed.
|
||||||
* The exit code of the compiled executable otherwise.
|
* The exit code of the compiled executable otherwise.
|
||||||
|
|
|
@ -6,6 +6,7 @@ module pref
|
||||||
import os.cmdline
|
import os.cmdline
|
||||||
import os
|
import os
|
||||||
import v.vcache
|
import v.vcache
|
||||||
|
import rand
|
||||||
|
|
||||||
pub enum BuildMode {
|
pub enum BuildMode {
|
||||||
// `v program.v'
|
// `v program.v'
|
||||||
|
@ -408,6 +409,44 @@ pub fn parse_args(args []string) (&Preferences, string) {
|
||||||
}
|
}
|
||||||
res.path = args[command_pos + 1]
|
res.path = args[command_pos + 1]
|
||||||
res.run_args = args[command_pos + 2..]
|
res.run_args = args[command_pos + 2..]
|
||||||
|
if res.path == '-' {
|
||||||
|
tmp_file_path := rand.ulid()
|
||||||
|
mut tmp_exe_file_path := res.out_name
|
||||||
|
mut output_option := ''
|
||||||
|
if tmp_exe_file_path == '' {
|
||||||
|
tmp_exe_file_path = '${tmp_file_path}.exe'
|
||||||
|
output_option = '-o "$tmp_exe_file_path"'
|
||||||
|
}
|
||||||
|
tmp_v_file_path := '${tmp_file_path}.v'
|
||||||
|
mut lines := []string{}
|
||||||
|
for {
|
||||||
|
iline := os.get_raw_line()
|
||||||
|
if iline.len == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
lines << iline
|
||||||
|
}
|
||||||
|
contents := lines.join('')
|
||||||
|
os.write_file(tmp_v_file_path, contents) or {
|
||||||
|
panic('Failed to create temporary file $tmp_v_file_path')
|
||||||
|
}
|
||||||
|
run_options := cmdline.options_before(args, ['run']).join(' ')
|
||||||
|
command_options := cmdline.options_after(args, ['run'])[1..].join(' ')
|
||||||
|
vexe := vexe_path()
|
||||||
|
tmp_cmd := '"$vexe" $output_option $run_options run "$tmp_v_file_path" $command_options'
|
||||||
|
//
|
||||||
|
res.vrun_elog('tmp_cmd: $tmp_cmd')
|
||||||
|
tmp_result := os.system(tmp_cmd)
|
||||||
|
res.vrun_elog('exit code: $tmp_result')
|
||||||
|
//
|
||||||
|
if output_option.len != 0 {
|
||||||
|
res.vrun_elog('remove tmp exe file: $tmp_exe_file_path')
|
||||||
|
os.rm(tmp_exe_file_path)
|
||||||
|
}
|
||||||
|
res.vrun_elog('remove tmp v file: $tmp_v_file_path')
|
||||||
|
os.rm(tmp_v_file_path)
|
||||||
|
exit(tmp_result)
|
||||||
|
}
|
||||||
must_exist(res.path)
|
must_exist(res.path)
|
||||||
if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path) &&
|
if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path) &&
|
||||||
os.is_file(res.path + '.v') {
|
os.is_file(res.path + '.v') {
|
||||||
|
@ -430,6 +469,12 @@ pub fn parse_args(args []string) (&Preferences, string) {
|
||||||
return res, command
|
return res, command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (pref &Preferences) vrun_elog(s string) {
|
||||||
|
if pref.is_verbose {
|
||||||
|
eprintln('> v run -, $s')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn must_exist(path string) {
|
fn must_exist(path string) {
|
||||||
if !os.exists(path) {
|
if !os.exists(path) {
|
||||||
eprintln('v expects that `$path` exists, but it does not')
|
eprintln('v expects that `$path` exists, but it does not')
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
const (
|
||||||
|
vexe = os.getenv('VEXE')
|
||||||
|
)
|
||||||
|
|
||||||
|
fn test_vexe_is_set() {
|
||||||
|
assert vexe != ''
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_pipe_to_v_run() ? {
|
||||||
|
cat_cmd := if os.user_os() == 'windows' { 'type' } else { 'cat' }
|
||||||
|
tmp_v_file := os.join_path(os.temp_dir(), 'generated_piped_program.v')
|
||||||
|
os.write_file(tmp_v_file, 'println(1 + 3)\nprintln("hello")\n') ?
|
||||||
|
assert os.is_file(tmp_v_file)
|
||||||
|
cmd := '"$cat_cmd" "$tmp_v_file" | "$vexe" run -'
|
||||||
|
res := os.exec(cmd) ?
|
||||||
|
// eprintln('>> cmd: $cmd | res: $res')
|
||||||
|
assert res.exit_code == 0
|
||||||
|
assert res.output.trim_space().split('\n') == ['4', 'hello']
|
||||||
|
os.rm(tmp_v_file)
|
||||||
|
assert !os.exists(tmp_v_file)
|
||||||
|
}
|
Loading…
Reference in New Issue