1use eyre::{Context, bail, eyre};
12use std::{
13 env::consts::{DLL_PREFIX, DLL_SUFFIX},
14 path::Path,
15};
16
17pub use dora_message::{config, uhlc};
18
19#[cfg(feature = "build")]
20pub mod build;
21pub mod descriptor;
22pub mod manifest;
23pub mod topics;
24pub mod types;
25
26pub fn adjust_shared_library_path(path: &Path) -> Result<std::path::PathBuf, eyre::ErrReport> {
48 let file_name = path
49 .file_name()
50 .ok_or_else(|| eyre!("shared library path has no file name"))?
51 .to_str()
52 .ok_or_else(|| eyre!("shared library file name is not valid UTF8"))?;
53 if file_name.starts_with("lib") {
54 bail!("Shared library file name must not start with `lib`, prefix is added automatically");
55 }
56 if path.extension().is_some() {
57 bail!("Shared library file name must have no extension, it is added automatically");
58 }
59
60 let library_filename = format!("{DLL_PREFIX}{file_name}{DLL_SUFFIX}");
61
62 let path = path.with_file_name(library_filename);
63 Ok(path)
64}
65
66pub fn get_python_path() -> Result<std::path::PathBuf, eyre::ErrReport> {
71 if let Ok(uv_path) = get_uv_path() {
73 let output = std::process::Command::new(&uv_path)
74 .args(["python", "find"])
75 .output();
76
77 if let Ok(output) = output
78 && output.status.success()
79 {
80 let python_path = String::from_utf8_lossy(&output.stdout).trim().to_string();
81 if !python_path.is_empty() {
82 let path = std::path::PathBuf::from(&python_path);
83 if path.exists() {
84 return Ok(path);
85 }
86 }
87 }
88 }
89
90 if let Ok(python) = which::which("python") {
92 if !is_python2(&python) {
94 return Ok(python);
95 }
96 }
97
98 which::which("python3").context(
100 "failed to find a valid Python 3 installation. Make sure that python3 is available.",
101 )
102}
103
104fn is_python2(python_path: &std::path::Path) -> bool {
105 let output = std::process::Command::new(python_path)
106 .args(["--version"])
107 .output();
108
109 match output {
110 Ok(output) => {
111 let version = if output.stdout.is_empty() {
113 String::from_utf8_lossy(&output.stderr)
114 } else {
115 String::from_utf8_lossy(&output.stdout)
116 };
117 version.starts_with("Python 2")
118 }
119 Err(_) => false,
120 }
121}
122
123pub fn get_uv_path() -> Result<std::path::PathBuf, eyre::ErrReport> {
125 which::which("uv")
126 .context("failed to find `uv`. Make sure to install it using: https://docs.astral.sh/uv/getting-started/installation/")
127}