100 lines
4.9 KiB
C++
100 lines
4.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 folder that holds what belongs to ONE tower and is changed on it:
|
|
// config.ini, the scan grid, the camera profile XMLs
|
|
// ($XDG_CONFIG_HOME/fire_gimbal_control, else ~/.config/fire_gimbal_control).
|
|
// It is outside the deployed project folder, so a deploy or an update never
|
|
// overwrites or deletes anything in it. Empty if it cannot be determined.
|
|
std::string towerConfigDir();
|
|
|
|
// The ordered list of locations searched for a config file, given an optional
|
|
// explicit --config argument. Exposed so callers can report what was tried.
|
|
//
|
|
// --config <path> explicit
|
|
// $FGC_CONFIG the environment
|
|
// <towerConfigDir()>/config.ini the normal answer on a tower
|
|
// ./config.ini the old place, and a development checkout
|
|
// <dir of the executable>/config.ini
|
|
std::vector<std::string> configSearchPaths(const std::string& cliArg = "");
|
|
|
|
// True when this is a tower (it has /etc/fire_gimbal_control/hardware.ini) and
|
|
// the config was found by searching, but outside towerConfigDir(): a tower whose
|
|
// files have not been moved yet (scripts/tower-config move).
|
|
bool configInOldPlace(const std::string& cliArg, const std::string& configPath);
|
|
|
|
// 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);
|
|
|
|
// How many <prefix>_*.log reports to keep per kind. Generous: these are a few
|
|
// hundred bytes each and written by hand-run commands, so the cap is about
|
|
// keeping the directory greppable rather than about disk.
|
|
inline constexpr int kDefaultReportsKept = 50;
|
|
|
|
// Delete all but the `keep` newest "<prefix>_*.log" in defaultLogDir().
|
|
//
|
|
// Only files this program GENERATED are eligible: the name must be exactly
|
|
// "<prefix>_YYYYMMDD-HHMMSS.log", as timestampedLogName() builds it. A
|
|
// prefix-only match would also cover `[Test] baseline_file`, which is
|
|
// configurable and may live in this directory - the pinned reference every
|
|
// self-test compares against. keep <= 0 prunes nothing.
|
|
void pruneLogFiles(const std::string& prefix, int keep);
|
|
|
|
// Write `text` to `defaultLogDir()/<name>`, creating the directory if needed.
|
|
// Returns the full path written, or "" on failure (and logs a warning).
|
|
//
|
|
// Then prunes older files of the same kind, the prefix being whatever precedes
|
|
// the first '_' in `name` - so `test_*.log`, `diag_*.log` and `pitch_setup_*.log`
|
|
// stay bounded without each caller having to remember. Pass keep = 0 to opt out.
|
|
std::string writeLogFile(const std::string& name, const std::string& text,
|
|
int keep = kDefaultReportsKept);
|
|
|
|
} // namespace fgc::paths
|