Skip to content

Commit

Permalink
Handle CPS_PATH and CPS_PREFIX_PATH according to the current spec
Browse files Browse the repository at this point in the history
Where CPS_PATH behaves more like PKG_CONFIG_PATH (which is what we were
already doing, incorrectly), and CPS_PREFIX_PATH has been added, and
acts more like CMAKE_PREFIX_PATH
  • Loading branch information
dcbaker committed Jul 23, 2024
1 parent 45d9d16 commit b48ff33
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 27 deletions.
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ foreach t : [['cps integration tests', 'cps-config.toml'], ['pkg-config compatib
python_interpreter,
args: [files('tests/runner.py'), cps_config, 'tests/cases/' + t[1]],
protocol : 'tap',
env : {'CPS_PATH' : meson.current_source_dir() / 'tests' / 'cps-files' },
env : {'CPS_PREFIX_PATH' : meson.current_source_dir() / 'tests' / 'cps-files' },
)
endforeach

Expand Down
3 changes: 3 additions & 0 deletions src/cps/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace cps {
if (const char * env_c = std::getenv("CPS_PATH")) {
env.cps_path = std::string(env_c);
}
if (const char * env_c = std::getenv("CPS_PREFIX_PATH")) {
env.cps_prefix_path = std::string(env_c);
}
if (std::getenv("PKG_CONFIG_DEBUG_SPEW") || std::getenv("CPS_CONFIG_DEBUG_SPEW")) {
env.debug_spew = true;
}
Expand Down
1 change: 1 addition & 0 deletions src/cps/env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace cps {

struct Env {
std::optional<std::string> cps_path = std::nullopt;
std::optional<std::string> cps_prefix_path = std::nullopt;
bool debug_spew = false;
};

Expand Down
80 changes: 55 additions & 25 deletions src/cps/search.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
// Copyright © 2023-2024 Dylan Baker
// Copyright © 2024 Bret Brown
// Copyright © 2024 Dylan Baker

#include "cps/search.hpp"

Expand Down Expand Up @@ -71,38 +71,73 @@ namespace cps::search {
return out;
}

const std::vector<fs::path> nix{"/usr", "/usr/local"};
// TODO: const std::vector<std::string> mac{""};
// TODO: const std::vector<std::string> win{""};
fs::path libdir() {
// TODO: libdir needs to be configurable based on the personality,
// and different name schemes.
// This is complicated by the fact that different distros have
// different schemes.
return "lib";
}

fs::path datadir() {
// TODO: needs to be configurable. see libdir above.
return "share";
}

const std::vector<fs::path> nix_prefix{"/usr", "/usr/local"};
// TODO: const std::vector<std::string> mac_prefix{""};
// TODO: const std::vector<std::string> win_prefix{""};

std::vector<fs::path> cached_paths{};

const std::vector<fs::path> search_paths(Env env) {
/// @brief expands a single search prefix into a set of full paths
/// @param prefix the prefix to build from
/// @return A vector of paths to search, in order
std::vector<fs::path> expand_prefix(const fs::path & prefix) {
std::vector<fs::path> paths{};

// TODO: macOS specific paths
// TODO: Windows specific paths

// TODO: handle name-like search paths
paths.emplace_back(prefix / libdir() / "cps");
paths.emplace_back(prefix / datadir() / "cps");

return paths;
};

/// @brief Expands CPS search prefixes into concrete paths
/// @param env stored environment variables
/// @return A vector of paths to search, in order
const std::vector<fs::path> search_paths(const Env & env) {
if (!cached_paths.empty()) {
return cached_paths;
}

if (env.cps_path) {
cached_paths.reserve(nix.size());
cached_paths.insert(cached_paths.end(), nix.begin(), nix.end());
auto && paths = utils::split(env.cps_path.value());
cached_paths.reserve(paths.size());
cached_paths.insert(cached_paths.end(), paths.begin(), paths.end());
}

if (env.cps_prefix_path) {
auto && prefixes = utils::split(env.cps_prefix_path.value());
for (auto && p : prefixes) {
auto && paths = expand_prefix(p);
cached_paths.reserve(cached_paths.size() + paths.size());
cached_paths.insert(cached_paths.end(), paths.begin(), paths.end());
}
}

for (auto && p : nix_prefix) {
auto && paths = expand_prefix(p);
cached_paths.reserve(cached_paths.size() + paths.size());
cached_paths.insert(cached_paths.end(), paths.begin(), paths.end());
} else {
cached_paths = nix;
}

return cached_paths;
}

const fs::path libdir() {
// TODO: libdir needs to be configurable based on the personality,
// and different name schemes.
// This is complicated by the fact that different distros have
// different schemes.
return "lib";
}

/// @brief Find all possible paths for a given CPS name
/// @param name The name of the CPS file to find
/// @return A vector of paths which patch the given name, or an error
Expand All @@ -119,15 +154,10 @@ namespace cps::search {
// dependency?
auto && paths = search_paths(env);
std::vector<fs::path> found{};
for (auto && prefix : paths) {
// TODO: <prefix>/<libdir>/cps/<name-like>/
// TODO: <prefix>/share/cps/<name-like>/
// TODO: <prefix>/share/cps/

const fs::path dir = prefix / libdir() / "cps";
if (fs::is_directory(dir)) {
for (auto && path : paths) {
if (fs::is_directory(path)) {
// TODO: <name-like>
const fs::path file = dir / fmt::format("{}.cps", name);
const fs::path file = path / fmt::format("{}.cps", name);
if (fs::is_regular_file(file)) {
found.push_back(file);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ foreach (test_name test_case IN ZIP_LISTS test_names test_cases)
NAME ${test_name}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND
${CMAKE_COMMAND} -E env CPS_PATH=${CMAKE_CURRENT_SOURCE_DIR}/cps-files
${CMAKE_COMMAND} -E env CPS_PREFIX_PATH=${CMAKE_CURRENT_SOURCE_DIR}/cps-files
${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/runner.py
$<TARGET_FILE:cps-config> ${test_case}
)
Expand Down

0 comments on commit b48ff33

Please sign in to comment.