2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org
.spearce
.jgit
.pgm
;
41 import static org
.spearce
.jgit
.lib
.Constants
.R_HEADS
;
42 import static org
.spearce
.jgit
.lib
.Constants
.R_REMOTES
;
43 import static org
.spearce
.jgit
.lib
.Constants
.R_TAGS
;
45 import java
.io
.BufferedWriter
;
46 import java
.io
.IOException
;
47 import java
.io
.OutputStreamWriter
;
48 import java
.io
.PrintWriter
;
50 import org
.kohsuke
.args4j
.CmdLineException
;
51 import org
.kohsuke
.args4j
.Option
;
52 import org
.spearce
.jgit
.lib
.ObjectId
;
53 import org
.spearce
.jgit
.lib
.Repository
;
54 import org
.spearce
.jgit
.pgm
.opt
.CmdLineParser
;
55 import org
.spearce
.jgit
.revwalk
.RevWalk
;
58 * Abstract command which can be invoked from the command line.
60 * Commands are configured with a single "current" repository and then the
61 * {@link #execute(String[])} method is invoked with the arguments that appear
62 * on the command line after the command name.
64 * Command constructors should perform as little work as possible as they may be
65 * invoked very early during process loading, and the command may not execute
66 * even though it was constructed.
68 public abstract class TextBuiltin
{
69 private String commandName
;
71 @Option(name
= "--help", usage
= "display this help text", aliases
= { "-h" })
74 /** Stream to output to, typically this is standard output. */
75 protected PrintWriter out
;
77 /** Git repository the command was invoked within. */
78 protected Repository db
;
80 /** RevWalk used during command line parsing, if it was required. */
81 protected RevWalk argWalk
;
83 final void setCommandName(final String name
) {
87 void init(final Repository repo
) {
89 out
= new PrintWriter(new BufferedWriter(new OutputStreamWriter(
90 System
.out
, "UTF-8")));
91 } catch (IOException e
) {
92 throw die("cannot create output stream");
98 * Parse arguments and run this command.
101 * command line arguments passed after the command name.
103 * an error occurred while processing the command. The main
104 * framework will catch the exception and print a message on
107 public final void execute(String
[] args
) throws Exception
{
108 parseArguments(args
);
113 * Parses the command line arguments prior to running.
115 * This method should only be invoked by {@link #execute(String[])}, prior
116 * to calling {@link #run()}. The default implementation parses all
117 * arguments into this object's instance fields.
120 * the arguments supplied on the command line, if any.
122 protected void parseArguments(final String
[] args
) {
123 final CmdLineParser clp
= new CmdLineParser(this);
125 clp
.parseArgument(args
);
126 } catch (CmdLineException err
) {
128 System
.err
.println("fatal: " + err
.getMessage());
134 printUsageAndExit(clp
);
137 argWalk
= clp
.getRevWalkGently();
141 * Print the usage line
145 public void printUsageAndExit(final CmdLineParser clp
) {
146 printUsageAndExit("", clp
);
150 * Print an error message and the usage line
155 public void printUsageAndExit(final String message
, final CmdLineParser clp
) {
156 System
.err
.println(message
);
157 System
.err
.print("jgit ");
158 System
.err
.print(commandName
);
159 clp
.printSingleLineUsage(System
.err
);
160 System
.err
.println();
162 System
.err
.println();
163 clp
.printUsage(System
.err
);
164 System
.err
.println();
170 * Perform the actions of this command.
172 * This method should only be invoked by {@link #execute(String[])}.
175 * an error occurred while processing the command. The main
176 * framework will catch the exception and print a message on
179 protected abstract void run() throws Exception
;
182 * @return the repository this command accesses.
184 public Repository
getRepository() {
188 protected ObjectId
resolve(final String s
) throws IOException
{
189 final ObjectId r
= db
.resolve(s
);
191 throw die("Not a revision: " + s
);
195 protected static Die
die(final String why
) {
199 protected String
abbreviateRef(String dst
, boolean abbreviateRemote
) {
200 if (dst
.startsWith(R_HEADS
))
201 dst
= dst
.substring(R_HEADS
.length());
202 else if (dst
.startsWith(R_TAGS
))
203 dst
= dst
.substring(R_TAGS
.length());
204 else if (abbreviateRemote
&& dst
.startsWith(R_REMOTES
))
205 dst
= dst
.substring(R_REMOTES
.length());