diff --git a/.gitignore b/.gitignore index 616978e..38b3c31 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,7 @@ go.work.sum # env file .env -.idea \ No newline at end of file +.idea +duckdb +duckdb.exe + diff --git a/download/download.go b/download/download.go index 39add2b..b9c09b0 100644 --- a/download/download.go +++ b/download/download.go @@ -76,7 +76,7 @@ func Do(spec Spec) (Result, error) { return res, nil } res.Downloaded = true - path := getGithubURL(spec) + path := getZipDownloadUrl(spec) tmpFile, err := fetchZip(path) if err != nil { return res, err @@ -84,7 +84,21 @@ func Do(spec Spec) (Result, error) { defer func() { _ = os.Remove(tmpFile) }() - return res, extractOne(tmpFile, entryName) + return res, processZip(spec, entryName, tmpFile) +} + +func processZip(spec Spec, entryName string, zipFile string) error { + if spec.Version != PreviewVersion { + return extractOne(zipFile, entryName) + } + return processPreviewZip(spec, entryName, zipFile) +} + +func getZipDownloadUrl(spec Spec) string { + if spec.Version == PreviewVersion { + return getPreviewZipUrl(spec) + } + return getGithubURL(spec) } func existsAppropriate(fileName string) bool { @@ -95,16 +109,21 @@ func existsAppropriate(fileName string) bool { } func getGithubURL(spec Spec) string { - var archivePrefix string - switch spec.Type { + archivePrefix := getPrefixByType(spec.Type) + return fmt.Sprintf("%s/download/%s/%s-%s-%s.zip", duckDbReleasesRoot, spec.Version, archivePrefix, spec.OS, spec.Arch) +} + +func getPrefixByType(typ BinType) string { + var prefix string + switch typ { case BinTypeCli: - archivePrefix = "duckdb_cli" + prefix = "duckdb_cli" case BinTypeDynLib: - archivePrefix = "libduckdb" + prefix = "libduckdb" default: panic("unhandled spec type") } - return fmt.Sprintf("%s/download/%s/%s-%s-%s.zip", duckDbReleasesRoot, spec.Version, archivePrefix, spec.OS, spec.Arch) + return prefix } func normalizeSpec(spec Spec) (Spec, error) { diff --git a/download/download_test.go b/download/download_test.go index 4110612..b9084ae 100644 --- a/download/download_test.go +++ b/download/download_test.go @@ -17,6 +17,7 @@ func TestDo(t *testing.T) { "v1.3.2", "v1.4.0", "latest", + "preview", } { t.Run(version, func(t *testing.T) { for _, arch := range []string{ diff --git a/download/preview.go b/download/preview.go new file mode 100644 index 0000000..3334d39 --- /dev/null +++ b/download/preview.go @@ -0,0 +1,51 @@ +package download + +import ( + "fmt" + "os" + + "github.com/ansel1/merry/v2" +) + +const ( + PreviewVersion = "preview" +) + +func getPreviewZipUrl(spec Spec) string { + // https://artifacts.duckdb.org/latest/duckdb-binaries-osx.zip + // https://artifacts.duckdb.org/latest/duckdb-binaries-windows.zip + // https://artifacts.duckdb.org/latest/duckdb-binaries-linux-amd64.zip + archSuffix := "" + if spec.OS == "linux" { + archSuffix = "-" + spec.Arch + } + return fmt.Sprintf("https://artifacts.duckdb.org/latest/duckdb-binaries-%s%s.zip", spec.OS, archSuffix) +} + +func processPreviewZip(spec Spec, entryName string, zipFile string) error { + innerZip := getInnerZipName(spec) + err := extractOne(zipFile, innerZip) + if err != nil { + return merry.Wrap(fmt.Errorf("failed to extract inner zip '%s' from '%s': %w", innerZip, zipFile, err)) + } + defer func() { + _ = os.Remove(innerZip) + }() + err = extractOne(innerZip, entryName) + if err != nil { + return merry.Wrap(fmt.Errorf("failed to extract entry '%s' from inner zip '%s': %w", entryName, innerZip, err)) + } + return nil +} + +func getInnerZipName(spec Spec) string { + // duckdb_cli-osx-universal.zip + // libduckdb-osx-universal.zip + // duckdb_cli-windows-arm64.zip + // libduckdb-windows-amd64.zip + // duckdb_cli-linux-amd64.zip + // libduckdb-linux-amd64.zip + prefix := getPrefixByType(spec.Type) + // For osx, spec.Arch has been normalized to universal in normalizeSpec + return fmt.Sprintf("%s-%s-%s.zip", prefix, spec.OS, spec.Arch) +} diff --git a/go.mod b/go.mod index b3dd233..4877963 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.24.7 require ( github.com/ansel1/merry/v2 v2.2.1 github.com/stretchr/testify v1.8.3 + golang.org/x/mod v0.28.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/mod v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect )