File indexing completed on 2024-12-15 04:56:12

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) version 3, or any
0008  * later version accepted by the membership of KDE e.V. (or its
0009  * successor approved by the membership of KDE e.V.), which shall
0010  * act as a proxy defined in Section 6 of version 3 of the license.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 
0021 #include "state.h"
0022 
0023 #include <QDebug>
0024 #include <QDir>
0025 #include <QJsonDocument>
0026 #include <QObject>
0027 
0028 #include <iostream>
0029 
0030 #ifdef HAVE_LIBGIT2
0031 #include <git2.h>
0032 #endif
0033 
0034 static const QString configFileName("hawd.conf");
0035 
0036 namespace HAWD
0037 {
0038 
0039 State::State(const QString &_configPath)
0040     : m_valid(true)
0041 {
0042     m_commitHash[0] = '\0';
0043     QString configPath = _configPath;
0044     if (configPath.isEmpty()) {
0045         QDir dir;
0046 
0047         while (!dir.exists(configFileName) && dir.cdUp()) { }
0048 
0049         if (dir.exists(configFileName)) {
0050             configPath = dir.absoluteFilePath(configFileName);
0051         }
0052 
0053         if (configPath.isEmpty()) {
0054             std::cerr << QObject::tr("Could not find hawd configuration. A hawd.conf file must be in the current directory or in a directory above it.").toStdString() << std::endl;
0055             m_valid = false;
0056             return;
0057         }
0058     }
0059 
0060     QFile configFile(configPath);
0061     if (configFile.open(QIODevice::ReadOnly)) {
0062         QJsonParseError error;
0063         QJsonDocument config = QJsonDocument::fromJson(configFile.readAll(), &error);
0064         if (config.isNull()) {
0065             std::cerr << QObject::tr("Error parsing config file at %1").arg(configPath).toStdString() << std::endl;
0066             std::cerr << '\t' << error.errorString().toStdString();
0067         } else {
0068             m_configData = config.object();
0069         }
0070     }
0071 }
0072 
0073 bool State::isValid() const
0074 {
0075     return m_valid;
0076 }
0077 
0078 QString tildeExpand(QString path)
0079 {
0080     if (path.isEmpty() || path.at(0) != '~') {
0081         return path;
0082     }
0083 
0084     return path.replace('~', QDir::homePath());
0085 }
0086 
0087 QString State::resultsPath() const
0088 {
0089     return tildeExpand(configValue("results").toString());
0090 }
0091 
0092 QString State::projectPath() const
0093 {
0094     return tildeExpand(configValue("project").toString());
0095 }
0096 
0097 DatasetDefinition State::datasetDefinition(const QString &name) const
0098 {
0099     return DatasetDefinition(projectPath() + '/' + name);
0100 }
0101 
0102 QVariant State::configValue(const QString &key) const
0103 {
0104     return m_configData.value(key).toVariant();
0105 }
0106 
0107 const char *State::commitHash() const
0108 {
0109     if (isValid() && m_commitHash[0] == '\0') {
0110         const_cast<State *>(this)->findGitHash();
0111     }
0112 
0113     return m_commitHash;
0114 }
0115 
0116 void State::findGitHash()
0117 {
0118 #ifdef HAVE_LIBGIT2
0119     git_libgit2_init();
0120     git_buf root = GIT_BUF_INIT_CONST(0, 0);
0121     int error = git_repository_discover(&root, projectPath().toStdString().data(), 0, NULL);
0122     if (!error) {
0123         git_repository *repo = NULL;
0124         int error = git_repository_open(&repo, root.ptr);
0125 
0126         if (!error) {
0127             git_oid oid;
0128             error = git_reference_name_to_id(&oid, repo, "HEAD" );
0129             if (!error) {
0130                 git_oid_tostr(m_commitHash, sizeof(m_commitHash), &oid);
0131             }
0132         }
0133 
0134         git_repository_free(repo);
0135     }
0136     git_buf_free(&root);
0137     git_libgit2_shutdown();
0138 #endif
0139 }
0140 
0141 } // namespace HAWD