///|
async fn read_line_from_stdin() -> String? raise CliError {
try @stdio.stdin.read_until("\n") catch {
err => raise CliError("failed to read input from stdin: \{(err)}")
} noraise {
line => line
}
}
///|
fn absolute_path(path : String) -> String raise CliError {
guard !@path.Path::is_absolute(path) else {
@path.Path::normalize(path).to_string()
}
guard @env.current_dir() is Some(cwd) else {
raise CliError("cannot locate current directory")
}
@path.Path::normalize(@path.Path::join(cwd, path)).to_string()
}
///|
async fn path_exists(path : String) -> Bool raise CliError {
try @fs.exists(path) catch {
err => raise CliError("failed to check path \{path}: \{(err)}")
} noraise {
exists => exists
}
}
///|
async fn ensure_dir_recursive(path : String) -> Unit raise CliError {
guard !path.is_empty() else { () }
guard !path_exists(path) else { ensure_dir(path) }
let parent = @path.Path::dirname(path).to_string()
if !parent.is_empty() && parent != path {
ensure_dir_recursive(parent)
}
ensure_dir(path)
}
///|
async fn write_new_string_file(
path : String,
content : String,
) -> Unit raise CliError {
guard !path_exists(path) else {
raise CliError("file already exists: \{path}")
}
try @fs.write_file(path, content, create_mode=CreateNew) catch {
err => raise CliError("failed to write file \{path}: \{(err)}")
} noraise {
_ => ()
}
}
///|
async fn write_or_truncate_string_file(
path : String,
content : String,
) -> Unit raise CliError {
try @fs.write_file(path, content, create_mode=CreateOrTruncate) catch {
err => raise CliError("failed to write file \{path}: \{(err)}")
} noraise {
_ => ()
}
}
///|
fn home_dir() -> String? {
let home = @env.get_env_var("HOME")
guard home is Some(path) && !path.is_empty() else {
let userprofile = @env.get_env_var("USERPROFILE")
guard userprofile is Some(path) && !path.is_empty() else { None }
Some(path)
}
Some(path)
}
///|
async fn verify_is_directory(path : String) -> Unit raise CliError {
try @fs.kind(path) catch {
err => raise CliError("failed to inspect directory \{path}: \{err}")
} noraise {
Directory => ()
_ => raise CliError("path exists but is not a directory: \{path}")
}
}
///|
async fn ensure_dir(path : String) -> Unit raise CliError {
guard !path_exists(path) else { verify_is_directory(path) }
try @fs.mkdir(path) catch {
err => raise CliError("failed to create directory \{path}: \{(err)}")
} noraise {
_ => ()
}
}
///|
async fn ensure_existing_dir(path : String) -> Unit raise CliError {
guard path_exists(path) else {
raise CliError("directory does not exist: \{path}")
}
verify_is_directory(path)
}