| namespace dds { | namespace dds { | ||||
| /** | |||||
| * Iterate over every library defined as part of the build plan | |||||
| */ | |||||
| inline auto iter_libraries(const build_plan& plan) { | inline auto iter_libraries(const build_plan& plan) { | ||||
| return // | return // | ||||
| plan.packages() // | plan.packages() // | ||||
| ; | ; | ||||
| } | } | ||||
| /** | |||||
| * Return a range iterating over ever file compilation defined in the given build plan | |||||
| */ | |||||
| inline auto iter_compilations(const build_plan& plan) { | inline auto iter_compilations(const build_plan& plan) { | ||||
| auto lib_compiles = // | auto lib_compiles = // | ||||
| iter_libraries(plan) // | iter_libraries(plan) // |
| if (src_dir.exists()) { | if (src_dir.exists()) { | ||||
| // Sort each source file between the three source arrays, depending on | // Sort each source file between the three source arrays, depending on | ||||
| // the kind of source that we are looking at. | // the kind of source that we are looking at. | ||||
| auto all_sources = src_dir.sources(); | |||||
| auto all_sources = src_dir.collect_sources(); | |||||
| for (const auto& sfile : all_sources) { | for (const auto& sfile : all_sources) { | ||||
| if (sfile.kind == source_kind::test) { | if (sfile.kind == source_kind::test) { | ||||
| test_sources.push_back(sfile); | test_sources.push_back(sfile); |
| using namespace dds; | using namespace dds; | ||||
| std::vector<source_file> source_directory::sources() const { | |||||
| std::vector<source_file> source_directory::collect_sources() const { | |||||
| using namespace ranges::views; | using namespace ranges::views; | ||||
| // Strips nullopt elements and lifts the value from the results | |||||
| auto drop_nulls = // | |||||
| filter([](auto&& opt) { return opt.has_value(); }) // | |||||
| | transform([](auto&& opt) { return *opt; }); // | |||||
| // Collect all source files from the directory | // Collect all source files from the directory | ||||
| return // | return // | ||||
| fs::recursive_directory_iterator(path) // | fs::recursive_directory_iterator(path) // | ||||
| | filter([](auto&& entry) { return entry.is_regular_file(); }) // | | filter([](auto&& entry) { return entry.is_regular_file(); }) // | ||||
| | transform([&](auto&& entry) { return source_file::from_path(entry, path); }) // | | transform([&](auto&& entry) { return source_file::from_path(entry, path); }) // | ||||
| // source_file::from_path returns an optional. Drop nulls | // source_file::from_path returns an optional. Drop nulls | ||||
| | drop_nulls // | |||||
| | filter([](auto&& opt) { return opt.has_value(); }) // | |||||
| | transform([](auto&& opt) { return *opt; }) // | |||||
| | ranges::to_vector; | | ranges::to_vector; | ||||
| } | } |
| namespace dds { | namespace dds { | ||||
| /** | |||||
| * A `source_directory` is a simple wrapper type that provides type safety and utilities to | |||||
| * represent a source directory. | |||||
| */ | |||||
| struct source_directory { | struct source_directory { | ||||
| /// The actual path to the directory | |||||
| fs::path path; | fs::path path; | ||||
| std::vector<source_file> sources() const; | |||||
| /** | |||||
| * Generate a vector of every source file contained in this directory (including subdirectories) | |||||
| */ | |||||
| std::vector<source_file> collect_sources() const; | |||||
| /** | |||||
| * Check if the directory exists | |||||
| */ | |||||
| bool exists() const noexcept { return fs::exists(path); } | bool exists() const noexcept { return fs::exists(path); } | ||||
| }; | }; | ||||
| if (!fs::is_directory(include_dir.path)) { | if (!fs::is_directory(include_dir.path)) { | ||||
| throw std::runtime_error("The `include` at the root of the project is not a directory"); | throw std::runtime_error("The `include` at the root of the project is not a directory"); | ||||
| } | } | ||||
| auto inc_sources = include_dir.sources(); | |||||
| auto inc_sources = include_dir.collect_sources(); | |||||
| // Drop any source files we found within `include/` | // Drop any source files we found within `include/` | ||||
| erase_if(sources, [&](auto& info) { | erase_if(sources, [&](auto& info) { | ||||
| if (info.kind != source_kind::header) { | if (info.kind != source_kind::header) { | ||||
| if (!fs::is_directory(src_dir.path)) { | if (!fs::is_directory(src_dir.path)) { | ||||
| throw std::runtime_error("The `src` at the root of the project is not a directory"); | throw std::runtime_error("The `src` at the root of the project is not a directory"); | ||||
| } | } | ||||
| auto src_sources = src_dir.sources(); | |||||
| auto src_sources = src_dir.collect_sources(); | |||||
| extend(sources, src_sources); | extend(sources, src_sources); | ||||
| } | } | ||||