Include a print command line usage string utility
[egit.git] / org.spearce.jgit.pgm / src / org / spearce / jgit / pgm / TextBuiltin.java
bloba68d87c04f7b31e5e2d54211ef0e49b00a257222
1 /*
2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
9 * conditions are met:
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
22 * written permission.
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;
57 /**
58 * Abstract command which can be invoked from the command line.
59 * <p>
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.
63 * <p>
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" })
72 private boolean help;
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) {
84 commandName = name;
87 void init(final Repository repo) {
88 try {
89 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
90 System.out, "UTF-8")));
91 } catch (IOException e) {
92 throw die("cannot create output stream");
94 db = repo;
97 /**
98 * Parse arguments and run this command.
100 * @param args
101 * command line arguments passed after the command name.
102 * @throws Exception
103 * an error occurred while processing the command. The main
104 * framework will catch the exception and print a message on
105 * standard error.
107 public final void execute(String[] args) throws Exception {
108 parseArguments(args);
109 run();
113 * Parses the command line arguments prior to running.
114 * <p>
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.
119 * @param args
120 * the arguments supplied on the command line, if any.
122 protected void parseArguments(final String[] args) {
123 final CmdLineParser clp = new CmdLineParser(this);
124 try {
125 clp.parseArgument(args);
126 } catch (CmdLineException err) {
127 if (!help) {
128 System.err.println("fatal: " + err.getMessage());
129 System.exit(1);
133 if (help) {
134 printUsageAndExit(clp);
137 argWalk = clp.getRevWalkGently();
141 * Print the usage line
143 * @param clp
145 public void printUsageAndExit(final CmdLineParser clp) {
146 printUsageAndExit("", clp);
150 * Print an error message and the usage line
152 * @param message
153 * @param clp
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();
166 System.exit(1);
170 * Perform the actions of this command.
171 * <p>
172 * This method should only be invoked by {@link #execute(String[])}.
174 * @throws Exception
175 * an error occurred while processing the command. The main
176 * framework will catch the exception and print a message on
177 * standard error.
179 protected abstract void run() throws Exception;
182 * @return the repository this command accesses.
184 public Repository getRepository() {
185 return db;
188 protected ObjectId resolve(final String s) throws IOException {
189 final ObjectId r = db.resolve(s);
190 if (r == null)
191 throw die("Not a revision: " + s);
192 return r;
195 protected static Die die(final String why) {
196 return new Die(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());
206 return dst;