export module cargoxx.resolver; import std; import cargoxx.util; import cargoxx.exec; import cargoxx.linkdb; export namespace cargoxx::resolver { // What `nix eval nixpkgs#` reports for a package: a confirmation that // the attribute exists, a best-effort version string, and the realized // nix-store path so later probes can scan its installed CMake configs. struct NixpkgsInfo { std::string attr; // the queried name, e.g. "simdjson" std::string version; // empty when the derivation has no version std::string out_path; // absolute /nix/store/... path }; // Pure parser exposed for unit testing. Accepts the raw JSON returned by // `nix eval --json --apply 'p: { ... }'` and extracts NixpkgsInfo. auto parse_nix_eval_json(std::string_view attr, std::string_view json) -> util::Result; // Runs `nix eval nixpkgs# --json --apply ...` via exec::run. Returns // `ResolutionUnknownPackage` when the attribute is missing, // `ResolutionNetworkError` on timeout or evaluator errors. auto nixpkgs_probe(const std::string& attr) -> util::Result; // One CMake config-file's IMPORTED targets together with the find_package // expression derived from its filename stem. struct NixCmakeCandidate { std::string find_package; // e.g. "fmt CONFIG REQUIRED" std::vector targets; // e.g. ["fmt::fmt"] std::filesystem::path config_file; // the *Config.cmake we scraped }; // Pure: scan a single CMake config text for `add_library(... IMPORTED)` // target names. ALIAS targets are also collected so canonical // `::` forms get picked up. auto scan_imported_targets(std::string_view config_text) -> std::vector; // Pure: turn a CMake config filename into the find_package name. // `fmtConfig.cmake` / `fmt-config.cmake` -> `fmt`. auto config_stem_to_package(std::string_view filename) -> std::string; // Walks /lib/cmake/** for *Config.cmake / *-config.cmake files. // Picks the candidate whose derived package name best matches `package_name` // (exact case-insensitive equality > prefix > first non-empty target list). // Returns ResolutionUnknownPackage when nothing usable is found. auto nix_cmake_scan(const std::filesystem::path& store_path, const std::string& package_name) -> util::Result; // Output of a conan-center-index recipe scrape. struct ConanRecipe { std::string find_package; // e.g. "fmt CONFIG REQUIRED" std::vector targets; // e.g. ["fmt::fmt"] }; // Pure: scrapes a conanfile.py text for `cmake_target_name` and // `cmake_file_name`. Handles both the modern // `cpp_info.set_property("cmake_target_name", "...")` form and the // legacy `cpp_info.names["cmake_find_package"] = "..."` form. Returns // ResolutionUnknownPackage when no recognizable recipe is found. auto parse_conanfile(std::string_view conanfile_text, const std::string& fallback_name) -> util::Result; // Fetches https://raw.githubusercontent.com/conan-io/conan-center-index/ // master/recipes//all/conanfile.py via `curl` and feeds it through // parse_conanfile. 404 → ResolutionUnknownPackage; transport errors → // ResolutionNetworkError. auto conan_probe(const std::string& name) -> util::Result; // Output of a microsoft/vcpkg port usage-file scrape. struct VcpkgRecipe { std::string find_package; // e.g. "fmt CONFIG REQUIRED" std::vector targets; // e.g. ["fmt::fmt"] }; // Pure: scrape a vcpkg port `usage` file (plain CMake) for the first // find_package(...) arguments and the targets named in the corresponding // target_link_libraries(...) call. Returns ResolutionUnknownPackage when // no find_package directive appears. auto parse_vcpkg_usage(std::string_view usage_text) -> util::Result; // Fetches https://raw.githubusercontent.com/microsoft/vcpkg/master/ports//usage // via `curl` and feeds it through parse_vcpkg_usage. 404 → // ResolutionUnknownPackage; transport errors → ResolutionNetworkError. auto vcpkg_probe(const std::string& name) -> util::Result; } // namespace cargoxx::resolver