diff options
author | Adrian Kummerlaender | 2015-12-24 00:11:06 +0100 |
---|---|---|
committer | Adrian Kummerlaender | 2015-12-24 00:11:06 +0100 |
commit | baf30b7b83822b7d6efd0c16761b8e42a1e96101 (patch) | |
tree | 33eebf92abdde2f2cfbba138bb506529a332955e /src/tracking | |
parent | cce63aca270c51fb3ce9790438e3c23864de0a87 (diff) | |
download | change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar.gz change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar.bz2 change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar.lz change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar.xz change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.tar.zst change-baf30b7b83822b7d6efd0c16761b8e42a1e96101.zip |
Match namespace and directory structure
Diffstat (limited to 'src/tracking')
-rw-r--r-- | src/tracking/change_tracker.cc | 92 | ||||
-rw-r--r-- | src/tracking/change_tracker.h | 32 |
2 files changed, 124 insertions, 0 deletions
diff --git a/src/tracking/change_tracker.cc b/src/tracking/change_tracker.cc new file mode 100644 index 0000000..913604e --- /dev/null +++ b/src/tracking/change_tracker.cc @@ -0,0 +1,92 @@ +#include "change_tracker.h" + +#include <boost/optional.hpp> +#include <boost/filesystem/fstream.hpp> + +namespace { + +// constants for increasing pair access readability +constexpr unsigned int EMPLACE_SUCCESS = 1; +constexpr unsigned int FILE_NAME = 0; +constexpr unsigned int DIFF_PROCESS = 1; + +boost::process::context getDefaultContext() { + boost::process::context context; + + context.environment = boost::process::self::get_environment(); + context.stdout_behavior = boost::process::capture_stream(); + context.stdin_behavior = boost::process::capture_stream(); + + return context; +} + +} + +namespace tracking { + +ChangeTracker::ChangeTracker(utility::Logger* logger): + logger_(logger), + children_() { } + +ChangeTracker::~ChangeTracker() { + for ( auto&& tracked : this->children_ ) { + std::get<DIFF_PROCESS>(tracked)->get_stdin().close(); + + this->logger_->forward(std::get<DIFF_PROCESS>(tracked)->get_stdout()); + + tracked.second->wait(); + } +} + +bool ChangeTracker::is_tracked(const std::string& file_path) const { + return this->children_.find(file_path) != this->children_.end(); +} + +// Begins tracking changes to a file reachable by a given path +// +// The actual tracking is performed by a `diff` instance that is +// spawned by this method and managed by this class. +// As `diff` is called as a new subprocess and because there is no +// straight forward way for checking / enforcing if it has already +// completed reading the initial contents of the file the command +// is structured in the following sequence: +// +// diff -p - $file_path +// +// This means that reading the final file contents is delegated to +// `diff` while the initial file contents are read by this method +// and written to `diff`'s standard input. +// +// If the `-` and `$file_path` arguments were exchanged there would +// be no way to: +// - be sure the initial contents are read before the changing +// syscall that triggered this tracking in the first place is +// performed +// - be sure that the initial file contents are read completly +// as `diff` seemingly only reads the first block of the first +// file provided if the second file argument is standard input +// +bool ChangeTracker::track(const std::string& file_path) { + auto result = this->children_.emplace( + file_path, + std::make_unique<boost::process::child>( + boost::process::launch_shell("diff -p - " + file_path, getDefaultContext()) + ) + ); + + if ( std::get<EMPLACE_SUCCESS>(result) ) { + boost::filesystem::ifstream file( + std::get<FILE_NAME>(*result.first) + ); + + if ( file.is_open() ) { + std::get<DIFF_PROCESS>(*result.first)->get_stdin() << file.rdbuf(); + } + + return true; + } else { + return false; + } +} + +} diff --git a/src/tracking/change_tracker.h b/src/tracking/change_tracker.h new file mode 100644 index 0000000..54af4f7 --- /dev/null +++ b/src/tracking/change_tracker.h @@ -0,0 +1,32 @@ +#ifndef CHANGE_SRC_TRACKING_CHANGE_TRACKER_H_ +#define CHANGE_SRC_TRACKING_CHANGE_TRACKER_H_ + +#include <unordered_map> + +#include <boost/process.hpp> + +#include "utility/logger.h" + +namespace tracking { + +class ChangeTracker { + public: + ChangeTracker(utility::Logger*); + ~ChangeTracker(); + + bool is_tracked(const std::string&) const; + + bool track(const std::string&); + + private: + utility::Logger* const logger_; + + std::unordered_map< + std::string, std::unique_ptr<boost::process::child> + > children_; + +}; + +} + +#endif // CHANGE_SRC_TRACKING_CHANGE_TRACKER_H_ |