Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 13 additions & 16 deletions batteries/builtins_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,38 +353,35 @@ var Builtins_encoding = map[string]*env.Builtin{
},

// Tests:
// equal { " " |is-space? } 1
// equal { "\t" |is-space? } 1
// equal { "\n" |is-space? } 1
// equal { "\r" |is-space? } 1
// equal { "a" |is-space? } 0
// equal { "A" |is-space? } 0
// equal { "1" |is-space? } 0
// equal { " " |is-space } true
// equal { "\t" |is-space } true
// equal { "\n" |is-space } true
// equal { "\r" |is-space } true
// equal { "a" |is-space } false
// equal { "A" |is-space } false
// equal { "1" |is-space } false
// Args:
// * input: string to check (should be single character)
// Returns:
// * integer 1 if character is whitespace, 0 otherwise
"is-space?": {
// * boolean true if character is whitespace, false otherwise
"is-space": {
Argsn: 1,
Doc: "Checks if a single character string is a whitespace character.",
Pure: true,
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch str := arg0.(type) {
case env.String:
if len(str.Value) == 0 {
return *env.NewInteger(0)
return *env.NewBoolean(false)
}
// Check first rune of the string
for _, r := range str.Value {
if unicode.IsSpace(r) {
return *env.NewInteger(1)
}
return *env.NewInteger(0)
return *env.NewBoolean(unicode.IsSpace(r))
}
return *env.NewInteger(0)
return *env.NewBoolean(false)
default:
ps.FailureFlag = true
return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "is-space?")
return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "is-space")
}
},
},
Expand Down
61 changes: 26 additions & 35 deletions batteries/builtins_os.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := filepath.Join(ps.WorkingPath, path.GetPath())
filePath := resolvePath(ps.WorkingPath, path.GetPath())
res := FileExists(filePath)
if res == -1 {
return evaldo.MakeBuiltinError(ps, "Error checking if path exists: "+filePath, "does-exists")
Expand Down Expand Up @@ -161,7 +161,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
newDir := filepath.Join(ps.WorkingPath, path.GetPath())
newDir := resolvePath(ps.WorkingPath, path.GetPath())
/*fmt.Println("-----------------------------")
fmt.Println(filepath.Dir(ps.WorkingPath))
fmt.Println(ps.WorkingPath)
Expand Down Expand Up @@ -206,7 +206,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := filepath.Join(ps.WorkingPath, path.GetPath())
filePath := resolvePath(ps.WorkingPath, path.GetPath())
err := os.Remove(filePath)
if err != nil {
return evaldo.MakeBuiltinError(ps, "Error removing file: "+err.Error(), "rm")
Expand All @@ -229,7 +229,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
dirPath := filepath.Join(ps.WorkingPath, path.GetPath())
dirPath := resolvePath(ps.WorkingPath, path.GetPath())
err := os.RemoveAll(dirPath)
if err != nil {
return evaldo.MakeBuiltinError(ps, "Error removing directory: "+err.Error(), "rmdir")
Expand All @@ -255,8 +255,8 @@ var Builtins_os = map[string]*env.Builtin{
case env.Uri:
switch dst := arg1.(type) {
case env.Uri:
srcPath := filepath.Join(ps.WorkingPath, src.GetPath())
dstPath := filepath.Join(ps.WorkingPath, dst.GetPath())
srcPath := resolvePath(ps.WorkingPath, src.GetPath())
dstPath := resolvePath(ps.WorkingPath, dst.GetPath())

// Read source file
data, err := os.ReadFile(srcPath)
Expand Down Expand Up @@ -296,7 +296,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := filepath.Join(ps.WorkingPath, path.GetPath())
filePath := resolvePath(ps.WorkingPath, path.GetPath())
info, err := os.Stat(filePath)
if err != nil {
return evaldo.MakeBuiltinError(ps, "Error getting file info: "+err.Error(), "file-info?")
Expand All @@ -317,51 +317,45 @@ var Builtins_os = map[string]*env.Builtin{
// Args:
// * path: uri representing the path to check
// Returns:
// * boolean: true if path is a directory, false otherwise
// * boolean: true if path is a directory, false otherwise. Fails if the path does not exist.
// Tags: #file #check
"is-dir?": {
"is-dir": {
Argsn: 1,
Doc: "Checks if a path is a directory.",
Doc: "Checks if a path is a directory. Fails if the path does not exist.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := filepath.Join(ps.WorkingPath, path.GetPath())
filePath := resolvePath(ps.WorkingPath, path.GetPath())
info, err := os.Stat(filePath)
if err != nil {
if os.IsNotExist(err) {
return *env.NewBoolean(false)
}
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-dir?")
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-dir")
}
return *env.NewBoolean(info.IsDir())
default:
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-dir?")
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-dir")
}
},
},

// Args:
// * path: uri representing the path to check
// Returns:
// * boolean: true if path is a regular file, false otherwise
// * boolean: true if path is a regular file, false otherwise. Fails if the path does not exist.
// Tags: #file #check
"is-file?": {
"is-file": {
Argsn: 1,
Doc: "Checks if a path is a regular file (not a directory).",
Doc: "Checks if a path is a regular file (not a directory). Fails if the path does not exist.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := filepath.Join(ps.WorkingPath, path.GetPath())
filePath := resolvePath(ps.WorkingPath, path.GetPath())
info, err := os.Stat(filePath)
if err != nil {
if os.IsNotExist(err) {
return *env.NewBoolean(false)
}
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-file?")
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-file")
}
return *env.NewBoolean(info.Mode().IsRegular())
default:
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-file?")
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-file")
}
},
},
Expand Down Expand Up @@ -408,7 +402,7 @@ var Builtins_os = map[string]*env.Builtin{
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch pattern := arg0.(type) {
case env.String:
patternPath := filepath.Join(ps.WorkingPath, pattern.Value)
patternPath := resolvePath(ps.WorkingPath, pattern.Value)
matches, err := filepath.Glob(patternPath)
if err != nil {
return evaldo.MakeBuiltinError(ps, "Error in glob pattern: "+err.Error(), "glob")
Expand Down Expand Up @@ -437,8 +431,8 @@ var Builtins_os = map[string]*env.Builtin{
case env.Uri:
switch dst := arg1.(type) {
case env.Uri:
oldPath := filepath.Join(ps.WorkingPath, src.GetPath())
newPath := filepath.Join(ps.WorkingPath, dst.GetPath())
oldPath := resolvePath(ps.WorkingPath, src.GetPath())
newPath := resolvePath(ps.WorkingPath, dst.GetPath())
err := os.Rename(oldPath, newPath)
if err != nil {
return evaldo.MakeBuiltinError(ps, "Error moving file: "+err.Error(), "mv")
Expand Down Expand Up @@ -776,23 +770,20 @@ var Builtins_os = map[string]*env.Builtin{
// Returns:
// * boolean: true if path is a symbolic link
// Tags: #file #check
"is-symlink?": {
"is-symlink": {
Argsn: 1,
Doc: "Checks if a path is a symbolic link.",
Doc: "Checks if a path is a symbolic link. Fails if the path does not exist.",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch path := arg0.(type) {
case env.Uri:
filePath := resolvePath(ps.WorkingPath, path.GetPath())
info, err := os.Lstat(filePath) // Use Lstat to not follow symlinks
if err != nil {
if os.IsNotExist(err) {
return *env.NewBoolean(false)
}
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-symlink?")
return evaldo.MakeBuiltinError(ps, "Error checking path: "+err.Error(), "is-symlink")
}
return *env.NewBoolean(info.Mode()&os.ModeSymlink != 0)
default:
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-symlink?")
return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "is-symlink")
}
},
},
Expand Down
1 change: 1 addition & 0 deletions internal/run_all_tests.rye
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ test-folders: {
"loops"
"recursion"
"context_advanced"
"batteries"
}

; Track results
Expand Down
10 changes: 5 additions & 5 deletions internal/unshare/02-filesystem.rye
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@
print "=== Filesystem isolation test ==="

; Check /home
either os/is-dir? %/home {
either os/does-exist %/home {
print " /home : VISIBLE (isolation NOT active or -unshare-fs=false)"
} {
print " /home : INVISIBLE (isolation OK)"
}

; Check /etc
either os/is-dir? %/etc {
either os/does-exist %/etc {
print " /etc : VISIBLE (isolation NOT active or -unshare-fs=false)"
} {
print " /etc : INVISIBLE (isolation OK)"
}

; Check /proc
either os/is-dir? %/proc {
either os/does-exist %/proc {
print " /proc : VISIBLE (isolation NOT active or -unshare-fs=false)"
} {
print " /proc : INVISIBLE (isolation OK)"
}

; CWD (.) must always be visible - our script is here
either os/is-dir? %. {
either os/does-exist %. {
print " . : VISIBLE (CWD OK)"
} {
print " . : INVISIBLE (ERROR: cannot see own directory!)"
}

; The script file itself must be readable
either os/is-file? %02-filesystem.rye {
either os/does-exist %02-filesystem.rye {
print " script : READABLE (CWD bind-mount OK)"
} {
print " script : NOT FOUND (ERROR: script file missing!)"
Expand Down
Loading