diff --git a/.github/workflows/gg_regressions_ci.yml b/.github/workflows/gg_regressions_ci.yml index 0612d2ef8d..d8e2f69bdc 100644 --- a/.github/workflows/gg_regressions_ci.yml +++ b/.github/workflows/gg_regressions_ci.yml @@ -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 diff --git a/cmd/tools/vgret.v b/cmd/tools/vgret.v index a9ae1c71a0..b66fb70f2f 100644 --- a/cmd/tools/vgret.v +++ b/cmd/tools/vgret.v @@ -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)?