From def2dd87529e60a55c91663144faad835d0d8d58 Mon Sep 17 00:00:00 2001 From: Marc Cataford Date: Sat, 4 Nov 2023 21:54:58 -0400 Subject: [PATCH] feat: use cached archive if available, allow skip using --no-cache (#3) --- cli.go | 3 +++ install_python.go | 37 +++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/cli.go b/cli.go index 6e6e86b..f92f9d9 100644 --- a/cli.go +++ b/cli.go @@ -6,6 +6,7 @@ import ( ) type Flags struct { + NoCache bool Verbose bool } @@ -92,6 +93,8 @@ func collectFlags(args []string) Flags { if arg == "--verbose" { collected.Verbose = true + } else if arg == "--no-cache" { + collected.NoCache = true } } diff --git a/install_python.go b/install_python.go index b078553..6ea98da 100644 --- a/install_python.go +++ b/install_python.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io" "net/http" @@ -32,7 +33,7 @@ func InstallPython(args []string, flags Flags, currentState State) error { return err } - packageMetadata, dlerr := downloadSource(version, "") + packageMetadata, dlerr := downloadSource(version, flags.NoCache) if dlerr != nil { return dlerr @@ -46,32 +47,36 @@ func InstallPython(args []string, flags Flags, currentState State) error { return nil } -// Fetches the Python tarball for version from python.org -// and stores it at . -func downloadSource(version string, destination string) (PackageMetadata, error) { +// Fetches the Python tarball for version from python.org. +func downloadSource(version string, skipCache bool) (PackageMetadata, error) { archiveName := fmt.Sprintf("Python-%s.tgz", version) archivePath := GetPathFromStateDirectory(path.Join("cache", archiveName)) sourceUrl := fmt.Sprintf("%s/%s/%s", pythonReleasesBaseURL, version, archiveName) - file, _ := os.Create(archivePath) client := http.Client{} dlPrint := StartFmtGroup(fmt.Sprintf("Downloading source for Python %s", version)) - - dlPrint(fmt.Sprintf("Fetching from %s", sourceUrl)) start := time.Now() - resp, err := client.Get(sourceUrl) + _, err := os.Stat(archivePath) - if err != nil { - return PackageMetadata{}, err + if errors.Is(err, os.ErrNotExist) || skipCache { + dlPrint(fmt.Sprintf("Fetching from %s", sourceUrl)) + + resp, err := client.Get(sourceUrl) + + if err != nil { + return PackageMetadata{}, err + } + + defer resp.Body.Close() + file, _ := os.Create(archivePath) + io.Copy(file, resp.Body) + + defer file.Close() + } else { + dlPrint(fmt.Sprintf("Found in cache: %s", archivePath)) } - defer resp.Body.Close() - - io.Copy(file, resp.Body) - - defer file.Close() - dlPrint(fmt.Sprintf("✅ Done (%s)", time.Since(start))) return PackageMetadata{ArchivePath: archivePath, Version: version}, nil }