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
51 changes: 30 additions & 21 deletions cmd/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,26 +251,35 @@ Examples:
deploymentConfig.Runtime = theproject.Bundler.Runtime
deploymentConfig.Command = append([]string{theproject.Deployment.Command}, theproject.Deployment.Args...)

if err := deployer.PreflightCheck(ctx, logger, deployer.DeployPreflightCheckData{
Dir: dir,
APIClient: client,
APIURL: apiUrl,
APIKey: token,
Envfile: envFile,
Project: theproject,
ProjectData: projectData,
Config: deploymentConfig,
OSEnvironment: loadOSEnv(),
PromptHelpers: createPromptHelper(),
}); err != nil {
errsystem.New(errsystem.ErrDeployProject, err).ShowErrorAndExit()
}

if err := deploymentConfig.Write(logger, dir); err != nil {
errsystem.New(errsystem.ErrWriteConfigurationFile, err,
errsystem.WithContextMessage("Error writing deployment config to disk")).ShowErrorAndExit()
var zipMutator util.ZipDirCallbackMutator

preflightAction := func() {
zm, err := deployer.PreflightCheck(ctx, logger, deployer.DeployPreflightCheckData{
Dir: dir,
APIClient: client,
APIURL: apiUrl,
APIKey: token,
Envfile: envFile,
Project: theproject,
ProjectData: projectData,
Config: deploymentConfig,
OSEnvironment: loadOSEnv(),
PromptHelpers: createPromptHelper(),
})
if err != nil {
errsystem.New(errsystem.ErrDeployProject, err).ShowErrorAndExit()
}

if err := deploymentConfig.Write(logger, dir); err != nil {
errsystem.New(errsystem.ErrWriteConfigurationFile, err,
errsystem.WithContextMessage("Error writing deployment config to disk")).ShowErrorAndExit()
}

zipMutator = zm
}

tui.ShowSpinner("Bundling ...", preflightAction)

var startResponse startResponse
var startRequest startRequest

Expand Down Expand Up @@ -469,15 +478,15 @@ Examples:
// zip up our directory
started := time.Now()
logger.Debug("creating a zip file of %s into %s", dir, tmpfile.Name())
if err := util.ZipDir(dir, tmpfile.Name(), func(fn string, fi os.FileInfo) bool {
if err := util.ZipDir(dir, tmpfile.Name(), util.WithMutator(zipMutator), util.WithMatcher(func(fn string, fi os.FileInfo) bool {
notok := rules.Ignore(fn, fi)
if notok {
logger.Trace("❌ %s", fn)
} else {
logger.Trace("❎ %s", fn)
}
return !notok
}); err != nil {
})); err != nil {
errsystem.New(errsystem.ErrCreateZipFile, err,
errsystem.WithContextMessage("Error zipping project")).ShowErrorAndExit()
}
Expand Down Expand Up @@ -575,7 +584,7 @@ Examples:
}
}

tui.ShowSpinner("Deploying ...", action)
tui.ShowSpinner("Uploading ...", action)

