Repository: zng-ui/zng (language: rust)

Issue:
Add AVIF to the prebuilt
The `image` crate needs to build `dav1d`  to provide AVIF support. Building `dav1d` is difficult, we should configure the release workflow to build it so that AVIF is available in view_prebuilt.



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9e30d6757..5986b15a4 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -64,44 +64,130 @@ jobs:
     runs-on: ubuntu-latest
     needs: ['check-ubuntu']
     steps:
+      - name: install dav1d dep nasm
+        uses: ilammy/setup-nasm@v1
+      - name: install dav1d python deps
+        run: |
+          pip install -U pip
+          pip install -U wheel setuptools
+          pip install -U meson ninja
+      - name: build dav1d
+        env:
+          DAV1D_DIR: dav1d_dir
+          LIB_PATH: lib/x86_64-linux-gnu
+        run: |
+          git clone --branch 1.3.0 --depth 1 https://code.videolan.org/videolan/dav1d.git
+          cd dav1d
+          meson build -Dprefix=$HOME/$DAV1D_DIR -Denable_tools=false -Denable_examples=false -Ddefault_library=static --buildtype release
+          ninja -C build
+          ninja -C build install
+          echo "PKG_CONFIG_PATH=$HOME/$DAV1D_DIR/$LIB_PATH/pkgconfig" >> $GITHUB_ENV
+          echo "LD_LIBRARY_PATH=$HOME/$DAV1D_DIR/$LIB_PATH" >> $GITHUB_ENV
+
       - uses: actions/checkout@v4
         with:
           ref: release
-      - run: cargo do prebuild
-      - uses: actions/upload-artifact@v4
+      - run: cargo do comment_feature -u "zng-view/Cargo.toml" avif
+      - name: cargo do prebuild --features avif
+        env:
+          SYSTEM_DEPS_LINK: static
+        run: cargo do prebuild --features avif
+      - run: cargo clean
+      - run: cargo do comment_feature "zng-view/Cargo.toml" avif
+      - name: upload prebuilt
+        uses: actions/upload-artifact@v4
         with:
           name: prebuilt-ubuntu
           path: zng-view-prebuilt/lib/libzng_view.so
-      - run: cargo clean
   prebuild-windows:
     runs-on: windows-latest
     needs: ['check-windows']
-    env:
-      CC: 'clang-cl'
-      CXX: 'clang-cl'
     steps:
+      - name: config msvc for dav1d
+        uses: ilammy/msvc-dev-cmd@v1
+      - name: install dav1d dep nasm
+        uses: ilammy/setup-nasm@v1
+      - name: install dav1d python deps
+        run: |
+          pip install -U pip
+          pip install -U wheel setuptools
+          pip install -U meson ninja
+      - name: setup dav1d env
+        shell: bash
+        run: |
+          echo "PKG_CONFIG=c:\build\bin\pkg-config.exe" >> $GITHUB_ENV
+          echo "PKG_CONFIG_PATH=C:\build\lib\pkgconfig" >> $GITHUB_ENV
+          echo "C:\build\bin" >> $GITHUB_PATH
+      - name: build dav1d dep pkg-config
+        run: |
+          git clone --branch meson-glib-subproject --depth 1 https://gitlab.freedesktop.org/tpm/pkg-config.git
+          cd pkg-config
+          meson build -Dprefix=C:\build --buildtype release
+          ninja -C build
+          ninja -C build install
+      - name: build dav1d
+        run: |
+          git clone --branch 1.3.0 --depth 1 https://code.videolan.org/videolan/dav1d.git
+          cd dav1d
+          meson build -Dprefix=C:\build -Denable_tools=false -Denable_examples=false -Ddefault_library=static --buildtype release
+          ninja -C build
+          ninja -C build install
+
       - uses: actions/checkout@v4
         with:
           ref: release
-      - run: cargo do prebuild
-      - uses: actions/upload-artifact@v4
+      - run: cargo do comment_feature -u "zng-view/Cargo.toml" avif
+      - name: cargo do prebuild --features avif
+        env:
+          CC: clang-cl
+          CXX: clang-cl
+          SYSTEM_DEPS_LINK: static
+        run: cargo do prebuild --features avif
+      - run: cargo clean
+      - run: cargo do comment_feature "zng-view/Cargo.toml" avif
+      - name: upload prebuilt
+        uses: actions/upload-artifact@v4
         with:
           name: prebuilt-windows
-          path: zng-view-prebuilt/lib/lzng_view.dll
-      - run: cargo clean
+          path: zng-view-prebuilt/lib/zng_view.dll
   prebuild-macos:
     runs-on: macos-13
     needs: ['check-macos']
     steps:
