Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart grouping in updated file list #22

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix windows infinite loop bug
  • Loading branch information
Quincunx271 committed Jun 2, 2019
commit cf1a914bec4ea5035183318e04c1c8811ae94f27
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ build/
*.pyc
_pmm/
.vscode/
.vs/
33 changes: 14 additions & 19 deletions src/pf/existing/detect_base_dir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string>
#include <utility>

#include <boost/range/iterator_range.hpp>
#include <range/v3/algorithm/find_if.hpp>

namespace fs = pf::fs;

Expand All @@ -30,25 +30,20 @@ std::optional<fs::path> parse_cmakecache_homedir(fs::path const& cmakecache) {
} // namespace

std::optional<fs::path> pf::detect_base_dir(fs::path from_dir) {
auto cur_dir = std::find_if(pf::ascending_iterator{from_dir},
pf::ascending_iterator{},
[](auto const& dir) {
return fs::exists(dir / "CMakeLists.txt")
|| fs::exists(dir / "CMakeCache.txt");
});

if (cur_dir == pf::ascending_iterator{}) {
return std::nullopt;
}
auto ascending_from = pf::ascending_paths(from_dir);
auto cur_dir = ranges::find_if(ascending_from, [](auto const& dir) {
return fs::exists(dir / "CMakeLists.txt") || fs::exists(dir / "CMakeCache.txt");
});

// Iterator always valid, but may be root dir `/`.
if (fs::exists(*cur_dir / "CMakeLists.txt")) {
return *std::find_if(pf::ascending_iterator{*cur_dir},
pf::ascending_iterator{},
[](auto const& path) {
return !fs::exists(path.parent_path() / "CMakeLists.txt");
});
auto ascending_cur = pf::ascending_paths(*cur_dir);
return *ranges::find_if(ascending_cur, [](auto const& path) {
return !fs::exists(path.parent_path() / "CMakeLists.txt");
});
} else if (fs::exists(*cur_dir / "CMakeCache.txt")) {
return ::parse_cmakecache_homedir(*cur_dir / "CMakeCache.txt");
} else {
return std::nullopt;
}

// There's a CMakeCache
return ::parse_cmakecache_homedir(*cur_dir / "CMakeCache.txt");
}
2 changes: 1 addition & 1 deletion src/pf/fs.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef PF_FS_HPP_INCLUDED
#define PF_FS_HPP_INCLUDED

#include <pf/fs/ascending_iterator.hpp>
#include <pf/fs/ascending_paths.hpp>
#include <pf/fs/core.hpp>
#include <pf/fs/glob.hpp>

Expand Down
1 change: 0 additions & 1 deletion src/pf/fs/ascending_iterator.cpp

This file was deleted.

53 changes: 0 additions & 53 deletions src/pf/fs/ascending_iterator.hpp

This file was deleted.

5 changes: 5 additions & 0 deletions src/pf/fs/ascending_paths.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "./ascending_paths.hpp"

#include <range/v3/range_concepts.hpp>

CONCEPT_ASSERT(ranges::InputRange<pf::ascending_paths>());
77 changes: 77 additions & 0 deletions src/pf/fs/ascending_paths.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef PF_FS_ASCENDING_PATHS_HPP_INCLUDED
#define PF_FS_ASCENDING_PATHS_HPP_INCLUDED

#include <iterator>
#include <utility>

#include <pf/fs/core.hpp>