format, _ := cmd.Flags().GetString("format")
if format == "json" {
Expand Down
31 changes: 30 additions & 1 deletion internal/bundler/bundler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bundler

import (
"archive/zip"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -269,6 +270,26 @@ var (
pyProjectVersionRegex = regexp.MustCompile(`version\s+=\s+"(.*?)"`)
)

/* NOTE: leaving this here for now but we don't need it for now but this will allow you to run uv python commands with virtual env
func runUVPython(ctx BundleContext, dir string, args ...string) ([]byte, error) {
venvPath := ".venv"
// python3 -m pip install --upgrade pip
pythonPath := filepath.Join(dir, venvPath, "bin", "python3")
fmt.Println(pythonPath, strings.Join(args, " "))
cmd := exec.CommandContext(ctx.Context, pythonPath, args...)
env := os.Environ()
env = append(env, "VIRTUAL_ENV="+venvPath)
env = append(env, "PATH="+filepath.Join(venvPath, "bin")+":"+os.Getenv("PATH"))
cmd.Env = env
cmd.Dir = dir
cmd.Stdin = os.Stdin
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("failed to run uv: %w. %s", err, string(out))
}
return out, nil
}*/

func bundlePython(ctx BundleContext, dir string, outdir string, theproject *project.Project) error {

if ctx.Install || !util.Exists(filepath.Join(dir, ".venv", "lib")) {
Expand Down Expand Up @@ -347,6 +368,15 @@ func getAgents(theproject *project.Project, filename string) []AgentConfig {
return agents
}

func CreateDeploymentMutator(ctx BundleContext) util.ZipDirCallbackMutator {
return func(writer *zip.Writer) error {
// NOTE: for now we don't need to do anything here
// but this is a hook for future use where we can add files to the zip
// before it is uploaded to the cloud
return nil
}
}

func Bundle(ctx BundleContext) error {
theproject := project.NewProject()
if err := theproject.Load(ctx.ProjectDir); err != nil {
Expand All @@ -367,7 +397,6 @@ func Bundle(ctx BundleContext) error {
if err := os.MkdirAll(outdir, 0755); err != nil {
return fmt.Errorf("failed to create .agentuity directory: %w", err)
}
ctx.Logger.Debug("bundling project %s to %s", dir, outdir)
switch theproject.Bundler.Language {
case "javascript":
return bundleJavascript(ctx, dir, outdir, theproject)
Expand Down
11 changes: 6 additions & 5 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,18 @@ type DeployPreflightCheckData struct {
OSEnvironment map[string]string
}

func PreflightCheck(ctx context.Context, logger logger.Logger, data DeployPreflightCheckData) error {
func PreflightCheck(ctx context.Context, logger logger.Logger, data DeployPreflightCheckData) (util.ZipDirCallbackMutator, error) {
started := time.Now()
if err := bundler.Bundle(bundler.BundleContext{
bundleCtx := bundler.BundleContext{
Context: context.Background(),
Logger: logger,
ProjectDir: data.Dir,
Production: true,
Project: data.Project,
}); err != nil {
return err
}
if err := bundler.Bundle(bundleCtx); err != nil {
return nil, err
}
logger.Debug("bundled in %s", time.Since(started))
return nil
return bundler.CreateDeploymentMutator(bundleCtx), nil
}
47 changes: 38 additions & 9 deletions internal/util/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,31 @@ func ListDir(dir string) ([]string, error) {
// ZipDirCallbackMatcher is a function that returns true if the file should be included in the zip
type ZipDirCallbackMatcher func(fn string, fi os.FileInfo) bool

type ZipDirCallbackMutator func(writer *zip.Writer) error

type options struct {
matcher ZipDirCallbackMatcher
mutator ZipDirCallbackMutator
}

type Option func(*options)

// WithMatcher will filter the files that are added to the zip
func WithMatcher(matcher ZipDirCallbackMatcher) Option {
return func(o *options) {
o.matcher = matcher
}
}

// WithMutator will mutate the zip file after it has been created allowing you to add files to the zip
func WithMutator(mutator ZipDirCallbackMutator) Option {
return func(o *options) {
o.mutator = mutator
}
}

// ZipDir will zip up a directory into the outfilename and return an error if it fails
func ZipDir(dir string, outfilename string, opts ...ZipDirCallbackMatcher) error {
func ZipDir(dir string, outfilename string, opts ...Option) error {
zf, err := os.Create(outfilename)
if err != nil {
return fmt.Errorf("error opening: %s. %w", outfilename, err)
Expand All @@ -118,6 +141,12 @@ func ZipDir(dir string, outfilename string, opts ...ZipDirCallbackMatcher) error
if err != nil {
return fmt.Errorf("error listing files: %w", err)
}
var options options
if len(opts) > 0 {
for _, opt := range opts {
opt(&options)
}
}
for _, file := range files {
fn, err := filepath.Rel(dir, file)
if err != nil {
Expand All @@ -131,16 +160,11 @@ func ZipDir(dir string, outfilename string, opts ...ZipDirCallbackMatcher) error
if err != nil {
return fmt.Errorf("error getting file info: %s. %w", file, err)
}
var notok bool
for _, opt := range opts {
if !opt(fn, fi) {
notok = true
break
if options.matcher != nil {
if !options.matcher(fn, fi) {
continue
}
}
if notok {
continue
}
}
rf, err := os.Open(file)
if err != nil {
Expand All @@ -157,6 +181,11 @@ func ZipDir(dir string, outfilename string, opts ...ZipDirCallbackMatcher) error
}
rf.Close()
}
if options.mutator != nil {
if err := options.mutator(zw); err != nil {
return fmt.Errorf("error mutating zip: %w", err)
}
}
zw.Flush()
zw.Close()
return zf.Close()
Expand Down
Loading