From 17266ecb0786616e841cf25434d0bdfcaad91199 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 18 Jan 2021 09:33:33 +0200 Subject: [PATCH] tools: support cmd/tools/.disable_autorecompilation in `v up` and `v self` too --- cmd/tools/vself.v | 2 ++ cmd/tools/vup.v | 5 ++++- vlib/v/util/recompilation/recompilation.v | 26 +++++++++++++++++++++++ vlib/v/util/util.v | 20 ++++++++++++++--- 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 vlib/v/util/recompilation/recompilation.v diff --git a/cmd/tools/vself.v b/cmd/tools/vself.v index 696ec356b0..6f7552e750 100644 --- a/cmd/tools/vself.v +++ b/cmd/tools/vself.v @@ -3,10 +3,12 @@ module main import os import os.cmdline import v.pref +import v.util.recompilation fn main() { vexe := pref.vexe_path() vroot := os.dir(vexe) + recompilation.must_be_enabled(vroot, 'Please install V from source, to use `v self` .') os.chdir(vroot) os.setenv('VCOLORS', 'always', true) self_idx := os.args.index('self') diff --git a/cmd/tools/vup.v b/cmd/tools/vup.v index d1b51f7b9a..63354b3bcd 100644 --- a/cmd/tools/vup.v +++ b/cmd/tools/vup.v @@ -3,6 +3,7 @@ module main import os import v.pref import v.util +import v.util.recompilation struct App { is_verbose bool @@ -12,15 +13,17 @@ struct App { fn new_app() App { vexe := os.real_path(pref.vexe_path()) + vroot := os.dir(vexe) return App{ is_verbose: '-v' in os.args vexe: vexe - vroot: os.dir(vexe) + vroot: vroot } } fn main() { app := new_app() + recompilation.must_be_enabled(app.vroot, 'Please install V from source, to use `v up` .') os.chdir(app.vroot) println('Updating V...') app.update_from_master() diff --git a/vlib/v/util/recompilation/recompilation.v b/vlib/v/util/recompilation/recompilation.v new file mode 100644 index 0000000000..10892cae5d --- /dev/null +++ b/vlib/v/util/recompilation/recompilation.v @@ -0,0 +1,26 @@ +module recompilation + +import os + +// disabling_file returns the path to a file, which if present, will disable the automatic recompilation +// that V attempts, when it detects that itself is newer than a tool .v source file. +// That file is intended to be made by `touch cmd/tools/.disable_autorecompilation` by package managers, +// so that tools like `v up` and `v self` will not work anymore, instead they will direct users to install +// V from source. +pub fn disabling_file(vroot string) string { + tools_folder := os.join_path(vroot, 'cmd', 'tools') + res := os.join_path(tools_folder, '.disable_autorecompilation') + return res +} + +// must_be_enabled is intended to be used by tools like `v self` and `v up`, to abort them +// early, when they detect that the V installation is part of a distro package, that has disabled autorecompilation. +pub fn must_be_enabled(vroot string, error_message string) { + file := disabling_file(vroot) + is_recompilation_disabled := os.exists(file) + if is_recompilation_disabled { + eprintln('Recompilation is disabled, since there is a "$file" file present.') + eprintln(error_message) + exit(1) + } +} diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index a48554d466..ba9933c586 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -7,6 +7,7 @@ import os import time import v.pref import v.vmod +import v.util.recompilation pub const ( v_version = '0.2.1' @@ -119,13 +120,23 @@ pub fn resolve_vroot(str string, dir string) ?string { return str.replace('@VROOT', os.real_path(vmod_path)) } +// launch_tool - starts a V tool in a separate process, passing it the `args`. +// All V tools are located in the cmd/tools folder, in files or folders prefixed by +// the letter `v`, followed by the tool name, i.e. `cmd/tools/vdoc/` or `cmd/tools/vpm.v`. +// The folder variant is suitable for larger and more complex tools, like `v doc`, because +// it provides you the ability to split their source in separate .v files, organized by topic, +// as well as have resources like static css/text/js files, that the tools can use. +// launch_tool uses a timestamp based detection mechanism, so that after `v self`, each tool +// will be recompiled too, before it is used, which guarantees that it would be up to date with +// V itself. That mechanism can be disabled by package managers by creating/touching a small +// `cmd/tools/.disable_autorecompilation` file, OR by changing the timestamps of all executables +// in cmd/tools to be < 1024 seconds (in unix time). pub fn launch_tool(is_verbose bool, tool_name string, args []string) { vexe := pref.vexe_path() vroot := os.dir(vexe) set_vroot_folder(vroot) tool_args := args_quote_paths(args) tools_folder := os.join_path(vroot, 'cmd', 'tools') - is_recompilation_disabled := os.exists(os.join_path(tools_folder, '.disable_autorecompilation')) tool_basename := os.real_path(os.join_path(tools_folder, tool_name)) mut tool_exe := '' mut tool_source := '' @@ -144,11 +155,14 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) { println('launch_tool tool_source : $tool_source') println('launch_tool tool_command: $tool_command') } - should_compile := should_recompile_tool(vexe, tool_source, tool_name, tool_exe) + disabling_file := recompilation.disabling_file(vroot) + is_recompilation_disabled := os.exists(disabling_file) + should_compile := !is_recompilation_disabled && + should_recompile_tool(vexe, tool_source, tool_name, tool_exe) if is_verbose { println('launch_tool should_compile: $should_compile') } - if should_compile && !is_recompilation_disabled { + if should_compile { emodules := external_module_dependencies_for_tool[tool_name] for emodule in emodules { check_module_is_installed(emodule, is_verbose) or { panic(err) }