Browse Source

Manager: Add feature to selectively comment and uncomment

master
Riyyi 3 years ago
parent
commit
abbf764a3e
  1. 113
      src/dotfile.cpp
  2. 4
      src/dotfile.h
  3. 9
      src/util/file.cpp
  4. 3
      src/util/file.h

113
src/dotfile.cpp

@ -17,6 +17,7 @@
#include "dotfile.h"
#include "machine.h"
#include "util/file.h"
std::vector<Dotfile::ExcludePath> Dotfile::s_excludePaths;
std::vector<std::filesystem::path> Dotfile::s_systemDirectories;
@ -70,7 +71,7 @@ void Dotfile::add(const std::vector<std::string>& targets)
}
sync(
targets, homeIndices, systemIndices,
SyncType::Pull, targets, homeIndices, systemIndices,
[](std::string* paths, const std::string& homePath, const std::string& homeDirectory) {
paths[0] = homePath;
paths[1] = homePath.substr(homeDirectory.size() + 1);
@ -129,7 +130,7 @@ void Dotfile::pullOrPush(SyncType type, const std::vector<std::string>& targets)
if (type == SyncType::Pull) {
sync(
dotfiles, homeIndices, systemIndices,
type, dotfiles, homeIndices, systemIndices,
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
// homeFile = /home/<user>/dotfiles/<file>
// copy: /home/<user>/<file> -> /home/<user>/dotfiles/<file>
@ -145,7 +146,7 @@ void Dotfile::pullOrPush(SyncType type, const std::vector<std::string>& targets)
}
else {
sync(
dotfiles, homeIndices, systemIndices,
type, dotfiles, homeIndices, systemIndices,
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
// homeFile = /home/<user>/dotfiles/<file>
// copy: /home/<user>/dotfiles/<file> -> /home/<user>/<file>
@ -161,7 +162,8 @@ void Dotfile::pullOrPush(SyncType type, const std::vector<std::string>& targets)
}
}
void Dotfile::sync(const std::vector<std::string>& paths, const std::vector<size_t>& homeIndices, const std::vector<size_t>& systemIndices,
void Dotfile::sync(SyncType type,
const std::vector<std::string>& paths, const std::vector<size_t>& homeIndices, const std::vector<size_t>& systemIndices,
const std::function<void(std::string*, const std::string&, const std::string&)>& generateHomePaths,
const std::function<void(std::string*, const std::string&)>& generateSystemPaths)
{
@ -223,13 +225,116 @@ void Dotfile::sync(const std::vector<std::string>& paths, const std::vector<size
std::string homePaths[2];
generateHomePaths(homePaths, paths.at(i), homeDirectory);
copy(homePaths[0], homePaths[1], true);
if (type == SyncType::Push) {
selectivelyCommentOrUncomment(homePaths[1]);
}
}
// /
for (size_t i : systemIndices) {
std::string systemPaths[2];
generateSystemPaths(systemPaths, paths.at(i));
copy(systemPaths[0], systemPaths[1], false);
if (type == SyncType::Push) {
selectivelyCommentOrUncomment(systemPaths[1]);
}
}
}
void Dotfile::selectivelyCommentOrUncomment(const std::string& path)
{
Util::File dotfile(path);
const std::string search[3] = {
"distro=",
"hostname=",
"user=",
};
// State of the loop
bool isFiltering = false;
std::string filter[3];
std::string commentCharacter;
size_t positionInFile = 0;
auto commentOrUncommentLine = [&](std::string& line, bool addComment) {
size_t lineLength = line.size();
size_t whiteSpaceBeforeComment = line.find_first_of(commentCharacter);
size_t contentAfterComment = line.find_first_not_of(commentCharacter + " \t");
// If there was no comment, grab whitespace correctly
if (whiteSpaceBeforeComment == std::string::npos) {
whiteSpaceBeforeComment = contentAfterComment;
}
if (!addComment) {
line = line.substr(0, whiteSpaceBeforeComment)
+ line.substr(contentAfterComment);
}
else {
line = line.substr(0, whiteSpaceBeforeComment)
+ commentCharacter + ' '
+ line.substr(contentAfterComment);
}
dotfile.replace(positionInFile, lineLength, line);
};
std::istringstream stream(dotfile.data());
for (std::string line; std::getline(stream, line); positionInFile += line.size() + 1) {
if (line.find(">>>") != std::string::npos) {
// Find machine info
size_t find = 0;
for (size_t i = 0; i < 3; ++i) {
find = line.find(search[i]) + search[i].size();
if (find < search[i].size()) {
continue;
}
filter[i] = line.substr(find, line.find_first_of(' ', find) - find);
}
// Get the characters used for commenting in this file-type
commentCharacter = line.substr(0, line.find_first_of(">>>"));
for (size_t i = commentCharacter.size() - 1; i != std::string::npos; --i) {
if (commentCharacter.at(i) == ' ' || commentCharacter.at(i) == '\t') {
commentCharacter.erase(i, 1);
}
}
isFiltering = true;
continue;
}
if (line.find("<<<") != std::string::npos) {
isFiltering = false;
filter[0] = "";
filter[1] = "";
filter[2] = "";
commentCharacter.clear();
continue;
}
if (!isFiltering) {
continue;
}
if (filter[0] != Machine::the().distroId() && !filter[0].empty()) {
commentOrUncommentLine(line, true);
continue;
}
else if (filter[1] != Machine::the().hostname() && !filter[1].empty()) {
commentOrUncommentLine(line, true);
continue;
}
else if (filter[2] != Machine::the().username() && !filter[2].empty()) {
commentOrUncommentLine(line, true);
continue;
}
commentOrUncommentLine(line, false);
}
dotfile.flush();
}
void Dotfile::forEachDotfile(const std::vector<std::string>& targets, const std::function<void(const std::filesystem::directory_entry&, size_t)>& callback)

4
src/dotfile.h

@ -49,9 +49,11 @@ public:
private:
void pullOrPush(SyncType type, const std::vector<std::string>& targets = {});
void sync(const std::vector<std::string>& paths, const std::vector<size_t>& homeIndices, const std::vector<size_t>& systemIndices,
void sync(SyncType type,
const std::vector<std::string>& paths, const std::vector<size_t>& homeIndices, const std::vector<size_t>& systemIndices,
const std::function<void(std::string*, const std::string&, const std::string&)>& generateHomePaths,
const std::function<void(std::string*, const std::string&)>& generateSystemPaths);
void selectivelyCommentOrUncomment(const std::string& path);
void forEachDotfile(const std::vector<std::string>& targets, const std::function<void(const std::filesystem::directory_entry&, size_t)>& callback);
bool filter(const std::filesystem::path& path);

9
src/util/file.cpp

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Riyyi
* Copyright (C) 2021-2022 Riyyi
*
* SPDX-License-Identifier: MIT
*/
@ -55,6 +55,13 @@ File& File::append(std::string data)
return *this;
}
File& File::replace(size_t index, size_t length, const std::string& data)
{
m_data.replace(index, length, data);
return *this;
}
File& File::flush()
{
// Create output stream object and open file

3
src/util/file.h

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Riyyi
* Copyright (C) 2021-2022 Riyyi
*
* SPDX-License-Identifier: MIT
*/
@ -18,6 +18,7 @@ public:
void clear();
File& append(std::string data);
File& replace(size_t index, size_t length, const std::string& data);
File& flush();
const char* c_str() const { return m_data.c_str(); }

Loading…
Cancel
Save