current commit
230531.11 · Moved headers inside a hypergrep namespace directory
#pragma once
#include <argparse/argparse.hpp>
#include <atomic>
#include <chrono>
#include <concurrentqueue/concurrentqueue.h>
#include <fcntl.h>
#include <filesystem>
#include <fmt/color.h>
#include <fmt/format.h>
#include <fstream>
#include <git2.h>
#include <hs/hs.h>
#include <hypergrep/compiler.hpp>
#include <hypergrep/constants.hpp>
#include <hypergrep/file_filter.hpp>
#include <hypergrep/file_search.hpp>
#include <hypergrep/is_binary.hpp>
#include <hypergrep/match_handler.hpp>
#include <hypergrep/search_options.hpp>
#include <hypergrep/size_to_bytes.hpp>
#include <limits>
#include <numeric>
#include <sys/mman.h>
#include <sys/stat.h>
#include <thread>
#include <unistd.h>
#include <vector>

class git_index_search {
public:
  git_index_search(std::string &pattern, const std::filesystem::path &path,
                   argparse::ArgumentParser &program);
  git_index_search(hs_database_t *database, hs_scratch_t *scratch,
                   hs_database_t *file_filter_database,
                   hs_scratch_t *file_filter_scratch,
                   const search_options &options,
                   const std::filesystem::path &path);
  ~git_index_search();
  void run(std::filesystem::path path);

private:
  bool process_file(const char *filename, hs_scratch_t *local_scratch,
                    char *buffer, std::string &lines);

  bool search_submodules(const char *dir, git_repository *this_repo);

  bool visit_git_index(const std::filesystem::path &dir, git_index *index);

  bool visit_git_repo(const std::filesystem::path &dir,
                      git_repository *repo = nullptr);

  bool try_dequeue_and_process_path(hs_scratch_t *local_scratch, char *buffer,
                                    std::string &lines);

  void search_thread_function();

private:
  static inline bool libgit2_initialized{false};
  std::filesystem::path basepath{};

  moodycamel::ConcurrentQueue<const char *> queue;
  moodycamel::ProducerToken ptok{queue};

  std::atomic<bool> running{true};
  std::atomic<std::size_t> num_files_enqueued{0};
  std::atomic<std::size_t> num_files_dequeued{0};

  bool non_owning_database{false};
  hs_database_t *database = NULL;
  hs_scratch_t *scratch = NULL;
  hs_database_t *file_filter_database = NULL;
  hs_scratch_t *file_filter_scratch = NULL;
  // If the filter pattern starts with '!'
  // then negate the result of the filter
  bool negate_filter{false};

  search_options options;

  std::vector<git_repository *> garbage_collect_repo;
  std::vector<git_index *> garbage_collect_index;
  std::vector<git_index_iterator *> garbage_collect_index_iterator;

  // Backlog
  std::vector<std::filesystem::path> submodule_paths;
};