Browse Source

Source distribution logic

default_compile_flags
vector-of-bool 5 years ago
parent
commit
d37eb7aba2
5 changed files with 202 additions and 19 deletions
  1. +62
    -19
      src/dds/ddslim.main.cpp
  2. +67
    -0
      src/dds/sdist.cpp
  3. +18
    -0
      src/dds/sdist.hpp
  4. +24
    -0
      src/dds/temp.cpp
  5. +31
    -0
      src/dds/temp.hpp

+ 62
- 19
src/dds/ddslim.main.cpp View File

@@ -1,5 +1,6 @@
#include <dds/build.hpp>
#include <dds/logging.hpp>
#include <dds/sdist.hpp>
#include <dds/util.hpp>
#include <libman/parse.hpp>

@@ -20,28 +21,61 @@ struct cli_base {
args::Group cmd_group{parser, "Available Commands"};
};

struct cli_build {
cli_base& base;
args::Command cmd{base.cmd_group, "build", "Build a library"};
struct common_flags {
args::Command& cmd;

args::HelpFlag _help{cmd, "help", "Print this hellp message and exit", {'h', "help"}};
};

args::HelpFlag _help{cmd, "help", "Display this help message and exit", {'h', "help"}};
struct common_project_flags {
args::Command& cmd;

path_flag lib_dir{cmd,
"lib_dir",
"The path to the directory containing the library",
{"lib-dir"},
dds::fs::current_path()};
path_flag out_dir{cmd,
"out_dir",
"The directory in which to write the built files",
{"out-dir"},
dds::fs::current_path() / "_build"};
path_flag root{cmd,
"project_dir",
"Path to the directory containing the project",
{"project-dir"},
dds::fs::current_path()};

string_flag export_name{cmd,
"export_name",
"Set the name of the export",
{"export-name", 'n'},
"Set the name of othe project",
{'n', "export-name"},
dds::fs::current_path().filename().string()};
};

struct cli_sdist {
cli_base& base;
args::Command cmd{base.cmd_group, "sdist", "Create a source distribution of a project"};

common_flags _common{cmd};

common_project_flags project{cmd};

path_flag out{cmd,
"out",
"The full destination of the source distribution",
{"out"},
dds::fs::current_path() / "project.dsd"};

args::Flag force{cmd, "force", "Forcibly replace an existing result", {"force"}};

int run() {
dds::sdist_params params;
params.project_dir = project.root.Get();
params.dest_path = out.Get();
params.force = force.Get();
dds::create_sdist(params);
return 0;
}
};

struct cli_build {
cli_base& base;
args::Command cmd{base.cmd_group, "build", "Build a project"};

common_flags _common{cmd};

common_project_flags project{cmd};

string_flag tc_filepath{cmd,
"toolchain_file",
@@ -75,6 +109,12 @@ struct cli_build {
{"jobs", 'j'},
0};

path_flag out{cmd,
"out",
"The root build directory",
{"out"},
dds::fs::current_path() / "_build"};

dds::toolchain _get_toolchain() {
const auto tc_path = tc_filepath.Get();
if (tc_path.find(":") == 0) {
@@ -92,9 +132,9 @@ struct cli_build {

int run() {
dds::build_params params;
params.root = lib_dir.Get();
params.out_root = out_dir.Get();
params.export_name = export_name.Get();
params.root = project.root.Get();
params.out_root = out.Get();
params.export_name = project.export_name.Get();
params.toolchain = _get_toolchain();
params.do_export = export_.Get();
params.build_tests = build_tests.Get();
@@ -126,6 +166,7 @@ int main(int argc, char** argv) {

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

+ 67
- 0
src/dds/sdist.cpp View File

@@ -0,0 +1,67 @@
#include "./sdist.hpp"

#include <dds/project.hpp>
#include <dds/temp.hpp>

#include <range/v3/algorithm/for_each.hpp>
#include <range/v3/view/filter.hpp>

#include <spdlog/spdlog.h>

using namespace dds;

namespace {

void sdist_copy_library(path_ref out_root, const library& lib, const sdist_params& params) {
auto sources_to_keep = //
lib.sources() //
| ranges::view::filter([&](const source_file& sf) {
if (sf.kind == source_kind::source || sf.kind == source_kind::header) {
return true;
}
if (sf.kind == source_kind::app && params.include_apps) {
return true;
}
if (sf.kind == source_kind::test && params.include_tests) {
return true;
}
return false;
});

spdlog::info("Export library source from {}", lib.base_dir().string());
for (const auto& source : sources_to_keep) {
auto relpath = fs::relative(source.path, lib.base_dir());
spdlog::info("Copy source file {}", relpath.string());
auto dest = out_root / relpath;
fs::create_directories(dest.parent_path());
fs::copy(source.path, dest);
}
}

} // namespace

void dds::create_sdist(const sdist_params& params) {
auto dest = params.dest_path;
if (fs::exists(dest)) {
if (!params.force) {
throw std::runtime_error(
fmt::format("Destination path '{}' already exists", dest.string()));
}
}

auto tempdir = temporary_dir::create();
create_sdist_in_dir(tempdir.path(), params);
if (fs::exists(dest) && params.force) {
fs::remove_all(params.dest_path);
}
fs::create_directories(params.dest_path.parent_path());
safe_rename(tempdir.path(), params.dest_path);
spdlog::info("Source distribution created in {}", params.dest_path.string());
}

void dds::create_sdist_in_dir(path_ref out, const sdist_params& params) {
auto project = project::from_directory(params.project_dir);
if (project.main_library()) {
sdist_copy_library(out, *project.main_library(), params);
}
}

+ 18
- 0
src/dds/sdist.hpp View File

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

#include <dds/util.hpp>

namespace dds {

struct sdist_params {
fs::path project_dir;
fs::path dest_path;
bool force = false;
bool include_apps = false;
bool include_tests = false;
};

void create_sdist(const sdist_params&);
void create_sdist_in_dir(path_ref, const sdist_params&);

} // namespace dds

+ 24
- 0
src/dds/temp.cpp View File

@@ -0,0 +1,24 @@
#include "./temp.hpp"

using namespace dds;

temporary_dir temporary_dir::create() {
auto base = fs::temp_directory_path();
auto file = (base / "dds-tmp-XXXXXX").string();

const char* tempdir_path = ::mktemp(file.data());

if (tempdir_path == nullptr) {
throw std::system_error(std::error_code(errno, std::system_category()),
"Failed to create a temporary directory");
}
auto path = fs::path(tempdir_path);
return std::make_shared<impl>(std::move(path));
}

temporary_dir::impl::~impl() {
std::error_code ec;
if (fs::exists(path, ec)) {
fs::remove_all(path, ec);
}
}

+ 31
- 0
src/dds/temp.hpp View File

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

#include <dds/util.hpp>

#include <memory>

namespace dds {

class temporary_dir {
struct impl {
fs::path path;
explicit impl(path_ref p)
: path(p) {}

impl(const impl&) = delete;

~impl();
};

std::shared_ptr<impl> _ptr;

temporary_dir(std::shared_ptr<impl> p)
: _ptr(p) {}

public:
static temporary_dir create();

path_ref path() const noexcept { return _ptr->path; }
};

} // namespace dds

Loading…
Cancel
Save