From f72b53cf3b3a4defafa4b5c1d542cbee4f3b2979 Mon Sep 17 00:00:00 2001 From: Jeff Haynie Date: Thu, 22 May 2025 11:06:20 -0500 Subject: [PATCH 1/2] Quality of life Improvement: if disk requested is smaller than needed in python, will tell you and potentially adjust --- cmd/bundle.go | 1 + internal/bundler/bundler.go | 58 +++++++++++++++++++++++++++++++++++ internal/deployer/deployer.go | 21 ++++++------- 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/cmd/bundle.go b/cmd/bundle.go index f6c7da93..2e126840 100644 --- a/cmd/bundle.go +++ b/cmd/bundle.go @@ -46,6 +46,7 @@ Examples: if err := bundler.Bundle(bundler.BundleContext{ Context: ctx, Logger: projectContext.Logger, + Project: projectContext.Project, ProjectDir: projectContext.Dir, Production: production, Install: install, diff --git a/internal/bundler/bundler.go b/internal/bundler/bundler.go index cfb4a012..aac01b6d 100644 --- a/internal/bundler/bundler.go +++ b/internal/bundler/bundler.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "math" "os" "os/exec" "path/filepath" @@ -19,6 +20,7 @@ import ( "github.com/agentuity/go-common/sys" "github.com/agentuity/go-common/tui" "github.com/evanw/esbuild/pkg/api" + "k8s.io/apimachinery/pkg/api/resource" ) var Version = "dev" @@ -34,6 +36,7 @@ type AgentConfig struct { type BundleContext struct { Context context.Context Logger logger.Logger + Project *project.Project ProjectDir string Production bool Install bool @@ -42,6 +45,20 @@ type BundleContext struct { Writer io.Writer } +func dirSize(path string) (int64, error) { + var size int64 + err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + size += info.Size() + } + return nil + }) + return size, err +} + func installSourceMapSupportIfNeeded(ctx BundleContext, dir string) error { // only bun needs to install this library to aide in parsing the source maps path := filepath.Join(dir, "node_modules", "source-map-js", "package.json") @@ -248,6 +265,47 @@ func bundlePython(ctx BundleContext, dir string, outdir string, theproject *proj config["environment"] = "production" } + if !ctx.DevMode { + venv := filepath.Join(dir, ".venv") + if !util.Exists(venv) { + return fmt.Errorf("python venv not found in %s", dir) + } + size, err := dirSize(venv) + if err != nil { + return fmt.Errorf("error calculating size of .venv: %w", err) + } + diskSize := resource.NewQuantity(size, resource.DecimalSI) + val, ok := diskSize.AsInt64() + if ok { + millisValue := fmt.Sprintf("%.0fMi", math.Round(float64(val)/1000/1000)) + askSize, err := resource.ParseQuantity(ctx.Project.Deployment.Resources.Disk) + if err != nil { + return fmt.Errorf("error parsing disk requirement: %w", err) + } + askVal, ok := askSize.AsInt64() + if ok { + if askVal < val { + if tui.HasTTY { + fmt.Println(tui.Warning(fmt.Sprintf("Warning: The deployment is larger (%s) than the requested disk size for the deployment (%s).", millisValue, ctx.Project.Deployment.Resources.Disk))) + if tui.AskForConfirm("Would you like to adjust the disk requirement?", 'y') != 'y' { + fmt.Println() + return fmt.Errorf("Disk request is too small. %s required but %s requested", millisValue, ctx.Project.Deployment.Resources.Disk) + } + fmt.Println() + ctx.Project.Deployment.Resources.Disk = millisValue + if err := ctx.Project.Save(dir); err != nil { + return fmt.Errorf("error saving project: %w", err) + } + tui.ShowSuccess("Disk requirement adjusted to %s", millisValue) + } else { + fmt.Printf("The deployment is larger (%s) than the requested disk size for the deployment (%s)\n", millisValue, ctx.Project.Deployment.Resources.Disk) + os.Exit(1) + } + } + } + } + } + pyproject := filepath.Join(dir, "pyproject.toml") if sys.Exists(pyproject) { pyprojectData, err := os.ReadFile(pyproject) diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index 7040d2cf..60c69909 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -68,17 +68,16 @@ type DeployPreflightCheckData struct { } func PreflightCheck(ctx context.Context, logger logger.Logger, data DeployPreflightCheckData) error { - if data.Project.Bundler.Enabled { - started := time.Now() - if err := bundler.Bundle(bundler.BundleContext{ - Context: context.Background(), - Logger: logger, - ProjectDir: data.Dir, - Production: true, - }); err != nil { - return err - } - logger.Debug("bundled in %s", time.Since(started)) + started := time.Now() + if err := bundler.Bundle(bundler.BundleContext{ + Context: context.Background(), + Logger: logger, + ProjectDir: data.Dir, + Production: true, + Project: data.Project, + }); err != nil { + return err } + logger.Debug("bundled in %s", time.Since(started)) return nil } From 01f7b10d3cd5b8e844035f0fd90db37dc98fb6fb Mon Sep 17 00:00:00 2001 From: Jeff Haynie Date: Thu, 22 May 2025 11:14:49 -0500 Subject: [PATCH 2/2] make it work for both JS and Py --- internal/bundler/bundler.go | 88 +++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/internal/bundler/bundler.go b/internal/bundler/bundler.go index aac01b6d..d814cfd5 100644 --- a/internal/bundler/bundler.go +++ b/internal/bundler/bundler.go @@ -59,6 +59,48 @@ func dirSize(path string) (int64, error) { return size, err } +func validateDiskRequest(ctx BundleContext, dir string) error { + if !ctx.DevMode { + if !util.Exists(dir) { + return fmt.Errorf("%s not found", dir) + } + size, err := dirSize(dir) + if err != nil { + return fmt.Errorf("error calculating size of %s: %w", dir, err) + } + diskSize := resource.NewQuantity(size, resource.DecimalSI) + val, ok := diskSize.AsInt64() + if ok { + millisValue := fmt.Sprintf("%.0fMi", math.Round(float64(val)/1000/1000)) + askSize, err := resource.ParseQuantity(ctx.Project.Deployment.Resources.Disk) + if err != nil { + return fmt.Errorf("error parsing disk requirement: %w", err) + } + askVal, ok := askSize.AsInt64() + if ok { + if askVal < val { + if tui.HasTTY { + fmt.Println(tui.Warning(fmt.Sprintf("Warning: The deployment is larger (%s) than the requested disk size for the deployment (%s).", millisValue, ctx.Project.Deployment.Resources.Disk))) + if tui.AskForConfirm("Would you like to adjust the disk requirement?", 'y') != 'y' { + fmt.Println() + return fmt.Errorf("Disk request is too small. %s required but %s requested", millisValue, ctx.Project.Deployment.Resources.Disk) + } + fmt.Println() + ctx.Project.Deployment.Resources.Disk = millisValue + if err := ctx.Project.Save(ctx.ProjectDir); err != nil { + return fmt.Errorf("error saving project: %w", err) + } + tui.ShowSuccess("Disk requirement adjusted to %s", millisValue) + } else { + return fmt.Errorf("The deployment is larger (%s) than the requested disk size for the deployment (%s)", millisValue, ctx.Project.Deployment.Resources.Disk) + } + } + } + } + } + return nil +} + func installSourceMapSupportIfNeeded(ctx BundleContext, dir string) error { // only bun needs to install this library to aide in parsing the source maps path := filepath.Join(dir, "node_modules", "source-map-js", "package.json") @@ -216,6 +258,11 @@ func bundleJavascript(ctx BundleContext, dir string, outdir string, theproject * os.Exit(2) return nil // This line will never be reached due to os.Exit } + + if err := validateDiskRequest(ctx, outdir); err != nil { + return err + } + return nil } @@ -265,45 +312,8 @@ func bundlePython(ctx BundleContext, dir string, outdir string, theproject *proj config["environment"] = "production" } - if !ctx.DevMode { - venv := filepath.Join(dir, ".venv") - if !util.Exists(venv) { - return fmt.Errorf("python venv not found in %s", dir) - } - size, err := dirSize(venv) - if err != nil { - return fmt.Errorf("error calculating size of .venv: %w", err) - } - diskSize := resource.NewQuantity(size, resource.DecimalSI) - val, ok := diskSize.AsInt64() - if ok { - millisValue := fmt.Sprintf("%.0fMi", math.Round(float64(val)/1000/1000)) - askSize, err := resource.ParseQuantity(ctx.Project.Deployment.Resources.Disk) - if err != nil { - return fmt.Errorf("error parsing disk requirement: %w", err) - } - askVal, ok := askSize.AsInt64() - if ok { - if askVal < val { - if tui.HasTTY { - fmt.Println(tui.Warning(fmt.Sprintf("Warning: The deployment is larger (%s) than the requested disk size for the deployment (%s).", millisValue, ctx.Project.Deployment.Resources.Disk))) - if tui.AskForConfirm("Would you like to adjust the disk requirement?", 'y') != 'y' { - fmt.Println() - return fmt.Errorf("Disk request is too small. %s required but %s requested", millisValue, ctx.Project.Deployment.Resources.Disk) - } - fmt.Println() - ctx.Project.Deployment.Resources.Disk = millisValue - if err := ctx.Project.Save(dir); err != nil { - return fmt.Errorf("error saving project: %w", err) - } - tui.ShowSuccess("Disk requirement adjusted to %s", millisValue) - } else { - fmt.Printf("The deployment is larger (%s) than the requested disk size for the deployment (%s)\n", millisValue, ctx.Project.Deployment.Resources.Disk) - os.Exit(1) - } - } - } - } + if err := validateDiskRequest(ctx, filepath.Join(dir, ".venv")); err != nil { + return err } pyproject := filepath.Join(dir, "pyproject.toml")