Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions pkg/tools/base_tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,7 @@ func (b *BaseTool) CreateInstallDir(version, distribution string) (string, error
// Download performs a robust download with checksum verification
func (b *BaseTool) Download(url, version string, cfg config.ToolConfig) (string, error) {
// Always determine file extension from the download URL
fileExtension := ExtTarGz // fallback
if strings.HasSuffix(url, ExtZip) {
fileExtension = ExtZip
} else if strings.HasSuffix(url, ExtTarXz) {
fileExtension = ExtTarXz
} else if strings.HasSuffix(url, ExtTarGz) {
fileExtension = ExtTarGz
}
fileExtension := detectFileExtensionFromURL(url)

// Create temporary file for download
tmpFile, err := os.CreateTemp("", fmt.Sprintf("%s-*%s", b.toolName, fileExtension))
Expand Down Expand Up @@ -554,6 +547,49 @@ func (b *BaseTool) StandardVerify(version string, cfg config.ToolConfig, getPath
return nil
}

// detectFileExtensionFromURL detects the correct file extension from a download URL
// This handles both direct URLs and redirect URLs (like Java's Disco API)
func detectFileExtensionFromURL(downloadURL string) string {
// First try direct URL suffix detection
if strings.HasSuffix(downloadURL, ExtZip) {
return ExtZip
}
if strings.HasSuffix(downloadURL, ExtTarXz) {
return ExtTarXz
}
if strings.HasSuffix(downloadURL, ExtTarGz) {
return ExtTarGz
}

// For redirect URLs (like Java Disco API), try to extract filename from URL path
// Example: https://github.com/adoptium/temurin22-binaries/releases/download/jdk-22.0.2%2B9/OpenJDK22U-jdk_x64_windows_hotspot_22.0.2_9.zip
if parsed, err := url.Parse(downloadURL); err == nil {
// Extract filename from URL path
pathParts := strings.Split(parsed.Path, "/")
if len(pathParts) > 0 {
filename := pathParts[len(pathParts)-1]
// URL decode the filename in case it's encoded
if decoded, err := url.QueryUnescape(filename); err == nil {
filename = decoded
}

// Check file extension in the filename
if strings.HasSuffix(strings.ToLower(filename), ".zip") {
return ExtZip
}
if strings.HasSuffix(strings.ToLower(filename), ".tar.xz") {
return ExtTarXz
}
if strings.HasSuffix(strings.ToLower(filename), ".tar.gz") || strings.HasSuffix(strings.ToLower(filename), ".tgz") {
return ExtTarGz
}
}
}

// Default fallback
return ExtTarGz
}

// StandardVerifyWithConfig provides standard verification using VerificationConfig
func (b *BaseTool) StandardVerifyWithConfig(version string, cfg config.ToolConfig, verifyConfig VerificationConfig) error {
return b.VerifyWithConfig(version, cfg, verifyConfig)
Expand Down
22 changes: 12 additions & 10 deletions pkg/tools/url_extension_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tools

import (
"strings"
"testing"
)

Expand Down Expand Up @@ -39,19 +38,22 @@ func TestURLExtensionDetection(t *testing.T) {
downloadURL: "https://example.com/tool-1.0.0.tar.xz",
expectedExt: ".tar.xz",
},
{
name: "Java Windows ZIP (GitHub redirect)",
downloadURL: "https://github.com/adoptium/temurin22-binaries/releases/download/jdk-22.0.2%2B9/OpenJDK22U-jdk_x64_windows_hotspot_22.0.2_9.zip",
expectedExt: ".zip",
},
{
name: "Java Linux tar.gz (GitHub redirect)",
downloadURL: "https://github.com/adoptium/temurin22-binaries/releases/download/jdk-22.0.2%2B9/OpenJDK22U-jdk_x64_linux_hotspot_22.0.2_9.tar.gz",
expectedExt: ".tar.gz",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Simulate what happens in Download method - always detect from URL
fileExtension := ExtTarGz // fallback
if strings.HasSuffix(tc.downloadURL, ExtZip) {
fileExtension = ExtZip
} else if strings.HasSuffix(tc.downloadURL, ExtTarXz) {
fileExtension = ExtTarXz
} else if strings.HasSuffix(tc.downloadURL, ExtTarGz) {
fileExtension = ExtTarGz
}
// Use the actual detection function from Download method
fileExtension := detectFileExtensionFromURL(tc.downloadURL)

if fileExtension != tc.expectedExt {
t.Errorf("Expected extension %s for URL %s, got %s", tc.expectedExt, tc.downloadURL, fileExtension)
Expand Down