Explorar el Código

Merge branch 'feature/integrate-deps-build' into develop

default_compile_flags
vector-of-bool hace 5 años
padre
commit
26aeaa8ba9
Se han modificado 37 ficheros con 538 adiciones y 622 borrados
  1. +79
    -0
      catalog.json
  2. +0
    -1
      remote.dds
  3. +94
    -8
      src/dds/build.cpp
  4. +1
    -1
      src/dds/build.hpp
  5. +14
    -11
      src/dds/build/params.hpp
  6. +3
    -1
      src/dds/build/plan/archive.cpp
  7. +8
    -3
      src/dds/build/plan/compile_exec.cpp
  8. +12
    -1
      src/dds/build/plan/library.hpp
  9. +6
    -8
      src/dds/catalog/catalog.cpp
  10. +1
    -3
      src/dds/catalog/catalog.hpp
  11. +0
    -36
      src/dds/catalog/catalog.test.cpp
  12. +2
    -2
      src/dds/catalog/get.cpp
  13. +45
    -157
      src/dds/dds.main.cpp
  14. +0
    -168
      src/dds/deps.cpp
  15. +0
    -14
      src/dds/deps.hpp
  16. +0
    -56
      src/dds/library.hpp
  17. +1
    -1
      src/dds/library/library.cpp
  18. +92
    -0
      src/dds/library/library.hpp
  19. +1
    -1
      src/dds/library/manifest.cpp
  20. +30
    -0
      src/dds/library/manifest.hpp
  21. +0
    -19
      src/dds/library_manifest.hpp
  22. +1
    -1
      src/dds/package/id.cpp
  23. +48
    -0
      src/dds/package/id.hpp
  24. +1
    -1
      src/dds/package/id.test.cpp
  25. +5
    -5
      src/dds/package/manifest.cpp
  26. +40
    -0
      src/dds/package/manifest.hpp
  27. +0
    -31
      src/dds/package_id.hpp
  28. +0
    -27
      src/dds/package_manifest.hpp
  29. +28
    -26
      src/dds/repo/repo.cpp
  30. +2
    -1
      src/dds/repo/repo.hpp
  31. +1
    -1
      src/dds/sdist.cpp
  32. +4
    -4
      src/dds/sdist.hpp
  33. +1
    -1
      src/dds/solve/solve.hpp
  34. +6
    -16
      tests/dds.py
  35. +2
    -13
      tests/deps/do_test.py
  36. +0
    -2
      tests/deps/use-spdlog/use_spdlog_test.py
  37. +10
    -2
      tools/ci.py

+ 79
- 0
catalog.json Ver fichero

@@ -0,0 +1,79 @@
{
"version": 1,
"packages": {
"range-v3": {
"0.10.0": {
"git": {
"url": "https://github.com/ericniebler/range-v3.git",
"ref": "0.10.0",
"auto-lib": "Niebler/range-v3"
},
"depends": {}
}
},
"spdlog": {
"1.4.2": {
"git": {
"url": "https://github.com/gabime/spdlog.git",
"ref": "v1.4.2",
"auto-lib": "spdlog/spdlog"
},
"depends": {}
}
},
"nlohmann-json": {
"3.7.1": {
"git": {
"url": "https://github.com/vector-of-bool/json.git",
"ref": "dds/3.7.1"
},
"depends": {}
}
},
"ms-wil": {
"2019.11.10": {
"git": {
"url": "https://github.com/vector-of-bool/wil.git",
"ref": "dds/2019.11.10"
},
"depends": {}
}
},
"neo-buffer": {
"0.1.0": {
"git": {
"url": "https://github.com/vector-of-bool/neo-buffer.git",
"ref": "develop"
},
"depends": {}
}
},
"neo-sqlite3": {
"0.2.2": {
"git": {
"url": "https://github.com/vector-of-bool/neo-sqlite3.git",
"ref": "0.2.2"
},
"depends": {}
}
},
"semver": {
"0.2.1": {
"git": {
"url": "https://github.com/vector-of-bool/semver.git",
"ref": "0.2.1"
},
"depends": {}
}
},
"pubgrub": {
"0.1.2": {
"git": {
"url": "https://github.com/vector-of-bool/pubgrub.git",
"ref": "0.1.2"
},
"depends": {}
}
}
}
}

+ 0
- 1
remote.dds Ver fichero

@@ -1,4 +1,3 @@
Remote-Package: range-v3 0.9.1; git url=https://github.com/ericniebler/range-v3.git ref=0.9.1 auto=Niebler/range-v3
Remote-Package: range-v3 0.10.0; git url=https://github.com/ericniebler/range-v3.git ref=0.10.0 auto=Niebler/range-v3
Remote-Package: spdlog 1.4.2; git url=https://github.com/gabime/spdlog.git ref=v1.4.2 auto=spdlog/spdlog


+ 94
- 8
src/dds/build.cpp Ver fichero

@@ -9,9 +9,14 @@
#include <libman/index.hpp>
#include <libman/parse.hpp>

#include <range/v3/algorithm/transform.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/transform.hpp>
#include <spdlog/spdlog.h>

#include <array>
#include <map>
#include <set>
#include <stdexcept>

using namespace dds;
@@ -185,30 +190,111 @@ void prepare_test_driver(library_build_params& lib_params,
}
}

void add_ureqs(usage_requirement_map& ureqs,
const sdist& sd,
const library& lib,
const library_plan& lib_plan,
build_env_ref env) {
lm::library& reqs = ureqs.add(sd.manifest.namespace_, lib.manifest().name);
reqs.include_paths.push_back(lib.public_include_dir());
reqs.name = lib.manifest().name;
reqs.uses = lib.manifest().uses;
reqs.links = lib.manifest().links;
if (lib_plan.create_archive()) {
reqs.linkable_path = lib_plan.create_archive()->calc_archive_file_path(env);
}
// TODO: preprocessor definitions
}

using sdist_index_type = std::map<std::string, std::reference_wrapper<const sdist>>;
using sdist_names = std::set<std::string>;

void add_sdist_to_build(build_plan& plan,
const sdist& sd,
const sdist_index_type& sd_idx,
build_env_ref env,
usage_requirement_map& ureqs,
sdist_names& already_added) {
if (already_added.find(sd.manifest.pkg_id.name) != already_added.end()) {
// This one has already been added
return;
}
spdlog::debug("Adding dependent build: {}", sd.manifest.pkg_id.name);
// Ensure that ever dependency is loaded up first)
for (const auto& dep : sd.manifest.dependencies) {
auto other = sd_idx.find(dep.name);
assert(other != sd_idx.end()
&& "Failed to load a transitive dependency shortly after initializing them. What?");
add_sdist_to_build(plan, other->second, sd_idx, env, ureqs, already_added);
}
// Record that we have been processed
already_added.insert(sd.manifest.pkg_id.name);
// Finally, actually add the package:
auto& pkg = plan.add_package(package_plan(sd.manifest.pkg_id.name, sd.manifest.namespace_));
auto libs = collect_libraries(sd.path);
for (const auto& lib : libs) {
shared_compile_file_rules comp_rules = lib.base_compile_rules();
library_build_params lib_params;
lib_params.out_subdir = fs::path("deps") / sd.manifest.pkg_id.name;
auto lib_plan = library_plan::create(lib, lib_params, ureqs);
// Create usage requirements for this libary.
add_ureqs(ureqs, sd, lib, lib_plan, env);
// Add it to the plan:
pkg.add_library(std::move(lib_plan));
}
}

