package template import ( "bytes" "errors" "fmt" "io/fs" "os" "path/filepath" "strings" "text/template" helperpkg "git.buran.team/main/cbc/helper" ) var ErrDockerfileNotExists = errors.New("dockerfile not exists") type Files map[string]string type Values map[string]any func Copy(path string, files Files, values Values) (string, error) { // Create temporary directoy sourceDirectory := helperpkg.PathNormalize(path) targetDirectory, err := os.MkdirTemp("/tmp", "cbc-*") if err != nil { return "", fmt.Errorf("can't create directory: %w", err) } // Template dockerfile sourceDockerfilePath := filepath.Join(sourceDirectory, "Dockerfile") targetDockerfilePath := filepath.Join(targetDirectory, "Dockerfile") if !fileExists(sourceDockerfilePath) { return "", ErrDockerfileNotExists } err = fileTemplate(sourceDockerfilePath, targetDockerfilePath, values) if err != nil { return "", fmt.Errorf("can't template file: %w", err) } // Template content sourceCodeDirectory := filepath.Join(sourceDirectory, "content") filepath.WalkDir( sourceCodeDirectory, func(path string, entry fs.DirEntry, err error) error { if !entry.Type().IsRegular() { return nil } err = fileTemplate( path, filepath.Join( targetDirectory, strings.Replace(path, sourceCodeDirectory, "", 1), ), values, ) if err != nil { return fmt.Errorf("can't template file: %w", err) } return nil }, ) // Create files for filePath, fileContent := range files { err := fileCreate( filepath.Join( targetDirectory, filePath, ), []byte(fileContent), ) if err != nil { return "", fmt.Errorf("can't create file: %w", err) } } return targetDirectory, nil } func Delete(path string) error { err := os.RemoveAll(path) if err != nil { return fmt.Errorf("can't delete temporary directory: %w", err) } return nil } func fileTemplate(sourcePath string, targetPath string, values Values) error { content, err := templateRender(sourcePath, values) if err != nil { return fmt.Errorf("can't render file: %w", err) } err = fileCreate(targetPath, content) if err != nil { return fmt.Errorf("can't create file: %w", err) } return nil } func fileExists(path string) bool { _, err := os.Stat(path) if err == os.ErrNotExist { return false } return true } func fileCreate(path string, content []byte) error { directory := filepath.Dir(path) err := os.MkdirAll(directory, 0o700) if err != nil { return fmt.Errorf("can't create destination directory: %w", err) } err = os.WriteFile(path, content, 0o600) if err != nil { return fmt.Errorf("can't write destination file: %w", err) } return nil } func templateRender(path string, values Values) ([]byte, error) { file, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("can't read template: %w", err) } var buffer bytes.Buffer template, err := template.New("").Parse(string(file)) if err != nil { return nil, fmt.Errorf("can't create template: %w", err) } err = template.Execute(&buffer, values) if err != nil { return nil, fmt.Errorf("can't render template: %w", err) } return buffer.Bytes(), err }