Skip to content

Commit 1c079c3

Browse files
committed
search: implement name like searches
I think this is now implemented according to the current (what will be 0.10) spec. This is vaguely tested. This uncovers some limitations of the prefix calculation code as well
1 parent c7fc654 commit 1c079c3

6 files changed

Lines changed: 91 additions & 21 deletions

File tree

src/search.cpp

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,49 @@ namespace search {
6969
return out;
7070
}
7171

72-
const std::vector<fs::path> search_paths() {
72+
/// @brief Build a combination of all prefixes, subdirs, and name-like paths
73+
/// @param roots the prefix roots
74+
/// @param name the name of the package to find
75+
/// @return all of the search paths combined into concrete instances
76+
const std::vector<fs::path> expand_search_paths(const std::vector<fs::path> & roots, std::string_view name) {
7377
// TODO: Windows paths
7478
// TODO: MacOS paths
79+
const std::vector<fs::path> segments{platform::libdir(), "share"};
80+
std::vector<fs::path> paths;
81+
82+
for (auto && root : roots) {
83+
for (auto && segment : segments) {
84+
if (const fs::path subdir = root / segment / "cps"; fs::is_directory(subdir)) {
85+
paths.emplace_back(subdir);
86+
if (const fs::path namedir = subdir / name; fs::is_directory(namedir)) {
87+
paths.emplace_back(namedir);
88+
for (const fs::path & name_subdir : fs::directory_iterator(namedir)) {
89+
if (fs::is_directory(name_subdir)) {
90+
paths.emplace_back(name_subdir);
91+
}
92+
}
93+
}
94+
}
95+
}
96+
}
97+
98+
return paths;
99+
}
100+
101+
/// @brief create concrete search paths for a specific package
102+
/// @param name the name of the pacakge
103+
/// @return a vector of those paths
104+
const std::vector<fs::path> search_paths(std::string_view name) {
105+
106+
// Build all of the roots to search
75107
std::vector<fs::path> roots;
76108
if (const char * env_c = std::getenv("CPS_PATH")) {
77109
auto && env = utils::split(env_c);
78110
roots.insert(roots.end(), env.begin(), env.end());
79111
}
80112
roots.emplace_back("/usr");
81113

82-
std::vector<fs::path> paths;
83-
for (auto && root : roots) {
84-
paths.emplace_back(root / platform::libdir() / "cps");
85-
paths.emplace_back(root / "share/cps");
86-
}
87-
return paths;
114+
return expand_search_paths(roots, name);
88115
}
89116

90117
/// @brief Find all possible paths for a given CPS name
@@ -97,19 +124,10 @@ namespace search {
97124
}
98125

99126
// TODO: Need something like pkgconf's --personality option
100-
// TODO: we likely either need to return all possible files, or load
101-
// a file
102-
// TODO: what to do about finding multiple versions of the same
103-
// dependency?
104-
auto && paths = search_paths();
127+
auto && paths = search_paths(name);
105128
std::vector<fs::path> found{};
106129
for (auto && dir : paths) {
107-
// TODO: <prefix>/<libdir>/cps/<name-like>/
108-
// TODO: <prefix>/share/cps/<name-like>/
109-
// TODO: <prefix>/share/cps/
110-
111130
if (fs::is_directory(dir)) {
112-
// TODO: <name-like>
113131
const fs::path file = dir / fmt::format("{}.cps", name);
114132
if (fs::is_regular_file(file)) {
115133
found.push_back(file);
@@ -262,13 +280,25 @@ namespace search {
262280
}
263281
}
264282

265-
fs::path calculate_prefix(const fs::path & path) {
283+
fs::path calculate_prefix(const fs::path & path, std::string_view name) {
266284
// TODO: Windows
267-
// TODO: /cps/<name-like>
285+
// TODO: Mac
286+
268287
std::vector<std::string> split = utils::split(std::string{path}, "/");
288+
// Sometimes the split() function puts an empty string
269289
if (split.back() == "") {
270290
split.pop_back();
271291
}
292+
// If split ends in name, ex: /usr/lib/cps/name/
293+
if (split.back() == name) {
294+
split.pop_back();
295+
}
296+
// If split ends in name/*, ex: /usr/lib/cps/name/*
297+
// Then drop both the */ and the name/
298+
if (*(split.end() - 2) == name) {
299+
split.pop_back();
300+
split.pop_back();
301+
}
272302
if (split.back() == "cps") {
273303
split.pop_back();
274304
}
@@ -352,7 +382,7 @@ namespace search {
352382
// TODO: Windows…
353383
auto && split = utils::split(s, "/");
354384
if (split[0] == "@prefix@") {
355-
fs::path p = calculate_prefix(node->data.package.cps_path);
385+
fs::path p = calculate_prefix(node->data.package.cps_path, node->data.package.name);
356386
for (auto it = split.begin() + 1; it != split.end(); ++it) {
357387
p /= *it;
358388
}

tests/cases.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,19 @@
7777
expected = "-I/sentinel/err -l/sentinel/lib/libfoo.a"
7878

7979
[[case]]
80-
name = "prefix calculated"
80+
name = "prefix calculated (found in root)"
81+
cps = "cps-path-not-set-root"
82+
args = ["--cflags-only-I", "--libs-only-l"]
83+
expected = "-I{prefix}/err -l{prefix}/lib/libfoo.a"
84+
85+
[[case]]
86+
name = "prefix calculated (found in root/name)"
87+
cps = "cps-path-not-set-subdir"
88+
args = ["--cflags-only-I", "--libs-only-l"]
89+
expected = "-I{prefix}/err -l{prefix}/lib/libfoo.a"
90+
91+
[[case]]
92+
name = "prefix calculated (root/name/*/)"
8193
cps = "cps-path-not-set"
8294
args = ["--cflags-only-I", "--libs-only-l"]
8395
expected = "-I{prefix}/err -l{prefix}/lib/libfoo.a"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"Name": "cps-path-not-set-root",
3+
"Cps-Version": "0.9.0",
4+
"Version": "1.0.0",
5+
"Components": {
6+
"default": {
7+
"Type": "archive",
8+
"Includes": {"C": ["@prefix@/err"]},
9+
"Location": "@prefix@/lib/libfoo.a"
10+
}
11+
},
12+
"Default-Components": ["default"]
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"Name": "cps-path-not-set-subdir",
3+
"Cps-Version": "0.9.0",
4+
"Version": "1.0.0",
5+
"Components": {
6+
"default": {
7+
"Type": "archive",
8+
"Includes": {"C": ["@prefix@/err"]},
9+
"Location": "@prefix@/lib/libfoo.a"
10+
}
11+
},
12+
"Default-Components": ["default"]
13+
}
14+
15+

tests/cases/lib/cps/cps-path-not-set.cps renamed to tests/cases/lib/cps/cps-path-not-set/foo/cps-path-not-set.cps

File renamed without changes.

0 commit comments

Comments
 (0)