Skip to content

Commit a2d5c38

Browse files
committed
feat: Add path resolver
1 parent 85f08b5 commit a2d5c38

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

src/global.rs

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ pub use input_message::*;
1818
mod input_source;
1919
pub use input_source::*;
2020

21+
mod paths;
22+
pub use paths::*;
23+
2124
use crate::{component::ComponentName, instance::InstanceHandle, models::Config};
2225

2326
pub trait Message: Sized {

src/global/paths.rs

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
use std::{
2+
io,
3+
path::{Path, PathBuf},
4+
};
5+
6+
#[derive(Debug, Clone, Copy)]
7+
enum ResolvedPaths {
8+
Production,
9+
Development,
10+
}
11+
12+
const ROOT_MARKER: &str = "$ROOT";
13+
14+
#[derive(Clone)]
15+
pub struct Paths {
16+
mode: ResolvedPaths,
17+
root: PathBuf,
18+
}
19+
20+
impl Paths {
21+
fn find_dev_root(first_root: &Path) -> Option<PathBuf> {
22+
let bn = first_root.file_name().and_then(std::ffi::OsStr::to_str);
23+
24+
if bn == Some("release") || bn == Some("debug") {
25+
// A Rust release dir?
26+
let mut current_root = first_root.parent();
27+
while let Some(root) = current_root {
28+
if root.file_name().and_then(std::ffi::OsStr::to_str) == Some("target") {
29+
// We need the parent of this one
30+
return root.parent().map(Path::to_owned);
31+
} else {
32+
// Keep going up
33+
current_root = root.parent();
34+
}
35+
}
36+
}
37+
38+
None
39+
}
40+
41+
fn find_bin_root(first_root: &Path) -> Option<PathBuf> {
42+
let bn = first_root.file_name().and_then(std::ffi::OsStr::to_str);
43+
44+
if bn == Some("bin") {
45+
return first_root.parent().map(|path| {
46+
let mut p = path.to_owned();
47+
p.push("share");
48+
p.push("hyperion");
49+
p
50+
});
51+
}
52+
53+
None
54+
}
55+
56+
pub fn new() -> io::Result<Self> {
57+
// Try to find the current exe
58+
let proc = std::env::current_exe()?;
59+
60+
// Find the 2nd parent
61+
let first_root = proc.parent().unwrap();
62+
63+
if let Some(dev_root) = Self::find_dev_root(first_root) {
64+
debug!(path = %dev_root.display(), "found development root");
65+
66+
Ok(Self {
67+
mode: ResolvedPaths::Development,
68+
root: dev_root,
69+
})
70+
} else if let Some(bin_root) = Self::find_bin_root(first_root) {
71+
debug!(path = %bin_root.display(), "found production root");
72+
73+
Ok(Self {
74+
mode: ResolvedPaths::Production,
75+
root: bin_root,
76+
})
77+
} else {
78+
debug!(path = %first_root.display(), "no root found, using binary");
79+
80+
Ok(Self {
81+
mode: ResolvedPaths::Production,
82+
root: first_root.to_owned(),
83+
})
84+
}
85+
}
86+
87+
pub fn resolve_path(&self, p: impl Into<PathBuf>) -> PathBuf {
88+
let p: PathBuf = p.into();
89+
90+
if p.is_absolute() {
91+
// Don't transform absolute paths
92+
trace!(path = %p.display(), "left unchanged");
93+
p
94+
} else {
95+
let mut out_path = PathBuf::new();
96+
let mut components = p.components().peekable();
97+
98+
if let Some(component) = components.peek() {
99+
if component.as_os_str().to_str() == Some(ROOT_MARKER) {
100+
out_path.extend(&self.root);
101+
components.next();
102+
103+
if let ResolvedPaths::Development = self.mode {
104+
match components.peek().and_then(|cmp| cmp.as_os_str().to_str()) {
105+
Some("webconfig") => {
106+
// Webconfig mapping
107+
components.next();
108+
out_path.extend(&PathBuf::from("ext/hyperion.ng/assets/webconfig"));
109+
}
110+
_ => {
111+
// No matching mapping
112+
}
113+
}
114+
}
115+
}
116+
}
117+
118+
out_path.extend(components);
119+
120+
trace!(src = %p.display(), dst = %out_path.display(), "remapped path");
121+
out_path
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)