+      - name: install dav1d dep nasm
+        uses: ilammy/setup-nasm@v1
+      - name: install dav1d python deps
+        run: |
+          pip install -U pip
+          pip install -U wheel setuptools
+          pip install -U meson ninja
+      - name: build dav1d
+        env:
+          DAV1D_DIR: dav1d_dir
+          LIB_PATH: lib
+        run: |
+          git clone --branch 1.3.0 --depth 1 https://code.videolan.org/videolan/dav1d.git
+          cd dav1d
+          meson build -Dprefix=$HOME/$DAV1D_DIR -Denable_tools=false -Denable_examples=false -Ddefault_library=static --buildtype release
+          ninja -C build
+          ninja -C build install
+          echo "PKG_CONFIG_PATH=$HOME/$DAV1D_DIR/$LIB_PATH/pkgconfig" >> $GITHUB_ENV
+          echo "LD_LIBRARY_PATH=$HOME/$DAV1D_DIR/$LIB_PATH" >> $GITHUB_ENV
       - uses: actions/checkout@v4
         with:
           ref: release
-      - run: cargo do prebuild
-      - uses: actions/upload-artifact@v4
+      - run: cargo do comment_feature -u "zng-view/Cargo.toml" avif
+      - name: cargo do prebuild --features avif
+        env:
+          SYSTEM_DEPS_LINK: static
+        run: cargo do prebuild --features avif
+      - run: cargo clean
+      - run: cargo do comment_feature "zng-view/Cargo.toml" avif
+      - name: upload prebuilt
+        uses: actions/upload-artifact@v4
         with:
           name: prebuilt-macos
           path: zng-view-prebuilt/lib/libzng_view.dylib
-      - run: cargo clean
 
   test-ubuntu:
     runs-on: ubuntu-latest
diff --git a/tools/do-tasks/src/main.rs b/tools/do-tasks/src/main.rs
index 65112993f..fa6671408 100644
--- a/tools/do-tasks/src/main.rs
+++ b/tools/do-tasks/src/main.rs
@@ -23,7 +23,9 @@ fn main() {
         "install" => install(args),
         "publish" => publish(args),
         "publish_version_tag" => publish_version_tag(args),
+        "comment_feature" => comment_feature(args),
         "version" => version(args),
+        "ls" => ls(args),
         "help" | "--help" => help(args),
         _ => fatal(f!("unknown task {task:?}, `{} help` to list tasks", do_cmd())),
     }
@@ -1079,7 +1081,7 @@ fn publish(mut args: Vec<&str>) {
     }
 }
 
-// used by `workflows/release-1-test-tag.yml`
+// used by `workflows/release.yml`
 fn publish_version_tag(mut args: Vec<&str>) {
     let version = util::crate_version("zng");
     let tag = format!("v{version}");
@@ -1096,6 +1098,53 @@ fn publish_version_tag(mut args: Vec<&str>) {
     print(f!("tag={tag}\n"));
 }
 
+// used by `workflows/release.yml`
+fn comment_feature(mut args: Vec<&str>) {
+    use std::fmt::*;
+
+    let uncomment = take_flag(&mut args, &["-u", "--uncomment"]);
+    let cargo = args[0];
+    let feature = args[1];
+    let feature_co = format!("# {feature}");
+
+    let (find, replace) = if uncomment {
+        (feature_co.as_str(), feature)
+    } else {
+        (feature, feature_co.as_str())
+    };
+
+    match std::fs::read_to_string(cargo) {
+        Ok(file) => {
+            let mut out = String::new();
+            let mut in_features = false;
+            let mut replaced = false;
+
+            for line in file.lines() {
+                if line == "[features]" {
+                    in_features = true;
+                } else if line.starts_with('[') && line.ends_with(']') {
+                    in_features = false;
+                } else if in_features && line.starts_with(find) {
+                    write!(&mut out, "{replace}{}\n", &line[find.len()..]).unwrap();
+                    replaced = true;
+                    continue;
+                }
+
+                write!(&mut out, "{line}\n").unwrap();
+            }
+
+            if !replaced {
+                fatal(f!("did not find `{find}` in `{cargo}`\n"));
+            }
+
+            std::fs::write(cargo, out.as_bytes()).unwrap();
+        }
+        Err(e) => {
+            error(e);
+        }
+    }
+}
+
 // do version
 //    Prints version of Rust and components.
 // USAGE:
@@ -1115,6 +1164,14 @@ fn version(args: Vec<&str>) {
     }
 }
 
+fn ls(args: Vec<&str>) {
+    println!("ls {:?}", args);
+
+    for p in util::glob(&format!("{}/**", args[0])) {
+        println!("{p}");
+    }
+}
+
 // do help, --help [task]
 //    Prints help for all tasks.
 // USAGE:
diff --git a/zng-view/Cargo.toml b/zng-view/Cargo.toml
index f82f06496..bfff53d4a 100644
--- a/zng-view/Cargo.toml
+++ b/zng-view/Cargo.toml
@@ -122,4 +122,4 @@ tempfile = "3.10"
 
 [package.metadata.docs.rs]
 all-features = true
-targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc", "x86_64-apple-darwin"]
\ No newline at end of file
+targets = ["x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc", "x86_64-apple-darwin"]


Test patch: