mirror of https://github.com/databricks/cli.git
102 lines
2.2 KiB
Go
102 lines
2.2 KiB
Go
|
package template
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/databricks/cli/libs/filer"
|
||
|
)
|
||
|
|
||
|
// Interface representing a file to be materialized from a template into a project
|
||
|
// instance
|
||
|
type file interface {
|
||
|
// Destination path for file. This is where the file will be created when
|
||
|
// PersistToDisk is called.
|
||
|
DstPath() *destinationPath
|
||
|
|
||
|
// Write file to disk at the destination path.
|
||
|
PersistToDisk() error
|
||
|
}
|
||
|
|
||
|
type destinationPath struct {
|
||
|
// Root path for the project instance. This path uses the system's default
|
||
|
// file separator. For example /foo/bar on Unix and C:\foo\bar on windows
|
||
|
root string
|
||
|
|
||
|
// Unix like file path relative to the "root" of the instantiated project. Is used to
|
||
|
// evaluate whether the file should be skipped by comparing it to a list of
|
||
|
// skip glob patterns.
|
||
|
relPath string
|
||
|
}
|
||
|
|
||
|
// Absolute path of the file, in the os native format. For example /foo/bar on
|
||
|
// Unix and C:\foo\bar on windows
|
||
|
func (f *destinationPath) absPath() string {
|
||
|
return filepath.Join(f.root, filepath.FromSlash(f.relPath))
|
||
|
}
|
||
|
|
||
|
type copyFile struct {
|
||
|
ctx context.Context
|
||
|
|
||
|
// Permissions bits for the destination file
|
||
|
perm fs.FileMode
|
||
|
|
||
|
dstPath *destinationPath
|
||
|
|
||
|
// Filer rooted at template root. Used to read srcPath.
|
||
|
srcFiler filer.Filer
|
||
|
|
||
|
// Relative path from template root for file to be copied.
|
||
|
srcPath string
|
||
|
}
|
||
|
|
||
|
func (f *copyFile) DstPath() *destinationPath {
|
||
|
return f.dstPath
|
||
|
}
|
||
|
|
||
|
func (f *copyFile) PersistToDisk() error {
|
||
|
path := f.DstPath().absPath()
|
||
|
err := os.MkdirAll(filepath.Dir(path), 0755)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
srcFile, err := f.srcFiler.Read(f.ctx, f.srcPath)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer srcFile.Close()
|
||
|
dstFile, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, f.perm)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer dstFile.Close()
|
||
|
_, err = io.Copy(dstFile, srcFile)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
type inMemoryFile struct {
|
||
|
dstPath *destinationPath
|
||
|
|
||
|
content []byte
|
||
|
|
||
|
// Permissions bits for the destination file
|
||
|
perm fs.FileMode
|
||
|
}
|
||
|
|
||
|
func (f *inMemoryFile) DstPath() *destinationPath {
|
||
|
return f.dstPath
|
||
|
}
|
||
|
|
||
|
func (f *inMemoryFile) PersistToDisk() error {
|
||
|
path := f.DstPath().absPath()
|
||
|
|
||
|
err := os.MkdirAll(filepath.Dir(path), 0755)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return os.WriteFile(path, f.content, f.perm)
|
||
|
}
|