* Supply a way to copy command data (including the config) so its safe to
[vng:vng.git] / src / AbstractCommand.h
1 /*
2  * This file is part of the vng project
3  * Copyright (C) 2008 Thomas Zander <tzander@trolltech.com>
4  *
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.
9  *
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.
14  *
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/>.
17  */
18
19 #ifndef ABSTRACTCOMMAND_H
20 #define ABSTRACTCOMMAND_H
21
22 #include "Configuration.h"
23
24 #include <QString>
25 #include <QProcess>
26 #include <QDir>
27 #include <QTextStream>
28
29 /**
30  * This baseclass can be used to inherit from in order to add new top-level commands to vng.
31  * Top level commands are things like 'whatsnew' and 'add'.
32  * @see CommandLineParser
33  */
34 class AbstractCommand {
35 public:
36     /// an enum of return codes to be used by start() and run() so all commands syncronize their codes.
37     enum ReturnCodes {
38         // note that Unix requires 'Ok' to be zero.
39         Ok = 0,
40         InvalidOptions = 1,
41         Disabled,
42         NotInRepo,
43         WriteError,
44         OtherVngError,
45         UserCancelled,
46         GitCrashed = 10,
47         GitFailed,
48         GitTimedOut
49     };
50
51     /**
52      * Constructor.
53      * @param name the name this command has. Used (o.a.) to create a Configuration object.
54      */
55     AbstractCommand(const char *name);
56     virtual ~AbstractCommand();
57
58     /**
59      * Start the execution of the commmand.
60      * This will setup various items and read the default options after which it will call run().
61      * @return the exit code as used by the comamnd.
62      * @see ReturnCodes
63      */
64     ReturnCodes start();
65
66     /// return the name of this command.
67     QString name() const;
68
69     void pullConfigDataFrom(const AbstractCommand *other);
70
71 protected:
72     /**
73      * return the short visual description of the arguments you can pass to this command.
74      * If the command takes arguments that are not options, you can make the help message print that
75      * by returning something in this method.
76      */
77     virtual QString argumentDescription() const = 0;
78
79     /**
80      * return long (multiline) Description of the command.
81      */
82     virtual QString commandDescription() const = 0;
83
84     /**
85      * Run the commmand from the repository root.
86      * @return the exit code as used by the comamnd.
87      * @see ReturnCodes
88      */
89     virtual ReturnCodes run() = 0;
90
91     /// returns the repository we are in.
92     QDir repository() const;
93     /// returns if the command is a dry run which means that user interaction should take place, but no files changed.
94     bool dryRun() const;
95
96     /// The configuation object for this command.
97     Configuration m_config;
98
99     /**
100      * Changes the arguments passed like they are paths to compensate for the repodir.
101      * In vng all commands work on the whole repo, which is accomplished by changing the current
102      * directory to the repo root before run() is called.
103      * In case the user passed relative path arguments the change in current directory needs to be
104      * reflected in the paths.
105      * This method will take all the arguments and assume they are paths. For relative paths (not
106      * starting with slash or a drive name) the change in directory will be applied.
107      */
108     QStringList rebasedArguments() const;
109
110     /// check if we are in a repository; return true if we are
111     bool checkInRepository() const;
112
113     bool shouldUsePager() const;
114
115     enum RebaseOptionFlag {
116         NoOption = 0,       ///< No options
117         /// For each command line argument, do a stat to find if the original file or the rebased file is meant.
118         CheckFileSystem = 1,
119         /// In case the rebased filename does not exist, print an error message saying so.
120         PrintError = 2
121     };
122     Q_DECLARE_FLAGS( RebaseOptions, RebaseOptionFlag )
123
124     /// make the current directory for vng the root of the repo. This will also populate the m_rebasedArguments list.
125     void moveToRoot(RebaseOptions options = NoOption);
126
127 private:
128     QDir m_repository;
129     bool m_dryRun;
130     QString m_name;
131     QStringList m_rebasedArguments;
132 };
133
134 #endif