common_test_util/
lib.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::path::{Path, PathBuf};
16use std::process::Command;
17use std::sync::LazyLock;
18
19pub mod flight;
20pub mod ports;
21pub mod recordbatch;
22pub mod temp_dir;
23
24// Rust is working on an env possibly named `CARGO_WORKSPACE_DIR` to find the root path to the
25// workspace, see https://github.com/rust-lang/cargo/issues/3946.
26// Until then, use this verbose way.
27static WORKSPACE_ROOT: LazyLock<PathBuf> = LazyLock::new(|| {
28    let output = Command::new(env!("CARGO"))
29        .args(["locate-project", "--workspace", "--message-format=plain"])
30        .output()
31        .unwrap()
32        .stdout;
33    let cargo_path = Path::new(std::str::from_utf8(&output).unwrap().trim());
34    cargo_path.parent().unwrap().to_path_buf()
35});
36
37/// Find the absolute path to a file or a directory in the workspace.
38/// The input `path` should be the relative path of the file or directory from workspace root.
39///
40/// For example, if the greptimedb project is placed under directory "/foo/bar/greptimedb/",
41/// and this function is invoked with path = "/src/common/test-util/src/lib.rs", you will get the
42/// absolute path to this file.
43///
44/// The return value is [PathBuf]. This is to adapt the Windows file system's style.
45/// However, the input argument is Unix style, this is to give user the most convenience.
46pub fn find_workspace_path(path: &str) -> PathBuf {
47    let mut buf = WORKSPACE_ROOT.clone();
48
49    // Manually "canonicalize" to avoid annoy Windows specific "\\?" path prefix.
50    path.split('/').for_each(|x| {
51        if x == ".." {
52            buf.pop();
53        } else if x != "." {
54            buf = buf.join(x);
55        }
56    });
57
58    buf
59}