- Expressive, Platform-portable scala library.
- Simplify system administration tasks.
- no 3rd party libraries, 100% scala.
For this functionality, plus reading of .csv
, expressive Date & Time functions, and more, see Pallet instead (has 3rd party dependencies).
Write one version of code to run in Linux, Mac, or Windows posix shell environments.
JVM support for java.nio.file.Path
objects that work everywhere.
Work with Posix paths in Windows, recognized mount points in /etc/fstab
.
-
Supported Scala Versions
scala 3.x
-
Tested Target environments
Linux
Darwin/OSX
Windows
Cygwin64
Msys64
Mingw64
Git-bash
WSL Linux
To use unifile
in an SBT
project, add this dependency to build.sbt
"org.vastblue" % "unifile_3" % "0.3.1"
For scala
or scala-cli
scripts, see examples below.
Simplicity and Universal Portability:
- Script as though you're running in a Linux environment.
- extends the range of scala scripting:
- read process command lines from
/proc/$PID/cmdline
files
In Windows, requires a posix shell:
(MSYS64, CYGWIN64, or WSL
)
Example code below assumes you have a recent version of coreutils:
(e.g., ubuntu
: 8.32-4.1ubuntu1, osx
: stable 9.4)
This allows you to use #!/usr/bin/env -S scala
in script hash-bang lines.
- import
vastblue.file.Paths
instead ofjava.nio.file.Paths
Paths.get
returnsjava.nio.file.Path
objectsPaths.get("/etc/fstab").toString
==C:\msys64\etc\fstab
(for example)
Examples below illustrate some of the capabilities.
The jvm doesn't support filesystem abstractions of cygwin64
, msys64
, etc.
Most platforms other than Windows
are unix-like, but:
- differing conventions and incompatibilities:
- Linux / OSX symantics of
/usr/bin/env
, etc.
- Linux / OSX symantics of
This library provides the missing piece.
This example might surprise developers working in a Windows
posix shell, since jvm
languages normally cannot see posix file paths that aren't also legal Windows
paths.
#!/usr/bin/env -S scala -cli shebang
//> using scala "3.3.1"
//> using lib "org.vastblue::unifile::0.3.1"
import vastblue.unifile.Paths
object FstabCli {
def main(args: Array[String]): Unit = {
// `shellRoot` is the native path corresponding to "/"
// display the native path and lines.size of /etc/fstab
val p = Paths.get("/etc/fstab")
val lines = java.nio.file.Files.readAllLines(p).asScala.toSeq
printf("env: %-10s| %-22s | %d lines\n",
_uname("-o"), p.norm, lines.size)
}
}
FstabCli.main(args)
Linux Mint # env: GNU/Linux | shellRoot: / | /etc/fstab | 21 lines
Darwin # env: Darwin | shellRoot: / | /etc/fstab | 0 lines
WSL Ubuntu # env: GNU/Linux | shellRoot: / | /etc/fstab | 6 lines
Cygwin64 # env: Cygwin | shellRoot: C:/cygwin64 | C:/cygwin64/etc/fstab | 24 lines
Msys64 # env: Msys | shellRoot: C:/msys64/ | C:/msys64/etc/fstab | 22 lines
Note that on Darwin, there is no /etc/fstab
file, so the Path#lines
extension returns Nil
.
Windows
: install one of the following:Linux
: required packages:sudo apt install coreutils
Darwin/OSX
:brew install coreutils
Things that maximize the odds of your script running on another system:
- use
scala 3
- use
posix
file paths by default - in
Windows
- represent paths internally with forward slashes and avoid drive letters
- drive letter not needed for paths on the current working drive (often C:)
- to access disks other than the working drive, mount them via
/etc/fstab
vastblue.Paths.get()
is can parse bothposix
andWindows
filesystem paths
- don't assume path strings use
java.nio.File.separator
orsys.props("line.separator")
- use them to format output, as appropriate, never to parse path strings
- split strings with
"(\r)?\n"
rather thanline.separator
split("\n")
can leave carriage-return debris lines ends
- create
java.nio.file.Path
objects in either of two ways:- `vastblue.file.Paths.get("/etc/fstab")
"/etc/fstab".path // guaranteed to use
vastblue.file.Paths.get()`
- if client needs glob expression command line arguments,
val argv = prepArgs(args.toSeq)
- this avoids exposure to the
Windows
jvm glob expansion bug, and - inserts
script
path ormain
method class asargv(0)
(as in C/C++) - argv(0) script name available as input parameter affecting script behaviour
- this avoids exposure to the