Skip to content

Commit

Permalink
Merge pull request #9 from nemomobile/upgrade-repo-sync-config
Browse files Browse the repository at this point in the history
Upgrade repo and sync config
  • Loading branch information
Denis Zalevskiy committed Aug 7, 2014
2 parents 9addd48 + 2c59b02 commit ece16e1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 59 deletions.
4 changes: 2 additions & 2 deletions include/vault/vault.hpp
Expand Up @@ -85,8 +85,8 @@ class Vault
void tagSnapshot(const QString &msg);
void resetMaster();

void init_(const QVariantMap &config);

void setup(const QVariantMap *config);
QString absolutePath(QString const &);
QString readFile(const QString &relPath);

void setVersion(File, int);
Expand Down
69 changes: 41 additions & 28 deletions src/vault-cli.cpp
Expand Up @@ -7,51 +7,64 @@
*/

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>

#include <vault/vault.hpp>
#include <qtaround/sys.hpp>
#include <qtaround/debug.hpp>

void set(QVariantMap &map, const sys::GetOpt &parser, const QString &option, bool optional = false)
void set(QVariantMap &map, const QCommandLineParser &parser, const QString &option, bool optional = false)
{
if (!optional || parser.isSet(option)) {
map.insert(option, parser.value(option));
}
}

int main(int argc, char **argv)
int main_(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QCommandLineParser parser;
parser.setApplicationDescription("The Vault");
parser.addHelpOption();

auto cmdline = sys::getopt({
{ "vault", QVariantMap{ {"short", "V"}, {"long", "vault"}, {"has_param", true} }},
{ "global", QVariantMap{ {"short", "G"}, {"long", "global"} }},
{ "action", QVariantMap{ {"short", "a"}, {"long", "action"}, {"has_param", true}, {"required", true} }},
{ "home", QVariantMap{ {"short", "H"}, {"long", "home"}, {"has_param", true} }},
{ "git-config", QVariantMap{ {"short", "g"}, {"long", "git-config"}, {"has_param", true} }},
{ "config-path", QVariantMap{ {"short", "c"}, {"long", "config-path"},
{"has_param", true}, {"default", "/etc/the-vault.json"} }},
{ "message", QVariantMap{ {"short", "m"}, {"long", "message"}, {"has_param", true} }},
{ "tag", QVariantMap{ {"short", "t"}, {"long", "tag"}, {"has_param", true} }},
{ "unit", QVariantMap{ {"short", "M"}, {"long", "unit"}, {"has_param", true} }},
{ "data", QVariantMap{ {"short", "d"}, {"long", "data"}, {"has_param", true} }}
}, false);
parser.addOption(QCommandLineOption(QStringList() << "a" << "action", "action", "action"));
parser.addOption(QCommandLineOption(QStringList() << "V" << "vault", "vault", "path"));
parser.addOption(QCommandLineOption(QStringList() << "H" << "home", "home", "home"));
parser.addOption(QCommandLineOption(QStringList() << "G" << "global", "global"));
parser.addOption(QCommandLineOption(QStringList() << "d" << "data", "data", "data"));
parser.addOption(QCommandLineOption(QStringList() << "M" << "unit", "unit", "unit"));
parser.addOption(QCommandLineOption(QStringList() << "c" << "config-path", "config-path", "config-path", "/etc/the-vault.json"));
parser.addOption(QCommandLineOption(QStringList() << "g" << "git-config", "git-config", "git-config"));
parser.addOption(QCommandLineOption(QStringList() << "m" << "message", "message", "message"));
parser.addOption(QCommandLineOption(QStringList() << "t" << "tag", "tag", "tag"));

parser.process(app);

QVariantMap options;
set(options, *cmdline, "action");
set(options, *cmdline, "vault", true);
set(options, *cmdline, "home", true);
set(options, *cmdline, "data", true);
set(options, *cmdline, "unit", true);
set(options, *cmdline, "config-path", true);
set(options, *cmdline, "git-config", true);
set(options, *cmdline, "message", true);
set(options, *cmdline, "tag", true);

options.insert("global", cmdline->isSet("global"));
set(options, parser, "action");
set(options, parser, "vault", true);
set(options, parser, "home", true);
set(options, parser, "data", true);
set(options, parser, "unit", true);
set(options, parser, "config-path", true);
set(options, parser, "git-config", true);
set(options, parser, "message", true);
set(options, parser, "tag", true);

vault::Vault::execute(options);
options.insert("global", parser.isSet("global"));

vault::Vault::execute(options);
return 0;
}

