1use eyre::{Context, bail, eyre};
2use std::{
3 env::consts::{DLL_PREFIX, DLL_SUFFIX},
4 path::Path,
5};
6
7pub use dora_message::{config, uhlc};
8
9#[cfg(feature = "build")]
10pub mod build;
11pub mod descriptor;
12#[cfg(feature = "type-inference")]
13pub mod inference;
14pub mod manifest;
15pub mod topics;
16pub mod types;
17
18pub fn adjust_shared_library_path(path: &Path) -> Result<std::path::PathBuf, eyre::ErrReport> {
40 let file_name = path
41 .file_name()
42 .ok_or_else(|| eyre!("shared library path has no file name"))?
43 .to_str()
44 .ok_or_else(|| eyre!("shared library file name is not valid UTF8"))?;
45 if file_name.starts_with("lib") {
46 bail!("Shared library file name must not start with `lib`, prefix is added automatically");
47 }
48 if path.extension().is_some() {
49 bail!("Shared library file name must have no extension, it is added automatically");
50 }
51
52 let library_filename = format!("{DLL_PREFIX}{file_name}{DLL_SUFFIX}");
53
54 let path = path.with_file_name(library_filename);
55 Ok(path)
56}
57
58pub fn get_python_path() -> Result<std::path::PathBuf, eyre::ErrReport> {
63 if let Ok(uv_path) = get_uv_path() {
65 let output = std::process::Command::new(&uv_path)
66 .args(["python", "find"])
67 .output();
68
69 if let Ok(output) = output
70 && output.status.success()
71 {
72 let python_path = String::from_utf8_lossy(&output.stdout).trim().to_string();
73 if !python_path.is_empty() {
74 let path = std::path::PathBuf::from(&python_path);
75 if path.exists() {
76 return Ok(path);
77 }
78 }
79 }
80 }
81
82 if let Ok(python) = which::which("python") {
84 if !is_python2(&python) {
86 return Ok(python);
87 }
88 }
89
90 which::which("python3").context(
92 "failed to find a valid Python 3 installation. Make sure that python3 is available.",
93 )
94}
95
96fn is_python2(python_path: &std::path::Path) -> bool {
97 let output = std::process::Command::new(python_path)
98 .args(["--version"])
99 .output();
100
101 match output {
102 Ok(output) => {
103 let version = if output.stdout.is_empty() {
105 String::from_utf8_lossy(&output.stderr)
106 } else {
107 String::from_utf8_lossy(&output.stdout)
108 };
109 version.starts_with("Python 2")
110 }
111 Err(_) => false,
112 }
113}
114
115pub fn get_uv_path() -> Result<std::path::PathBuf, eyre::ErrReport> {
117 which::which("uv")
118 .context("failed to find `uv`. Make sure to install it using: https://docs.astral.sh/uv/getting-started/installation/")
119}