Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Antler project changes #9

Merged
merged 16 commits into from
Mar 13, 2023
Merged

Antler project changes #9

merged 16 commits into from
Mar 13, 2023

Conversation

larryk85
Copy link
Contributor

@larryk85 larryk85 commented Mar 6, 2023

There is still more I have to do this. But getting the review started will be great and getting docs in line with this will also be good.

It is functioning, the external deps is still nerfed for right now, I will fix my branch and push those changes later today/tonight.

Quite a few changes have occurred.

You can play around with creating a project and smart contract and see how it works and test it for me. You can also pull the repo https://github.com/larryk85/antler-proj-hello-example for an example of a project that uses libraries and dependencies. It should fully propagate and build that project.

Apologies, I have more tests but they are in a few commits that I rolled back so that you can start the review today with something that you can use. Later today I will add those back along with throwing in the implementation to fully support the external dependencies.

@@ -108,40 +98,12 @@ object::type_t object::type() const noexcept {


void object::upsert_dependency(antler::project::dependency&& dep) noexcept {
// If possible, find a dependency with matching name and reutrn it.
// If possible, find a dependency with matching name and reurrn it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return

@jolly-fellow
Copy link
Contributor

You can play around with creating a project and smart contract and see how it works and test it for me. You can also pull the repo https://github.com/larryk85/antler-proj-hello-example for an example of a project that uses libraries and dependencies. It should fully propagate and build that project.

IMHO it should be https://github.com/larryk85/antler-proj-example-hello

/// @param opts Compile time options for this object. May be empty.
object(type_t ot, std::string_view name, antler::project::language lang, std::string_view opts);
/// @param copts Compile time options for this object. May be empty.
/// @param lopts Compile time options for this object. May be empty.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compile time options -> Linker options

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

type_t m_type = none; ///< Object type: app, lib, or test.
std::string m_name; ///< Object name.
type_t m_type = type_t::error; ///< Object type: app, lib, or test.
std::string m_name = ""; ///< Object name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like same as default construction. What is the reason for having that set explicitly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No just missed that.

std::size_t i=0, p=0;

for (; i < s.size(); i++) {
if (detail::is_delim<Delims...>(s[i])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can get rid of lines 38-39 adding something like this:

if (detail::is_delim<Delims...>(s[i]) || i+1 == s.size()) { ... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will never pickup the last character of the final substring.

@@ -33,17 +37,18 @@ namespace { // anonymous
/// @return An optional string that is populated with the file contents *if* the load was successful; otherwise, it's invalid for any error.
[[nodiscard]] std::optional<std::string> load(const std::filesystem::path& path, std::ostream& os) {
Copy link
Contributor

@dimas1185 dimas1185 Mar 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like we pass cerr stream as a class method parameter.
If we want to substitute entire cerr for unit tests purposes we can do it same way we have it in native library when we use _prints. So I recommend at least add TODO section about this for future

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed all of the error logging in another branch to fix some other issues that will be a follow on to this one.


/// Test to see if a file has the magic maintenance string.
/// @return true if the file either does NOT exist OR contains the magic
[[nodiscard]] bool has_magic(const std::filesystem::path& path, std::ostream& error_stream = std::cerr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the other branch to follow this PR all of the project-parse and project-populate has collapsed to just a handful of type overloads for yaml conversions. So, I can make any changes here, but they will be gone anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misspoke, project-print and parse have collapsed into a handful of conversion struct overloads.

Populate has transformed into a 'cmake' class that is handling all of the population so we can possibly change the 'backend' at a later date.

inline static c4::csubstr to_csubstr(std::string_view sv) noexcept { return {sv.data(), sv.size()}; }
inline static c4::csubstr to_csubstr(token tok) noexcept { return to_csubstr(system::to_string(tok)); }
inline static c4::csubstr to_csubstr(version v) noexcept { return to_csubstr(v.to_string()); }

void project::print(std::ostream& os) const noexcept {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion to remove stream passed as a parameter. At least add TODO section about that

//--- alphabetic --------------------------------------------------------------------------------------------------------

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add TODO: remove error stream passed as a parameter in future in favor of other system (probably like we have innative library)

"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs)\n"
"add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)\n\n";

REQUIRE( ss.str() == cmake_preamble_expected );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test fails on my machine

Copy link
Contributor

@dimas1185 dimas1185 Mar 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

antler-proj/tests/cmake_tests.cpp:30: FAILED:
REQUIRE( ss.str() == cmake_preamble_expected )
with expansion:
"# Generated with antler-proj tool, modify at your own risk
cmake_minimum_required(VERSION 3.11)
project("test_proj" VERSION 1.0.0)

"

"# Generated with antler-proj tool, modify at your own risk
cmake_minimum_required(VERSION 3.13)
project("test_proj" VERSION 1.0.0)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/apps)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)

"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these tests have been rewritten in the latest branch.

/// @param error_stream The stream to print failure reports to.
/// @return true for success; false indidates failure.
[[nodiscard]] static bool init_dirs(const std::filesystem::path& path, bool expect_empty = true, std::ostream& error_stream = std::cerr) noexcept;
[[nodiscard]] static bool init_dirs(const std::filesystem::path& path, std::ostream& error_stream = std::cerr) noexcept;

/// Search this and directories above for `project.yaml` file.
/// @note if path extension is `.yaml` no directory search is performed, instead return value indicating existence of path a regular file.
/// @param path This is the search path to begin with; if the project file was found, it is updated to the path to that file.
/// @return true if the project file was found and is a regular file; otherwise, false.
[[nodiscard]] static bool update_path(std::filesystem::path& path) noexcept;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this interface seems to me too non-standard and confusing. I would redo this into something like this:

   [[nodiscard]] static std::filesystem::path find_project(const std::filesystem::path& search_path) noexcept;

inline bool remove_file(std::string_view fn) { return std::filesystem::remove_all(fn); }

inline bool load_project(std::string_view fn, antler::project::project& proj) {
auto p = std::filesystem::canonical(std::filesystem::path(fn));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if that is needed, maybe we should move canonical conversion into update_path?

struct source <object::type_t::app> {
inline static void create_source_file(std::filesystem::path p, const object& obj) {
std::string name = std::string(obj.name());
p /= std::filesystem::path("apps") / name / (name+".cpp");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are using filesystem::path a lot, I suggest to make a literal to reduce verbosity

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std doesn't have a literal for path, we could add one. But, I would argue the major gain we would get here.

REQUIRE(load_project("./foo", proj));

// should fail if directory exists
REQUIRE(!proj.init_dirs(std::filesystem::path("./foo")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

antler-proj/tests/init_tests.cpp:24: FAILED:
REQUIRE( !proj.init_dirs(std::filesystem::path("./foo")) )
with expansion:
false

@@ -1,4 +1,4 @@
#include <test_common.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this test, string::from is unused

std::filesystem::create_directory(bin_dir);
std::string cmake_cmd = "cmake -S " + build_dir.string() + " -B " + bin_dir.string();

return system::execute("cmake -S " + build_dir.string() + " -B " + bin_dir.string()); //cmake_cmd);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove debug comment


inline bool remove_file(std::string_view fn) { return std::filesystem::remove_all(fn); }

inline bool load_project(std::string_view fn, antler::project::project& proj) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have almost identical function in tools/common.hpp. likely it can be reused

: tup(depends<Ts>(app)...) {}

template <std::size_t I=0>
constexpr inline int exec() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per the code it calls exec from first tuple element that has subcommand pointer. Was this an intention?
if so it seems to me that we don't need it and can simply call antler::add_to_project.exec() directly.
If this supposed to call exec for every element with subcommand available, it should be redone.

Copy link
Contributor Author

@larryk85 larryk85 Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subcommand in this case is a lexical interface that is only populated when the particular subcommand is given on the command line.

So, antler-proj add will create a subcommand so that elements subcommand will be true, if antler-proj remove is called then that's subcommand will be created and its exec will be called.

Its not designed to work with multiple subcommands being called at once, you can't do that via the command line system any how.

Also, by creating I mean that CLI11 will populate that subcommand and it overloads the bool conversion operator. So, true means the subcommand has been seen in the command string.

for (auto& o : objs) {
if (o.remove_dependency(dep)) {
std::cout << "Removing dependency: " << dep << " from: " << o.name() << std::endl;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add else for tracking errors and perhaps move lambda out of this block so we can reuse it to replace lines 40-46

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't really an error here, it is a glob remove dependency. So it is perfectly valid to call with a dependency that the system doesn't even have. It would be a bit much to print that it didn't remove it from every other object in the system.

Copy link
Contributor

@dimas1185 dimas1185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order of importance:

  • two tests failed on my machine: must be fixed
  • there are few comments for cleanup unused code and minor refactor that are nice to consider or add TODO for future. It should take ~30 minutes for those changes

Copy link
Contributor

@dimas1185 dimas1185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on daily call discussion, I'm approving this PR as an exception as there is another branch that supposed to overwrite it and replace tests

@ScottBailey
Copy link
Contributor

based on daily call discussion, I'm approving this PR as an exception as there is another branch that supposed to overwrite it and replace tests

Same.

Copy link
Contributor

@ScottBailey ScottBailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving as a development change. Upcoming PRs will address problems here and there's little point in investing significant energy into this PR.

@ScottBailey ScottBailey merged commit fc772a7 into initial_dev Mar 13, 2023
@ScottBailey ScottBailey deleted the larryk85/proj-changes branch March 13, 2023 15:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants