Skip to content

Commit 7f5495f

Browse files
engalarclaude
andcommitted
refactor(launcher): exclude zstd/tar from Windows build
Windows launcher downloads daemon as .exe.zip (stdlib archive/zip only). The zstd and archive/tar libraries are only needed on Linux/macOS where daemon archives are .tar.zst. Split extractTarZst into: extract_unix.go (//go:build !windows) — real implementation with zstd+tar extract_windows.go (//go:build windows) — stub that returns an error Remove github.com/klauspost/compress/zstd and archive/tar from daemon.go; they are no longer imported by the Windows build. Result: Windows launcher drops from 9.4 MB (debug) to 9.0 MB, and from 6.7 MB to 6.3 MB in release builds (-s -w -trimpath). Smaller binary = faster antivirus scanning on domain-joined Windows machines. Skip tar.zst tests on Windows (TestExtractTarZst_*, TestDownloadDaemon Version_LinuxTarZst) — Linux CI still exercises the full extraction path. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent 0a3805e commit 7f5495f

5 files changed

Lines changed: 80 additions & 40 deletions

File tree

cmd/mxcli-launcher/daemon.go

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
package main
44

55
import (
6-
"archive/tar"
76
"archive/zip"
87
"crypto/sha256"
98
"encoding/hex"
@@ -20,7 +19,6 @@ import (
2019
"strings"
2120
"time"
2221

23-
"github.com/klauspost/compress/zstd"
2422
"github.com/mendixlabs/mxcli/internal/launcherproto"
2523
)
2624

@@ -229,43 +227,6 @@ func parseChecksumFile(content, filename string) (string, error) {
229227
return "", fmt.Errorf("no checksum for %q in SHA256SUMS", filename)
230228
}
231229

232-
func extractTarZst(r io.Reader, destPath, expectedName string) error {
233-
zr, err := zstd.NewReader(r)
234-
if err != nil {
235-
return err
236-
}
237-
defer zr.Close()
238-
tr := tar.NewReader(zr)
239-
for {
240-
hdr, err := tr.Next()
241-
if err == io.EOF {
242-
break
243-
}
244-
if err != nil {
245-
return err
246-
}
247-
if hdr.Typeflag != tar.TypeReg {
248-
continue
249-
}
250-
if filepath.Base(hdr.Name) != expectedName {
251-
continue
252-
}
253-
tmp := destPath + ".tmp"
254-
f, err := os.OpenFile(tmp, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
255-
if err != nil {
256-
return err
257-
}
258-
if _, err := io.Copy(f, tr); err != nil {
259-
f.Close()
260-
os.Remove(tmp)
261-
return err
262-
}
263-
f.Close()
264-
return os.Rename(tmp, destPath)
265-
}
266-
return fmt.Errorf("no file named %q found in archive", expectedName)
267-
}
268-
269230
func extractZip(srcPath, destPath, expectedName string) error {
270231
zr, err := zip.OpenReader(srcPath)
271232
if err != nil {

cmd/mxcli-launcher/daemon_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ func makeTarZst(t *testing.T, files map[string][]byte) *bytes.Buffer {
9999
}
100100

101101
func TestExtractTarZst_CorrectFilename(t *testing.T) {
102+
if runtime.GOOS == "windows" {
103+
t.Skip("tar.zst extraction not compiled on Windows (daemon uses .exe.zip)")
104+
}
102105
archive := makeTarZst(t, map[string][]byte{"mxcli-daemon": []byte("binary-data")})
103106
dest := filepath.Join(t.TempDir(), "mxcli-daemon")
104107
if err := extractTarZst(archive, dest, "mxcli-daemon"); err != nil {
@@ -111,6 +114,9 @@ func TestExtractTarZst_CorrectFilename(t *testing.T) {
111114
}
112115

113116
func TestExtractTarZst_RejectsWrongFilename(t *testing.T) {
117+
if runtime.GOOS == "windows" {
118+
t.Skip("tar.zst extraction not compiled on Windows (daemon uses .exe.zip)")
119+
}
114120
archive := makeTarZst(t, map[string][]byte{"readme.txt": []byte("docs")})
115121
dest := filepath.Join(t.TempDir(), "mxcli-daemon")
116122
if err := extractTarZst(archive, dest, "mxcli-daemon"); err == nil {

cmd/mxcli-launcher/extract_unix.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
//go:build !windows
4+
5+
package main
6+
7+
import (
8+
"archive/tar"
9+
"fmt"
10+
"io"
11+
"os"
12+
"path/filepath"
13+
14+
"github.com/klauspost/compress/zstd"
15+
)
16+
17+
// extractTarZst extracts expectedName from a .tar.zst archive into destPath.
18+
// Used on Linux and macOS where daemon archives are compressed with zstd.
19+
func extractTarZst(r io.Reader, destPath, expectedName string) error {
20+
zr, err := zstd.NewReader(r)
21+
if err != nil {
22+
return err
23+
}
24+
defer zr.Close()
25+
tr := tar.NewReader(zr)
26+
for {
27+
hdr, err := tr.Next()
28+
if err == io.EOF {
29+
break
30+
}
31+
if err != nil {
32+
return err
33+
}
34+
if hdr.Typeflag != tar.TypeReg {
35+
continue
36+
}
37+
if filepath.Base(hdr.Name) != expectedName {
38+
continue
39+
}
40+
tmp := destPath + ".tmp"
41+
f, err := os.OpenFile(tmp, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
42+
if err != nil {
43+
return err
44+
}
45+
if _, err := io.Copy(f, tr); err != nil {
46+
f.Close()
47+
os.Remove(tmp)
48+
return err
49+
}
50+
f.Close()
51+
return os.Rename(tmp, destPath)
52+
}
53+
return fmt.Errorf("no file named %q found in archive", expectedName)
54+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
//go:build windows
4+
5+
package main
6+
7+
import (
8+
"fmt"
9+
"io"
10+
)
11+
12+
// extractTarZst is not used on Windows (daemon is distributed as .exe.zip).
13+
// This stub satisfies the compiler on Windows without importing zstd/tar.
14+
func extractTarZst(_ io.Reader, _, expectedName string) error {
15+
return fmt.Errorf("tar.zst extraction not supported on Windows (expected %q)", expectedName)
16+
}

cmd/mxcli-launcher/install_update_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,12 @@ func TestDownloadDaemonVersion_WindowsZipOnLinuxCI(t *testing.T) {
422422
}
423423

424424
func TestDownloadDaemonVersion_LinuxTarZst(t *testing.T) {
425+
if runtime.GOOS == "windows" {
426+
t.Skip("tar.zst extraction not compiled on Windows; Linux CI covers this path")
427+
}
425428
t.Parallel()
426429
// Mirrors TestDownloadDaemon_FreshInstall but explicitly targets Linux/amd64
427-
// so both Unix and Windows hosts exercise the tar.zst path.
430+
// so Unix hosts exercise the tar.zst path.
428431
e, _ := newInstallEnvForPlatform(t, &testfixtures.FakeGitHub{LatestTag: "v0.15.0"}, []byte("linux-binary"), "linux", "amd64")
429432

430433
dest := e.daemonBinaryPath()

0 commit comments

Comments
 (0)