v.vcache: extract v.vcache to a separate module, to test it and reuse it

pull/6688/head
Delyan Angelov 2020-10-26 18:28:35 +02:00
parent 0c192cfd64
commit cf21c63183
4 changed files with 102 additions and 4 deletions

View File

@ -4,6 +4,7 @@
module pref
import os
import v.vcache
pub const (
default_module_path = mpath()
@ -73,7 +74,8 @@ pub fn (mut p Preferences) fill_with_defaults() {
}
// Prepare the cache manager. All options that can affect the generated cached .c files
// should go into res.cache_manager.vopts, which is used as a salt for the cache hash.
p.cache_manager = new_cache_manager([
p.cache_manager = vcache.new_cache_manager([
@VHASH, // ensure that different v versions use separate build artefacts
'$p.backend | $p.os | $p.ccompiler',
p.cflags.trim_space(),
p.third_party_option.trim_space(),

View File

@ -5,6 +5,7 @@ module pref
import os.cmdline
import os
import v.vcache
pub enum BuildMode {
// `v program.v'
@ -130,7 +131,7 @@ pub mut:
is_apk bool // build as Android .apk format
cleanup_files []string // list of temporary *.tmp.c and *.tmp.c.rsp files. Cleaned up on successfull builds.
build_options []string // list of options, that should be passed down to `build-module`, if needed for -usecache
cache_manager CacheManager
cache_manager vcache.CacheManager
}
pub fn parse_args(args []string) (&Preferences, string) {

View File

@ -1,4 +1,4 @@
module pref
module vcache
import os
import hash
@ -13,6 +13,7 @@ import hash
// Cleanup of the cache is simple: just delete the $VCACHE folder.
// The cache tree will look like this:
// │ $VCACHE
// │ ├── README.md <-- a short description of the folder's purpose.
// │ ├── 0f
// │ │ ├── 0f004f983ab9c487b0d7c1a0a73840a5.txt
// │ │ ├── 0f599edf5e16c2756fbcdd4c865087ac.description.txt <-- build details
@ -32,11 +33,20 @@ pub mut:
k2cpath map[string]string // key -> filesystem cache path for the object
}
fn new_cache_manager(opts []string) CacheManager {
pub fn new_cache_manager(opts []string) CacheManager {
mut vcache_basepath := os.getenv('VCACHE')
if vcache_basepath == '' {
vcache_basepath = os.join_path(os.home_dir(), '.vmodules', 'cache')
}
if !os.is_dir(vcache_basepath) {
os.mkdir_all(vcache_basepath)
readme_content := 'This folder contains cached build artifacts from the V build system.
|You can safely delete it, if it is getting too large.
|It will be recreated the next time you compile something with V.
|You can change its location with the VCACHE environment variable.
'.strip_margin()
os.write_file(os.join_path(vcache_basepath, 'README.md'), readme_content)
}
return CacheManager{
basepath: vcache_basepath
vopts: opts.join('|')

View File

@ -0,0 +1,85 @@
import os
import v.vcache
const (
vcache_folder = os.join_path(os.temp_dir(), 'vcache_folder')
)
fn check_cache_entry_fpath_invariants(x string, extension string) {
a := x.replace(vcache_folder + os.path_separator, '').split(os.path_separator)
assert a.len > 0
assert a[0].len == 2
assert a[1].len > 32
assert os.file_ext(a[1]) == extension
assert a[1][0..2] == a[0]
}
fn testsuite_begin() ? {
os.setenv('VCACHE', vcache_folder, true)
// eprintln('testsuite_begin, vcache_folder = $vcache_folder')
os.rmdir_all(vcache_folder)
vcache.new_cache_manager([])
assert os.is_dir(vcache_folder)
}
fn test_save_and_load() ? {
mut cm := vcache.new_cache_manager([])
x := cm.save('.txt', 'first/cache/entry', 'hello') ?
check_cache_entry_fpath_invariants(x, '.txt')
}
fn test_different_options_should_produce_different_cache_entries_for_same_key_and_content() ? {
mut cm1 := vcache.new_cache_manager([])
mut cm2 := vcache.new_cache_manager(['-cc tcc'])
mut cm3 := vcache.new_cache_manager(['-cc gcc'])
x := cm1.save('.txt', 'first/cache/entry', 'hello') ?
y := cm2.save('.txt', 'first/cache/entry', 'hello') ?
z := cm3.save('.txt', 'first/cache/entry', 'hello') ?
check_cache_entry_fpath_invariants(x, '.txt')
check_cache_entry_fpath_invariants(y, '.txt')
check_cache_entry_fpath_invariants(z, '.txt')
}
fn test_exists() ? {
mut cm := vcache.new_cache_manager([])
cm.exists('.o', 'abc') or {
assert true
}
//
x := cm.save('.x', 'abc', '') ?
cm.exists('.o', 'abc') or {
assert true
}
//
y := cm.save('.o', 'zbc', '') ?
cm.exists('.o', 'abc') or {
assert true
}
//
z := cm.save('.o', 'abc', '') ?
cm.exists('.o', 'abc') or {
assert false
}
//
assert os.is_file(x)
assert os.is_file(y)
assert os.is_file(z)
assert x != y
assert x != z
assert y != z
}
fn test_readme_exists_and_is_readable() ? {
vcache.new_cache_manager([])
freadme := os.join_path(vcache_folder, 'README.md')
assert os.is_file(freadme)
x := os.read_file(freadme) ?
assert x.len > 0
assert x.starts_with('This folder contains cached build artifacts')
}
fn testsuite_end() {
os.chdir(os.wd_at_startup)
os.rmdir_all(vcache_folder)
assert !os.is_dir(vcache_folder)
}