obrimbasecli/essential/visible/service/helper/filesystem/filesystem.go

678 lines
16 KiB
Go

/*
|--------------------------------------------------------------------------
| Manifest
|--------------------------------------------------------------------------
|
| Name:
| - Filesystem
|
| Purpose:
| - Provide reusable, OS-agnostic filesystem operations through a unified execution interface.
|
| Guideline:
| - Use for deterministic filesystem listing, validation, creation, deletion, and permission operations.
| - Execute exactly one operation per invocation.
| - Validate configuration before execution.
| - Return structured output for all execution paths.
| - Remain independent from runtime execution layers.
|
| Example:
| - ObrimFilesystem("list", map[string]any{"strategy":"user"})
| - ObrimFilesystem("create", map[string]any{"entity":"directory","name":"example"})
|
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Credit
|--------------------------------------------------------------------------
|
| Contributor:
| - Rajon Ahmed
| - Scionite
|
|--------------------------------------------------------------------------
*/
package filesystem
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"time"
"go/module/essential/visible/service/helper/log"
"go/module/essential/visible/service/helper/status"
)
type ObrimFilesystemResult struct {
Status bool `json:"status"`
Code string `json:"code"`
Payload any `json:"payload"`
}
type obrimFilesystemEntry struct {
Name string `json:"name"`
Path string `json:"path"`
Entity string `json:"entity"`
Size int64 `json:"size"`
Modified time.Time `json:"modified"`
Created time.Time `json:"created"`
IsHidden bool `json:"hidden"`
IsSymlink bool `json:"symlink"`
Permissions string `json:"permission"`
}
var obrimFilesystemSupportedTypes = map[string]bool{
"list": true,
"check": true,
"create": true,
"delete": true,
"permission": true,
}
var obrimFilesystemAllowedKeys = map[string]map[string]bool{
"list": {
"entity": true, "strategy": true, "base": true, "name": true,
"recursive": true, "include_hidden": true, "sort_by": true,
"sort_order": true, "filter_pattern": true, "follow_symlink": true,
"absolute_path": true,
},
"check": {
"entity": true, "strategy": true, "base": true, "name": true,
"readable": true, "writable": true,
},
"create": {
"entity": true, "strategy": true, "base": true, "name": true,
"hidden": true,
},
"delete": {
"entity": true, "strategy": true, "base": true, "name": true,
"recursive": true,
},
"permission": {
"entity": true, "strategy": true, "base": true, "name": true,
"mode": true, "permission": true,
},
}
// ObrimFilesystem executes a filesystem operation and returns a structured result.
func ObrimFilesystem(operationType string, config map[string]any) map[string]any {
log.ObrimLog("INIT", fmt.Sprintf("filesystem operation: %s", operationType))
if err := obrimFilesystemValidate(operationType, config); err != nil {
status.ObrimStatus("ERROR", err.Error())
log.ObrimLog("ERROR", err.Error())
return map[string]any{
"status": false,
"code": "FAILED_VALIDATION",
"payload": nil,
}
}
switch operationType {
case "list":
return obrimFilesystemList(config)
case "check":
return obrimFilesystemCheck(config)
case "create":
return obrimFilesystemCreate(config)
case "delete":
return obrimFilesystemDelete(config)
case "permission":
return obrimFilesystemPermission(config)
default:
status.ObrimStatus("ERROR", "Unsupported operation.")
return map[string]any{
"status": false,
"code": "FAILED_UNSUPPORTED_OPERATION",
"payload": nil,
}
}
}
// obrimFilesystemValidate validates operation type and configuration.
func obrimFilesystemValidate(operationType string, config map[string]any) error {
if !obrimFilesystemSupportedTypes[operationType] {
return errors.New("unsupported operation type")
}
allowed := obrimFilesystemAllowedKeys[operationType]
for key := range config {
if !allowed[key] {
return fmt.Errorf("unsupported config key: %s", key)
}
}
if operationType != "list" {
if _, exists := config["name"]; !exists {
return errors.New("name is required")
}
}
if operationType == "create" || operationType == "delete" {
entity := fmt.Sprintf("%v", config["entity"])
if entity != "file" && entity != "directory" {
return errors.New("invalid entity")
}
}
if operationType == "permission" {
mode := fmt.Sprintf("%v", config["mode"])
if mode != "read" && mode != "write" {
return errors.New("invalid permission mode")
}
if mode == "write" {
if err := obrimFilesystemPermissionValidate(config); err != nil {
return err
}
}
}
return nil
}
// obrimFilesystemResolve resolves and normalizes filesystem paths.
func obrimFilesystemResolve(config map[string]any) (string, error) {
strategy := fmt.Sprintf("%v", config["strategy"])
var base string
switch strategy {
case "", "user":
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
base = home
case "custom":
base = fmt.Sprintf("%v", config["base"])
if base == "" {
return "", errors.New("base path required")
}
default:
return "", errors.New("invalid strategy")
}
name := fmt.Sprintf("%v", config["name"])
return filepath.Clean(filepath.Join(base, name)), nil
}
// obrimFilesystemPayload builds standardized payload structures.
func obrimFilesystemPayload(data map[string]any) map[string]any {
return data
}
// obrimFilesystemEntityType determines filesystem entity type.
func obrimFilesystemEntityType(path string) string {
info, err := os.Stat(path)
if err != nil {
return "unknown"
}
if info.IsDir() {
return "directory"
}
return "file"
}
// obrimFilesystemPermissionValidate validates permission specifications.
func obrimFilesystemPermissionValidate(config map[string]any) error {
permission := fmt.Sprintf("%v", config["permission"])
if permission == "" {
return errors.New("permission is required")
}
_, err := strconv.ParseUint(permission, 8, 32)
return err
}
// obrimFilesystemList executes filesystem listing operations.
func obrimFilesystemList(config map[string]any) map[string]any {
base, err := obrimFilesystemResolve(map[string]any{
"strategy": config["strategy"],
"base": config["base"],
"name": "",
})
if err != nil {
return map[string]any{
"status": false,
"code": "FAILED_PATH_RESOLUTION",
"payload": nil,
}
}
entries, err := obrimFilesystemListTraverse(base, config)
if err != nil {
return map[string]any{
"status": false,
"code": "FAILED_LIST",
"payload": nil,
}
}
entries = obrimFilesystemListFilter(entries, config)
entries = obrimFilesystemListSort(entries, config)
status.ObrimStatus("SUCCESS", "Filesystem listing completed.")
return map[string]any{
"status": true,
"code": "SUCCESS_LIST",
"payload": obrimFilesystemPayload(map[string]any{
"entries": entries,
"total": len(entries),
"recursive": config["recursive"] == true,
"base_path": base,
}),
}
}
// obrimFilesystemListTraverse traverses filesystem entities.
func obrimFilesystemListTraverse(base string, config map[string]any) ([]obrimFilesystemEntry, error) {
recursive := config["recursive"] == true
includeHidden := config["include_hidden"] == true
followSymlink := config["follow_symlink"] == true
absolute := config["absolute_path"] == true
var entries []obrimFilesystemEntry
if recursive {
err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if path == base {
return nil
}
if !includeHidden && strings.HasPrefix(info.Name(), ".") {
if info.IsDir() {
return filepath.SkipDir
}
return nil
}
if info.Mode()&os.ModeSymlink != 0 && !followSymlink {
return nil
}
entryPath := path
if !absolute {
entryPath = info.Name()
}
entries = append(entries, obrimFilesystemEntry{
Name: info.Name(),
Path: entryPath,
Entity: obrimFilesystemEntityType(path),
Size: info.Size(),
Modified: info.ModTime(),
Created: info.ModTime(),
IsHidden: strings.HasPrefix(info.Name(), "."),
IsSymlink: info.Mode()&os.ModeSymlink != 0,
Permissions: info.Mode().Perm().String(),
})
return nil
})
return entries, err
}
list, err := os.ReadDir(base)
if err != nil {
return nil, err
}
for _, item := range list {
if !includeHidden && strings.HasPrefix(item.Name(), ".") {
continue
}
info, err := item.Info()
if err != nil {
continue
}
path := filepath.Join(base, item.Name())
entryPath := path
if !absolute {
entryPath = item.Name()
}
entries = append(entries, obrimFilesystemEntry{
Name: item.Name(),
Path: entryPath,
Entity: obrimFilesystemEntityType(path),
Size: info.Size(),
Modified: info.ModTime(),
Created: info.ModTime(),
IsHidden: strings.HasPrefix(item.Name(), "."),
IsSymlink: info.Mode()&os.ModeSymlink != 0,
Permissions: info.Mode().Perm().String(),
})
}
return entries, nil
}
// obrimFilesystemListFilter applies entity and pattern filtering.
func obrimFilesystemListFilter(entries []obrimFilesystemEntry, config map[string]any) []obrimFilesystemEntry {
entity := fmt.Sprintf("%v", config["entity"])
pattern := fmt.Sprintf("%v", config["filter_pattern"])
var filtered []obrimFilesystemEntry
for _, entry := range entries {
if entity != "" && entry.Entity != entity {
continue
}
if pattern != "" {
match, _ := filepath.Match(pattern, entry.Name)
if !match {
continue
}
}
filtered = append(filtered, entry)
}
return filtered
}
// obrimFilesystemListSort applies result sorting behavior.
func obrimFilesystemListSort(entries []obrimFilesystemEntry, config map[string]any) []obrimFilesystemEntry {
sortBy := fmt.Sprintf("%v", config["sort_by"])
order := fmt.Sprintf("%v", config["sort_order"])
sort.Slice(entries, func(i, j int) bool {
result := false
switch sortBy {
case "size":
result = entries[i].Size < entries[j].Size
case "modified":
result = entries[i].Modified.Before(entries[j].Modified)
case "created":
result = entries[i].Created.Before(entries[j].Created)
default:
result = entries[i].Name < entries[j].Name
}
if order == "desc" {
return !result
}
return result
})
return entries
}
// obrimFilesystemCheck executes filesystem validation operations.
func obrimFilesystemCheck(config map[string]any) map[string]any {
path, err := obrimFilesystemResolve(config)
if err != nil {
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
}
_, err = os.Stat(path)
exists := err == nil
readable, writable := obrimFilesystemCheckAccess(path)
return map[string]any{
"status": true,
"code": "SUCCESS_CHECK",
"payload": map[string]any{
"path": path,
"exists": exists,
"entity": obrimFilesystemEntityType(path),
"readable": readable,
"writable": writable,
},
}
}
// obrimFilesystemCheckAccess verifies filesystem accessibility.
func obrimFilesystemCheckAccess(path string) (bool, bool) {
readable := true
writable := true
file, err := os.Open(path)
if err != nil {
readable = false
} else {
_ = file.Close()
}
file, err = os.OpenFile(path, os.O_WRONLY, 0)
if err != nil {
writable = false
} else {
_ = file.Close()
}
return readable, writable
}
// obrimFilesystemCreate executes filesystem entity creation operations.
func obrimFilesystemCreate(config map[string]any) map[string]any {
path, err := obrimFilesystemResolve(config)
if err != nil {
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
}
entity := fmt.Sprintf("%v", config["entity"])
if entity == "file" {
err = obrimFilesystemCreateFile(path)
} else {
err = obrimFilesystemCreateDirectory(path)
}
if err != nil {
return map[string]any{"status": false, "code": "FAILED_CREATE", "payload": nil}
}
return map[string]any{
"status": true,
"code": "SUCCESS_CREATE",
"payload": map[string]any{
"path": path,
"entity": entity,
"hidden": config["hidden"] == true,
"created": true,
},
}
}
// obrimFilesystemCreateFile creates a filesystem file.
func obrimFilesystemCreateFile(path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
return err
}
file, err := os.Create(path)
if err != nil {
return err
}
return file.Close()
}
// obrimFilesystemCreateDirectory creates a filesystem directory.
func obrimFilesystemCreateDirectory(path string) error {
return os.MkdirAll(path, 0755)
}
// obrimFilesystemDelete executes filesystem entity deletion operations.
func obrimFilesystemDelete(config map[string]any) map[string]any {
path, err := obrimFilesystemResolve(config)
if err != nil {
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
}
entity := fmt.Sprintf("%v", config["entity"])
if entity == "file" {
err = obrimFilesystemDeleteFile(path)
} else {
err = obrimFilesystemDeleteDirectory(path, config["recursive"] == true)
}
if err != nil {
return map[string]any{"status": false, "code": "FAILED_DELETE", "payload": nil}
}
return map[string]any{
"status": true,
"code": "SUCCESS_DELETE",
"payload": map[string]any{
"path": path,
"entity": entity,
"deleted": true,
},
}
}
// obrimFilesystemDeleteFile deletes a filesystem file.
func obrimFilesystemDeleteFile(path string) error {
return os.Remove(path)
}
// obrimFilesystemDeleteDirectory deletes a filesystem directory.
func obrimFilesystemDeleteDirectory(path string, recursive bool) error {
if recursive {
return os.RemoveAll(path)
}
return os.Remove(path)
}
// obrimFilesystemPermission executes filesystem permission operations.
func obrimFilesystemPermission(config map[string]any) map[string]any {
path, err := obrimFilesystemResolve(config)
if err != nil {
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
}
mode := fmt.Sprintf("%v", config["mode"])
if mode == "read" {
return obrimFilesystemPermissionRead(path)
}
return obrimFilesystemPermissionWrite(path, fmt.Sprintf("%v", config["permission"]))
}
// obrimFilesystemPermissionRead retrieves filesystem permissions.
func obrimFilesystemPermissionRead(path string) map[string]any {
info, err := os.Stat(path)
if err != nil {
return map[string]any{"status": false, "code": "FAILED_PERMISSION_READ", "payload": nil}
}
return map[string]any{
"status": true,
"code": "SUCCESS_PERMISSION_READ",
"payload": map[string]any{
"path": path,
"permission": info.Mode().Perm().String(),
"mode": "read",
"updated": false,
},
}
}
// obrimFilesystemPermissionWrite updates filesystem permissions.
func obrimFilesystemPermissionWrite(path string, permission string) map[string]any {
if runtime.GOOS == "windows" {
return map[string]any{
"status": false,
"code": "FAILED_PERMISSION_UNSUPPORTED",
"payload": nil,
}
}
value, err := strconv.ParseUint(permission, 8, 32)
if err != nil {
return map[string]any{
"status": false,
"code": "FAILED_PERMISSION_VALIDATION",
"payload": nil,
}
}
err = os.Chmod(path, os.FileMode(value))
if err != nil {
return map[string]any{
"status": false,
"code": "FAILED_PERMISSION_WRITE",
"payload": nil,
}
}
return map[string]any{
"status": true,
"code": "SUCCESS_PERMISSION_WRITE",
"payload": map[string]any{
"path": path,
"permission": permission,
"mode": "write",
"updated": true,
},
}
}