diff options
Diffstat (limited to 'internal/system/mkdir.go')
| -rw-r--r-- | internal/system/mkdir.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/internal/system/mkdir.go b/internal/system/mkdir.go new file mode 100644 index 00000000..f375579c --- /dev/null +++ b/internal/system/mkdir.go @@ -0,0 +1,76 @@ +package system + +import ( + "errors" + "fmt" + "os" + + "hakurei.app/container/check" + "hakurei.app/hst" +) + +// Ensure ensures the existence of a directory. +func (sys *I) Ensure(name *check.Absolute, perm os.FileMode) *I { + sys.ops = append(sys.ops, &mkdirOp{User, name.String(), perm, false}) + return sys +} + +// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied. +func (sys *I) Ephemeral(et hst.Enablement, name *check.Absolute, perm os.FileMode) *I { + sys.ops = append(sys.ops, &mkdirOp{et, name.String(), perm, true}) + return sys +} + +// mkdirOp implements [I.Ensure] and [I.Ephemeral]. +type mkdirOp struct { + et hst.Enablement + path string + perm os.FileMode + ephemeral bool +} + +func (m *mkdirOp) Type() hst.Enablement { return m.et } + +func (m *mkdirOp) apply(sys *I) error { + sys.msg.Verbose("ensuring directory", m) + + if err := sys.mkdir(m.path, m.perm); err != nil { + if !errors.Is(err, os.ErrExist) { + return newOpError("mkdir", err, false) + } + // directory exists, ensure mode + return newOpError("mkdir", sys.chmod(m.path, m.perm), false) + } else { + return nil + } +} + +func (m *mkdirOp) revert(sys *I, ec *Criteria) error { + if !m.ephemeral { + // skip non-ephemeral dir and do not log anything + return nil + } + + if ec.hasType(m.Type()) { + sys.msg.Verbose("destroying ephemeral directory", m) + return newOpError("mkdir", sys.remove(m.path), true) + } else { + sys.msg.Verbose("skipping ephemeral directory", m) + return nil + } +} + +func (m *mkdirOp) Is(o Op) bool { + target, ok := o.(*mkdirOp) + return ok && m != nil && target != nil && *m == *target +} + +func (m *mkdirOp) Path() string { return m.path } + +func (m *mkdirOp) String() string { + t := "ensure" + if m.ephemeral { + t = TypeString(m.Type()) + } + return fmt.Sprintf("mode: %s type: %s path: %q", m.perm.String(), t, m.path) +} |