namespace pf {

class ascending_paths {
class sentinel {};

class iterator {
public:
using value_type = fs::path;
using reference = value_type const&;
using pointer = value_type const*;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;

iterator() = default;

iterator(sentinel)
: iterator() {}

explicit iterator(fs::path current)
: current_{std::move(current)} {}

iterator& operator++() {
current_ = current_.parent_path();
return *this;
}

iterator operator++(int) {
auto cpy = *this;
current_ = current_.parent_path();
return cpy;
}

reference operator*() const { return current_; }
pointer operator->() const { return &**this; }

friend bool operator==(iterator const& it, sentinel) {
// ``path.parent_path()`` returns ``path`` if ``!has_relative_path()``,
// which is how we know that we've reached the end.
return !it.current_.has_relative_path();
}

friend bool operator==(sentinel end, iterator const& it) { return it == end; }
friend bool operator!=(iterator const& it, sentinel end) { return !(it == end); }
friend bool operator!=(sentinel end, iterator const& it) { return !(it == end); }

friend bool operator==(iterator const& lhs, iterator const& rhs) {
return lhs.current_ == rhs.current_;
}
friend bool operator!=(iterator const& lhs, iterator const& rhs) { return !(lhs == rhs); }

private:
fs::path current_ = {"/"};
};

public:
// Canonicalize, such that the path doesn't need to exist
explicit ascending_paths(fs::path const& p)
: current_{fs::weakly_canonical(p)} {}

iterator begin() const { return iterator{current_}; }
sentinel end() const { return sentinel{}; }

private:
fs::path current_;
};

} // namespace pf

#endif // PF_FS_ASCENDING_PATHS_HPP_INCLUDED
16 changes: 13 additions & 3 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set(PF_TEST_BINDIR "${CMAKE_CURRENT_BINARY_DIR}")
set(PF_TEST_SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}")

add_library(pf-test-lib STATIC test-main.cpp compare_fs.hpp compare_fs.cpp)
target_link_libraries(pf-test-lib PUBLIC Catch2::Catch2 pf::pitchfork)
target_link_libraries(pf-test-lib PUBLIC Catch2::Catch2 pf::pitchfork range-v3)
target_compile_definitions(pf-test-lib
PUBLIC
"PF_TEST_BINDIR=\"${CMAKE_CURRENT_BINARY_DIR}\""
Expand Down Expand Up @@ -37,13 +37,14 @@ endfunction()

function(pf_add_query_test ID)
set(options)
set(list_args PASS_REGULAR_EXPRESSION FAIL_REGULAR_EXPRESSION)
set(args)
set(list_args COMMAND PASS_REGULAR_EXPRESSION FAIL_REGULAR_EXPRESSION)

cmake_parse_arguments(PARSE_ARGV 1 ARG "${options}" "${args}" "${list_args}")

add_test(
NAME "query:${ID}"
COMMAND pf query "${ID}"
COMMAND ${ARG_COMMAND}
)
set_tests_properties("query:${ID}"
PROPERTIES
Expand All @@ -59,6 +60,15 @@ pf_add_test_exe(existing
existing/update_source_files.cpp)
configure_directory(existing/sample)

pf_add_test_exe(test.lib
fs/ascending_paths.cpp
)

pf_add_query_test(project.root
COMMAND pf query project.root
PASS_REGULAR_EXPRESSION "${PROJECT_SOURCE_DIR}"
)
pf_add_query_test(project.root.specified
COMMAND pf "--base-dir=/some/absolute/path" query project.root
PASS_REGULAR_EXPRESSION "/some/absolute/path" "C:\\\\some\\\\absolute\\\\path"
)
31 changes: 31 additions & 0 deletions tests/fs/ascending_paths.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <pf/fs/ascending_paths.hpp>

#include <range/v3/algorithm/reverse.hpp>
#include <range/v3/to_container.hpp>
#include <range/v3/view/drop_while.hpp>
#include <range/v3/view/partial_sum.hpp>

#include <catch2/catch.hpp>

namespace fs = std::filesystem;

TEST_CASE("ascending_paths makes sense") {
fs::path p = GENERATE(values({
fs::path{""},
fs::current_path(),
fs::path{"/some/long/path/that/probably/doesnt/exist"},
}));
CAPTURE(p);

std::vector<fs::path> const result = pf::ascending_paths(p) | ranges::to_vector;

std::vector<fs::path> expected = fs::weakly_canonical(p)
| ranges::view::partial_sum([](fs::path const& lhs, fs::path const& rhs) {
return lhs / rhs;
})
| ranges::view::drop_while([](fs::path const& p) { return !p.has_relative_path(); })
| ranges::to_vector;
ranges::reverse(expected);

CHECK(result == expected);
}