diff --git a/pkg/zeaburpack/image.go b/pkg/zeaburpack/image.go index 9e5c1691..006dda72 100644 --- a/pkg/zeaburpack/image.go +++ b/pkg/zeaburpack/image.go @@ -3,6 +3,7 @@ package zeaburpack import ( "bufio" "fmt" + "io" "math/rand" "os" "os/exec" @@ -91,6 +92,7 @@ func buildImage(opt *buildImageOptions) error { newDockerfile := strings.Join(lines, "\n") tempDir := os.TempDir() + srcDIr := opt.AbsPath buildID := strconv.Itoa(rand.Int()) err := os.MkdirAll(path.Join(tempDir, buildID), 0o755) @@ -105,12 +107,47 @@ func buildImage(opt *buildImageOptions) error { } dockerIgnore := []string{".next", "node_modules", ".zeabur"} - dockerIgnorePath := path.Join(tempDir, buildID, ".dockerignore") + dockerIgnorePath := path.Join(srcDIr, ".dockerignore") + isDockerIgnoreExists := false + // if .dockerignore exists, we need to append the content to the end of the file + if fileExists(dockerIgnorePath) { + isDockerIgnoreExists = true + err := backupFile(dockerIgnorePath, dockerIgnorePath+".bak") + if err != nil { + return fmt.Errorf("copy .dockerignore: %w", err) + } + dockerIgnoreFile, err := os.ReadFile(path.Join(srcDIr, ".dockerignore")) + if err != nil { + return fmt.Errorf("read .dockerignore: %w", err) + } + dockerIgnore = append(dockerIgnore, strings.Split(string(dockerIgnoreFile), "\n")...) + err = appendToFile(dockerIgnorePath, strings.Join(dockerIgnore, "\n")) + if err != nil { + return fmt.Errorf("append .dockerignore: %w", err) + } + } + // if .dockerignore does not exist, we need to create it err = os.WriteFile(dockerIgnorePath, []byte(strings.Join(dockerIgnore, "\n")), 0o644) if err != nil { return fmt.Errorf("write .dockerignore: %w", err) } + defer func() { + if !isDockerIgnoreExists { + // remove the .dockerignore file we created + err := os.Remove(dockerIgnorePath) + if err != nil { + println("failed to remove .dockerignore: " + err.Error()) + } + } else { + // restore the .dockerignore file + err = os.Rename(dockerIgnorePath+".bak", dockerIgnorePath) + if err != nil { + println("failed to restore .dockerignore: " + err.Error()) + } + } + }() + dockerCmd := []string{ "buildx", "build", @@ -178,3 +215,44 @@ func buildImage(opt *buildImageOptions) error { return cmd.Wait() } + +func fileExists(filename string) bool { + _, err := os.Stat(filename) + return !os.IsNotExist(err) +} + +func appendToFile(filename, content string) error { + file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer file.Close() + + _, err = file.WriteString(content) + if err != nil { + return err + } + + return nil +} + +func backupFile(sourceFile, destinationFile string) error { + source, err := os.Open(sourceFile) + if err != nil { + return err + } + defer source.Close() + + destination, err := os.Create(destinationFile) + if err != nil { + return err + } + defer destination.Close() + + _, err = io.Copy(destination, source) + if err != nil { + return err + } + + return nil +}