Browse Source

`build-deps` command to build a set of dependencies

default_compile_flags
vector-of-bool 5 years ago
parent
commit
cef6707c36
4 changed files with 132 additions and 18 deletions
  1. +114
    -11
      src/dds.main.cpp
  2. +7
    -7
      tests/dds.py
  3. +4
    -0
      tests/deps/build-deps/project/deps.dds
  4. +7
    -0
      tests/deps/build-deps/test_build_deps.py

+ 114
- 11
src/dds.main.cpp View File

@@ -8,6 +8,8 @@
#include <dds/util/paths.hpp>
#include <dds/util/signal.hpp>

#include <range/v3/action/join.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/group_by.hpp>
#include <range/v3/view/transform.hpp>

@@ -66,6 +68,15 @@ struct catalog_path_flag : path_flag {
dds::catalog open() { return dds::catalog::open(Get()); }
};

struct num_jobs_flag : args::ValueFlag<int> {
num_jobs_flag(args::Group& cmd)
: ValueFlag(cmd,
"jobs",
"Set the number of parallel jobs when compiling files",
{"jobs", 'j'},
0) {}
};

/**
* Base class holds the actual argument parser
*/
@@ -494,11 +505,7 @@ struct cli_build {
"Path to an existing libman index from which to load deps (usually INDEX.lmi)",
{"lm-index", 'I'}};

args::ValueFlag<int> num_jobs{cmd,
"jobs",
"Set the number of parallel jobs when compiling files",
{"jobs", 'j'},
0};
num_jobs_flag n_jobs{cmd};

path_flag out{cmd,
"out",
@@ -510,7 +517,7 @@ struct cli_build {
dds::build_params params;
params.out_root = out.Get();
params.toolchain = tc_filepath.get_toolchain();
params.parallel_jobs = num_jobs.Get();
params.parallel_jobs = n_jobs.Get();
dds::package_manifest man;
const auto man_filepath = project.root.Get() / "package.dds";
if (exists(man_filepath)) {
@@ -559,6 +566,99 @@ struct cli_build {
}
};

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

struct cli_build_deps {
cli_base& base;
args::Command cmd{base.cmd_group,
"build-deps",
"Build a set of dependencies and emit a libman index"};

toolchain_flag tc{cmd};
repo_path_flag repo_path{cmd};
catalog_path_flag cat_path{cmd};
num_jobs_flag n_jobs{cmd};

args::ValueFlagList<dds::fs::path> deps_files{cmd,
"deps-file",
"Install dependencies from the named files",
{"deps", 'd'}};

path_flag out_path{cmd,
"out-path",
"Directory where build results should be placed",
{"out", 'o'},
dds::fs::current_path() / "_deps"};

path_flag lmi_path{cmd,
"lmi-path",
"Path to the output libman index file (INDEX.lmi)",
{"lmi-path"},
dds::fs::current_path() / "INDEX.lmi"};

args::PositionalList<std::string> deps{cmd, "deps", "List of dependencies to install"};

int run() {
dds::build_params params;
params.out_root = out_path.Get();
params.toolchain = tc.get_toolchain();
params.parallel_jobs = n_jobs.Get();

dds::builder bd;
dds::sdist_build_params sdist_params;

auto all_file_deps
= deps_files.Get() //
| ranges::views::transform([&](auto dep_fpath) {
spdlog::info("Reading deps from {}", dep_fpath.string());
return dds::package_manifest::load_from_file(dep_fpath).dependencies;
})
| ranges::actions::join;

auto cmd_deps = ranges::views::transform(deps.Get(), [&](auto dep_str) {
return dds::dependency::parse_depends_string(dep_str);
});

auto all_deps = ranges::views::concat(all_file_deps, cmd_deps) | ranges::to_vector;

auto cat = cat_path.open();
dds::repository::with_repository( //
repo_path.Get(),
dds::repo_flags::write_lock | dds::repo_flags::create_if_absent,
[&](dds::repository repo) {
// Download dependencies
spdlog::info("Loading {} dependencies", all_deps.size());
auto deps = repo.solve(all_deps, cat);
for (const dds::package_id& pk : deps) {
auto exists = !!repo.find(pk);
if (!exists) {
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);
}
auto sdist_ptr = repo.find(pk);
assert(sdist_ptr);
dds::sdist_build_params deps_params;
deps_params.subdir = sdist_ptr->manifest.pkg_id.to_string();
bd.add(*sdist_ptr, deps_params);
}
});

bd.build(params);
return 0;
}
};

} // namespace

/*
@@ -578,11 +678,12 @@ int main(int argc, char** argv) {
spdlog::set_pattern("[%H:%M:%S] [%^%-5l%$] %v");
args::ArgumentParser parser("DDS - The drop-dead-simple library manager");

cli_base cli{parser};
cli_build build{cli};
cli_sdist sdist{cli};
cli_repo repo{cli};
cli_catalog catalog{cli};
cli_base cli{parser};
cli_build build{cli};
cli_sdist sdist{cli};
cli_repo repo{cli};
cli_catalog catalog{cli};
cli_build_deps build_deps{cli};
try {
parser.ParseCLI(argc, argv);
} catch (const args::Help&) {
@@ -608,6 +709,8 @@ int main(int argc, char** argv) {
return repo.run();
} else if (catalog.cmd) {
return catalog.run();
} else if (build_deps.cmd) {
return build_deps.run();
} else {
assert(false);
std::terminate();

+ 7
- 7
tests/dds.py View File

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

def deps_build(self, *,
def build_deps(self, args: proc.CommandLine, *,
toolchain: str = None) -> subprocess.CompletedProcess:
return self.run([
'deps',
'build',
'build-deps',
f'--toolchain={toolchain or self.default_builtin_toolchain}',
self.repo_dir_arg,
f'--deps-build-dir={self.deps_build_dir}',
f'--repo-dir={self.repo_dir}',
f'--out={self.deps_build_dir}',
f'--lmi-path={self.lmi_path}',
args,
])

def build(self,
@@ -117,9 +117,9 @@ class DDS:
@property
def default_builtin_toolchain(self) -> str:
if os.name == 'posix':
return ':gcc-9'
return ':c++17:gcc-9'
elif os.name == 'nt':
return ':msvc'
return ':c++17:msvc'
else:
raise RuntimeError(
f'No default builtin toolchain defined for tests on platform "{os.name}"'

+ 4
- 0
tests/deps/build-deps/project/deps.dds View File

@@ -0,0 +1,4 @@
Name: dummy
Version: 0.0.0

Depends: neo-sqlite3 +0.0.0

+ 7
- 0
tests/deps/build-deps/test_build_deps.py View File

@@ -0,0 +1,7 @@
from tests import dds, DDS


def test_build_deps(dds: DDS):
assert not dds.deps_build_dir.is_dir()
dds.build_deps(['-d', 'deps.dds'])
assert dds.deps_build_dir.is_dir()

Loading…
Cancel
Save