You can also list your dependencies as an inline string in your CMakeLists.txt | You can also list your dependencies as an inline string in your CMakeLists.txt | ||||
instead of a separate file:: | instead of a separate file:: | ||||
pmm(DDS DEPENDS "neo-sqlite3 ^0.2.2") | |||||
pmm(DDS DEPENDS neo-sqlite3^0.2.2) | |||||
Since you'll probably want to be using ``libman.cmake`` at the same time, the | Since you'll probably want to be using ``libman.cmake`` at the same time, the | ||||
calls for ``CMakeCM`` and ``DDS`` can simply be combined. This is how our new | calls for ``CMakeCM`` and ``DDS`` can simply be combined. This is how our new | ||||
include(pmm.cmake) | include(pmm.cmake) | ||||
pmm(CMakeCM ROLLING | pmm(CMakeCM ROLLING | ||||
DDS DEPENDS "neo-sqlite3 ^0.2.2" | |||||
DDS DEPENDS neo-sqlite3^0.2.2 | |||||
) | ) | ||||
include(libman) | include(libman) |
using namespace dds; | using namespace dds; | ||||
dependency dependency::parse_depends_string(std::string_view str) { | dependency dependency::parse_depends_string(std::string_view str) { | ||||
const auto str_begin = str.data(); | |||||
auto str_iter = str_begin; | |||||
const auto str_end = str_iter + str.size(); | |||||
while (str_iter != str_end && !std::isspace(*str_iter)) { | |||||
++str_iter; | |||||
auto sep_pos = str.find_first_of("=@^~+"); | |||||
if (sep_pos == str.npos) { | |||||
throw_user_error<errc::invalid_version_range_string>("Invalid dependency string '{}'", str); | |||||
} | } | ||||
auto name = trim_view(std::string_view(str_begin, str_iter - str_begin)); | |||||
auto version_str = trim_view(std::string_view(str_iter, str_end - str_iter)); | |||||
auto name = str.substr(0, sep_pos); | |||||
if (str[sep_pos] == '@') { | |||||
++sep_pos; | |||||
} | |||||
auto range_str = str.substr(sep_pos); | |||||
try { | try { | ||||
auto rng = semver::range::parse_restricted(version_str); | |||||
auto rng = semver::range::parse_restricted(range_str); | |||||
return dependency{std::string(name), {rng.low(), rng.high()}}; | return dependency{std::string(name), {rng.low(), rng.high()}}; | ||||
} catch (const semver::invalid_range&) { | } catch (const semver::invalid_range&) { | ||||
throw_user_error<errc::invalid_version_range_string>( | throw_user_error<errc::invalid_version_range_string>( | ||||
"Invalid version range string '{}' in dependency declaration '{}'", version_str, str); | |||||
"Invalid version range string '{}' in dependency string '{}'", range_str, str); | |||||
} | } | ||||
} | } | ||||
#include <dds/deps.hpp> | |||||
#include <catch2/catch.hpp> | |||||
TEST_CASE("Parse dependency strings") { | |||||
struct case_ { | |||||
std::string depstr; | |||||
std::string name; | |||||
std::string low; | |||||
std::string high; | |||||
}; | |||||
auto cur = GENERATE(Catch::Generators::values<case_>({ | |||||
{"foo@1.2.3", "foo", "1.2.3", "1.2.4"}, | |||||
{"foo=1.2.3", "foo", "1.2.3", "1.2.4"}, | |||||
{"foo^1.2.3", "foo", "1.2.3", "2.0.0"}, | |||||
{"foo~1.2.3", "foo", "1.2.3", "1.3.0"}, | |||||
{"foo+1.2.3", "foo", "1.2.3", semver::version::max_version().to_string()}, | |||||
})); | |||||
auto dep = dds::dependency::parse_depends_string(cur.depstr); | |||||
CHECK(dep.name == cur.name); | |||||
CHECK(dep.versions.num_intervals() == 1); | |||||
auto ver_iv = *dep.versions.iter_intervals().begin(); | |||||
CHECK(ver_iv.low == semver::version::parse(cur.low)); | |||||
CHECK(ver_iv.high == semver::version::parse(cur.high)); | |||||
} |
def test_build_deps_from_cmd(dds: DDS): | def test_build_deps_from_cmd(dds: DDS): | ||||
assert not dds.deps_build_dir.is_dir() | assert not dds.deps_build_dir.is_dir() | ||||
dds.catalog_import(dds.source_root / 'catalog.json') | dds.catalog_import(dds.source_root / 'catalog.json') | ||||
dds.build_deps(['neo-sqlite3 =0.2.2']) | |||||
dds.build_deps(['neo-sqlite3=0.2.2']) | |||||
assert (dds.deps_build_dir / 'neo-sqlite3@0.2.2').is_dir() | assert (dds.deps_build_dir / 'neo-sqlite3@0.2.2').is_dir() | ||||
assert (dds.scratch_dir / 'INDEX.lmi').is_file() | assert (dds.scratch_dir / 'INDEX.lmi').is_file() | ||||
assert (dds.deps_build_dir / '_libman/neo-sqlite3.lmp').is_file() | assert (dds.deps_build_dir / '_libman/neo-sqlite3.lmp').is_file() | ||||
def test_multiple_deps(dds: DDS): | def test_multiple_deps(dds: DDS): | ||||
assert not dds.deps_build_dir.is_dir() | assert not dds.deps_build_dir.is_dir() | ||||
dds.catalog_import(dds.source_root / 'catalog.json') | dds.catalog_import(dds.source_root / 'catalog.json') | ||||
dds.build_deps(['neo-sqlite3 ^0.2.2', 'neo-sqlite3 ~0.2.0']) | |||||
dds.build_deps(['neo-sqlite3^0.2.2', 'neo-sqlite3~0.2.0']) | |||||
assert (dds.deps_build_dir / 'neo-sqlite3@0.2.2').is_dir() | assert (dds.deps_build_dir / 'neo-sqlite3@0.2.2').is_dir() | ||||
assert (dds.scratch_dir / 'INDEX.lmi').is_file() | assert (dds.scratch_dir / 'INDEX.lmi').is_file() | ||||
assert (dds.deps_build_dir / '_libman/neo-sqlite3.lmp').is_file() | assert (dds.deps_build_dir / '_libman/neo-sqlite3.lmp').is_file() |