///|
/// Filesystem path helpers and pm3 directory layout.
///
/// pm3 deliberately keeps its own, tiny path layer instead of pulling in a
/// platform path library: the daemon only ever deals with POSIX-style paths.
///|
/// Return the directory part of `path` (everything before the last `/`).
/// Returns `"."` when there is no separator.
pub fn path_dirname(path : String) -> String {
let view = path.view()
match view.rev_find("/") {
Some(index) =>
if index == 0 {
"/"
} else {
view.view(start_offset=0, end_offset=index).to_owned()
}
None => "."
}
}
///|
/// Return the final component of `path`.
pub fn path_basename(path : String) -> String {
let view = path.view()
match view.rev_find("/") {
Some(index) =>
view.view(start_offset=index + 1, end_offset=view.length()).to_owned()
None => path
}
}
///|
/// Join two path segments with a single `/`.
pub fn path_join(left : String, right : String) -> String {
if left.length() == 0 {
return right
}
if left.view().has_suffix("/") {
"\{left}\{right}"
} else {
"\{left}/\{right}"
}
}
///|
/// Remove a trailing `suffix` from `name`, if present.
pub fn strip_suffix_owned(name : String, suffix : String) -> String {
match name.view().strip_suffix(suffix) {
Some(view) => view.to_owned()
None => name
}
}
///|
/// The pm3 home directory. Honours `PM3_HOME`, otherwise `$HOME/.pm3`.
pub fn pm3_home() -> String {
match @env.get_env_var("PM3_HOME") {
Some(p) if p.length() > 0 => p
_ => {
let home = match @env.get_env_var("HOME") {
Some(h) if h.length() > 0 => h
_ => "/tmp"
}
path_join(home, ".pm3")
}
}
}
///|
/// Directory holding the daemon's own state (dump, port, config).
pub fn pm3_state_dir() -> String {
pm3_home()
}
///|
/// Directory holding application log files.
pub fn pm3_log_dir() -> String {
path_join(pm3_home(), "logs")
}
///|
/// Path of the serialized process list.
pub fn pm3_dump_path() -> String {
path_join(pm3_home(), "dump.json")
}
///|
/// Path of the persisted log-rotation configuration.
///
/// `logrotate.json` is the historical name and is still read, but new installs
/// are steered at `config.toml` / `config.json`, which can hold more than the
/// rotation policy.
pub fn pm3_logrotate_config_path() -> String {
path_join(pm3_home(), "logrotate.json")
}
///|
/// Path of the TOML configuration file.
pub fn pm3_config_toml_path() -> String {
path_join(pm3_home(), "config.toml")
}
///|
/// Path of the JSON configuration file.
pub fn pm3_config_json_path() -> String {
path_join(pm3_home(), "config.json")
}
///|
/// Configuration files pm3 looks for, in order of precedence. Only TOML and
/// JSON are supported; the last entry is the pre-`config.*` name.
pub fn pm3_config_candidates() -> Array[String] {
[pm3_config_toml_path(), pm3_config_json_path(), pm3_logrotate_config_path()]
}
///|
/// Path of the file that publishes the daemon's TCP port.
pub fn pm3_port_path() -> String {
path_join(pm3_home(), "daemon.port")
}
///|
/// Path of the file that publishes the daemon's process id.
pub fn pm3_pid_path() -> String {
path_join(pm3_home(), "daemon.pid")
}
///|
/// Path of the daemon's own stdout/stderr log.
pub fn pm3_daemon_log_path() -> String {
path_join(pm3_home(), "pm3.log")
}