feat(files): support creating directories

This commit is contained in:
Julien Dessaux 2024-08-27 08:40:51 +02:00
parent ccec94a4dd
commit e7572a1382
Signed by: adyxax
GPG key ID: F92E51B86E07177E

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"errors" "errors"
"fmt"
"io" "io"
"io/fs" "io/fs"
"log/slog" "log/slog"
@ -17,16 +18,37 @@ func init() {
files = make([]*FilePromise, 0) files = make([]*FilePromise, 0)
} }
type FileType int
const (
FILE = iota
DIRECTORY
)
type FilePromise struct { type FilePromise struct {
chain []Promise chain []Promise
contents Value contents Value
dirPermissions *Permissions dirPermissions *Permissions
err error err error
filename Value filename Value
fileType FileType
permissions *Permissions permissions *Permissions
status Status status Status
} }
func Directory(filename any) *FilePromise {
return &FilePromise{
chain: nil,
contents: nil,
dirPermissions: nil,
err: nil,
filename: interfaceToTemplateValue(filename),
fileType: DIRECTORY,
permissions: nil,
status: PROMISED,
}
}
func File(filename any) *FilePromise { func File(filename any) *FilePromise {
return &FilePromise{ return &FilePromise{
chain: nil, chain: nil,
@ -34,6 +56,7 @@ func File(filename any) *FilePromise {
dirPermissions: nil, dirPermissions: nil,
err: nil, err: nil,
filename: interfaceToTemplateValue(filename), filename: interfaceToTemplateValue(filename),
fileType: FILE,
permissions: nil, permissions: nil,
status: PROMISED, status: PROMISED,
} }
@ -71,31 +94,38 @@ func (f *FilePromise) Promise() Promise {
func (f *FilePromise) Resolve() { func (f *FilePromise) Resolve() {
filename := f.filename.String() filename := f.filename.String()
if f.dirPermissions != nil { if f.status, f.err = makeDirectoriesHierarchy(filepath.Dir(filename), f.dirPermissions); f.err != nil {
if f.status, f.err = makeDirectoriesHierarchy(filepath.Dir(filename), f.dirPermissions); f.err != nil { return
}
switch f.fileType {
case DIRECTORY:
if f.status, f.err = makeDirectoriesHierarchy(filepath.Clean(filename), f.dirPermissions); f.err != nil {
return return
} }
} case FILE:
if f.contents != nil { if f.contents != nil {
var sumFile []byte var sumFile []byte
sumFile, f.err = sha256sumOfFile(filename) sumFile, f.err = sha256sumOfFile(filename)
if f.err != nil { if f.err != nil {
if !errors.Is(f.err, fs.ErrNotExist) { if !errors.Is(f.err, fs.ErrNotExist) {
slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err) slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
f.status = BROKEN f.status = BROKEN
return return
}
}
contents := f.contents.Bytes()
sumContents := sha256sum(contents)
if !bytes.Equal(sumFile, sumContents) {
if f.err = writeFile(filename, contents); f.err != nil {
f.status = BROKEN
slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
return
}
f.status = REPAIRED
} }
} }
contents := f.contents.Bytes() default:
sumContents := sha256sum(contents) panic(fmt.Errorf("unknown File type enum value %d", f.fileType))
if !bytes.Equal(sumFile, sumContents) {
if f.err = writeFile(filename, contents); f.err != nil {
f.status = BROKEN
slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
return
}
f.status = REPAIRED
}
} }
if f.permissions != nil { if f.permissions != nil {
var status Status var status Status