diff --git a/cmd/v/v.v b/cmd/v/v.v index 19605ac0b0..a522bc0c22 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -79,7 +79,7 @@ fn main() { util.launch_tool(false, 'vrepl', os.args[1..]) return } - args_and_flags := util.join_env_vflags_and_os_args()[1..] + mut args_and_flags := util.join_env_vflags_and_os_args()[1..] prefs, command := pref.parse_args(external_tools, args_and_flags) if prefs.use_cache && os.user_os() == 'windows' { eprintln('-usecache is currently disabled on windows') diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index af8b784290..ebd7f824ae 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -697,6 +697,14 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences if !res.is_bare && res.bare_builtin_dir != '' { eprintln('`-bare-builtin-dir` must be used with `-freestanding`') } + if command.ends_with('.vsh') { + // `v build.vsh gcc` is the same as `v run build.vsh gcc`, + // i.e. compiling, then running the script, passing the args + // after it to the script: + res.is_run = true + res.path = command + res.run_args = args[command_pos + 1..] + } if command == 'build-module' { res.build_mode = .build_module if command_pos + 1 >= args.len { diff --git a/vlib/v/tests/vsh_envbang_test.v b/vlib/v/tests/vsh_envbang_test.v new file mode 100644 index 0000000000..3c6b489e4f --- /dev/null +++ b/vlib/v/tests/vsh_envbang_test.v @@ -0,0 +1,36 @@ +import os +import rand + +fn test_envbang_script_runs() ? { + env_location := '/usr/bin/env' + $if windows { + skip_test('windows does not support envbang lines') + } + if !os.exists(env_location) { + skip_test('$env_location does not exist') + } + if !os.is_executable(env_location) { + skip_test('$env_location is not executable') + } + os.find_abs_path_of_executable('v') or { skip_test('v is not in PATH') } + rndname := rand.ulid() + rnd_vsh_script_path := os.real_path(os.join_path(os.cache_dir(), '${rndname}.vsh')) + os.write_file(rnd_vsh_script_path, "#!$env_location v +import os +println('hello') +println(os.args) +") ? + os.chmod(rnd_vsh_script_path, 0o700) ? + res := os.execute('"$rnd_vsh_script_path" abc 123 -option') + assert res.exit_code == 0 + lines := res.output.split_into_lines() + assert lines[0] == 'hello' + assert lines[1].ends_with(", 'abc', '123', '-option']") + os.rm(rnd_vsh_script_path) ? +} + +[noreturn] +fn skip_test(reason string) { + println('skipping test, because $reason .') + exit(0) +}