fwt_software/include/fgc/Paths.h

63 lines
2.9 KiB
C++

#pragma once
#include <optional>
#include <string>
#include <vector>
namespace fgc::paths {
// Expand a leading "~" (to $HOME) and any "$VAR" / "${VAR}" environment
// references in `path`. Returns the expanded path (unchanged if nothing to do).
std::string expandUser(const std::string& path);
// Absolute directory containing the running executable (via /proc/self/exe).
// Returns empty string if it cannot be determined.
std::string executableDir();
// The ordered list of locations searched for a config file, given an optional
// explicit --config argument. Exposed so callers can report what was tried.
std::vector<std::string> configSearchPaths(const std::string& cliArg = "");
// Resolve the config file path using configSearchPaths(): the first existing,
// readable file wins. Returns nullopt if none is found.
std::optional<std::string> resolveConfigPath(const std::string& cliArg = "");
// The ordered list of locations searched for hardware.ini - the assembly-time
// description of THIS machine (which board, which sensors are fitted, which
// device nodes they are on). Deliberately NOT derived from the config.ini path:
//
// --hardware <path> explicit, for dev and testing
// $FGC_HARDWARE the service environment
// /etc/fire_gimbal_control/hardware.ini the normal answer on a tower
// <dir of config.ini>/hardware.ini so a dev checkout just works
//
// /etc is where credentials.env already lives: root-owned, per-device, and
// OUTSIDE the deploy tree, so an rsync cannot overwrite or delete it. Keeping the
// assembly description there makes "a deploy never touches it" a property of
// where the file is, not of an exclude rule someone has to maintain.
std::vector<std::string> hardwareSearchPaths(const std::string& cliArg = "",
const std::string& configPath = "");
// Resolve hardware.ini using hardwareSearchPaths(); first existing file wins.
// Returns nullopt when there is none - which is not an error: the program then
// falls back to reading the assembly keys from config.ini as it always has.
std::optional<std::string> resolveHardwarePath(const std::string& cliArg = "",
const std::string& configPath = "");
// Default image output directory when none is configured
// ($XDG_DATA_HOME/fire_gimbal_control/images, else ~/.local/share/...).
std::string defaultOutputDir();
// Directory for diagnostic/calibration logfiles
// ($XDG_DATA_HOME/fire_gimbal_control/logs, else ~/.local/share/...).
std::string defaultLogDir();
// "<prefix>_YYYYMMDD-HHMMSS.log" using the local clock.
std::string timestampedLogName(const std::string& prefix);
// Write `text` to `defaultLogDir()/<name>`, creating the directory if needed.
// Returns the full path written, or "" on failure (and logs a warning).
std::string writeLogFile(const std::string& name, const std::string& text);
} // namespace fgc::paths