Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package zvm for openSUSE:Factory checked in 
at 2026-09-04 12:39:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/zvm (Old)
 and      /work/SRC/openSUSE:Factory/.zvm.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "zvm"

Fri Sep  4 12:39:18 2026 rev:13 rq:1375489 version:0.8.27

Changes:
--------
--- /work/SRC/openSUSE:Factory/zvm/zvm.changes  2026-05-25 22:00:33.778244688 
+0200
+++ /work/SRC/openSUSE:Factory/.zvm.new.1265/zvm.changes        2026-09-04 
12:40:09.409050945 +0200
@@ -1,0 +2,6 @@
+Sat Jul 18 14:06:45 UTC 2026 - Andrea Manzini <[email protected]>
+
+- Update to 0.8.27:
+  * added support for http.timeout 
+
+-------------------------------------------------------------------

Old:
----
  zvm-0.8.22.tar.gz

New:
----
  zvm-0.8.27.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ zvm.spec ++++++
--- /var/tmp/diff_new_pack.AJQTKW/_old  2026-09-04 12:40:10.103075317 +0200
+++ /var/tmp/diff_new_pack.AJQTKW/_new  2026-09-04 12:40:10.105075387 +0200
@@ -17,14 +17,14 @@
 
 
 Name:           zvm
-Version:        0.8.22
+Version:        0.8.27
 Release:        0
 Summary:        Easily install/upgrade between different versions of Zig
 License:        MIT
 URL:            https://github.com/tristanisham/zvm
 Source:         
https://github.com/tristanisham/zvm/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
 Source1:        vendor.tar.xz
-BuildRequires:  golang(API) >= 1.22
+BuildRequires:  golang(API) >= 1.26
 
 %description
 Zig Version Manager (zvm) is a tool for managing your Zig installs. With std

++++++ vendor.tar.xz ++++++

