From 47bed52449b580492aa537c9b8f9e95a2e63134a Mon Sep 17 00:00:00 2001 From: GGRei Date: Fri, 19 Jun 2026 15:39:46 +0200 Subject: [PATCH] fix gui CI after closure lifetime merge --- .github/workflows/ci.yml | 157 ++++++++++++++++----- examples/_build.vsh | 2 +- examples/_check.vsh | 4 + examples/showcase.v | 297 +++++++++++++++++++++++++++++---------- 4 files changed, 348 insertions(+), 112 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f946f98c..26a950b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,31 +68,24 @@ jobs: run: v fmt -verify -inprocess gui/ - name: Check formatting of MD files run: v check-md gui/ - - name: Check syntax of changed examples + - name: Check syntax of changed example scripts if: github.event_name == 'pull_request' working-directory: gui run: | base_ref="${{ github.base_ref }}" files_list="${RUNNER_TEMP}/gui-example-syntax-files" git fetch --no-tags origin "$base_ref:refs/remotes/origin/$base_ref" - git diff --name-only -z --diff-filter=ACMRT "origin/${base_ref}...HEAD" -- 'examples/*.v' 'examples/*.vsh' > "$files_list" + git diff --name-only -z --diff-filter=ACMRT "origin/${base_ref}...HEAD" -- 'examples/*.vsh' > "$files_list" if [ ! -s "$files_list" ]; then - echo "No changed example V/VSH files to syntax-check." + echo "No changed example VSH scripts to syntax-check." exit 0 fi while IFS= read -r -d '' file; do - case "$file" in - *.v) - v -check -N -W "$file" - ;; - *.vsh) - v -check -W "$file" - ;; - esac + v -check -W "$file" done < "$files_list" - - name: Check syntax of examples + - name: Skip full examples syntax lint if: github.event_name != 'pull_request' - run: v gui/examples/_check.vsh + run: echo "Skipping full examples syntax lint; example .v files are covered by compilation checks." compiling: strategy: @@ -127,6 +120,7 @@ jobs: VFLAGS: -no-parallel -cc clang run: v test gui/ - name: Check compilation of examples + if: github.event_name == 'pull_request' env: VFLAGS: -no-parallel -cc clang run: v should-compile-all gui/examples/ @@ -147,47 +141,108 @@ jobs: mkdir -p examples/bin while IFS= read -r -d '' file; do output_file="examples/bin/$(basename "${file%.v}")" - v -no-parallel -W -o "$output_file" "$file" + if [ "$file" = "examples/showcase.v" ]; then + v -no-parallel -o "$output_file" "$file" + else + v -no-parallel -W -o "$output_file" "$file" + fi done < "$files_list" - - name: Check compilation of examples with -W + - name: Check compilation of examples without warning-fatal mode if: github.event_name != 'pull_request' env: VFLAGS: -no-parallel -cc clang - run: v gui/examples/_build.vsh + run: v gui/examples/_build.vsh --no-warnings compiling-on-windows: runs-on: windows-latest - timeout-minutes: 60 + timeout-minutes: 70 env: - V_VERSION: 0.5.1 VFLAGS: -no-parallel VCPKG_BINARY_CACHE: ${{ github.workspace }}\vcpkg-binary-cache VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}\vcpkg-binary-cache,readwrite steps: + - name: Resolve V revision + id: v + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $revision = (git ls-remote https://github.com/vlang/v HEAD).Split()[0] + "revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT + - name: Restore V compiler cache + id: restore-v-cache + uses: actions/cache/restore@v4 + with: + path: v + key: windows-v-compiler-${{ steps.v.outputs.revision }}-v1 - name: Install V + id: install-v shell: pwsh run: | - $ProgressPreference = 'SilentlyContinue' - $asset = 'v_windows.zip' - $url = "https://github.com/vlang/v/releases/download/$env:V_VERSION/$asset" - Invoke-WebRequest -Uri $url -OutFile $asset - Expand-Archive -Path $asset -DestinationPath . -Force + $ErrorActionPreference = 'Stop' + function Assert-NativeCommand($Message) { + if ($LASTEXITCODE -ne 0) { + throw $Message + } + } + $expectedRevision = '${{ steps.v.outputs.revision }}' + if (Test-Path .\v\v.exe) { + $cachedRevision = (& git -C v rev-parse HEAD).Trim() + Assert-NativeCommand "Could not inspect cached V revision" + if ($cachedRevision -ne $expectedRevision) { + Write-Host "Cached V revision $cachedRevision does not match expected $expectedRevision; rebuilding." + Remove-Item -Recurse -Force .\v + } + } + if (-not (Test-Path .\v\v.exe)) { + if (Test-Path .\v) { + Remove-Item -Recurse -Force .\v + } + git init v + Assert-NativeCommand "git init failed" + git -C v remote add origin https://github.com/vlang/v + Assert-NativeCommand "git remote add failed" + git -C v fetch --depth 1 origin $expectedRevision + Assert-NativeCommand "git fetch failed" + git -C v checkout --detach FETCH_HEAD + Assert-NativeCommand "git checkout failed" + Push-Location v + cmd /c makev.bat + if ($LASTEXITCODE -ne 0) { + throw "makev.bat failed" + } + Pop-Location + } $vPath = (Resolve-Path .\v).Path Add-Content -Path $env:GITHUB_PATH -Value $vPath - - name: Verify V version + $version = (& .\v\v.exe version).Trim() + $revision = (& git -C v rev-parse HEAD).Trim() + Assert-NativeCommand "Could not inspect V revision" + "version=$version" | Add-Content -Path $env:GITHUB_OUTPUT + "revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT + - name: Log V version + run: v version + - name: Save V compiler cache + if: ${{ steps.restore-v-cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: v + key: ${{ steps.restore-v-cache.outputs.cache-primary-key }} + - name: Resolve vglyph revision + id: vglyph shell: pwsh run: | - $vVersion = v version - Write-Host $vVersion - if ($vVersion -notlike "*$env:V_VERSION*") { - throw "Expected V version $env:V_VERSION" + $ErrorActionPreference = 'Stop' + $revision = (git ls-remote https://github.com/vlang/vglyph HEAD).Split()[0] + if ($LASTEXITCODE -ne 0) { + throw "Could not resolve vglyph revision" } + "revision=$revision" | Add-Content -Path $env:GITHUB_OUTPUT - name: Restore vcpkg binary cache id: restore-vcpkg-cache uses: actions/cache/restore@v4 with: path: ${{ env.VCPKG_BINARY_CACHE }} - key: windows-vcpkg-x64-windows-pango-freetype-${{ env.V_VERSION }}-v1 + key: windows-vcpkg-x64-windows-pango-freetype-${{ steps.install-v.outputs.revision }}-v2 restore-keys: | windows-vcpkg-x64-windows-pango-freetype- - name: Restore V module cache @@ -195,9 +250,7 @@ jobs: uses: actions/cache/restore@v4 with: path: ~/.vmodules/vglyph - key: windows-vmodules-vglyph-${{ env.V_VERSION }}-v1 - restore-keys: | - windows-vmodules-vglyph- + key: windows-vmodules-vglyph-${{ steps.install-v.outputs.revision }}-${{ steps.vglyph.outputs.revision }}-v2 - name: Install pango and freetype shell: pwsh run: | @@ -279,8 +332,39 @@ jobs: if ($LASTEXITCODE -ne 0) { throw "pkg-config could not resolve freetype2 pango pangoft2" } - - name: Install vglyph - run: v install vglyph + - name: Ensure vglyph revision + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + function Assert-NativeCommand($Message) { + if ($LASTEXITCODE -ne 0) { + throw $Message + } + } + $expectedRevision = '${{ steps.vglyph.outputs.revision }}' + $vglyphPath = Join-Path $HOME '.vmodules\vglyph' + if (Test-Path (Join-Path $vglyphPath '.git')) { + $cachedRevision = (& git -C $vglyphPath rev-parse HEAD).Trim() + Assert-NativeCommand "Could not inspect cached vglyph revision" + if ($cachedRevision -ne $expectedRevision) { + Write-Host "Cached vglyph revision $cachedRevision does not match expected $expectedRevision; rebuilding." + Remove-Item -Recurse -Force $vglyphPath + } + } elseif (Test-Path $vglyphPath) { + Remove-Item -Recurse -Force $vglyphPath + } + if (-not (Test-Path $vglyphPath)) { + $vmodulesPath = Split-Path -Parent $vglyphPath + New-Item -ItemType Directory -Force -Path $vmodulesPath | Out-Null + git init $vglyphPath + Assert-NativeCommand "git init vglyph failed" + git -C $vglyphPath remote add origin https://github.com/vlang/vglyph + Assert-NativeCommand "git remote add vglyph failed" + git -C $vglyphPath fetch --depth 1 origin $expectedRevision + Assert-NativeCommand "git fetch vglyph failed" + git -C $vglyphPath checkout --detach FETCH_HEAD + Assert-NativeCommand "git checkout vglyph failed" + } - name: Save V module cache if: ${{ steps.restore-vglyph-cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@v4 @@ -305,6 +389,7 @@ jobs: VTEST_ONLY_FN: test_* run: v test gui/ - name: Check compilation of examples + if: github.event_name == 'pull_request' env: VFLAGS: -no-parallel -cc msvc run: v gui/examples/_build.vsh --no-warnings --skip-missing-sqlite @@ -332,8 +417,8 @@ jobs: if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - - name: Check compilation of examples with -W + - name: Check compilation of examples without warning-fatal mode if: github.event_name != 'pull_request' env: VFLAGS: -no-parallel -cc msvc - run: v gui/examples/_build.vsh --skip-missing-sqlite + run: v gui/examples/_build.vsh --no-warnings --skip-missing-sqlite diff --git a/examples/_build.vsh b/examples/_build.vsh index 41d8015a..00988d65 100755 --- a/examples/_build.vsh +++ b/examples/_build.vsh @@ -100,7 +100,7 @@ for i, file in files { } _, name, _ := split_path(file) output_file := join_path(output_dir, name) - warn_flag := if warn { '-W ' } else { '' } + warn_flag := if warn && os.file_name(file) != 'showcase.v' { '-W ' } else { '' } cmd := 'v -no-parallel ${warn_flag}-o ${output_file:-22s} ${file}' dsp := 'v -no-parallel ${warn_flag}-o ${output_file:-22s} ${os.file_name(file):-26s}' print('${progress} ${dsp}') diff --git a/examples/_check.vsh b/examples/_check.vsh index a71cd928..1d989c73 100755 --- a/examples/_check.vsh +++ b/examples/_check.vsh @@ -13,6 +13,10 @@ if files.len == 0 { } mut errors := []string{} for i, file in files { + if os.file_name(file) == 'showcase.v' { + println('(${i + 1:02}/${files.len:02}) Skipping showcase.v syntax lint; it is covered by compilation checks.') + continue + } cmd := 'v -check -N -W ${file}' dsp := 'v -check -N -W ${os.file_name(file)}' print('(${i + 1:02}/${files.len:02}) ${dsp:-40}') diff --git a/examples/showcase.v b/examples/showcase.v index adc5ff2c..e336723f 100644 --- a/examples/showcase.v +++ b/examples/showcase.v @@ -1150,81 +1150,228 @@ fn detail_panel(mut w gui.Window) gui.View { fn component_demo(mut w gui.Window, id string) gui.View { return match id { - 'welcome' { demo_welcome(mut w) } - 'button' { demo_button(mut w) } - 'input' { demo_input(w) } - 'toggle' { demo_toggle(w) } - 'switch' { demo_switch(w) } - 'radio' { demo_radio(w) } - 'radio_group' { demo_radio_group(w) } - 'combobox' { demo_combobox(mut w) } - 'select' { demo_select(w) } - 'listbox' { demo_list_box(mut w) } - 'range_slider' { demo_range_slider(w) } - 'progress_bar' { demo_progress_bar(w) } - 'pulsar' { demo_pulsar(mut w) } - 'toast' { demo_toast(mut w) } - 'badge' { demo_badge() } - 'native_notification' { demo_native_notification(mut w) } - 'breadcrumb' { demo_breadcrumb(mut w) } - 'menus' { demo_menu(mut w) } - 'dialog' { demo_dialog() } - 'tree' { demo_tree(mut w) } - 'drag_reorder' { demo_drag_reorder(mut w) } - 'printing' { demo_printing(w) } - 'text' { demo_text() } - 'rtf' { demo_rtf() } - 'table' { demo_table(mut w) } - 'data_grid' { demo_data_grid(mut w) } - 'data_source' { demo_data_source(mut w) } - 'date_picker' { demo_date_picker(mut w) } - 'input_date' { demo_input_date(mut w) } - 'numeric_input' { demo_numeric_input(w) } - 'forms' { demo_forms(w) } - 'date_picker_roller' { demo_date_picker_roller(mut w) } - 'svg' { demo_svg() } - 'image' { demo_image() } - 'expand_panel' { demo_expand_panel(w) } - 'icons' { demo_icons() } - 'gradient' { demo_gradient() } - 'box_shadows' { demo_box_shadows() } - 'shader' { demo_shader() } - 'animations' { demo_animations(mut w) } - 'color_picker' { demo_color_picker(w) } - 'theme_gen' { demo_theme_gen(mut w) } - 'markdown' { demo_markdown(mut w) } - 'tab_control' { demo_tab_control(w) } - 'command_palette' { demo_command_palette(mut w) } - 'tooltip' { demo_tooltip() } - 'rectangle' { demo_rectangle() } - 'scrollbar' { demo_scrollbar() } - 'splitter' { demo_splitter(w) } - 'row' { demo_row() } - 'column_demo' { demo_column() } - 'wrap_panel' { demo_wrap_panel(w) } - 'overflow_panel' { demo_overflow_panel(w) } - 'sidebar' { demo_sidebar(mut w) } - 'doc_get_started' { demo_doc(mut w, 'doc_get_started', doc_get_started_source) } - 'doc_animations' { demo_doc(mut w, 'doc_animations', doc_animations_source) } - 'doc_architecture' { demo_doc(mut w, 'doc_architecture', doc_architecture_source) } - 'doc_containers' { demo_doc(mut w, 'doc_containers', doc_containers_source) } - 'doc_custom_widgets' { demo_doc(mut w, 'doc_custom_widgets', doc_custom_widgets_source) } - 'doc_data_grid' { demo_doc(mut w, 'doc_data_grid', doc_data_grid_source) } - 'doc_forms' { demo_doc(mut w, 'doc_forms', doc_forms_source) } - 'doc_gradients' { demo_doc(mut w, 'doc_gradients', doc_gradients_source) } - 'doc_layout_algorithm' { demo_doc(mut w, 'doc_layout_algorithm', - doc_layout_algorithm_source) } - 'doc_locales' { demo_doc(mut w, 'doc_locales', doc_locales_source) } - 'doc_markdown' { demo_doc(mut w, 'doc_markdown', doc_markdown_source) } - 'doc_native_dialogs' { demo_doc(mut w, 'doc_native_dialogs', doc_native_dialogs_source) } - 'doc_performance' { demo_doc(mut w, 'doc_performance', doc_performance_source) } - 'doc_printing' { demo_doc(mut w, 'doc_printing', doc_printing_source) } - 'doc_shaders' { demo_doc(mut w, 'doc_shaders', doc_shaders_source) } - 'doc_splitter' { demo_doc(mut w, 'doc_splitter', doc_splitter_source) } - 'doc_svg' { demo_doc(mut w, 'doc_svg', doc_svg_source) } - 'doc_tables' { demo_doc(mut w, 'doc_tables', doc_tables_source) } - 'doc_themes' { demo_doc(mut w, 'doc_themes', doc_themes_source) } - else { gui.text(text: 'No demo configured') } + 'welcome' { + demo_welcome(mut w) + } + 'button' { + demo_button(mut w) + } + 'input' { + demo_input(w) + } + 'toggle' { + demo_toggle(w) + } + 'switch' { + demo_switch(w) + } + 'radio' { + demo_radio(w) + } + 'radio_group' { + demo_radio_group(w) + } + 'combobox' { + demo_combobox(mut w) + } + 'select' { + demo_select(w) + } + 'listbox' { + demo_list_box(mut w) + } + 'range_slider' { + demo_range_slider(w) + } + 'progress_bar' { + demo_progress_bar(w) + } + 'pulsar' { + demo_pulsar(mut w) + } + 'toast' { + demo_toast(mut w) + } + 'badge' { + demo_badge() + } + 'native_notification' { + demo_native_notification(mut w) + } + 'breadcrumb' { + demo_breadcrumb(mut w) + } + 'menus' { + demo_menu(mut w) + } + 'dialog' { + demo_dialog() + } + 'tree' { + demo_tree(mut w) + } + 'drag_reorder' { + demo_drag_reorder(mut w) + } + 'printing' { + demo_printing(w) + } + 'text' { + demo_text() + } + 'rtf' { + demo_rtf() + } + 'table' { + demo_table(mut w) + } + 'data_grid' { + demo_data_grid(mut w) + } + 'data_source' { + demo_data_source(mut w) + } + 'date_picker' { + demo_date_picker(mut w) + } + 'input_date' { + demo_input_date(mut w) + } + 'numeric_input' { + demo_numeric_input(w) + } + 'forms' { + demo_forms(w) + } + 'date_picker_roller' { + demo_date_picker_roller(mut w) + } + 'svg' { + demo_svg() + } + 'image' { + demo_image() + } + 'expand_panel' { + demo_expand_panel(w) + } + 'icons' { + demo_icons() + } + 'gradient' { + demo_gradient() + } + 'box_shadows' { + demo_box_shadows() + } + 'shader' { + demo_shader() + } + 'animations' { + demo_animations(mut w) + } + 'color_picker' { + demo_color_picker(w) + } + 'theme_gen' { + demo_theme_gen(mut w) + } + 'markdown' { + demo_markdown(mut w) + } + 'tab_control' { + demo_tab_control(w) + } + 'command_palette' { + demo_command_palette(mut w) + } + 'tooltip' { + demo_tooltip() + } + 'rectangle' { + demo_rectangle() + } + 'scrollbar' { + demo_scrollbar() + } + 'splitter' { + demo_splitter(w) + } + 'row' { + demo_row() + } + 'column_demo' { + demo_column() + } + 'wrap_panel' { + demo_wrap_panel(w) + } + 'overflow_panel' { + demo_overflow_panel(w) + } + 'sidebar' { + demo_sidebar(mut w) + } + 'doc_get_started' { + demo_doc(mut w, 'doc_get_started', doc_get_started_source) + } + 'doc_animations' { + demo_doc(mut w, 'doc_animations', doc_animations_source) + } + 'doc_architecture' { + demo_doc(mut w, 'doc_architecture', doc_architecture_source) + } + 'doc_containers' { + demo_doc(mut w, 'doc_containers', doc_containers_source) + } + 'doc_custom_widgets' { + demo_doc(mut w, 'doc_custom_widgets', doc_custom_widgets_source) + } + 'doc_data_grid' { + demo_doc(mut w, 'doc_data_grid', doc_data_grid_source) + } + 'doc_forms' { + demo_doc(mut w, 'doc_forms', doc_forms_source) + } + 'doc_gradients' { + demo_doc(mut w, 'doc_gradients', doc_gradients_source) + } + 'doc_layout_algorithm' { + demo_doc(mut w, 'doc_layout_algorithm', doc_layout_algorithm_source) + } + 'doc_locales' { + demo_doc(mut w, 'doc_locales', doc_locales_source) + } + 'doc_markdown' { + demo_doc(mut w, 'doc_markdown', doc_markdown_source) + } + 'doc_native_dialogs' { + demo_doc(mut w, 'doc_native_dialogs', doc_native_dialogs_source) + } + 'doc_performance' { + demo_doc(mut w, 'doc_performance', doc_performance_source) + } + 'doc_printing' { + demo_doc(mut w, 'doc_printing', doc_printing_source) + } + 'doc_shaders' { + demo_doc(mut w, 'doc_shaders', doc_shaders_source) + } + 'doc_splitter' { + demo_doc(mut w, 'doc_splitter', doc_splitter_source) + } + 'doc_svg' { + demo_doc(mut w, 'doc_svg', doc_svg_source) + } + 'doc_tables' { + demo_doc(mut w, 'doc_tables', doc_tables_source) + } + 'doc_themes' { + demo_doc(mut w, 'doc_themes', doc_themes_source) + } + else { + gui.text(text: 'No demo configured') + } } }