Manager: Add feature to selectively comment and uncomment
This commit is contained in:
+109
-4
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "dotfile.h"
|
#include "dotfile.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
|
#include "util/file.h"
|
||||||
|
|
||||||
std::vector<Dotfile::ExcludePath> Dotfile::s_excludePaths;
|
std::vector<Dotfile::ExcludePath> Dotfile::s_excludePaths;
|
||||||
std::vector<std::filesystem::path> Dotfile::s_systemDirectories;
|
std::vector<std::filesystem::path> Dotfile::s_systemDirectories;
|
||||||
@@ -70,7 +71,7 @@ void Dotfile::add(const std::vector<std::string>& targets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sync(
|
sync(
|
||||||
targets, homeIndices, systemIndices,
|
SyncType::Pull, targets, homeIndices, systemIndices,
|
||||||
[](std::string* paths, const std::string& homePath, const std::string& homeDirectory) {
|
[](std::string* paths, const std::string& homePath, const std::string& homeDirectory) {
|
||||||
paths[0] = homePath;
|
paths[0] = homePath;
|
||||||
paths[1] = homePath.substr(homeDirectory.size() + 1);
|
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) {
|
if (type == SyncType::Pull) {
|
||||||
sync(
|
sync(
|
||||||
dotfiles, homeIndices, systemIndices,
|
type, dotfiles, homeIndices, systemIndices,
|
||||||
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
|
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
|
||||||
// homeFile = /home/<user>/dotfiles/<file>
|
// homeFile = /home/<user>/dotfiles/<file>
|
||||||
// copy: /home/<user>/<file> -> /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 {
|
else {
|
||||||
sync(
|
sync(
|
||||||
dotfiles, homeIndices, systemIndices,
|
type, dotfiles, homeIndices, systemIndices,
|
||||||
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
|
[](std::string* paths, const std::string& homeFile, const std::string& homeDirectory) {
|
||||||
// homeFile = /home/<user>/dotfiles/<file>
|
// homeFile = /home/<user>/dotfiles/<file>
|
||||||
// copy: /home/<user>/dotfiles/<file> -> /home/<user>/<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&, const std::string&)>& generateHomePaths,
|
||||||
const std::function<void(std::string*, const std::string&)>& generateSystemPaths)
|
const std::function<void(std::string*, const std::string&)>& generateSystemPaths)
|
||||||
{
|
{
|
||||||
@@ -223,14 +225,117 @@ void Dotfile::sync(const std::vector<std::string>& paths, const std::vector<size
|
|||||||
std::string homePaths[2];
|
std::string homePaths[2];
|
||||||
generateHomePaths(homePaths, paths.at(i), homeDirectory);
|
generateHomePaths(homePaths, paths.at(i), homeDirectory);
|
||||||
copy(homePaths[0], homePaths[1], true);
|
copy(homePaths[0], homePaths[1], true);
|
||||||
|
if (type == SyncType::Push) {
|
||||||
|
selectivelyCommentOrUncomment(homePaths[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// /
|
// /
|
||||||
for (size_t i : systemIndices) {
|
for (size_t i : systemIndices) {
|
||||||
std::string systemPaths[2];
|
std::string systemPaths[2];
|
||||||
generateSystemPaths(systemPaths, paths.at(i));
|
generateSystemPaths(systemPaths, paths.at(i));
|
||||||
copy(systemPaths[0], systemPaths[1], false);
|
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)
|
void Dotfile::forEachDotfile(const std::vector<std::string>& targets, const std::function<void(const std::filesystem::directory_entry&, size_t)>& callback)
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -49,9 +49,11 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void pullOrPush(SyncType type, const std::vector<std::string>& targets = {});
|
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&, const std::string&)>& generateHomePaths,
|
||||||
const std::function<void(std::string*, const std::string&)>& generateSystemPaths);
|
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);
|
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);
|
bool filter(const std::filesystem::path& path);
|
||||||
|
|||||||
+8
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 Riyyi
|
* Copyright (C) 2021-2022 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -55,6 +55,13 @@ File& File::append(std::string data)
|
|||||||
return *this;
|
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()
|
File& File::flush()
|
||||||
{
|
{
|
||||||
// Create output stream object and open file
|
// Create output stream object and open file
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 Riyyi
|
* Copyright (C) 2021-2022 Riyyi
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
@@ -18,6 +18,7 @@ public:
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
File& append(std::string data);
|
File& append(std::string data);
|
||||||
|
File& replace(size_t index, size_t length, const std::string& data);
|
||||||
File& flush();
|
File& flush();
|
||||||
|
|
||||||
const char* c_str() const { return m_data.c_str(); }
|
const char* c_str() const { return m_data.c_str(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user