Documentation
¶
Overview ¶
Package os provides OS helpers: file probes, safe writes, copy, line I/O, and platform/architecture detection.
Index ¶
- Constants
- func AtomicWrite(path string, data []byte, perm os.FileMode) error
- func CopyFile(src, dst string) error
- func EnsureDir(dir string, perm os.FileMode) error
- func EnsureFile(path string, perm os.FileMode) error
- func Exists(path string) (bool, error)
- func IsAndroid() bool
- func IsBSD() bool
- func IsDarwin() bool
- func IsDir(path string) (bool, error)
- func IsExecutable(path string) (bool, error)
- func IsFile(path string) (bool, error)
- func IsIOS() bool
- func IsLinux() bool
- func IsSymlink(path string) (bool, error)
- func IsUnix() bool
- func IsWasm() bool
- func IsWindows() bool
- func IsWritableDir(dir string) bool
- func ReadLines(path string) ([]string, error)
- func SameFile(a, b string) (bool, error)
- func Trash(path string) error
- func WriteLines(path string, lines []string, perm os.FileMode) error
Examples ¶
Constants ¶
const ( Arch386 = "386" ArchAMD64 = "amd64" ArchARM = "arm" ArchARM64 = "arm64" ArchLoong64 = "loong64" ArchMIPS = "mips" ArchMIPS64 = "mips64" ArchMIPS64LE = "mips64le" ArchMIPSLE = "mipsle" ArchPPC64 = "ppc64" ArchPPC64LE = "ppc64le" ArchRISCV64 = "riscv64" ArchS390X = "s390x" ArchWASM = "wasm" )
Arch constants are the recognized runtime.GOARCH values. Go exposes GOARCH only as a string, so these name the tokens to avoid scattering string literals across build-time comparisons.
const ( PlatformAIX = "aix" PlatformAndroid = "android" PlatformDarwin = "darwin" PlatformDragonfly = "dragonfly" PlatformFreeBSD = "freebsd" PlatformIllumos = "illumos" PlatformIOS = "ios" PlatformJS = "js" PlatformLinux = "linux" PlatformNetBSD = "netbsd" PlatformOpenBSD = "openbsd" PlatformPlan9 = "plan9" PlatformSolaris = "solaris" PlatformWASIP1 = "wasip1" PlatformWindows = "windows" )
Platform constants are the recognized runtime.GOOS values. Go exposes GOOS only as a string, so these name the tokens to avoid scattering string literals across build-time comparisons.
Variables ¶
This section is empty.
Functions ¶
func AtomicWrite ¶
AtomicWrite writes `data` to `path` via a temp-file-and-rename in the same directory. The temp file is removed on any failure.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "config.txt")
if err := xos.AtomicWrite(path, []byte("hello\n"), 0o600); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(path)
fmt.Printf("%s", data)
}
Output: hello
func CopyFile ¶
CopyFile copies `src` to `dst`, preserving `src`'s mode bits. `dst` is fsynced before close. When `src` and `dst` are the same file (including via hard link) CopyFile is a no-op.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
src := filepath.Join(dir, "src.txt")
dst := filepath.Join(dir, "dst.txt")
_ = os.WriteFile(src, []byte("hello\n"), 0o600)
if err := xos.CopyFile(src, dst); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(dst)
fmt.Printf("%s", data)
}
Output: hello
func EnsureDir ¶
EnsureDir creates `dir` and any missing parents, and guarantees `dir` itself has mode `perm` even if it already existed with a different mode or the umask interfered at creation time. Pre-existing parents are left untouched.
Example ¶
EnsureDir creates missing parent directories, like mkdir -p.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
nested := filepath.Join(dir, "a", "b", "c")
if err := xos.EnsureDir(nested, 0o755); err != nil {
fmt.Println(err)
return
}
isDir, _ := xos.IsDir(nested)
fmt.Println(isDir)
}
Output: true
func EnsureFile ¶
EnsureFile creates `path` as an empty file with mode `perm` if it does not exist, creating any missing parent directories. An existing file's contents, mode, and timestamps are left untouched.
Example ¶
EnsureFile creates the file and any missing parent directories.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "a", "b", "config.txt")
if err := xos.EnsureFile(path, 0o600); err != nil {
fmt.Println(err)
return
}
isFile, _ := xos.IsFile(path)
fmt.Println(isFile)
}
Output: true
func Exists ¶
Exists reports whether `path` exists.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
exists, _ := xos.Exists(path)
missing, _ := xos.Exists(filepath.Join(dir, "missing.txt"))
fmt.Println(exists)
fmt.Println(missing)
}
Output: true false
func IsAndroid ¶ added in v0.3.0
func IsAndroid() bool
IsAndroid reports whether the program is running on Android. Android is its own GOOS but is also Unix-like, so it additionally satisfies IsUnix.
func IsBSD ¶ added in v0.3.0
func IsBSD() bool
IsBSD reports whether the program is running on a BSD-family OS: FreeBSD, NetBSD, OpenBSD, or DragonFly BSD. Go has no `bsd` build constraint, so this is a fixed GOOS set. macOS is deliberately excluded even though Darwin is BSD-derived; use IsDarwin for it. Every OS reported here is also Unix-like, so it satisfies IsUnix.
func IsDarwin ¶ added in v0.3.0
func IsDarwin() bool
IsDarwin reports whether the program is running on macOS. It matches Go's `darwin` GOOS token; iOS is a separate GOOS (see IsIOS) and reports false.
func IsDir ¶
IsDir reports whether `path` is a directory.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
isDir, _ := xos.IsDir(dir)
notDir, _ := xos.IsDir(path)
fmt.Println(isDir)
fmt.Println(notDir)
}
Output: true false
func IsExecutable ¶
IsExecutable reports whether `path`, with every symlink resolved, is a regular file that the current process can run as a binary. It answers the practical question rather than merely inspecting the permission bits: on Unix via `access(2)` with `X_OK` (so the owner/group/other bit that actually applies to this process is used), and on Windows via the resolved file's extension appearing in `%PATHEXT%` (Windows has no execute bit). A non-existent path reports false; a directory is traversable, not runnable, so it also reports false.
func IsFile ¶
IsFile reports whether `path` is a regular file.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
file, _ := xos.IsFile(path)
notFile, _ := xos.IsFile(dir)
fmt.Println(file)
fmt.Println(notFile)
}
Output: true false
func IsIOS ¶ added in v0.3.0
func IsIOS() bool
IsIOS reports whether the program is running on iOS. iOS is its own GOOS - distinct from macOS (see IsDarwin) - but is also Unix-like, so it additionally satisfies IsUnix.
func IsLinux ¶ added in v0.3.0
func IsLinux() bool
IsLinux reports whether the program is running on Linux.
func IsSymlink ¶
IsSymlink reports whether `path` is a symbolic link.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
link := filepath.Join(dir, "link.txt")
_ = os.Symlink(path, link)
isLink, _ := xos.IsSymlink(link)
notLink, _ := xos.IsSymlink(path)
fmt.Println(isLink)
fmt.Println(notLink)
}
Output: true false
func IsUnix ¶ added in v0.3.0
func IsUnix() bool
IsUnix reports whether the program is running on a Unix-like OS. It mirrors Go's `unix` build constraint - which spans Linux, macOS, the BSDs, and mobile GOOSes, among others - rather than any single GOOS, so IsLinux, IsDarwin, IsAndroid, IsIOS, and IsBSD all imply IsUnix.
func IsWasm ¶ added in v0.3.0
func IsWasm() bool
IsWasm reports whether the program was compiled to WebAssembly. Unlike the OS predicates it checks the architecture (runtime.GOARCH), not the OS, since WebAssembly runs under either the `js` or `wasip1` GOOS.
func IsWindows ¶ added in v0.3.0
func IsWindows() bool
IsWindows reports whether the program is running on Windows.
func IsWritableDir ¶
IsWritableDir reports whether `dir` exists and the current process can create files in it. Uses a probe file rather than permission-bit inspection so that ACLs and immutable mounts are handled correctly.
Example ¶
A missing path is not a writable directory.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
fmt.Println(xos.IsWritableDir(dir))
fmt.Println(xos.IsWritableDir(filepath.Join(dir, "missing")))
}
Output: true false
func ReadLines ¶
ReadLines reads `path` and returns its non-empty, trimmed lines.
Example ¶
ReadLines drops blank lines and trims surrounding whitespace.
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "lines.txt")
_ = os.WriteFile(path, []byte(" alpha \n\n\tbeta\n\ngamma\n"), 0o600)
lines, _ := xos.ReadLines(path)
for _, line := range lines {
fmt.Println(line)
}
}
Output: alpha beta gamma
func SameFile ¶
SameFile reports whether `a` and `b` identify the same file. Missing leaf paths are compared after resolving their parent directories, and existing files are compared with os.SameFile to detect hard links.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "file.txt")
_ = os.WriteFile(path, []byte("hello"), 0o600)
link := filepath.Join(dir, "link.txt")
_ = os.Link(path, link)
other := filepath.Join(dir, "other.txt")
_ = os.WriteFile(other, []byte("hello"), 0o600)
same, _ := xos.SameFile(path, link)
different, _ := xos.SameFile(path, other)
fmt.Println(same)
fmt.Println(different)
}
Output: true false
func Trash ¶
Trash asks the operating system to move `path` to its trash (or recycle bin) rather than removing it permanently like os.Remove, so it can typically be recovered. The `path` is resolved to an absolute path first, so a relative path trashes the intended file regardless of the working directory.
The mechanism is platform-specific: the system trash tool on macOS (so the Finder's "Put Back" works), the FreeDesktop.org trash specification on Linux and other Unix systems, and the shell file operation that targets the Recycle Bin on Windows. Recoverability is the OS's to honor, not a guarantee: an environment with the Recycle Bin disabled, for instance, may delete outright.
Where the platform cannot trash, it returns an error wrapping errors.ErrUnsupported, so a caller can detect the case and decide what to do (e.g. fall back to os.Remove). This covers a macOS older than 15 (which lacks the system trash tool) and a Unix file with no usable same-device trash.
func WriteLines ¶
WriteLines atomically writes `lines` to `path`, one per line, with a trailing newline.
Example ¶
package main
import (
"fmt"
"os"
"path/filepath"
xos "github.com/gechr/x/os"
)
func main() {
dir, _ := os.MkdirTemp("", "example")
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "lines.txt")
if err := xos.WriteLines(path, []string{"alpha", "beta"}, 0o600); err != nil {
fmt.Println(err)
return
}
data, _ := os.ReadFile(path)
fmt.Printf("%q\n", data)
}
Output: "alpha\nbeta\n"
Types ¶
This section is empty.