All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 34s
				
			Test / Hpkg (push) Successful in 4m3s
				
			Test / Sandbox (race detector) (push) Successful in 4m26s
				
			Test / Hakurei (race detector) (push) Successful in 5m19s
				
			Test / Sandbox (push) Successful in 1m28s
				
			Test / Hakurei (push) Successful in 2m16s
				
			Test / Flake checks (push) Successful in 1m37s
				
			This allows use of absolute pathname values without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			77 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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)
 | |
| }
 |