int main(int argc, char **argv)
{
try {
return main_(argc, argv);
} catch (std::exception const &e) {
debug::error("Error:", e.what());
} catch (...) {
debug::error("Unknown error");
}
return 1;
}
91 changes: 63 additions & 28 deletions src/vault.cpp
Expand Up @@ -43,7 +43,7 @@ using Gittin::ResetOptions;
using Gittin::CheckoutOptions;

namespace version {
static const int tree = 2;
static const int tree = 3;
static const int repository = 2;
}

Expand All @@ -70,6 +70,7 @@ Vault::Vault(const QString &path)
, m_vcs(path)
, m_config(&m_vcs)
{
setup(nullptr);
}

static QVariantMap parseKvPairs(const QString &cfg)
Expand Down Expand Up @@ -106,7 +107,9 @@ bool Vault::UnitPath::exists() const
void Vault::execute(const QVariantMap &options)
{
QString action = options.value("action").toString();
debug::debug("Action:", action);
if (options.value("global").toBool()) {
debug::debug("Global action");
if (action == "register") {
if (!options.contains("data")) {
error::raise({{"action", action}, {"msg", "Needs data" }});
Expand Down Expand Up @@ -201,9 +204,15 @@ int Vault::getVersion(File src)
return readFile(fileName(src)).toInt();
}

void Vault::init_(const QVariantMap &config)
QString Vault::absolutePath(QString const &relativePath)
{
return os::path::join(m_path, relativePath);
}

void Vault::setup(const QVariantMap *config)
{
auto createRepo = [m_path, &m_vcs]() {
debug::debug("Creating repo at", m_path);
if (!os::path::exists(m_path))
if (!os::mkdir(m_path))
error::raise({{"msg", "Can't create repo dir"}, {"path", m_path}});
Expand All @@ -212,9 +221,10 @@ void Vault::init_(const QVariantMap &config)
error::raise({{"msg", "Can't init git repo"}, {"path", m_path}});
};

auto setupGitConfig = [this, &config]() {
auto setupGitConfig = [this, config]() {
debug::debug("Setup git config", *config);
m_vcs.setConfigValue("status.showUntrackedFiles", "all");
for (auto it = config.begin(); it != config.end(); ++it)
for (auto it = config->begin(); it != config->end(); ++it)
m_vcs.setConfigValue(it.key(), it.value().toString());
};

Expand All @@ -225,6 +235,7 @@ void Vault::init_(const QVariantMap &config)
};

auto initVersions = [this]() {
debug::debug("Init vault versions");
setVersion(File::VersionTree, version::tree);
m_vcs.add(fileName(File::VersionTree));
m_vcs.commit("anchor");
Expand All @@ -239,18 +250,26 @@ void Vault::init_(const QVariantMap &config)
};

auto updateTreeVersion = [this](unsigned current) {
debug::info("Updating tree version from", current, "to", version::repository);
// since v2 there is no 'latest' tag
if (current < 2)
debug::info("Updating tree version from", current, "to", version::tree);

if (current < 2) {
debug::info("since v2 there is no 'latest' tag");
snapshot("latest").remove();
}

if (current < 3) {
debug::info("Since v3 information about units is not "
"under version control and moved to the .units dir."
"Old .modules is deprecated.");
}

setVersion(File::VersionTree, version::tree);
m_vcs.add(fileName(File::VersionTree));
m_vcs.commit("vault format version");
};

auto updateRepoVersion = [this, &excludeServiceFiles](unsigned current) {
debug::info("Updating repo version from", current, "to", version::tree);
debug::info("Updating repo version from", current, "to", version::repository);
if (current < 1) {
// state tracking file is appeared in version 1
// all .vault.* are also going to be ignored
Expand All @@ -259,7 +278,32 @@ void Vault::init_(const QVariantMap &config)
setVersion(File::VersionRepo, version::repository);
};

if (!exists()) {
auto syncConfigGlobal = [this]() {
auto global = vault::config::global();
if (global)
this->config().update(global->units());
};

if (exists() && !isInvalid()) {
debug::debug("Repository exists and it is not invalid, setup");

auto v = getVersion(File::VersionTree);
if (v < version::tree)
updateTreeVersion(v);

v = getVersion(File::VersionRepo);
if (v < version::repository)
updateRepoVersion(v);

excludeServiceFiles();
setState("new");
if (config)
setupGitConfig();

syncConfigGlobal();
} else if (config) {
debug::info("Repository initialization is requested");

if (os::path::exists(m_path))
error::raise({{"msg", "Vault dir already exists, can't create"}, {"path", m_path}});

Expand All @@ -268,29 +312,19 @@ void Vault::init_(const QVariantMap &config)
setupGitConfig();
excludeServiceFiles();
initVersions();
syncConfigGlobal();
setState("new");
} catch (...) {
os::rmtree(m_path);
throw;
}
} else if (!isInvalid()) {
auto v = getVersion(File::VersionTree);
if (v < version::tree)
updateTreeVersion(v);

v = getVersion(File::VersionRepo);
if (v < version::repository)
updateRepoVersion(v);

excludeServiceFiles();
setState("new");
}
}

bool Vault::init(const QVariantMap &config)
{
try {
init_(config);
setup(&config);
return true;
} catch (std::exception const &e) {
debug::error("Error:", e.what(), ", initializing repository", m_path);
Expand All @@ -302,7 +336,7 @@ bool Vault::init(const QVariantMap &config)

bool Vault::ensureValid()
{
if (!os::path::exists(os::path::join(m_path, ".git"))) {
if (!os::path::exists(absolutePath(".git"))) {
debug::info("Can't find .git", m_path);
return false;
}
Expand All @@ -311,7 +345,7 @@ bool Vault::ensureValid()
return false;
}

auto versionTreeFile = os::path::join(m_path, fileName(File::VersionTree));
auto versionTreeFile = absolutePath(fileName(File::VersionTree));
if (!os::path::isFile(versionTreeFile)) {
resetMaster();
if (!os::path::isFile(versionTreeFile)) {
Expand Down Expand Up @@ -441,6 +475,7 @@ Vault::Result Vault::restore(const Snapshot &snapshot, const QString &home, cons
}
}

debug::debug("Restore units:", usedUnits);
for (const QString &unit: usedUnits) {
if (restoreUnit(home, unit, progress)) {
res.failedUnits.removeOne(unit);
Expand Down Expand Up @@ -489,13 +524,13 @@ bool Vault::exists() const

bool Vault::isInvalid()
{
QString storage(os::path::join(m_path, ".git"));
QString storage(absolutePath(".git"));
QString blob_storage(os::path::join(storage, "blobs"));
if (!os::path::exists(storage) || !os::path::exists(blob_storage)) {
return true;
}

QString anchor(os::path::join(m_path, fileName(File::VersionTree)));
QString anchor(absolutePath(fileName(File::VersionTree)));
if (!os::path::isFile(anchor)) {
resetMaster();
if (!os::path::isFile(anchor))
Expand All @@ -506,11 +541,11 @@ bool Vault::isInvalid()

bool Vault::writeFile(const QString &path, const QString &content)
{
QFile file(os::path::join(m_path, path));
QFile file(absolutePath(path));
if (!content.endsWith('\n')) {
return os::write_file(os::path::join(m_path, path), content + '\n');
return os::write_file(absolutePath(path), content + '\n');
}
return os::write_file(os::path::join(m_path, path), content);
return os::write_file(absolutePath(path), content);
}

bool Vault::setState(const QString &state)
Expand Down
2 changes: 1 addition & 1 deletion src/vault_config.cpp
Expand Up @@ -90,7 +90,7 @@ Config::Config(const QString &unitsDir)
: m_unitsDir(unitsDir)
{
if (unitsDir.isEmpty()) {
error::raise({{"msg", "Wrong configuration"}, {"cfg", unitsDir}});
error::raise({{"msg", "Empty configuration path"}});
}

load();
Expand Down

0 comments on commit ece16e1

Please sign in to comment.