Make 'diff' also able to generate a diff between HEAD and a random named branch
[vng.git] / src / Configuration.cpp
blob416ea2e349fa2b92628db2ed54be38173c609098
1 /*
2 * This file is part of the vng project
3 * Copyright (C) 2008 Thomas Zander <tzander@trolltech.com>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "Configuration.h"
19 #include "Logger.h"
20 #include "GitRunner.h"
21 #include "AbstractCommand.h"
23 #include <QDebug>
24 #include <QMutexLocker>
25 #include <QProcess>
27 #ifndef Q_OS_WIN
28 #include <unistd.h>
29 #endif
31 #define EditedFilesDatabase "vng-editedfiles"
33 Configuration::Configuration(const QString &section)
34 : m_repoDir("."),
35 m_section(section),
36 m_dirty(true),
37 m_emptyRepo(false),
38 m_fetchedBranches(false)
42 bool Configuration::contains(const QString & key) const
44 const_cast<Configuration*> (this)->readConfig();
45 return m_options.contains(key);
48 QDir Configuration::repository() const
50 const_cast<Configuration*> (this)->readConfig();
51 return m_repoDir;
54 QDir Configuration::repositoryMetaDir() const
56 const_cast<Configuration*> (this)->readConfig();
57 return m_repoMetaDataDir;
60 void Configuration::readConfig()
62 if (!m_dirty)
63 return;
64 m_dirty = false;
65 QObject deleterParent;
67 QDir dir = QDir::current();
68 do {
69 QDir git = dir;
70 if (git.cd(".git")) {
71 m_repoDir = dir;
72 m_repoMetaDataDir = git;
73 QDir refs(git.absoluteFilePath("refs/heads"));
74 m_emptyRepo = refs.count() == 2; // only '.' and '..'
75 break;
77 if (!dir.cdUp())
78 break;
79 } while(!dir.isRoot());
81 QString home = QDir::homePath();
82 QFile *config;
83 config = new QFile(home + "/.vng/config", &deleterParent);
84 if (! config->exists())
85 config = new QFile(home + "/.darcs/defaults", &deleterParent);
86 if (config->exists()) {
87 if (! config->open(QIODevice::ReadOnly)) {
88 Logger::error() << "Failed to open config file, is it readable?\n";
89 return;
92 char buf[1024];
93 while(true) {
94 qint64 lineLength = config->readLine(buf, sizeof(buf));
95 if (lineLength == -1)
96 break;
97 QString line = QString::fromUtf8(buf, lineLength);
98 QString option;
99 if (line.startsWith("ALL "))
100 option = line.mid(3).trimmed();
101 else if (line.length() > m_section.length() && line.startsWith(m_section))
102 option = line.mid(m_section.length()).trimmed();
103 if (! option.isEmpty()) {
104 const int index = option.indexOf(' ');
105 if (index > 0) {
106 m_options.insert(option.left(index).trimmed(), option.mid(index).trimmed());
108 else
109 m_options.insert(option, QString());
112 config->close();
116 QString Configuration::optionArgument(const QString &optionName, const QString &defaultValue) const
118 if (m_options.contains(optionName))
119 return m_options[optionName];
120 return defaultValue;
123 bool Configuration::colorTerm() const
125 #ifndef Q_OS_WIN
126 if (isatty(1))
127 return QString(getenv("TERM")) != QString("dumb") && !Logger::hasNonColorPager();
128 #endif
129 return false;
132 bool Configuration::isEmptyRepo() const
134 const_cast<Configuration*> (this)->readConfig();
135 return m_emptyRepo;
138 QList<Branch> Configuration::allBranches()
140 fetchBranches();
141 QList<Branch> answer;
142 answer += m_localBranches;
143 answer += m_remoteBranches;
144 return answer;
147 QList<Branch> Configuration::branches()
149 fetchBranches();
150 return m_localBranches;
153 QList<Branch> Configuration::remoteBranches()
155 fetchBranches();
156 return m_remoteBranches;
159 void Configuration::fetchBranches()
161 if (m_fetchedBranches)
162 return;
163 m_fetchedBranches = true;
165 QProcess git;
166 QStringList arguments;
167 arguments << "ls-remote" << ".";
168 GitRunner runner(git, arguments);
169 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitForStandardOutput);
170 if (rc != AbstractCommand::Ok) {
171 return;
173 char buf[1024];
174 while(true) {
175 qint64 lineLength = Vng::readLine(&git, buf, sizeof(buf));
176 if (lineLength == -1)
177 break;
178 if (lineLength > 46) { // only take stuff that is in the 'refs' dir.
179 QString name(buf + 46);
180 name = name.trimmed(); // remove linefeed
181 Branch branch(name, QString::fromLatin1(buf, 40));
182 if (name.startsWith("remotes"))
183 m_remoteBranches.append(branch);
184 else
185 m_localBranches.append(branch);
190 void Configuration::shareConfigData(Configuration &other)
192 // TODO copy branch data etc.