Make add work a lot faster by caching the filetree once, avoiding calling git for...
[vng.git] / Configuration.cpp
blob6e3b4a430ab79f970a109b7a8b73f2bd6b9e84e2
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 <QProcess>
26 #ifndef Q_OS_WIN
27 #include <unistd.h>
28 #endif
30 Configuration::Configuration(const QString &section)
31 : m_repoDir("."),
32 m_section(section),
33 m_dirty(true),
34 m_emptyRepo(false),
35 m_fetchedBranches(false)
39 bool Configuration::contains(const QString & key) const
41 const_cast<Configuration*> (this)->readConfig();
42 return m_options.contains(key);
45 QDir Configuration::repository() const
47 const_cast<Configuration*> (this)->readConfig();
48 return m_repoDir;
51 QDir Configuration::repositoryMetaDir() const
53 const_cast<Configuration*> (this)->readConfig();
54 return m_repoMetaDataDir;
57 void Configuration::readConfig()
59 if (!m_dirty)
60 return;
61 m_dirty = false;
62 QObject deleterParent;
64 QDir dir = QDir::current();
65 do {
66 QDir git = dir;
67 if (git.cd(".git")) {
68 m_repoDir = dir;
69 m_repoMetaDataDir = git;
70 QDir refs(git.absoluteFilePath("refs/heads"));
71 m_emptyRepo = refs.count() == 2; // only '.' and '..'
72 break;
74 if (!dir.cdUp())
75 break;
76 } while(!dir.isRoot());
78 QString home = QDir::homePath();
79 QFile *config;
80 config = new QFile(home + "/.vng/config", &deleterParent);
81 if (! config->exists())
82 config = new QFile(home + "/.darcs/defaults", &deleterParent);
83 if (config->exists()) {
84 if (! config->open(QIODevice::ReadOnly)) {
85 Logger::error() << "Failed to open config file, is it readable?\n";
86 return;
89 char buf[1024];
90 while(true) {
91 qint64 lineLength = config->readLine(buf, sizeof(buf));
92 if (lineLength == -1)
93 break;
94 QString line = QString::fromUtf8(buf, lineLength);
95 QString option;
96 if (line.startsWith("ALL "))
97 option = line.mid(3).trimmed();
98 else if (line.length() > m_section.length() && line.startsWith(m_section))
99 option = line.mid(m_section.length()).trimmed();
100 if (! option.isEmpty()) {
101 const int index = option.indexOf(' ');
102 if (index > 0) {
103 m_options.insert(option.left(index).trimmed(), option.mid(index).trimmed());
105 else
106 m_options.insert(option, QString());
109 config->close();
113 QString Configuration::optionArgument(const QString &optionName, const QString &defaultValue) const
115 if (m_options.contains(optionName))
116 return m_options[optionName];
117 return defaultValue;
120 bool Configuration::colorTerm() const
122 #ifndef Q_OS_WIN
123 if (isatty(1))
124 return QString(getenv("TERM")) != QString("dumb") && !Logger::hasNonColorPager();
125 #endif
126 return false;
129 bool Configuration::isEmptyRepo() const
131 const_cast<Configuration*> (this)->readConfig();
132 return m_emptyRepo;
135 QList<Branch> Configuration::allBranches()
137 fetchBranches();
138 QList<Branch> answer;
139 answer += m_localBranches;
140 answer += m_remoteBranches;
141 return answer;
144 QList<Branch> Configuration::branches()
146 fetchBranches();
147 return m_localBranches;
150 QList<Branch> Configuration::remoteBranches()
152 fetchBranches();
153 return m_remoteBranches;
156 void Configuration::fetchBranches()
158 if (m_fetchedBranches)
159 return;
160 m_fetchedBranches = true;
162 QProcess git;
163 QStringList arguments;
164 arguments << "ls-remote" << ".";
165 GitRunner runner(git, arguments);
166 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitForStandardOutput);
167 if (rc != AbstractCommand::Ok) {
168 return;
170 char buf[1024];
171 while(true) {
172 qint64 lineLength = Vng::readLine(&git, buf, sizeof(buf));
173 if (lineLength == -1)
174 break;
175 if (lineLength > 46) { // only take stuff that is in the 'refs' dir.
176 QString name(buf + 46);
177 name = name.trimmed(); // remove linefeed
178 Branch branch(name);
179 if (name.startsWith("remotes"))
180 m_remoteBranches.append(branch);
181 else
182 m_localBranches.append(branch);