++++++ zvm-0.8.22.tar.gz -> zvm-0.8.27.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/.vscode/launch.json 
new/zvm-0.8.27/.vscode/launch.json
--- old/zvm-0.8.22/.vscode/launch.json  2026-05-24 15:55:19.000000000 +0200
+++ new/zvm-0.8.27/.vscode/launch.json  1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-{
-  // Use IntelliSense to learn about possible attributes.
-  // Hover to view descriptions of existing attributes.
-  // For more information, visit: 
https://go.microsoft.com/fwlink/?linkid=830387
-  "version": "0.2.0",
-  "configurations": [
-    {
-      "name": "Launch Package",
-      "type": "go",
-      "request": "launch",
-      "mode": "auto",
-      "program": "${fileDirname}"
-    }
-  ]
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/.vscode/settings.json 
new/zvm-0.8.27/.vscode/settings.json
--- old/zvm-0.8.22/.vscode/settings.json        2026-05-24 15:55:19.000000000 
+0200
+++ new/zvm-0.8.27/.vscode/settings.json        1970-01-01 01:00:00.000000000 
+0100
@@ -1,4 +0,0 @@
-{
-  "deno.enable": true,
-  "deno.unstable": true
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/README.md new/zvm-0.8.27/README.md
--- old/zvm-0.8.22/README.md    2026-05-24 15:55:19.000000000 +0200
+++ new/zvm-0.8.27/README.md    2026-06-09 20:25:04.000000000 +0200
@@ -134,7 +134,7 @@
 it, and install it on your `$PATH`. Or, you could install ZVM and run
 `zvm i master` every time you want to update. `zvm` is a static binary under a
 permissive license. It supports more platforms than any other Zig version
-manager. Its only dependency is `tar` on Unix-based systems. Whether you're on
+manager. ZVM has no system dependencies. Whether you're on
 Windows, MacOS, Linux, a flavor of BSD, or Plan 9 `zvm` will let you install,
 switch between, and run multiple versions of Zig.
 
@@ -232,6 +232,13 @@
 You can also enable the old behavior by setting the new `alwaysForceInstall`
 field to `true` in `~/.zvm/settings.json`.
 
+### Customize HTTP Timeout
+You can pass a custom HTTP timeout (in seconds) for `zvm i` using the 
`--http.timeout` flag or by setting the `ZVM_HTTP_TIMEOUT` environment variable.
+
+```sh
+zvm i --http.timeout 30
+```
+
 ### Install ZLS with ZVM
 
 You can now install ZLS with your Zig download! To install ZLS with ZVM, simply
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/cli/install.go 
new/zvm-0.8.27/cli/install.go
--- old/zvm-0.8.22/cli/install.go       2026-05-24 15:55:19.000000000 +0200
+++ new/zvm-0.8.27/cli/install.go       2026-06-09 20:25:04.000000000 +0200
@@ -7,6 +7,7 @@
 import (
        "archive/tar"
        "archive/zip"
+       "bufio"
        "crypto/sha256"
        "crypto/tls"
        "encoding/hex"
@@ -23,6 +24,7 @@
        "path/filepath"
        "runtime"
        "slices"
+       "strconv"
        "strings"
        "time"
 
@@ -36,14 +38,16 @@
        "github.com/tristanisham/clr"
 )
 
+const httpDefaultTimeout = (60 * 3) * time.Second
+
 // Install downloads and installs the specified Zig version.
 // It handles checking for existing installations, verifying checksums,
 // and extracting the downloaded bundle.
 func (z *ZVM) Install(version string, force bool, mirror bool) (string, error) 
{
-       err := os.MkdirAll(z.baseDir, 0755)
-       if err != nil {
+       if err := os.MkdirAll(z.baseDir, 0755); err != nil {
                return version, err
        }
+
        rawVersionStructure, err := z.fetchVersionMap()
        if err != nil {
                return version, err
@@ -107,11 +111,28 @@
 
        var tarResp *http.Response
        var minisig minisign.Signature
-       mirror = mirror && z.Settings.UseMirrorList() && 
z.Settings.VersionMapUrl == DefaultSettings.VersionMapUrl
+       var verifyMinisig bool
+
+       // Only the official version map serves builds signed with the pinned
+       // minisign key; custom version maps distribute their own builds, so
+       // signature verification can't apply to them.
+       isOfficialVMUSet := z.Settings.VersionMapUrl == 
DefaultSettings.VersionMapUrl
+       mirror = mirror && z.Settings.UseMirrorList() && isOfficialVMUSet
        if mirror {
                tarResp, minisig, err = 
attemptMirrorDownload(z.Settings.MirrorListUrl, tarPath)
+               verifyMinisig = err == nil
        } else {
-               tarResp, err = attemptDownload(tarPath)
+               tarResp, err = attemptDownload(tarPath, nil)
+               if err == nil && isOfficialVMUSet {
+                       // ziglang.org publishes a .minisig for every build, so 
a missing
+                       // signature is a failed download, not a reason to skip 
verification.
+                       minisig, err = attemptMinisigDownload(tarPath, nil)
+                       if err != nil {
+                               tarResp.Body.Close()
+                               err = fmt.Errorf("minisign signature download 
failed: %w", err)
+                       }
+                       verifyMinisig = err == nil
+               }
        }
 
        if err != nil {
@@ -176,7 +197,7 @@
                log.Warnf("No shasum provided by host")
        }
 
-       if mirror {
+       if verifyMinisig {
                fmt.Println("Checking minisign signature...")
                pubkey, err := minisign.NewPublicKey(z.Settings.MinisignPubKey)
                if err != nil {
@@ -266,7 +287,7 @@
        }
        tarName := path.Base(tarURLParsed.Path)
 
-       resp, err := attemptDownload(mirrorListURL)
+       resp, err := attemptDownload(mirrorListURL, nil)
        if err != nil {
                return nil, minisign.Signature{}, fmt.Errorf("%w: %w", 
ErrDownloadFail, err)
        }
@@ -292,13 +313,13 @@
                }
 
                log.Debug("attemptMirrorDownload", "mirror", i, "mirrorURL", 
mirrorTarURL)
-               tarResp, err := attemptDownload(mirrorTarURL)
+               tarResp, err := attemptDownload(mirrorTarURL, nil)
                if err != nil {
                        log.Debug("mirror tar error", "mirror", mirror, 
"error", err)
                        continue
                }
 
-               minisig, err := attemptMinisigDownload(mirrorTarURL)
+               minisig, err := attemptMinisigDownload(mirrorTarURL, nil)
                if err != nil {
                        log.Debug("mirror minisig error", "mirror", mirror, 
"error", err)
                        tarResp.Body.Close()
@@ -312,8 +333,8 @@
 }
 
 // attemptMinisigDownload downloads the minisign signature for a given tarball 
URL.
-func attemptMinisigDownload(tarURL string) (minisign.Signature, error) {
-       minisigResp, err := attemptDownload(tarURL + ".minisig")
+func attemptMinisigDownload(tarURL string, client *http.Client) 
(minisign.Signature, error) {
+       minisigResp, err := attemptDownload(tarURL+".minisig", client)
        if err != nil {
                return minisign.Signature{}, err
        }
@@ -328,13 +349,29 @@
 }
 
 // attemptDownload creates a generic http request for ZVM.
-func attemptDownload(url string) (*http.Response, error) {
+func attemptDownload(url string, client *http.Client) (*http.Response, error) {
        req, err := createDownloadReq(url)
        if err != nil {
                return nil, fmt.Errorf("%w: %w", ErrDownloadFail, err)
        }
 
-       client := http.DefaultClient
+       if client == nil {
+               client = &http.Client{}
+       }
+
+       envTimeout := os.Getenv("ZVM_HTTP_TIMEOUT")
+       if envTimeout != "" {
+               timeout, err := strconv.Atoi(envTimeout)
+               if err == nil {
+                       client.Timeout = time.Duration(timeout) * time.Second
+               } else {
+                       client.Timeout = httpDefaultTimeout
+               }
+       } else {
+               client.Timeout = httpDefaultTimeout
+       }
+
+       log.Debug("using client", "timeout", client.Timeout.String())
 
        // Checks the ZVM_SKIP_TLS_VERIFY environment variable and
        // toggles verifying a secure connection.
@@ -345,10 +382,8 @@
                }
 
                log.Debug("ZVM_SKIP_TLS_VERIFY", "enabled", true)
-               client = &http.Client{
-                       Transport: &http.Transport{
-                               TLSClientConfig: 
&tls.Config{InsecureSkipVerify: true},
-                       },
+               client.Transport = &http.Transport{
+                       TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
                }
        } else {
                // Yeah, yeah. Just an easy way to do the call.
@@ -360,7 +395,8 @@
                return nil, fmt.Errorf("%w: %w", ErrDownloadFail, err)
        }
 
-       if resp.StatusCode != 200 {
+       if resp.StatusCode != http.StatusOK {
+               resp.Body.Close()
                return nil, fmt.Errorf("%w: %s", ErrDownloadFail, resp.Status)
        }
 
@@ -497,7 +533,7 @@
 
        log.Debug("tarPath", "url", tarPath)
 
-       tarResp, err := attemptDownload(tarPath)
+       tarResp, err := attemptDownload(tarPath, nil)
        if err != nil {
                return err
        }
@@ -760,7 +796,9 @@
        }
        defer file.Close()
 
-       xzReader, err := xz.NewReader(file)
+       bufferedReader := bufio.NewReaderSize(file, 256*1024)
+
+       xzReader, err := xz.NewReader(bufferedReader)
        if err != nil {
                return fmt.Errorf("failed to initalize xz reader %w", err)
        }
@@ -831,72 +869,104 @@
 
 // unzipSource extracts a .zip file to the specified destination directory.
 func unzipSource(source, destination string) error {
-       // 1. Open the zip file
+       var timer time.Time
+       if meta.Debug {
+               timer = time.Now()
+       }
+
        reader, err := zip.OpenReader(source)
        if err != nil {
                return err
        }
-
        defer reader.Close()
 
-       // 2. Get the absolute destination path
        destination, err = filepath.Abs(destination)
        if err != nil {
                return err
        }
 
-       os.MkdirAll(destination, 0755)
+       if err := os.MkdirAll(destination, 0755); err != nil {
+               return fmt.Errorf("failed to create destination directory: %w", 
err)
+       }
 
-       extractAndWriteFile := func(f *zip.File) error {
-               rc, err := f.Open()
-               if err != nil {
-                       return err
-               }
+       root, err := os.OpenRoot(destination)
+       if err != nil {
+               return fmt.Errorf("failed to open root %w", err)
+       }
+       defer root.Close()
+
+       for _, f := range reader.File {
+               name := filepath.Clean(f.Name)
+               mode := f.Mode()
+               perm := mode.Perm()
 
-               defer func() {
-                       if err := rc.Close(); err != nil {
-                               panic(err)
+               if mode.IsDir() {
+                       if perm == 0 {
+                               perm = 0755
                        }
-               }()
 
-               path := filepath.Join(destination, f.Name)
-               // TODO look into how to make this more efficient and to trim 
excess calls.
-               root, err := os.OpenRoot(path)
-               if err != nil {
-                       return fmt.Errorf("failed to open root %w", err)
+                       if err := root.MkdirAll(name, perm); err != nil {
+                               return fmt.Errorf("failed to create directory 
%q: %w", f.Name, err)
+                       }
+                       continue
                }
 
-               if f.FileInfo().IsDir() {
-                       root.MkdirAll(path, f.Mode())
-               } else {
-                       root.MkdirAll(filepath.Dir(path), f.Mode())
-                       f, err := root.OpenFile(path, 
os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
+               if err := root.MkdirAll(filepath.Dir(name), 0755); err != nil {
+                       return fmt.Errorf("failed to create parent directory 
for %q: %w", f.Name, err)
+               }
+
+               if mode&os.ModeSymlink != 0 {
+                       src, err := f.Open()
                        if err != nil {
-                               return fmt.Errorf("failed to open file %w", err)
+                               return fmt.Errorf("failed to open symlink %q: 
%w", f.Name, err)
                        }
 
-                       defer func() {
-                               if err := f.Close(); err != nil {
-                                       panic(err)
-                               }
-                       }()
+                       targetBytes, readErr := io.ReadAll(src)
+                       closeErr := src.Close()
+                       if readErr != nil {
+                               return fmt.Errorf("failed to read symlink %q: 
%w", f.Name, readErr)
+                       }
+                       if closeErr != nil {
+                               return fmt.Errorf("failed to close symlink %q: 
%w", f.Name, closeErr)
+                       }
 
-                       _, err = io.Copy(f, rc)
-                       if err != nil {
-                               return fmt.Errorf("failed to copy zip archive 
%w", err)
+                       if err := root.Symlink(string(targetBytes), name); err 
!= nil {
+                               return fmt.Errorf("failed to create symlink %q: 
%w", f.Name, err)
                        }
+                       continue
                }
 
-               return nil
-       }
+               if perm == 0 {
+                       perm = 0644
+               }
 
-       // 3. Iterate over zip files inside the archive and unzip each of them
-       for _, f := range reader.File {
-               err := extractAndWriteFile(f)
+               src, err := f.Open()
                if err != nil {
-                       return err
+                       return fmt.Errorf("failed to open file %q: %w", f.Name, 
err)
+               }
+
+               outFile, err := root.OpenFile(name, 
os.O_CREATE|os.O_WRONLY|os.O_TRUNC, perm)
+               if err != nil {
+                       src.Close()
+                       return fmt.Errorf("failed to create file %q: %w", 
f.Name, err)
                }
 
+               _, copyErr := io.Copy(outFile, src)
+               closeOutErr := outFile.Close()
+               closeSrcErr := src.Close()
+               if copyErr != nil {
+                       return fmt.Errorf("failed to write file %q: %w", 
f.Name, copyErr)
+               }
+               if closeOutErr != nil {
+                       return fmt.Errorf("failed to close file %q: %w", 
f.Name, closeOutErr)
+               }
+               if closeSrcErr != nil {
+                       return fmt.Errorf("failed to close zip entry %q: %w", 
f.Name, closeSrcErr)
+               }
+       }
+
+       if meta.Debug {
+               log.Debug("unzipSource", "duration", time.Since(timer))
        }
 
        return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/cli/meta/version.go 
new/zvm-0.8.27/cli/meta/version.go
--- old/zvm-0.8.22/cli/meta/version.go  2026-05-24 15:55:19.000000000 +0200
+++ new/zvm-0.8.27/cli/meta/version.go  2026-06-09 20:25:04.000000000 +0200
@@ -10,7 +10,7 @@
 )
 
 const (
-       VERSION = "v0.8.22"
+       VERSION = "v0.8.25"
 
        // VERSION = "v0.0.0" // For testing zvm upgrade
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/zvm-0.8.22/main.go new/zvm-0.8.27/main.go
--- old/zvm-0.8.22/main.go      2026-05-24 15:55:19.000000000 +0200
+++ new/zvm-0.8.27/main.go      2026-06-09 20:25:04.000000000 +0200
@@ -9,6 +9,7 @@
        "errors"
        "fmt"
        "os"
+       "strconv"
        "strings"
        "time"
 
@@ -101,6 +102,11 @@
                                        Usage:   "override the target 
architecture (e.g., x86_64, aarch64, arm, riscv64)",
                                        Sources: 
opts.EnvVars("ZVM_TARGET_ARCH"),
                                },
+                               &opts.IntFlag{
+                                       Name:    "http.timeout",
+                                       Usage:   "set a custom timeout for http 
requests",
+                                       Sources: 
opts.EnvVars("ZVM_HTTP_TIMEOUT"),
+                               },
                        },
                        Description: "To install the latest version, use 
`master`",
                        // Args:        true,
@@ -129,10 +135,16 @@
                                if v := cmd.String("target-os"); v != "" {
                                        os.Setenv("ZVM_TARGET_OS", v)
                                }
+
                                if v := cmd.String("target-arch"); v != "" {
                                        os.Setenv("ZVM_TARGET_ARCH", v)
                                }
 
+                               // HTTP Settings
+                               if v := cmd.Int64("http.timeout"); v != 0 {
+                                       os.Setenv("ZVM_HTTP_TIMEOUT", 
strconv.FormatInt(v, 10))
+                               }
+
                                // Install Zig
                                resolvedVersion, err := 
zvm.Install(req.Package, force, !cmd.Bool("nomirror"))
                                if err != nil {

Reply via email to