move commands to their own subdir
[vng.git] / commands / Push.cpp
blob003057d8cf873bec7d4d9e2b4ca1153c2822a790
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/>.
19 #include "Push.h"
20 #include "CommandLineParser.h"
21 #include "Logger.h"
22 #include "GitRunner.h"
23 #include "Vng.h"
25 #include <QProcess>
26 #include <QDebug>
27 #include <QRegExp>
29 static const CommandLineOption options[] = {
30 // TODO :)
31 // {"--matches=PATTERN", "select patches matching PATTERN"},
32 // {"-p REGEXP, --patches=REGEXP", "select patches matching REGEXP"},
33 // {"-t REGEXP, --tags=REGEXP", "select tags matching REGEXP"},
34 // {"-a, --all", "answer yes to all patches"},
35 // {"-i, --interactive", "prompt user interactively"},
36 // {"-s, --summary", "summarize changes"},
37 // {"--no-summary", "don't summarize changes"},
38 {"--set-default", "set default repository [DEFAULT]"},
39 {"--no-set-default", "don't set default repository"},
40 CommandLineLastOption
43 Push::Push()
44 : AbstractCommand("Push")
46 CommandLineParser::addOptionDefinitions(options);
47 CommandLineParser::setArgumentDefinition("push [ReturnCodes]" );
50 AbstractCommand::ReturnCodes Push::run()
52 if (! checkInRepository())
53 return NotInRepo;
54 CommandLineParser *args = CommandLineParser::instance();
56 QProcess git;
57 QStringList arguments;
58 arguments << "config" << "-l";
59 GitRunner runner(git, arguments);
60 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitForStandardOutput);
61 if (rc != Ok) {
62 Logger::error() << "Failed to read configuration\n";
63 return rc;
66 QRegExp re("remote\\.(.*)url=(.*)\n");
67 QHash<QString, QString> repoNames;
68 char buf[1024];
69 while (true) { //read relevant lines into repoNames hash
70 qint64 length = Vng::readLine(&git, buf, sizeof(buf));
71 if (length < 0)
72 break;
73 QString line(buf);
74 if (re.exactMatch(line)) {
75 QString context = re.cap(1);
76 if (context.endsWith("."))
77 context = context.left(context.length()-1);
78 repoNames.insert(context, re.cap(2));
82 QString repo("");
83 if (args->arguments().count() > 1)
84 repo = args->arguments()[1];
86 QString url = repo;
87 if (repo.isEmpty())
88 repo = "default"; // the name we store the default as.
89 if (repoNames.contains(repo))
90 url = repoNames[repo];
91 if (url.isEmpty()) { // print help
92 Logger::standardOut() << "failed: Missing argument [REPOSITORY]\n";
93 Logger::standardOut().flush();
94 args->usage(name(), argumentDescription());
95 Logger::standardOut() << endl << commandDescription();
96 return Ok;
99 Logger::warn() << "Pushing to `" << url << "'\n";
100 Logger::warn().flush(); // make sure its printed before git asks for an ssh pwd.
101 if (dryRun())
102 return Ok;
104 // TODO when not using --all ask the remote for all the refs it has and detect which ones we still have to push
105 // TODO use interview to ask which refs to push instead of all below
106 arguments.clear();
107 arguments << "push" << url;
108 runner.setArguments(arguments);
109 rc = runner.start(GitRunner::WaitForStandardOutput);
110 if (rc != Ok) {
111 Logger::error() << "Git push failed\n";
112 return rc;
115 /* TODO for some reason qprocess doesn't give me any output if the child process already finished :(
116 while (true) {
117 qint64 length = Vng::readLine(&git, buf, sizeof(buf));
118 if (length < 0)
119 break;
120 Logger::info() << QString(buf);
123 git.waitForFinished(-1);
125 if ( !(args->contains("no-set-default")
126 || m_config.contains("no-set-default") && ! args->contains("set-default"))
127 && repo == url) { // lets set as default
128 arguments.clear();
129 arguments << "config" << "--add" << "remote.default.url" << repo;
130 runner.setArguments(arguments);
131 rc = runner.start(GitRunner::WaitUntilFinished);
132 if (rc != Ok) {
133 Logger::error() << "Warning; Failed to store the default value\n";
134 return rc;
138 return Ok;
141 QString Push::argumentDescription() const
143 return "[REPOSITORY]";
146 QString Push::commandDescription() const
148 return "Push is the opposite of pull. Push allows you to copy changes from the\n"
149 "current repository into another repository.\n";