mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
tools: let v gret
make an easily visible diff.png image after regressions, and upload it too, to make CI failures easier to diagnose
This commit is contained in:
parent
fcaf529228
commit
b27b6b2047
13
.github/workflows/gg_regressions_ci.yml
vendored
13
.github/workflows/gg_regressions_ci.yml
vendored
@ -21,10 +21,13 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build local v
|
||||
run: make -j4
|
||||
run: make
|
||||
|
||||
- uses: openrndr/setup-opengl@v1.1
|
||||
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
# imagemagick : convert, mogrify
|
||||
# xvfb : xvfb (installed by openrndr/setup-opengl@v1.1)
|
||||
# openimageio-tools : idiff
|
||||
# libxcursor-dev libxi-dev : V gfx deps
|
||||
@ -33,14 +36,9 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install imagemagick openimageio-tools mesa-common-dev libxcursor-dev libxi-dev freeglut3-dev
|
||||
wget https://raw.githubusercontent.com/tremby/imgur.sh/c98345d/imgur.sh
|
||||
git clone https://github.com/Larpon/gg-regression-images gg-regression-images
|
||||
chmod +x ./imgur.sh
|
||||
|
||||
- uses: openrndr/setup-opengl@v1.1
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: Larpon/gg-regression-images
|
||||
path: gg-regression-images
|
||||
|
||||
- name: Sample and compare
|
||||
id: compare
|
||||
continue-on-error: true
|
||||
@ -52,4 +50,5 @@ jobs:
|
||||
if: steps.compare.outcome != 'success'
|
||||
run: |
|
||||
./imgur.sh /tmp/fail.png
|
||||
./imgur.sh /tmp/diff.png
|
||||
exit 1
|
||||
|
@ -37,7 +37,7 @@ import flag
|
||||
import toml
|
||||
|
||||
const (
|
||||
tool_name = os.file_name(os.executable())
|
||||
tool_name = 'vgret'
|
||||
tool_version = '0.0.1'
|
||||
tool_description = '\n Dump and/or compare rendered frames of `gg` based apps
|
||||
|
||||
@ -57,7 +57,7 @@ Examples:
|
||||
const (
|
||||
supported_hosts = ['linux']
|
||||
// External tool executables
|
||||
v_exe = vexe()
|
||||
v_exe = os.getenv('VEXE')
|
||||
idiff_exe = os.find_abs_path_of_executable('idiff') or { '' }
|
||||
)
|
||||
|
||||
@ -105,11 +105,27 @@ mut:
|
||||
config Config
|
||||
}
|
||||
|
||||
fn (opt Options) verbose_execute(cmd string) os.Result {
|
||||
opt.verbose_eprintln('Running `$cmd`')
|
||||
return os.execute(cmd)
|
||||
}
|
||||
|
||||
fn (opt Options) verbose_eprintln(msg string) {
|
||||
if opt.verbose {
|
||||
eprintln(msg)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if os.args.len == 1 {
|
||||
println('Usage: $tool_name PATH \n$tool_description\n$tool_name -h for more help...')
|
||||
if runtime_os !in supported_hosts {
|
||||
eprintln('$tool_name is currently only supported on $supported_hosts hosts')
|
||||
exit(1)
|
||||
}
|
||||
if os.args.len == 1 {
|
||||
eprintln('Usage: $tool_name PATH \n$tool_description\n$tool_name -h for more help...')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
mut fp := flag.new_flag_parser(os.args[1..])
|
||||
fp.application(tool_name)
|
||||
fp.version(tool_version)
|
||||
@ -131,17 +147,17 @@ fn main() {
|
||||
}
|
||||
|
||||
toml_conf := fp.string('toml-config', `t`, default_toml, 'Path or string with TOML configuration')
|
||||
|
||||
ensure_env(opt) or { panic(err) }
|
||||
|
||||
arg_paths := fp.finalize() or { panic(err) }
|
||||
|
||||
arg_paths := fp.finalize()?
|
||||
if arg_paths.len == 0 {
|
||||
println(fp.usage())
|
||||
println('\nError missing arguments')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if !os.exists(tmp_dir) {
|
||||
os.mkdir_all(tmp_dir)?
|
||||
}
|
||||
|
||||
opt.config = new_config(opt.root_path, toml_conf)?
|
||||
|
||||
gen_in_path := arg_paths[0]
|
||||
@ -154,13 +170,15 @@ fn main() {
|
||||
all_paths_in_use := [path, gen_in_path, target_path]
|
||||
for path_in_use in all_paths_in_use {
|
||||
if !os.is_dir(path_in_use) {
|
||||
panic('`$path_in_use` is not a directory')
|
||||
eprintln('`$path_in_use` is not a directory')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
if path == target_path || gen_in_path == target_path || gen_in_path == path {
|
||||
panic('Compare paths can not be the same directory `$path`/`$target_path`/`$gen_in_path`')
|
||||
eprintln('Compare paths can not be the same directory `$path`/`$target_path`/`$gen_in_path`')
|
||||
exit(1)
|
||||
}
|
||||
compare_screenshots(opt, gen_in_path, target_path) or { panic(err) }
|
||||
compare_screenshots(opt, gen_in_path, target_path)?
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,21 +202,15 @@ fn generate_screenshots(mut opt Options, output_path string) ? {
|
||||
rel_out_path = file
|
||||
}
|
||||
|
||||
if opt.verbose {
|
||||
eprintln('Compiling shaders (if needed) for `$file`')
|
||||
}
|
||||
sh_result := os.execute('${os.quoted_path(v_exe)} shader ${os.quoted_path(app_path)}')
|
||||
opt.verbose_eprintln('Compiling shaders (if needed) for `$file`')
|
||||
sh_result := opt.verbose_execute('${os.quoted_path(v_exe)} shader ${os.quoted_path(app_path)}')
|
||||
if sh_result.exit_code != 0 {
|
||||
if opt.verbose {
|
||||
eprintln('Skipping shader compile for `$file` v shader failed with:\n$sh_result.output')
|
||||
}
|
||||
opt.verbose_eprintln('Skipping shader compile for `$file` v shader failed with:\n$sh_result.output')
|
||||
continue
|
||||
}
|
||||
|
||||
if !os.exists(dst_path) {
|
||||
if opt.verbose {
|
||||
eprintln('Creating output path `$dst_path`')
|
||||
}
|
||||
opt.verbose_eprintln('Creating output path `$dst_path`')
|
||||
os.mkdir_all(dst_path)?
|
||||
}
|
||||
|
||||
@ -221,18 +233,13 @@ fn compare_screenshots(opt Options, output_path string, target_path string) ? {
|
||||
mut warns := map[string]string{}
|
||||
for app_config in opt.config.apps {
|
||||
screenshots := app_config.screenshots
|
||||
if opt.verbose {
|
||||
eprintln('Comparing $screenshots.len screenshots in `$output_path` with `$target_path`')
|
||||
}
|
||||
opt.verbose_eprintln('Comparing $screenshots.len screenshots in `$output_path` with `$target_path`')
|
||||
for screenshot in screenshots {
|
||||
relative_screenshot := screenshot.all_after(output_path + os.path_separator)
|
||||
|
||||
src := screenshot
|
||||
target := os.join_path(target_path, relative_screenshot)
|
||||
|
||||
if opt.verbose {
|
||||
eprintln('Comparing `$src` with `$target` with $app_config.compare.method')
|
||||
}
|
||||
opt.verbose_eprintln('Comparing `$src` with `$target` with $app_config.compare.method')
|
||||
|
||||
if app_config.compare.method == 'idiff' {
|
||||
if idiff_exe == '' {
|
||||
@ -242,14 +249,9 @@ fn compare_screenshots(opt Options, output_path string, target_path string) ? {
|
||||
'.diff.tif')
|
||||
flags := app_config.compare.flags.join(' ')
|
||||
diff_cmd := '${os.quoted_path(idiff_exe)} $flags -abs -od -o ${os.quoted_path(diff_file)} -abs ${os.quoted_path(src)} ${os.quoted_path(target)}'
|
||||
if opt.verbose {
|
||||
eprintln('Running: $diff_cmd')
|
||||
}
|
||||
|
||||
result := os.execute(diff_cmd)
|
||||
|
||||
if opt.verbose && result.exit_code == 0 {
|
||||
eprintln('OUTPUT: \n$result.output')
|
||||
result := opt.verbose_execute(diff_cmd)
|
||||
if result.exit_code == 0 {
|
||||
opt.verbose_eprintln('OUTPUT: \n$result.output')
|
||||
}
|
||||
if result.exit_code != 0 {
|
||||
eprintln('OUTPUT: \n$result.output')
|
||||
@ -278,15 +280,19 @@ fn compare_screenshots(opt Options, output_path string, target_path string) ? {
|
||||
}
|
||||
first := fails.keys()[0]
|
||||
fail_copy := os.join_path(os.temp_dir(), 'fail.' + first.all_after_last('.'))
|
||||
os.cp(first, fail_copy) or { panic(err) }
|
||||
os.cp(first, fail_copy)?
|
||||
eprintln('First failed file `$first` is copied to `$fail_copy`')
|
||||
|
||||
diff_file := os.join_path(os.temp_dir(), os.file_name(first).all_before_last('.') +
|
||||
'.diff.tif')
|
||||
diff_copy := os.join_path(os.temp_dir(), 'diff.tif')
|
||||
if os.is_file(diff_file) {
|
||||
os.cp(diff_file, diff_copy) or { panic(err) }
|
||||
os.cp(diff_file, diff_copy)?
|
||||
eprintln('First failed diff file `$diff_file` is copied to `$diff_copy`')
|
||||
eprintln('Removing alpha channel from $diff_copy ...')
|
||||
final_fail_result_file := os.join_path(os.temp_dir(), 'diff.png')
|
||||
opt.verbose_execute('convert ${os.quoted_path(diff_copy)} -alpha off ${os.quoted_path(final_fail_result_file)}')
|
||||
eprintln('Final diff file: `$final_fail_result_file`')
|
||||
}
|
||||
exit(1)
|
||||
}
|
||||
@ -295,25 +301,16 @@ fn compare_screenshots(opt Options, output_path string, target_path string) ? {
|
||||
fn take_screenshots(opt Options, app AppConfig) ?[]string {
|
||||
out_path := app.screenshots_path
|
||||
if !opt.compare_only {
|
||||
if opt.verbose {
|
||||
eprintln('Taking screenshot(s) of `$app.path` to `$out_path`')
|
||||
}
|
||||
|
||||
opt.verbose_eprintln('Taking screenshot(s) of `$app.path` to `$out_path`')
|
||||
if app.capture.method == 'gg_record' {
|
||||
for k, v in app.capture.env {
|
||||
rv := v.replace('\$OUT_PATH', out_path)
|
||||
if opt.verbose {
|
||||
eprintln('Setting ENV `$k` = $rv ...')
|
||||
}
|
||||
opt.verbose_eprintln('Setting ENV `$k` = $rv ...')
|
||||
os.setenv('$k', rv, true)
|
||||
}
|
||||
|
||||
mut flags := app.capture.flags.join(' ')
|
||||
v_cmd := '${os.quoted_path(v_exe)} $flags -d gg_record run ${os.quoted_path(app.abs_path)}'
|
||||
if opt.verbose {
|
||||
eprintln('Running `$v_cmd`')
|
||||
}
|
||||
result := os.execute('$v_cmd')
|
||||
result := opt.verbose_execute('${os.quoted_path(v_exe)} $flags -d gg_record run ${os.quoted_path(app.abs_path)}')
|
||||
if result.exit_code != 0 {
|
||||
return error('Failed taking screenshot of `$app.abs_path`:\n$result.output')
|
||||
}
|
||||
@ -329,30 +326,6 @@ fn take_screenshots(opt Options, app AppConfig) ?[]string {
|
||||
return screenshots
|
||||
}
|
||||
|
||||
// ensure_env returns nothing if everything is okay.
|
||||
fn ensure_env(opt Options) ? {
|
||||
if !os.exists(tmp_dir) {
|
||||
os.mkdir_all(tmp_dir)?
|
||||
}
|
||||
|
||||
if runtime_os !in supported_hosts {
|
||||
return error('$tool_name is currently only supported on $supported_hosts hosts')
|
||||
}
|
||||
}
|
||||
|
||||
// vexe returns the absolute path to the V compiler.
|
||||
fn vexe() string {
|
||||
mut exe := os.getenv('VEXE')
|
||||
if os.is_executable(exe) {
|
||||
return os.real_path(exe)
|
||||
}
|
||||
possible_symlink := os.find_abs_path_of_executable('v') or { '' }
|
||||
if os.is_executable(possible_symlink) {
|
||||
exe = os.real_path(possible_symlink)
|
||||
}
|
||||
return exe
|
||||
}
|
||||
|
||||
fn new_config(root_path string, toml_config string) ?Config {
|
||||
doc := if os.is_file(toml_config) {
|
||||
toml.parse_file(toml_config)?
|
||||
|
Loading…
Reference in New Issue
Block a user