-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
217 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,7 @@ pub const vab_env_vars = [ | |
'AAPT2', | ||
'JAVA_HOME', | ||
'VEXE', | ||
'VAB_EXE', | ||
'VMODULES', | ||
] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import os | ||
import vab.vabxt | ||
import vab.vxt | ||
import vab.android.util | ||
|
||
const test_dir_base = os.join_path(os.vtmp_dir(), 'vab', 'tests', 'runtime') | ||
const apk_arch_dirs = ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64', 'armeabi'] | ||
|
||
fn setup_apk_build(id string) (string, string) { | ||
test_dir := os.join_path(test_dir_base, id) | ||
os.rm(test_dir) or {} | ||
os.mkdir_all(test_dir) or { panic('mkdir_all failed making "${test_dir}": ${err}') } | ||
|
||
// vab (per design) implicitly deploys to any devices sat via `--device-id`. | ||
// Make sure no deployment is done after build if CI/other sets `ANDROID_SERIAL` | ||
os.unsetenv('ANDROID_SERIAL') | ||
vab := vabxt.vabexe() | ||
assert vab != '', 'vab needs to be installed to run this test' | ||
return vab, test_dir | ||
} | ||
|
||
fn v_example(path string) string { | ||
v_root := vxt.home() | ||
examples_root := os.join_path(v_root, 'examples') | ||
example := os.join_path(examples_root, ...path.split('/')) | ||
assert os.is_file(example) || os.is_dir(example) == true, 'example not found. Ensure a full V source install (with examples) is present' | ||
return example | ||
} | ||
|
||
fn run(cmd string) { | ||
eprintln('running: ${cmd}') | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
dump(res.output) | ||
} | ||
assert res.exit_code == 0 | ||
} | ||
|
||
fn extract_and_check_apk(libname string, path string) { | ||
expected_lib_name := libname | ||
expected_apk := os.join_path(path, '${expected_lib_name}.apk') | ||
assert os.is_file(expected_apk) | ||
|
||
extract_dir := os.join_path(path, 'extracted') | ||
extracted_apk_path := os.join_path(extract_dir, expected_lib_name) | ||
util.unzip(expected_apk, extracted_apk_path) or { | ||
panic('unzip failed extracting "${expected_apk}": ${err}') | ||
} | ||
|
||
dump(os.ls(extracted_apk_path) or { panic('ls failed on "${extracted_apk_path}": ${err}') }) | ||
// test that expected libs are actually present in the apk | ||
for arch in apk_arch_dirs { | ||
lib_dir := os.join_path(extracted_apk_path, 'lib', arch) | ||
dump(os.ls(lib_dir) or { panic('ls failed on "${lib_dir}": ${err}') }) | ||
assert os.is_file(os.join_path(lib_dir, 'lib${expected_lib_name}.so')) | ||
} | ||
} | ||
|
||
fn test_build_apk_way_1() { | ||
vab, test_dir := setup_apk_build(@FN) | ||
|
||
vab_cmd := [vab, '-o', test_dir, v_example('gg/worker_thread.v')].join(' ') | ||
run(vab_cmd) | ||
|
||
extract_and_check_apk('v_test_app', test_dir) | ||
} | ||
|
||
fn test_build_apk_way_2() { | ||
vab, test_dir := setup_apk_build(@FN) | ||
|
||
vab_cmd := [vab, v_example('sokol/particles'), '-o', test_dir].join(' ') | ||
run(vab_cmd) | ||
|
||
extract_and_check_apk('v_test_app', test_dir) | ||
} | ||
|
||
fn test_build_apk_way_3() { | ||
vab, test_dir := setup_apk_build(@FN) | ||
|
||
vab_cmd := [vab, '-f "-d trace_moves_spool_to_sbin"', v_example('sokol/particles'), | ||
'-o', test_dir].join(' ') | ||
run(vab_cmd) | ||
|
||
extract_and_check_apk('v_test_app', test_dir) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright(C) 2019-2022 Lars Pontoppidan. All rights reserved. | ||
// Use of this source code is governed by an MIT license file distributed with this software package | ||
module vabxt | ||
|
||
import os | ||
import regex | ||
|
||
// vabexe returns the path to the `vab` executable if found | ||
// on the host platform, otherwise a blank `string`. | ||
pub fn vabexe() string { | ||
mut exe := os.getenv('VAB_EXE') | ||
$if !windows { | ||
if os.is_executable(exe) { | ||
return os.real_path(exe) | ||
} | ||
possible_symlink := os.find_abs_path_of_executable('vab') or { '' } | ||
if os.is_executable(possible_symlink) { | ||
return os.real_path(possible_symlink) | ||
} | ||
vmodules_path := vmodules() or { '' } | ||
if os.is_file(os.join_path(vmodules_path, 'vab', 'vab')) { | ||
return os.join_path(vmodules_path, 'vab', 'vab') | ||
} | ||
} $else { | ||
if os.exists(exe) { | ||
return exe | ||
} | ||
system_path := os.find_abs_path_of_executable('vab') or { '' } | ||
if os.exists(system_path) { | ||
exe = system_path | ||
} | ||
if !os.exists(exe) { | ||
res := os.execute('where.exe vab') | ||
if res.exit_code != 0 { | ||
exe = '' | ||
} else { | ||
return res.output.trim('\n\r') | ||
} | ||
} | ||
vmodules_path := vmodules() or { '' } | ||
if os.is_file(os.join_path(vmodules_path, 'vab', 'vab.exe')) { | ||
return os.join_path(vmodules_path, 'vab', 'vab.exe') | ||
} | ||
} | ||
|
||
return exe | ||
} | ||
|
||
// vmodules returns the path to the `.vmodules` folder if found | ||
pub fn vmodules() !string { | ||
mut vmodules_path := os.getenv('VMODULES') | ||
if !os.is_dir(vmodules_path) { | ||
vmodules_path = os.join_path(os.home_dir(), '.vmodules') | ||
} | ||
if !os.is_dir(vmodules_path) { | ||
return error(@MOD + '.' + @FN + ': no valid v modules path found at "${vmodules_path}"') | ||
} | ||
return vmodules_path | ||
} | ||
|
||
pub fn found() bool { | ||
return home() != '' | ||
} | ||
|
||
pub fn home() string { | ||
// credits to @spytheman: | ||
// https://discord.com/channels/592103645835821068/592294828432424960/746040606358503484 | ||
mut exe := vabexe() | ||
$if !windows { | ||
if os.is_executable(exe) { | ||
return os.dir(exe) | ||
} | ||
} $else { | ||
if os.exists(exe) { | ||
exe = exe.replace('/', os.path_separator) | ||
// Skip the `.bin\` dir | ||
if os.dir(exe).ends_with('.bin') { | ||
exe = os.dir(exe) | ||
} | ||
return os.dir(exe) | ||
} | ||
} | ||
return '' | ||
} | ||
|
||
pub fn version() string { | ||
mut version := '' | ||
vab := vabexe() | ||
if vab != '' { | ||
vab_version := os.execute(vab + ' --version') | ||
if vab_version.exit_code != 0 { | ||
return version | ||
} | ||
output := vab_version.output | ||
mut re := regex.regex_opt(r'.*(\d+\.?\d*\.?\d*)') or { panic(err) } | ||
start, _ := re.match_string(output) | ||
if start >= 0 && re.groups.len > 0 { | ||
version = output[re.groups[0]..re.groups[1]] | ||
} | ||
return version | ||
} | ||
return '0.0.0' | ||
} | ||
|
||
pub fn version_commit_hash() string { | ||
mut hash := '' | ||
vab := vabexe() | ||
if vab != '' { | ||
vab_version := os.execute(vab + ' --version') | ||
if vab_version.exit_code != 0 { | ||
return '' | ||
} | ||
output := vab_version.output | ||
mut re := regex.regex_opt(r'.*\d+\.?\d*\.?\d* ([a-fA-F0-9]{7,})') or { panic(err) } | ||
start, _ := re.match_string(output) | ||
if start >= 0 && re.groups.len > 0 { | ||
hash = output[re.groups[0]..re.groups[1]] | ||
} | ||
return hash | ||
} | ||
return 'deadbeef' | ||
} |