1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: add -raw-vsh-tmp-prefix tmp flag, to allow for executing scripts without .vsh extension (#15829)

This commit is contained in:
Annie 2022-09-20 14:52:18 +02:00 committed by GitHub
parent 453cc41c32
commit 8f7958273b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 35 deletions

View File

@ -263,6 +263,22 @@ fn get_all_commands() []Command {
rmfile: 'v.c' rmfile: 'v.c'
} }
} }
$if !windows {
res << Command{
line: '$vexe -raw-vsh-tmp-prefix tmp vlib/v/tests/script_with_no_extension'
okmsg: 'V can crun a script, that lacks a .vsh extension'
runcmd: .execute
expect: 'Test\n'
rmfile: 'vlib/v/tests/tmp.script_with_no_extension'
}
res << Command{
line: '$vexe -raw-vsh-tmp-prefix tmp run vlib/v/tests/script_with_no_extension'
okmsg: 'V can run a script, that lacks a .vsh extension'
runcmd: .execute
expect: 'Test\n'
}
}
return res return res
} }

View File

@ -127,6 +127,7 @@ To do so, run the command `v up`.
* [Hot code reloading](#hot-code-reloading) * [Hot code reloading](#hot-code-reloading)
* [Cross compilation](#cross-compilation) * [Cross compilation](#cross-compilation)
* [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v) * [Cross-platform shell scripts in V](#cross-platform-shell-scripts-in-v)
* [Vsh scripts with no extension](#vsh-scripts-with-no-extension)
* [Attributes](#attributes) * [Attributes](#attributes)
* [Goto](#goto) * [Goto](#goto)
* [Appendices](#appendices) * [Appendices](#appendices)
@ -5949,6 +5950,18 @@ Or just run it more like a traditional Bash script:
On Unix-like platforms, the file can be run directly after making it executable using `chmod +x`: On Unix-like platforms, the file can be run directly after making it executable using `chmod +x`:
`./deploy.vsh` `./deploy.vsh`
## Vsh scripts with no extension
Whilst V does normally not allow vsh scripts without the designated file extension, there is a way
to circumvent this rule and have a file with a fully custom name and shebang. Whilst this feature
exists it is only recommended for specific usecases like scripts that will be put in the path and
should **not** be used for things like build or deploy scripts. To access this feature start the
file with `#!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp` where `tmp` is the prefix for
the built executable. This will run in crun mode so it will only rebuild if changes to the script
were made and keep the binary as `tmp.<scriptfilename>`. **Caution**: if this filename already
exists the file will be overriden. If you want to rebuild each time and not keep this binary instead
use `#!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp run`.
## Attributes ## Attributes
V has several attributes that modify the behavior of functions and structs. V has several attributes that modify the behavior of functions and structs.

View File

@ -309,7 +309,7 @@ pub fn (v &Builder) get_user_files() []string {
is_real_file := does_exist && !os.is_dir(dir) is_real_file := does_exist && !os.is_dir(dir)
resolved_link := if is_real_file && os.is_link(dir) { os.real_path(dir) } else { dir } resolved_link := if is_real_file && os.is_link(dir) { os.real_path(dir) } else { dir }
if is_real_file && (dir.ends_with('.v') || resolved_link.ends_with('.vsh') if is_real_file && (dir.ends_with('.v') || resolved_link.ends_with('.vsh')
|| dir.ends_with('.vv')) { || v.pref.raw_vsh_tmp_prefix != '' || dir.ends_with('.vv')) {
single_v_file := if resolved_link.ends_with('.vsh') { resolved_link } else { dir } single_v_file := if resolved_link.ends_with('.vsh') { resolved_link } else { dir }
// Just compile one file and get parent dir // Just compile one file and get parent dir
user_files << single_v_file user_files << single_v_file

View File

@ -50,7 +50,11 @@ pub fn (mut p Preferences) fill_with_defaults() {
base = filename base = filename
} }
target_dir := if os.is_dir(rpath) { rpath } else { os.dir(rpath) } target_dir := if os.is_dir(rpath) { rpath } else { os.dir(rpath) }
p.out_name = os.join_path(target_dir, base) if p.raw_vsh_tmp_prefix != '' {
p.out_name = os.join_path(target_dir, p.raw_vsh_tmp_prefix + '.' + base)
} else {
p.out_name = os.join_path(target_dir, base)
}
// Do *NOT* be tempted to generate binaries in the current work folder, // Do *NOT* be tempted to generate binaries in the current work folder,
// when -o is not given by default, like Go, Clang, GCC etc do. // when -o is not given by default, like Go, Clang, GCC etc do.
// //
@ -119,7 +123,7 @@ pub fn (mut p Preferences) fill_with_defaults() {
p.ccompiler_type = cc_from_string(p.ccompiler) p.ccompiler_type = cc_from_string(p.ccompiler)
p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('_test.vv') p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('_test.vv')
|| p.path.all_before_last('.v').all_before_last('.').ends_with('_test') || p.path.all_before_last('.v').all_before_last('.').ends_with('_test')
p.is_vsh = p.path.ends_with('.vsh') p.is_vsh = p.path.ends_with('.vsh') || p.raw_vsh_tmp_prefix != ''
p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv') p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv')
if p.third_party_option == '' { if p.third_party_option == '' {
p.third_party_option = p.cflags p.third_party_option = p.cflags

View File

@ -102,37 +102,38 @@ pub mut:
// verbosity VerboseLevel // verbosity VerboseLevel
is_verbose bool is_verbose bool
// nofmt bool // disable vfmt // nofmt bool // disable vfmt
is_glibc bool // if GLIBC will be linked is_glibc bool // if GLIBC will be linked
is_musl bool // if MUSL will be linked is_musl bool // if MUSL will be linked
is_test bool // `v test string_test.v` is_test bool // `v test string_test.v`
is_script bool // single file mode (`v program.v`), main function can be skipped is_script bool // single file mode (`v program.v`), main function can be skipped
is_vsh bool // v script (`file.vsh`) file, the `os` module should be made global is_vsh bool // v script (`file.vsh`) file, the `os` module should be made global
is_livemain bool // main program that contains live/hot code raw_vsh_tmp_prefix string // The prefix used for executables, when a script lacks the .vsh extension
is_liveshared bool // a shared library, that will be used in a -live main program is_livemain bool // main program that contains live/hot code
is_shared bool // an ordinary shared library, -shared, no matter if it is live or not is_liveshared bool // a shared library, that will be used in a -live main program
is_o bool // building an .o file is_shared bool // an ordinary shared library, -shared, no matter if it is live or not
is_prof bool // benchmark every function is_o bool // building an .o file
is_prod bool // use "-O2" is_prof bool // benchmark every function
is_repl bool is_prod bool // use "-O2"
is_run bool // compile and run a v program, passing arguments to it, and deleting the executable afterwards is_repl bool
is_crun bool // similar to run, but does not recompile the executable, if there were no changes to the sources is_run bool // compile and run a v program, passing arguments to it, and deleting the executable afterwards
is_debug bool // turned on by -g or -cg, it tells v to pass -g to the C backend compiler. is_crun bool // similar to run, but does not recompile the executable, if there were no changes to the sources
is_vlines bool // turned on by -g (it slows down .tmp.c generation slightly). is_debug bool // turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run is_vlines bool // turned on by -g (it slows down .tmp.c generation slightly).
show_timings bool // show how much time each compiler stage took is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
is_fmt bool show_timings bool // show how much time each compiler stage took
is_vet bool is_fmt bool
is_vweb bool // skip _ var warning in templates is_vet bool
is_ios_simulator bool is_vweb bool // skip _ var warning in templates
is_apk bool // build as Android .apk format is_ios_simulator bool
is_help bool // -h, -help or --help was passed is_apk bool // build as Android .apk format
is_cstrict bool // turn on more C warnings; slightly slower is_help bool // -h, -help or --help was passed
test_runner string // can be 'simple' (fastest, but much less detailed), 'tap', 'normal' is_cstrict bool // turn on more C warnings; slightly slower
profile_file string // the profile results will be stored inside profile_file test_runner string // can be 'simple' (fastest, but much less detailed), 'tap', 'normal'
profile_no_inline bool // when true, [inline] functions would not be profiled profile_file string // the profile results will be stored inside profile_file
profile_fns []string // when set, profiling will be off by default, but inside these functions (and what they call) it will be on. profile_no_inline bool // when true, [inline] functions would not be profiled
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc profile_fns []string // when set, profiling will be off by default, but inside these functions (and what they call) it will be on.
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX" translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
// Note: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files, // Note: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files,
// which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks). // which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
sanitize bool // use Clang's new "-fsanitize" option sanitize bool // use Clang's new "-fsanitize" option
@ -705,6 +706,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
res.custom_prelude = prelude res.custom_prelude = prelude
i++ i++
} }
'-raw-vsh-tmp-prefix' {
res.raw_vsh_tmp_prefix = cmdline.option(current_args, arg, '')
i++
}
'-cmain' { '-cmain' {
res.cmain = cmdline.option(current_args, '-cmain', '') res.cmain = cmdline.option(current_args, '-cmain', '')
i++ i++
@ -814,7 +819,7 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
if !res.is_bare && res.bare_builtin_dir != '' { if !res.is_bare && res.bare_builtin_dir != '' {
eprintln_cond(show_output, '`-bare-builtin-dir` must be used with `-freestanding`') eprintln_cond(show_output, '`-bare-builtin-dir` must be used with `-freestanding`')
} }
if command.ends_with('.vsh') { if command.ends_with('.vsh') || (res.raw_vsh_tmp_prefix != '' && !res.is_run) {
// `v build.vsh gcc` is the same as `v run build.vsh gcc`, // `v build.vsh gcc` is the same as `v run build.vsh gcc`,
// i.e. compiling, then running the script, passing the args // i.e. compiling, then running the script, passing the args
// after it to the script: // after it to the script: