0a5e51add6bb78def2a1d0f56f3d7cc9ab2e56e5
[vng.git] / src / VngCommandLine.cpp
blob0a5e51add6bb78def2a1d0f56f3d7cc9ab2e56e5
1 /*
2 * This file is part of the vng project
3 * Copyright (C) 2008 Thomas Zander <tzander@trolltech.com>
4 * Copyright (C) 2002-2005 David Roundy
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "VngCommandLine.h"
20 #include "CommandLineParser.h"
21 #include "Logger.h"
23 // commands
24 #include "commands/Add.h"
25 #include "commands/AmendRecord.h"
26 #include "commands/Branches.h"
27 #include "commands/Changes.h"
28 #include "commands/Diff.h"
29 #include "commands/Dist.h"
30 #include "commands/Initialize.h"
31 #include "commands/Move.h"
32 #include "commands/Pull.h"
33 #include "commands/Push.h"
34 #include "commands/Record.h"
35 #include "commands/Remove.h"
36 #include "commands/Revert.h"
37 #include "commands/UnRecord.h"
38 #include "commands/UnRevert.h"
39 #include "commands/WhatsNew.h"
41 #include <QTextStream>
43 #define VERSION "vng version 0.28 (>2009-06-10)"
45 VngCommandLine::VngCommandLine(int argc, char **argv)
46 : QCoreApplication(argc, argv)
48 if (argc > 1)
49 m_command = QString::fromLocal8Bit(argv[1]);
50 if (m_command == QLatin1String("help") && argc > 2) { // 'help foo' -> 'foo -h'
51 argv[1] = argv[2];
52 argv[2] = new char[3];// this is a memory leak, do we care?
53 argv[2][0] = '-';
54 argv[2][1] = 'h';
55 argv[2][2] = 0;
56 m_command = QString::fromLocal8Bit(argv[1]);
59 CommandLineParser::init(argc, argv);
62 VngCommandLine::~VngCommandLine()
64 delete CommandLineParser::instance();
67 int VngCommandLine::run()
69 if (m_command == QLatin1String("--extended-help")) {
70 printExtendedHelp();
71 return 0;
73 if (m_command == QLatin1String("--version") || m_command == QLatin1String("-v")
74 #if defined(Q_OS_WIN)
75 || m_command == QLatin1String("/V")
76 #endif
77 ) {
78 QTextStream out(stdout);
79 out << VERSION << endl;
80 return 0;
82 if (m_command.isEmpty()) {
83 printHelp();
84 return 0;
87 if (m_command == QLatin1String("--commands")) { // for commandline completion.
88 Configuration config("");
89 QTextStream out(stdout);
90 out << "help" << endl;
91 out << "initialize" << endl;
92 out << "--help" << endl;
93 out << "--version" << endl;
94 out << "--extended--help" << endl;
95 if (QDir(config.repository().absolutePath() + QLatin1String("/.git")).exists()) {
96 out << "add" << endl;
97 out << "amend-record" << endl;
98 out << "branches" << endl;
99 out << "changes" << endl;
100 out << "diff" << endl;
101 out << "dist" << endl;
102 out << "log" << endl;
103 out << "move" << endl;
104 out << "mv" << endl;
105 out << "pull" << endl;
106 out << "push" << endl;
107 out << "record" << endl;
108 out << "remove" << endl;
109 out << "revert" << endl;
110 out << "rm" << endl;
111 out << "unrecord" << endl;
112 out << "unrevert" << endl;
113 out << "whatsnew" << endl;
115 return 0;
118 // autoComplete command
119 QStringList commands;
120 // keep this list sorted in the sourcecode. In vim just select the lines and do a :'<,'>!sort
121 commands << QLatin1String("add");
122 commands << QLatin1String("amend-record");
123 commands << QLatin1String("branches");
124 commands << QLatin1String("changes");
125 commands << QLatin1String("diff");
126 commands << QLatin1String("dist");
127 commands << QLatin1String("help");
128 commands << QLatin1String("initialize");
129 commands << QLatin1String("log");
130 commands << QLatin1String("move");
131 commands << QLatin1String("mv");
132 commands << QLatin1String("pull");
133 commands << QLatin1String("push");
134 commands << QLatin1String("record");
135 commands << QLatin1String("remove");
136 commands << QLatin1String("revert");
137 commands << QLatin1String("rm");
138 commands << QLatin1String("unrecord");
139 commands << QLatin1String("unrevert");
140 commands << QLatin1String("whatsnew");
142 QString command;
143 foreach(QString s, commands) {
144 if (m_command == s) { // perfect match
145 command = m_command;
146 break;
148 if (! command.isEmpty()) {
149 if (s.startsWith(m_command)) {
150 QTextStream out(stdout);
151 out << "vng failed: " << "Ambiguous command..." << endl;
152 return -1;
154 else
155 break; // found best match.
157 if (s.startsWith(m_command)) {
158 command = s;
159 continue;
162 if (command.isEmpty()) {
163 if (! m_command.isEmpty()) {
164 QTextStream out(stdout);
165 out << "vng failed: " << "Invalid command `" << m_command << "'\n\n";
167 printHelp();
168 return 0;
170 m_command = command;
172 AbstractCommand *ac = 0;
173 if (m_command == QLatin1String("whatsnew"))
174 ac = new WhatsNew();
175 else if (m_command == QLatin1String("add"))
176 ac = new Add();
177 else if (m_command == QLatin1String("amend-record"))
178 ac = new AmendRecord();
179 else if (m_command == QLatin1String("branches"))
180 ac = new Branches();
181 else if (m_command == QLatin1String("changes") || m_command == QLatin1String("log"))
182 ac = new Changes();
183 else if (m_command == QLatin1String("initialize"))
184 ac = new Initialize();
185 else if (m_command == QLatin1String("move") || m_command == QLatin1String("mv"))
186 ac = new Move();
187 else if (m_command == QLatin1String("pull"))
188 ac = new Pull();
189 else if (m_command == QLatin1String("push"))
190 ac = new Push();
191 else if (m_command == QLatin1String("remove") || m_command == QLatin1String("rm"))
192 ac = new Remove();
193 else if (m_command == QLatin1String("revert"))
194 ac = new Revert();
195 else if (m_command == QLatin1String("unrecord"))
196 ac = new UnRecord();
197 else if (m_command == QLatin1String("unrevert"))
198 ac = new UnRevert();
199 else if (m_command == QLatin1String("diff"))
200 ac = new Diff();
201 else if (m_command == QLatin1String("dist"))
202 ac = new Dist();
203 else if (command == QLatin1String("help")) {
204 printHelp();
205 return 0;
207 else if (m_command == QLatin1String("record"))
208 ac = new Record();
210 Q_ASSERT(ac);
211 return ac->start();
214 void VngCommandLine::printHelp()
216 QTextStream out(stdout);
217 out << "Usage: vng COMMAND ...\n\n" << VERSION << endl;
218 out << "Commands:" << endl;
219 out << " help Display help for vng or a single commands." << endl;
220 out << "Changing and querying the working copy:" << endl;
221 Configuration config(QString());
222 out << " add Add one or more new files or directories." << endl;
223 out << " remove Remove one or more files or directories from the repository." << endl;
224 out << " mv Move/rename one or more files or directories." << endl;
225 out << " revert Revert to the recorded version (safe the first time only)." << endl;
226 out << " unrevert Undo the last revert (may fail if changes after the revert)." << endl;
227 out << " whatsnew Display unrecorded changes in the working copy." << endl;
228 out << "Copying changes between the working copy and the repository:" << endl;
229 out << " record Save changes in the working copy to the repository as a patch." << endl;
230 out << " unrecord Remove recorded patches without changing the working copy." << endl;
231 out << " amend-record Replace a patch with a better version before it leaves your repository." << endl;
232 out << "Copying patches between repositories with working copy update:" << endl;
233 out << " pull Copy and apply patches from another repository to this one." << endl;
234 out << " push Copy and apply patches from this repository to another one." << endl;
235 out << "Querying the repository:" << endl;
236 out << " diff Create a diff between two versions of the repository." << endl;
237 // out << " branches " << endl;
238 out << " dist Create a distribution tarball." << endl;
239 out << " changes Gives a changelog-style summary of the repository history." << endl;
240 out << "Administrating repositories:" << endl;
241 out << " initialize Initialize a new source tree as a vng repository." << endl;
242 out << endl;
243 out << "Use 'vng --extended-help' for more detailed help." << endl;
244 out << "Use 'vng COMMAND --help' for help on a single command." << endl;
245 out << "Use 'vng --version' to see the vng version number." << endl;
248 void VngCommandLine::printExtendedHelp()
250 QTextStream out(stdout);
251 out << VERSION << endl;
252 out << "Usage: vng COMMAND ...\n\n";
253 out << "Extended Help:\n\n";
254 out << "A vng repository consists of:\n\n";
255 out << " - a set of PATCHES\n";
256 out << " - a WORKING directory\n\n";
257 out << "Here is a description of which of these components is altered by each\n";
258 out << "command, and how it is used or altered:\n\n";
259 out << " whatsnew Show the differences between WORKING and the \"recorded\"\n";
260 out << " version, that is, the result of applying all PATCHES in the\n";
261 out << " repository. This difference, we will call LOCAL CHANGES.\n\n";
262 out << " record Add a patch to PATCHES representing the LOCAL CHANGES.\n\n";
263 out << " unrecord Delete a patch from PATCHES, but *do not* alter WORKING.\n\n";
264 out << " revert Remove LOCAL CHANGES. Note that this command is interactive,\n";
265 out << " so you can use it to revert only some of these changes.\n\n";
266 out << " unrevert Undo the last revert operation.\n\n";
267 // out << " unpull Delete a patch from PATCHES and unapply it from WORKING.\n";
268 // out << " Note that this command works for any patch, not just one that\n";
269 // out << " was previously \"pull\"ed. If there are no LOCAL CHANGES,\n";
270 // out << " this command is equivalent to \"vng unrecord; vng revert\"\n\n";
271 // out << " rollback Create the inverse of a particular patch and add it to PATCHES,\n";
272 // out << " but DO NOT apply it to WORKING. Note that this command is the\n";
273 // out << " only way to wind up with a patch in PATCHES which has not been\n";
274 // out << " applied to WORKING.\n\n";
278 // a C main function
279 int main(int argc, char **argv)
281 VngCommandLine vng(argc, argv);
282 return vng.run();