void add_deps_to_build(build_plan& plan,
usage_requirement_map& ureqs,
const build_params& params,
build_env_ref env) {
auto sd_idx = params.dep_sdists //
| ranges::views::transform([](const auto& sd) {
return std::pair(sd.manifest.pkg_id.name, std::cref(sd));
}) //
| ranges::to<sdist_index_type>();

sdist_names already_added;
for (const sdist& sd : params.dep_sdists) {
add_sdist_to_build(plan, sd, sd_idx, env, ureqs, already_added);
}
}

} // namespace

void dds::build(const build_params& params, const package_manifest& man) {
fs::create_directories(params.out_root);
auto db = database::open(params.out_root / ".dds.db");
dds::build_env env{params.toolchain, params.out_root, db};

// The build plan we will fill out:
build_plan plan;

// Collect libraries for the current project
auto libs = collect_libraries(params.root);
if (!libs.size()) {
spdlog::warn("Nothing found to build!");
return;
}

build_plan plan;
auto& pkg = plan.add_package(package_plan(man.pk_id.name, man.namespace_));
usage_requirement_map ureqs;

usage_requirement_map ureqs
= load_usage_requirements(params.root, params.out_root, params.lm_index);
if (params.existing_lm_index) {
ureqs = load_usage_requirements(params.root, params.out_root, *params.existing_lm_index);
} else {
add_deps_to_build(plan, ureqs, params, env);
}

// Initialize the build plan for this project.
auto& pkg = plan.add_package(package_plan(man.pkg_id.name, man.namespace_));

// assert(false && "Not ready yet!");

library_build_params lib_params;
lib_params.build_tests = params.build_tests;
lib_params.build_apps = params.build_apps;
lib_params.enable_warnings = params.enable_warnings;

fs::create_directories(params.out_root);
auto db = database::open(params.out_root / ".dds.db");
dds::build_env env{params.toolchain, params.out_root, db};

if (man.test_driver) {
prepare_test_driver(lib_params, params, man, env);
}

+ 1
- 1
src/dds/build.hpp Ver fichero

@@ -1,7 +1,7 @@
#pragma once

#include <dds/build/params.hpp>
#include <dds/package_manifest.hpp>
#include <dds/package/manifest.hpp>

namespace dds {


+ 14
- 11
src/dds/build/params.hpp Ver fichero

@@ -2,21 +2,24 @@

#include <dds/toolchain/toolchain.hpp>
#include <dds/util/fs.hpp>
#include <dds/sdist.hpp>

#include <optional>

namespace dds {

struct build_params {
fs::path root;
fs::path out_root;
fs::path lm_index;
dds::toolchain toolchain;
bool do_export = false;
bool build_tests = false;
bool enable_warnings = false;
bool build_apps = false;
bool build_deps = false;
bool generate_compdb = true;
int parallel_jobs = 0;
fs::path root;
fs::path out_root;
std::optional<fs::path> existing_lm_index;
dds::toolchain toolchain;
std::vector<sdist> dep_sdists;
bool do_export = false;
bool build_tests = false;
bool enable_warnings = false;
bool build_apps = false;
bool generate_compdb = true;
int parallel_jobs = 0;
};

} // namespace dds

+ 3
- 1
src/dds/build/plan/archive.cpp Ver fichero

@@ -9,7 +9,8 @@
using namespace dds;

fs::path create_archive_plan::calc_archive_file_path(const build_env& env) const noexcept {
return env.output_root / fmt::format("{}{}{}", "lib", _name, env.toolchain.archive_suffix());
return env.output_root / _subdir
/ fmt::format("{}{}{}", "lib", _name, env.toolchain.archive_suffix());
}

void create_archive_plan::archive(const build_env& env) const {
@@ -28,6 +29,7 @@ void create_archive_plan::archive(const build_env& env) const {
}

spdlog::info("[{}] Archive: {}", _name, out_relpath);
fs::create_directories(ar.out_path.parent_path());
auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>([&] { return run_proc(ar_cmd); });
spdlog::info("[{}] Archive: {} - {:n}ms", _name, out_relpath, dur_ms.count());


+ 8
- 3
src/dds/build/plan/compile_exec.cpp Ver fichero

@@ -178,6 +178,10 @@ compile_file_full realize_plan(const compile_file_plan& plan, build_env_ref env)
}

bool should_compile(const compile_file_full& comp, build_env_ref env) {
if (!fs::exists(comp.object_file_path)) {
// The output file simply doesn't exist. We have to recompile, of course.
return true;
}
database& db = env.db;
auto rb_info = get_rebuild_info(db, comp.object_file_path);
if (rb_info.previous_command.empty()) {
@@ -205,11 +209,12 @@ bool dds::detail::compile_all(const ref_vector<const compile_file_plan>& compile
auto each_realized = //
compiles //
| views::transform([&](auto&& plan) { return realize_plan(plan, env); }) //
| views::filter([&](auto&& real) { return should_compile(real, env); });
| views::filter([&](auto&& real) { return should_compile(real, env); }) //
| ranges::to_vector;

const auto total = compiles.size();
const auto total = each_realized.size();
const auto max_digits = fmt::format("{}", total).size();
compile_counter counter{{0}, total, max_digits};
compile_counter counter{{1}, total, max_digits};

std::vector<deps_info> all_new_deps;
std::mutex mut;

+ 12
- 1
src/dds/build/plan/library.hpp Ver fichero

@@ -2,7 +2,7 @@

#include <dds/build/plan/archive.hpp>
#include <dds/build/plan/exe.hpp>
#include <dds/library.hpp>
#include <dds/library/library.hpp>
#include <dds/usage_reqs.hpp>
#include <dds/util/fs.hpp>

@@ -12,6 +12,17 @@

namespace dds {

struct library_build_params {
fs::path out_subdir;
bool build_tests = false;
bool build_apps = false;
bool enable_warnings = false;

// Extras for compiling tests:
std::vector<fs::path> test_include_dirs;
std::vector<fs::path> test_link_files;
};

class library_plan {
std::string _name;
fs::path _source_root;

+ 6
- 8
src/dds/catalog/catalog.cpp Ver fichero

@@ -30,11 +30,12 @@ void migrate_repodb_1(sqlite3::database& db) {
lm_name TEXT,
lm_namespace TEXT,
UNIQUE(name, version),
CONSTRAINT has_remote_info CHECK(
CONSTRAINT has_source_info CHECK(
(
git_url NOT NULL
AND git_ref NOT NULL
)
= 1
),
CONSTRAINT valid_lm_info CHECK(
(
@@ -92,6 +93,9 @@ void ensure_migrated(sqlite3::database& db) {
} // namespace

catalog catalog::open(const std::string& db_path) {
if (db_path != ":memory:") {
fs::create_directories(fs::weakly_canonical(db_path).parent_path());
}
auto db = sqlite3::database::open(db_path);
try {
ensure_migrated(db);
@@ -211,7 +215,7 @@ std::optional<package_info> catalog::get(const package_id& pk_id) const noexcept
git_remote_listing{
*git_url,
*git_ref,
lm_name ? std::make_optional(lm::usage{*lm_name, *lm_namespace}) : std::nullopt,
lm_name ? std::make_optional(lm::usage{*lm_namespace, *lm_name}) : std::nullopt,
},
};
}
@@ -341,9 +345,3 @@ void catalog::import_json_str(std::string_view content) {
}
}
}

std::vector<package_id> catalog::solve_requirements(const std::vector<dependency>& deps) const {
return dds::solve(deps,
[&](std::string_view pkg_name) { return this->by_name(pkg_name); },
[&](const package_id& pkg) { return this->dependencies_of(pkg); });
}

+ 1
- 3
src/dds/catalog/catalog.hpp Ver fichero

@@ -2,7 +2,7 @@

#include <dds/catalog/git.hpp>
#include <dds/deps.hpp>
#include <dds/package_id.hpp>
#include <dds/package/id.hpp>
#include <dds/util/fs.hpp>

#include <neo/sqlite3/database.hpp>
@@ -50,8 +50,6 @@ public:
auto content = dds::slurp_file(json_path);
import_json_str(content);
}

std::vector<package_id> solve_requirements(const std::vector<dependency>& deps) const;
};

} // namespace dds

+ 0
- 36
src/dds/catalog/catalog.test.cpp Ver fichero

@@ -90,39 +90,3 @@ TEST_CASE_METHOD(catalog_test_case, "Parse JSON repo") {
== dds::version_range_set{semver::version::parse("4.2.1"),
semver::version::parse("4.3.0")});
}

TEST_CASE_METHOD(catalog_test_case, "Simple solve") {
db.import_json_str(R"({
"version": 1,
"packages": {
"foo": {
"1.2.3": {
"depends": {
"bar": "~4.2.1"
},
"git": {
"url": "http://example.com",
"ref": "master"
}
}
},
"bar": {
"4.2.3": {
"depends": {},
"git": {
"url": "http://example.com",
"ref": "master"
}
}
}
}
})");
auto sln = db.solve_requirements({{"foo",
dds::version_range_set{semver::version::parse("1.0.0"),
semver::version::parse("2.0.0")}}});
REQUIRE(sln.size() == 2);
CHECK(sln[0].name == "foo");
CHECK(sln[0].version == semver::version::parse("1.2.3"));
CHECK(sln[1].name == "bar");
CHECK(sln[1].version == semver::version::parse("4.2.3"));
}

+ 2
- 2
src/dds/catalog/get.cpp Ver fichero

@@ -52,12 +52,12 @@ temporary_sdist do_pull_sdist(const package_info& listing, const git_remote_list

temporary_sdist dds::get_package_sdist(const package_info& pkg) {
auto tsd = std::visit([&](auto&& remote) { return do_pull_sdist(pkg, remote); }, pkg.remote);
if (!(tsd.sdist.manifest.pk_id == pkg.ident)) {
if (!(tsd.sdist.manifest.pkg_id == pkg.ident)) {
throw std::runtime_error(fmt::format(
"The package name@version in the generated sdist does not match the name listed in "
"the remote listing file (expected '{}', but got '{}')",
pkg.ident.to_string(),
tsd.sdist.manifest.pk_id.to_string()));
tsd.sdist.manifest.pkg_id.to_string()));
}
return tsd;
}

+ 45
- 157
src/dds/dds.main.cpp Ver fichero

@@ -276,6 +276,8 @@ struct cli_catalog {
return get.run();
} else if (add.cmd) {
return add.run();
} else if (list.cmd) {
return list.run();
} else {
assert(false);
std::terminate();
@@ -310,7 +312,7 @@ struct cli_repo {
int run() {
auto list_contents = [&](dds::repository repo) {
auto same_name = [](auto&& a, auto&& b) {
return a.manifest.pk_id.name == b.manifest.pk_id.name;
return a.manifest.pkg_id.name == b.manifest.pkg_id.name;
};

auto all = repo.iter_sdists();
@@ -319,13 +321,13 @@ struct cli_repo {
| ranges::views::transform(ranges::to_vector) //
| ranges::views::transform([](auto&& grp) {
assert(grp.size() > 0);
return std::pair(grp[0].manifest.pk_id.name, grp);
return std::pair(grp[0].manifest.pkg_id.name, grp);
});

for (const auto& [name, grp] : grp_by_name) {
spdlog::info("{}:", name);
for (const dds::sdist& sd : grp) {
spdlog::info(" - {}", sd.manifest.pk_id.version.to_string());
spdlog::info(" - {}", sd.manifest.pkg_id.version.to_string());
}
}

@@ -478,21 +480,21 @@ struct cli_build {

common_project_flags project{cmd};

args::Flag build_tests{cmd, "build_tests", "Build and run the tests", {"tests", 'T'}};
args::Flag build_apps{cmd, "build_apps", "Build applications", {"apps", 'A'}};
args::Flag export_{cmd, "export", "Generate a library export", {"export", 'E'}};
catalog_path_flag cat_path{cmd};
repo_path_flag repo_path{cmd};

args::Flag no_tests{cmd, "no-tests", "Do not build and run tests", {"no-tests"}};
args::Flag no_apps{cmd, "no-apps", "Do not compile and link applications", {"no-apps"}};
args::Flag no_warnings{cmd, "no-warings", "Disable build warnings", {"no-warnings"}};
toolchain_flag tc_filepath{cmd};

args::Flag enable_warnings{cmd,
"enable_warnings",
"Enable compiler warnings",
{"warnings", 'W'}};
args::Flag export_{cmd, "export", "Generate a library export", {"export", 'E'}};

path_flag lm_index{cmd,
"lm_index",
"Path to a libman index (usually INDEX.lmi)",
{"lm-index", 'I'},
dds::fs::path()};
path_flag
lm_index{cmd,
"lm_index",
"Path to an existing libman index from which to load deps (usually INDEX.lmi)",
{"lm-index", 'I'}};

args::ValueFlag<int> num_jobs{cmd,
"jobs",
@@ -512,159 +514,48 @@ struct cli_build {
params.out_root = out.Get();
params.toolchain = tc_filepath.get_toolchain();
params.do_export = export_.Get();
params.build_tests = build_tests.Get();
params.build_apps = build_apps.Get();
params.enable_warnings = enable_warnings.Get();
params.build_tests = !no_tests.Get();
params.build_apps = !no_apps.Get();
params.enable_warnings = !no_warnings.Get();
params.parallel_jobs = num_jobs.Get();
params.lm_index = lm_index.Get();
dds::package_manifest man;
const auto man_filepath = params.root / "package.dds";
if (exists(man_filepath)) {
man = dds::package_manifest::load_from_file(man_filepath);
}
dds::build(params, man);
return 0;
}
};

/*
######## ######## ######## ######
## ## ## ## ## ## ##
## ## ## ## ## ##
## ## ###### ######## ######
## ## ## ## ##
## ## ## ## ## ##
######## ######## ## ######
*/

struct cli_deps {
cli_base& base;
args::Command cmd{base.cmd_group, "deps", "Obtain/inspect/build deps for the project"};

common_flags _flags{cmd};
common_project_flags project{cmd};

args::Group deps_group{cmd, "Subcommands"};

dds::package_manifest load_package_manifest() {
return dds::package_manifest::load_from_file(project.root.Get() / "package.dds");
}

struct {
cli_deps& parent;
args::Command cmd{parent.deps_group, "ls", "List project dependencies"};
common_flags _common{cmd};

int run() {
const auto man = parent.load_package_manifest();
for (const auto& dep : man.dependencies) {
std::cout << dep.name << " " << dep.versions << '\n';
}
return 0;
}
} ls{*this};

struct {
cli_deps& parent;
args::Command cmd{parent.deps_group,
"get",
"Ensure we have local copies of the project dependencies"};
common_flags _common{cmd};

repo_path_flag repo_where{cmd};
catalog_path_flag catalog_path{cmd};

int run() {
auto man = parent.load_package_manifest();
auto catalog = catalog_path.open();
bool failed = false;
auto solved_deps = catalog.solve_requirements(man.dependencies);
dds::repository::with_repository( //
repo_where.Get(),
if (lm_index) {
params.existing_lm_index = lm_index.Get();
} else {
// Download and build dependencies
// Build the dependencies
auto cat = cat_path.open();
params.dep_sdists = dds::repository::with_repository( //
this->repo_path.Get(),
dds::repo_flags::write_lock | dds::repo_flags::create_if_absent,
[&](dds::repository repo) {
for (const dds::package_id& pk : solved_deps) {
// Download dependencies
auto deps = repo.solve(man.dependencies, cat);
for (const dds::package_id& pk : deps) {
auto exists = !!repo.find(pk);
if (!exists) {
spdlog::info("Pull remote: {}", pk.to_string());
auto opt_pkg = catalog.get(pk);
if (opt_pkg) {
auto tsd = dds::get_package_sdist(*opt_pkg);
repo.add_sdist(tsd.sdist, dds::if_exists::ignore);
} else {
spdlog::error("No remote listing for {}", pk.to_string());
failed = true;
}
} else {
spdlog::info("Okay: {}", pk.to_string());
spdlog::info("Download dependency: {}", pk.to_string());
auto opt_pkg = cat.get(pk);
assert(opt_pkg);
auto tsd = dds::get_package_sdist(*opt_pkg);
repo.add_sdist(tsd.sdist, dds::if_exists::throw_exc);
}
}
return deps //
| ranges::views::transform([&](auto& id) {
auto ptr = repo.find(id);
assert(ptr);
return *ptr;
})
| ranges::to_vector;
});
if (failed) {
return 1;
}
return 0;
}
} get{*this};

struct {
cli_deps& parent;
args::Command cmd{parent.deps_group, "build", "Build project dependencies"};
common_flags _common{cmd};

path_flag build_dir{cmd,
"build_dir",
"Directory where build results will be stored",
{"deps-build-dir"},
dds::fs::current_path() / "_build/deps"};
path_flag lmi_path{cmd,
"lmi_path",
"Destination for the INDEX.lmi file",
{"lmi-path"},
dds::fs::current_path() / "_build/INDEX.lmi"};
args::Flag no_lmi{cmd,
"no_lmi",
"If specified, will not generate an INDEX.lmi",
{"skip-lmi"}};

repo_path_flag repo_where{cmd};

toolchain_flag tc_filepath{cmd};

int run() {
auto man = parent.load_package_manifest();
auto deps = dds::repository::with_repository( //
repo_where.Get(),
dds::repo_flags::read,
[&](dds::repository repo) {
return repo.solve(man.dependencies);
});

auto tc = tc_filepath.get_toolchain();
auto bdir = build_dir.Get();
dds::fs::create_directories(bdir);
auto db = dds::database::open(bdir / ".dds.db");
dds::build_env env{std::move(tc), bdir, db};

auto plan = dds::create_deps_build_plan(deps, env);
plan.compile_all(env, 6);
plan.archive_all(env, 6);
if (!no_lmi.Get()) {
write_libman_index(lmi_path.Get(), plan, env);
}
return 0;
}
} build{*this};

int run() {
if (ls.cmd) {
return ls.run();
} else if (build.cmd) {
return build.run();
} else if (get.cmd) {
return get.run();
}
std::terminate();
dds::build(params, man);
return 0;
}
};

@@ -691,7 +582,6 @@ int main(int argc, char** argv) {
cli_build build{cli};
cli_sdist sdist{cli};
cli_repo repo{cli};
cli_deps deps{cli};
cli_catalog catalog{cli};
try {
parser.ParseCLI(argc, argv);
@@ -716,8 +606,6 @@ int main(int argc, char** argv) {
return sdist.run();
} else if (repo.cmd) {
return repo.run();
} else if (deps.cmd) {
return deps.run();
} else if (catalog.cmd) {
return catalog.run();
} else {

+ 0
- 168
src/dds/deps.cpp Ver fichero

@@ -41,171 +41,3 @@ dependency dependency::parse_depends_string(std::string_view str) {
str));
}
}

using sdist_index_type = std::map<std::string, std::reference_wrapper<const sdist>>;
using sdist_names = std::set<std::string>;

namespace {

void resolve_ureqs_(shared_compile_file_rules& rules,
const package_manifest& man,
const sdist_index_type& sd_idx) {
for (const dependency& dep : man.dependencies) {
auto found = sd_idx.find(dep.name);
if (found == sd_idx.end()) {
throw std::runtime_error(
fmt::format("Unable to resolve dependency '{}' (required by '{}')",
dep.name,
man.pk_id.to_string()));
}
resolve_ureqs_(rules, found->second.get().manifest, sd_idx);
auto lib_src = found->second.get().path / "src";
auto lib_include = found->second.get().path / "include";
if (fs::exists(lib_include)) {
rules.include_dirs().push_back(lib_include);
} else {
rules.include_dirs().push_back(lib_src);
}
}
}

void resolve_ureqs(shared_compile_file_rules rules,
const sdist& sd,
const library& lib,
const library_plan& lib_plan,
build_env_ref env,
usage_requirement_map& ureqs) {
// Add the transitive requirements for this library to our compile rules.
for (auto&& use : lib.manifest().uses) {
ureqs.apply(rules, use.namespace_, use.name);
}

// Create usage requirements for this libary.
lm::library& reqs = ureqs.add(sd.manifest.namespace_, lib.manifest().name);
reqs.include_paths.push_back(lib.public_include_dir());
reqs.name = lib.manifest().name;
reqs.uses = lib.manifest().uses;
reqs.links = lib.manifest().links;
if (lib_plan.create_archive()) {
reqs.linkable_path = lib_plan.create_archive()->calc_archive_file_path(env);
}
// TODO: preprocessor definitions
}

void add_sdist_to_dep_plan(build_plan& plan,
const sdist& sd,
build_env_ref env,
const sdist_index_type& sd_idx,
usage_requirement_map& ureqs,
sdist_names& already_added) {
if (already_added.find(sd.manifest.pk_id.name) != already_added.end()) {
// We've already loaded this package into the plan.
return;
}
spdlog::debug("Add to plan: {}", sd.manifest.pk_id.name);
// First, load every dependency
for (const auto& dep : sd.manifest.dependencies) {
auto other = sd_idx.find(dep.name);
assert(other != sd_idx.end()
&& "Failed to load a transitive dependency shortly after initializing them. What?");
add_sdist_to_dep_plan(plan, other->second, env, sd_idx, ureqs, already_added);
}
// Record that we have been processed:
already_added.insert(sd.manifest.pk_id.name);
// Add the package:
auto& pkg = plan.add_package(package_plan(sd.manifest.pk_id.name, sd.manifest.namespace_));
auto libs = collect_libraries(sd.path);
for (const auto& lib : libs) {
shared_compile_file_rules comp_rules = lib.base_compile_rules();
library_build_params params;
auto lib_plan = library_plan::create(lib, params, ureqs);
resolve_ureqs(comp_rules, sd, lib, lib_plan, env, ureqs);
pkg.add_library(std::move(lib_plan));
}
}

} // namespace

build_plan dds::create_deps_build_plan(const std::vector<sdist>& deps, build_env_ref env) {
auto sd_idx = deps //
| ranges::views::transform([](const auto& sd) {
return std::pair(sd.manifest.pk_id.name, std::cref(sd));
}) //
| ranges::to<sdist_index_type>();

build_plan plan;
usage_requirement_map ureqs;
sdist_names already_added;
for (const sdist& sd : deps) {
spdlog::info("Recording dependency: {}", sd.manifest.pk_id.name);
add_sdist_to_dep_plan(plan, sd, env, sd_idx, ureqs, already_added);
}
return plan;
}

namespace {

fs::path generate_lml(const library_plan& lib, path_ref libdir, const build_env& env) {
auto fname = lib.name() + ".lml";
auto lml_path = libdir / fname;

std::vector<lm::pair> kvs;
kvs.emplace_back("Type", "Library");
kvs.emplace_back("Name", lib.name());
if (lib.create_archive()) {
kvs.emplace_back("Path",
fs::relative(lib.create_archive()->calc_archive_file_path(env),
lml_path.parent_path())
.string());
}
auto pub_inc_dir = lib.source_root() / "include";
auto src_dir = lib.source_root() / "src";
if (!fs::exists(pub_inc_dir)) {
pub_inc_dir = src_dir;
}
kvs.emplace_back("Include-Path", pub_inc_dir.string());

// TODO: Uses, Preprocessor-Define, and Special-Uses

fs::create_directories(lml_path.parent_path());
lm::write_pairs(lml_path, kvs);
return lml_path;
}

fs::path generate_lmp(const package_plan& pkg, path_ref basedir, const build_env& env) {
auto fname = pkg.name() + ".lmp";
auto lmp_path = basedir / fname;

std::vector<lm::pair> kvs;
kvs.emplace_back("Type", "Package");
kvs.emplace_back("Name", pkg.name());
kvs.emplace_back("Namespace", pkg.namespace_());

for (auto&& lib : pkg.libraries()) {
auto lml = generate_lml(lib, basedir / pkg.name(), env);
kvs.emplace_back("Library", fs::relative(lml, lmp_path.parent_path()).string());
}

// TODO: `Requires` for transitive package imports

fs::create_directories(lmp_path.parent_path());
lm::write_pairs(lmp_path, kvs);
return lmp_path;
}

} // namespace

void dds::write_libman_index(path_ref out_filepath, const build_plan& plan, const build_env& env) {
fs::create_directories(out_filepath.parent_path());
auto lm_items_dir = out_filepath.parent_path() / "_libman";
std::vector<lm::pair> kvs;
kvs.emplace_back("Type", "Index");
for (const package_plan& pkg : plan.packages()) {
auto pkg_lmp = generate_lmp(pkg, lm_items_dir, env);
kvs.emplace_back("Package",
fmt::format("{}; {}",
pkg.name(),
fs::relative(pkg_lmp, out_filepath.parent_path()).string()));
}
lm::write_pairs(out_filepath, kvs);
}

+ 0
- 14
src/dds/deps.hpp Ver fichero

@@ -10,16 +10,6 @@

namespace dds {

struct sdist;
class repository;

enum class version_strength {
exact,
patch,
minor,
major,
};

using version_range_set = pubgrub::interval_set<semver::version>;

struct dependency {
@@ -29,8 +19,4 @@ struct dependency {
static dependency parse_depends_string(std::string_view str);
};

build_plan create_deps_build_plan(const std::vector<sdist>& deps, build_env_ref env);

void write_libman_index(path_ref where, const build_plan& plan, const build_env& env);

} // namespace dds

+ 0
- 56
src/dds/library.hpp Ver fichero

@@ -1,56 +0,0 @@
#pragma once

#include <dds/build/plan/compile_file.hpp>
#include <dds/build/source_dir.hpp>
#include <dds/library_manifest.hpp>
#include <dds/source.hpp>

#include <string>

namespace dds {

struct library_ident {
std::string namespace_;
std::string name;
};

class library {
fs::path _path;
source_list _sources;
library_manifest _man;

library(path_ref dir, source_list&& src, library_manifest&& man)
: _path(dir)
, _sources(std::move(src))
, _man(std::move(man)) {}

public:
static library from_directory(path_ref);

auto& manifest() const noexcept { return _man; }

source_directory src_dir() const noexcept { return source_directory{path() / "src"}; }
source_directory include_dir() const noexcept { return source_directory{path() / "include"}; }

path_ref path() const noexcept { return _path; }
fs::path public_include_dir() const noexcept;
fs::path private_include_dir() const noexcept;

const source_list& all_sources() const noexcept { return _sources; }
shared_compile_file_rules base_compile_rules() const noexcept;
};

struct library_build_params {
fs::path out_subdir;
bool build_tests = false;
bool build_apps = false;
bool enable_warnings = false;

// Extras for compiling tests:
std::vector<fs::path> test_include_dirs;
std::vector<fs::path> test_link_files;
};

std::vector<library> collect_libraries(path_ref where);

} // namespace dds

src/dds/library.cpp → src/dds/library/library.cpp Ver fichero

@@ -1,4 +1,4 @@
#include <dds/library.hpp>
#include <dds/library/library.hpp>

#include <dds/build/plan/compile_file.hpp>
#include <dds/build/source_dir.hpp>

+ 92
- 0
src/dds/library/library.hpp Ver fichero

@@ -0,0 +1,92 @@
#pragma once

#include <dds/build/plan/compile_file.hpp>
#include <dds/build/source_dir.hpp>
#include <dds/library/manifest.hpp>
#include <dds/source.hpp>

#include <string>

namespace dds {

/**
* Represents a library that exists on the filesystem
*/
class library {
// The path containing the source directories for this library
fs::path _path;
// The sources that are part of this library
source_list _sources;
// The library manifest associated with this library (may be generated)
library_manifest _man;

// Private constructor. Use named constructor `from_directory`, which will build
// the construct arguments approperiately
library(path_ref dir, source_list&& src, library_manifest&& man)
: _path(dir)
, _sources(std::move(src))
, _man(std::move(man)) {}

public:
/**
* Create a library object that refers to the library contained at the given
* directory path. This will load the sources and manifest properly and
* return the resulting library object.
*/
static library from_directory(path_ref);

/**
* Obtain the manifest for this library
*/
const library_manifest& manifest() const noexcept { return _man; }

/**
* The `src/` directory for this library.
*/
source_directory src_dir() const noexcept { return source_directory{path() / "src"}; }

/**
* The `include/` directory for this library
*/
source_directory include_dir() const noexcept { return source_directory{path() / "include"}; }

/**
* The root path for this library (parent of `src/` and `include/`, if present)
*/
path_ref path() const noexcept { return _path; }

/**
* The directory that should be considered the "public" include directory.
* Dependees that want to use this library should add this to their #include
* search path.
*/
fs::path public_include_dir() const noexcept;

/**
* The directory that contains the "private" heders for this libary. This
* directory should be added to the search path of the library when it is
* being built, but NOT to the search path of the dependees.
*/
fs::path private_include_dir() const noexcept;

/**
* Get the sources that this library contains
*/
const source_list& all_sources() const noexcept { return _sources; }

/**
* Generate a compile rules object that should be used when compiling
* this library.
*/
shared_compile_file_rules base_compile_rules() const noexcept;
};

/**
* Given the root source directory of a project/package/sdist, collect all of
* the libraries that it contains. There may be a library directly in `where`,
* but there might also be libraries in `where/libs`. This function will find
* them all.
*/
std::vector<library> collect_libraries(path_ref where);

} // namespace dds

src/dds/library_manifest.cpp → src/dds/library/manifest.cpp Ver fichero

@@ -1,4 +1,4 @@
#include "./library_manifest.hpp"
#include "./manifest.hpp"

#include <dds/util/algo.hpp>
#include <range/v3/view/transform.hpp>

+ 30
- 0
src/dds/library/manifest.hpp Ver fichero

@@ -0,0 +1,30 @@
#pragma once

#include <dds/util/fs.hpp>

#include <libman/library.hpp>

#include <vector>

namespace dds {

/**
* Represents the contents of a `library.dds`. This is somewhat a stripped-down
* version of lm::library, to only represent exactly the parts that we want to
* offer via `library.dds`.
*/
struct library_manifest {
/// The name of the library
std::string name;
/// The libraries that the owning library "uses"
std::vector<lm::usage> uses;
/// The libraries that the owning library must be linked with
std::vector<lm::usage> links;

/**
* Load the library manifest from an existing file
*/
static library_manifest load_from_file(const fs::path&);
};

} // namespace dds

+ 0
- 19
src/dds/library_manifest.hpp Ver fichero

@@ -1,19 +0,0 @@
#pragma once

#include <dds/util/fs.hpp>

#include <libman/library.hpp>

#include <vector>

namespace dds {

struct library_manifest {
std::string name;
std::vector<lm::usage> uses;
std::vector<lm::usage> links;

static library_manifest load_from_file(const fs::path&);
};

} // namespace dds

src/dds/package_id.cpp → src/dds/package/id.cpp Ver fichero

@@ -1,4 +1,4 @@
#include <dds/package_id.hpp>
#include <dds/package/id.hpp>

#include <spdlog/fmt/fmt.h>


+ 48
- 0
src/dds/package/id.hpp Ver fichero

@@ -0,0 +1,48 @@
#pragma once

#include <semver/version.hpp>

#include <string>
#include <string_view>
#include <tuple>

namespace dds {

/**
* Represents a unique package ID. We store this as a simple name-version pair.
*
* In text, this is represented with an `@` symbol in between. The `parse` and
* `to_string` method convert between this textual representation, and supports
* full round-trips.
*/
struct package_id {
/// The name of the package
std::string name;
/// The version of the package
semver::version version;

/// Default-initialize a package_id with a blank name and a default version
package_id() = default;
/// Construct a package ID from a name-version pair
package_id(std::string_view s, semver::version v);

/**
* Parse the given string into a package_id object.
*/
static package_id parse(std::string_view);

/**
* Convert this package_id into its corresponding textual representation.
* The returned string can be passed back to `parse()` for a round-trip
*/
std::string to_string() const noexcept;

friend bool operator<(const package_id& lhs, const package_id& rhs) noexcept {
return std::tie(lhs.name, lhs.version) < std::tie(rhs.name, rhs.version);
}
friend bool operator==(const package_id& lhs, const package_id& rhs) noexcept {
return std::tie(lhs.name, lhs.version) == std::tie(rhs.name, rhs.version);
}
};

} // namespace dds

src/dds/package_id.test.cpp → src/dds/package/id.test.cpp Ver fichero

@@ -1,4 +1,4 @@
#include <dds/package_id.hpp>
#include <dds/package/id.hpp>

#include <catch2/catch.hpp>


src/dds/package_manifest.cpp → src/dds/package/manifest.cpp Ver fichero

@@ -1,4 +1,4 @@
#include "./package_manifest.hpp"
#include "./manifest.hpp"

#include <dds/util/string.hpp>
#include <libman/parse.hpp>
@@ -18,14 +18,14 @@ package_manifest package_manifest::load_from_file(const fs::path& fpath) {
std::optional<std::string> opt_test_driver;
lm::read(fmt::format("Reading package manifest '{}'", fpath.string()),
kvs,
lm::read_required("Name", ret.pk_id.name),
lm::read_required("Name", ret.pkg_id.name),
lm::read_opt("Namespace", ret.namespace_),
lm::read_required("Version", version_str),
lm::read_accumulate("Depends", depends_strs),
lm::read_opt("Test-Driver", opt_test_driver),
lm::reject_unknown());

if (ret.pk_id.name.empty()) {
if (ret.pkg_id.name.empty()) {
throw std::runtime_error(
fmt::format("'Name' field in [{}] may not be an empty string", fpath.string()));
}
@@ -45,10 +45,10 @@ package_manifest package_manifest::load_from_file(const fs::path& fpath) {
}

if (ret.namespace_.empty()) {
ret.namespace_ = ret.pk_id.name;
ret.namespace_ = ret.pkg_id.name;
}

ret.pk_id.version = semver::version::parse(version_str);
ret.pkg_id.version = semver::version::parse(version_str);

ret.dependencies = depends_strs //
| ranges::views::transform(dependency::parse_depends_string) //

+ 40
- 0
src/dds/package/manifest.hpp Ver fichero

@@ -0,0 +1,40 @@
#pragma once

#include <dds/deps.hpp>
#include <dds/package/id.hpp>
#include <dds/util/fs.hpp>

#include <optional>
#include <string>
#include <vector>

namespace dds {

/**
* Possible values for Test-Driver in a package.dds
*/
enum class test_lib {
catch_,
catch_main,
};

/**
* Struct representing the contents of a `packaeg.dds` file.
*/
struct package_manifest {
/// The package ID, as determined by `Name` and `Version` together
package_id pkg_id;
/// The declared `Namespace` of the package. This directly corresponds with the libman Namespace
std::string namespace_;
/// The `Test-Driver` that this package declares, or `nullopt` if absent.
std::optional<test_lib> test_driver;
/// The dependencies declared with the `Depends` fields, if any.
std::vector<dependency> dependencies;

/**
* Load a package manifest from a file on disk.
*/
static package_manifest load_from_file(path_ref);
};

} // namespace dds

+ 0
- 31
src/dds/package_id.hpp Ver fichero

@@ -1,31 +0,0 @@
#pragma once

#include <semver/version.hpp>

#include <string>
#include <string_view>
#include <tuple>

namespace dds {

struct package_id {
std::string name;
semver::version version;

package_id() = default;
package_id(std::string_view s, semver::version v);

static package_id parse(std::string_view);
std::string to_string() const noexcept;

auto tie() const noexcept { return std::tie(name, version); }

friend bool operator<(const package_id& lhs, const package_id& rhs) noexcept {
return lhs.tie() < rhs.tie();
}
friend bool operator==(const package_id& lhs, const package_id& rhs) noexcept {
return lhs.tie() == rhs.tie();
}
};

} // namespace dds

+ 0
- 27
src/dds/package_manifest.hpp Ver fichero

@@ -1,27 +0,0 @@
#pragma once

#include <dds/deps.hpp>
#include <dds/package_id.hpp>
#include <dds/util/fs.hpp>
#include <semver/version.hpp>

#include <optional>
#include <string>
#include <vector>

namespace dds {

enum class test_lib {
catch_,
catch_main,
};

struct package_manifest {
package_id pk_id;
std::string namespace_;
std::optional<test_lib> test_driver;
std::vector<dependency> dependencies;
static package_manifest load_from_file(path_ref);
};

} // namespace dds

+ 28
- 26
src/dds/repo/repo.cpp Ver fichero

@@ -1,5 +1,6 @@
#include "./repo.hpp"

#include <dds/catalog/catalog.hpp>
#include <dds/sdist.hpp>
#include <dds/solve/solve.hpp>
#include <dds/util/paths.hpp>
@@ -8,7 +9,9 @@
#include <spdlog/spdlog.h>

#include <range/v3/action/sort.hpp>
#include <range/v3/action/unique.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/transform.hpp>

@@ -71,7 +74,7 @@ void repository::add_sdist(const sdist& sd, if_exists ife_action) {
"repository, we'll hard-exit immediately.");
std::terminate();
}
auto sd_dest = _root / sd.manifest.pk_id.to_string();
auto sd_dest = _root / sd.manifest.pkg_id.to_string();
if (fs::exists(sd_dest)) {
auto msg = fmt::format("Source distribution '{}' is already available in the local repo",
sd.path.string());
@@ -95,7 +98,8 @@ void repository::add_sdist(const sdist& sd, if_exists ife_action) {
fs::remove_all(sd_dest);
}
fs::rename(tmp_copy, sd_dest);
spdlog::info("Source distribution '{}' successfully exported", sd.manifest.pk_id.to_string());
_sdists.insert(sdist::from_directory(sd_dest));
spdlog::info("Source distribution '{}' successfully exported", sd.manifest.pkg_id.to_string());
}

const sdist* repository::find(const package_id& pkg) const noexcept {
@@ -106,29 +110,27 @@ const sdist* repository::find(const package_id& pkg) const noexcept {
return &*found;
}

std::vector<sdist> repository::solve(const std::vector<dependency>& deps) const {
auto ids = dds::solve(deps,
[&](std::string_view name) -> std::vector<package_id> {
auto items = ranges::views::all(_sdists) //
| ranges::views::filter([&](const sdist& sd) {
return sd.manifest.pk_id.name == name;
})
| ranges::views::transform(
[](const sdist& sd) { return sd.manifest.pk_id; })
| ranges::to_vector;
ranges::sort(items, std::less<>{});
return items;
},
[&](const package_id& pkg_id) {
auto found = find(pkg_id);
assert(found);
std::vector<package_id> repository::solve(const std::vector<dependency>& deps,
const catalog& ctlg) const {
return dds::solve(deps,
[&](std::string_view name) -> std::vector<package_id> {
auto mine = ranges::views::all(_sdists) //
| ranges::views::filter([&](const sdist& sd) {
return sd.manifest.pkg_id.name == name;
})
| ranges::views::transform(
[](const sdist& sd) { return sd.manifest.pkg_id; });
auto avail = ctlg.by_name(name);
auto all = ranges::views::concat(mine, avail) | ranges::to_vector;
ranges::sort(all, std::less<>{});
ranges::unique(all, std::less<>{});
return all;
},
[&](const package_id& pkg_id) {
auto found = find(pkg_id);
if (found) {
return found->manifest.dependencies;
});
return ids //
| ranges::views::transform([&](const package_id& pk_id) {
auto found = find(pk_id);
assert(found);
return *found;
}) //
| ranges::to_vector;
}
return ctlg.dependencies_of(pkg_id);
});
}

+ 2
- 1
src/dds/repo/repo.hpp Ver fichero

@@ -2,6 +2,7 @@

#include <dds/sdist.hpp>
#include <dds/util/flock.hpp>
#include <dds/catalog/catalog.hpp>
#include <dds/util/fs.hpp>

#include <functional>
@@ -96,7 +97,7 @@ public:
return r;
}

std::vector<sdist> solve(const std::vector<dependency>& deps) const;
std::vector<package_id> solve(const std::vector<dependency>& deps, const catalog&) const;
};

} // namespace dds

+ 1
- 1
src/dds/sdist.cpp Ver fichero

@@ -93,7 +93,7 @@ sdist dds::create_sdist_in_dir(path_ref out, const sdist_params& params) {
sdist_export_file(out, params.project_dir, man_path);
auto pkg_man = package_manifest::load_from_file(man_path);

spdlog::info("Generated export as {}", pkg_man.pk_id.to_string());
spdlog::info("Generated export as {}", pkg_man.pkg_id.to_string());

return sdist::from_directory(out);
}

+ 4
- 4
src/dds/sdist.hpp Ver fichero

@@ -2,7 +2,7 @@

#include <tuple>

#include <dds/package_manifest.hpp>
#include <dds/package/manifest.hpp>
#include <dds/util/fs.hpp>

namespace dds {
@@ -28,13 +28,13 @@ struct sdist {

inline constexpr struct sdist_compare_t {
bool operator()(const sdist& lhs, const sdist& rhs) const {
return lhs.manifest.pk_id < rhs.manifest.pk_id;
return lhs.manifest.pkg_id < rhs.manifest.pkg_id;
}
bool operator()(const sdist& lhs, const package_id& rhs) const {
return lhs.manifest.pk_id < rhs;
return lhs.manifest.pkg_id < rhs;
}
bool operator()(const package_id& lhs, const sdist& rhs) const {
return lhs < rhs.manifest.pk_id;
return lhs < rhs.manifest.pkg_id;
}
using is_transparent = int;
} sdist_compare;

+ 1
- 1
src/dds/solve/solve.hpp Ver fichero

@@ -1,7 +1,7 @@
#pragma once

#include <dds/deps.hpp>
#include <dds/package_id.hpp>
#include <dds/package/id.hpp>

#include <functional>


+ 6
- 16
tests/dds.py Ver fichero

@@ -69,17 +69,6 @@ class DDS:
def project_dir_arg(self) -> str:
return f'--project-dir={self.source_root}'

def deps_ls(self) -> subprocess.CompletedProcess:
return self.run(['deps', 'ls'])

def deps_get(self) -> subprocess.CompletedProcess:
return self.run([
'deps',
'get',
f'--catalog={self.catalog_path}',
self.repo_dir_arg,
])

def deps_build(self, *,
toolchain: str = None) -> subprocess.CompletedProcess:
return self.run([
@@ -101,12 +90,13 @@ class DDS:
return self.run([
'build',
f'--out={self.build_dir}',
['--tests'] if tests else [],
['--apps'] if apps else [],
['--warnings'] if warnings else [],
['--export'] if export else [],
f'--toolchain={toolchain or self.default_builtin_toolchain}',
f'--lm-index={self.lmi_path}',
f'--catalog={self.catalog_path}',
f'--repo-dir={self.repo_dir}',
['--no-tests'] if not tests else [],
['--no-apps'] if not apps else [],
['--no-warnings'] if not warnings else [],
['--export'] if export else [],
self.project_dir_arg,
])


+ 2
- 13
tests/deps/do_test.py Ver fichero

@@ -9,28 +9,17 @@ dds_conf = dds_fixture_conf(
)


@dds_conf
def test_ls(dds: DDS):
dds.run(['deps', 'ls'])


@dds_conf
def test_deps_build(dds: DDS):
dds.catalog_import(dds.source_root / 'catalog.json')
assert not dds.repo_dir.exists()
dds.deps_get()
assert dds.repo_dir.exists(), '`deps get` did not generate a repo directory'

assert not dds.lmi_path.exists()
dds.deps_build()
assert dds.lmi_path.exists(), '`deps build` did not generate the build dir'
dds.build()
assert dds.repo_dir.exists(), '`Building` did not generate a repo directory'


@dds_fixture_conf_1('use-remote')
def test_use_nlohmann_json_remote(dds: DDS):
dds.catalog_import(dds.source_root / 'catalog.json')
dds.deps_get()
dds.deps_build()
dds.build(apps=True)

app_exe = dds.build_dir / f'app{dds.exe_suffix}'

+ 0
- 2
tests/deps/use-spdlog/use_spdlog_test.py Ver fichero

@@ -5,9 +5,7 @@ from dds_ci import proc

def test_get_build_use_spdlog(dds: DDS):
dds.catalog_import(dds.source_root / 'catalog.json')
dds.deps_get()
tc_fname = 'gcc.tc.dds' if 'gcc' in dds.default_builtin_toolchain else 'msvc.tc.dds'
tc = str(dds.test_dir / tc_fname)
dds.deps_build(toolchain=tc)
dds.build(toolchain=tc, apps=True)
proc.check_run((dds.build_dir / 'use-spdlog').with_suffix(dds.exe_suffix))

+ 10
- 2
tools/ci.py Ver fichero

@@ -98,8 +98,8 @@ def main(argv: Sequence[str]) -> int:
else:
assert False, 'impossible'

ci_repo_dir = paths.BUILD_DIR / '_ci-repo'
if not opts.skip_deps:
ci_repo_dir = paths.BUILD_DIR / '_ci-repo'
if ci_repo_dir.exists():
shutil.rmtree(ci_repo_dir)
self_deps_get(paths.PREBUILT_DDS, ci_repo_dir)
@@ -112,10 +112,18 @@ def main(argv: Sequence[str]) -> int:
dds_flags=['--warnings', '--tests', '--apps'])
print('Main build PASSED!')

cat_path = paths.BUILD_DIR / 'catalog.db'
proc.check_run([
paths.CUR_BUILT_DDS,
'catalog',
'import',
('--catalog', cat_path),
('--json', paths.PROJECT_ROOT / 'catalog.json'),
])
self_build(
paths.CUR_BUILT_DDS,
toolchain=opts.toolchain,
dds_flags=['--warnings', '--tests', '--apps'])
dds_flags=[f'--repo-dir={ci_repo_dir}', f'--catalog={cat_path}'])
print('Bootstrap test PASSED!')

return pytest.main([

Cargando…
Cancelar
Guardar