View Javadoc
1   /*
2    * Copyright (C) 2013, Christian Halstrick <christian.halstrick@sap.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.lib;
12  
13  import java.text.MessageFormat;
14  
15  import org.eclipse.jgit.errors.IllegalTodoFileModification;
16  import org.eclipse.jgit.internal.JGitText;
17  
18  /**
19   * Describes a single line in a file formatted like the git-rebase-todo file.
20   *
21   * @since 3.2
22   */
23  public class RebaseTodoLine {
24  	/**
25  	 * Describes rebase actions
26  	 */
27  	@SuppressWarnings("nls")
28  	public enum Action {
29  		/** Use commit */
30  		PICK("pick", "p"),
31  
32  		/** Use commit, but edit the commit message */
33  		REWORD("reword", "r"),
34  
35  		/** Use commit, but stop for amending */
36  		EDIT("edit", "e"),
37  
38  		/** Use commit, but meld into previous commit */
39  		SQUASH("squash", "s"),
40  
41  		/** like "squash", but discard this commit's log message */
42  		FIXUP("fixup", "f"),
43  
44  		/**
45  		 * A comment in the file. Also blank lines (or lines containing only
46  		 * whitespaces) are reported as comments
47  		 */
48  		COMMENT("comment", "#");
49  
50  		private final String token;
51  
52  		private final String shortToken;
53  
54  		private Action(String token, String shortToken) {
55  			this.token = token;
56  			this.shortToken = shortToken;
57  		}
58  
59  		/**
60  		 * @return full action token name
61  		 */
62  		public String toToken() {
63  			return this.token;
64  		}
65  
66  		@Override
67  		public String toString() {
68  			return "Action[" + token + "]";
69  		}
70  
71  		/**
72  		 * @param token
73  		 * @return the Action
74  		 */
75  		public static Action parse(String token) {
76  			for (Action action : Action.values()) {
77  				if (action.token.equals(token)
78  						|| action.shortToken.equals(token))
79  					return action;
80  			}
81  			throw new IllegalArgumentException(MessageFormat.format(
82  					JGitText.get().unknownOrUnsupportedCommand, token,
83  					Action.values()));
84  		}
85  	}
86  
87  	Action action;
88  
89  	final AbbreviatedObjectId commit;
90  
91  	String shortMessage;
92  
93  	String comment;
94  
95  	/**
96  	 * Create a new comment line
97  	 *
98  	 * @param newComment
99  	 *            the new comment
100 	 */
101 	public RebaseTodoLine(String newComment) {
102 		this.action = Action.COMMENT;
103 		setComment(newComment);
104 		this.commit = null;
105 		this.shortMessage = null;
106 	}
107 
108 	/**
109 	 * Create a new non-comment line
110 	 *
111 	 * @param action
112 	 *            a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action} object.
113 	 * @param commit
114 	 *            a {@link org.eclipse.jgit.lib.AbbreviatedObjectId} object.
115 	 * @param shortMessage
116 	 *            a {@link java.lang.String} object.
117 	 */
118 	public RebaseTodoLine(Action action, AbbreviatedObjectId commit,
119 			String shortMessage) {
120 		this.action = action;
121 		this.commit = commit;
122 		this.shortMessage = shortMessage;
123 		this.comment = null;
124 	}
125 
126 	/**
127 	 * Get rebase action type
128 	 *
129 	 * @return rebase action type
130 	 */
131 	public Action getAction() {
132 		return action;
133 	}
134 
135 	/**
136 	 * Set the action. It's not allowed to set a non-comment action on a line
137 	 * which was a comment line before. But you are allowed to set the comment
138 	 * action on a non-comment line and afterwards change the action back to
139 	 * non-comment.
140 	 *
141 	 * @param newAction
142 	 *            a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action} object.
143 	 * @throws org.eclipse.jgit.errors.IllegalTodoFileModification
144 	 *             on attempt to set a non-comment action on a line which was a
145 	 *             comment line before.
146 	 */
147 	public void setAction(Action newAction) throws IllegalTodoFileModification {
148 		if (!Action.COMMENT.equals(action) && Action.COMMENT.equals(newAction)) {
149 			// transforming from non-comment to comment
150 			if (comment == null)
151 				// no comment was explicitly set. Take the old line as comment
152 				// text
153 				comment = "# " + action.token + " " //$NON-NLS-1$ //$NON-NLS-2$
154 						+ ((commit == null) ? "null" : commit.name()) + " " //$NON-NLS-1$ //$NON-NLS-2$
155 						+ ((shortMessage == null) ? "null" : shortMessage); //$NON-NLS-1$
156 		} else if (Action.COMMENT.equals(action) && !Action.COMMENT.equals(newAction)) {
157 			// transforming from comment to non-comment
158 			if (commit == null)
159 				throw new IllegalTodoFileModification(MessageFormat.format(
160 						JGitText.get().cannotChangeActionOnComment, action,
161 						newAction));
162 		}
163 		this.action = newAction;
164 	}
165 
166 	/**
167 	 * <p>
168 	 * Set a comment for this line that is used if this line's
169 	 * {@link org.eclipse.jgit.lib.RebaseTodoLine#action} is a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action#COMMENT}
170 	 * </p>
171 	 * It's allowed to unset the comment by calling
172 	 * <code>setComment(null)</code> <br>
173 	 * A valid comment either starts with a hash (i.e. <code>'#'</code>), is an
174 	 * empty string, or consists of only spaces and tabs.<br>
175 	 * If the argument <code>newComment</code> doesn't match these requirements
176 	 * an Exception is thrown.
177 	 *
178 	 * @param newComment
179 	 *            the comment
180 	 */
181 	public void setComment(String newComment) {
182 		if (newComment == null) {
183 			this.comment = null;
184 			return;
185 		}
186 
187 		if (newComment.contains("\n") || newComment.contains("\r")) //$NON-NLS-1$ //$NON-NLS-2$
188 			throw createInvalidCommentException(newComment);
189 
190 		if (newComment.trim().length() == 0 || newComment.startsWith("#")) { //$NON-NLS-1$
191 			this.comment = newComment;
192 			return;
193 		}
194 
195 		throw createInvalidCommentException(newComment);
196 	}
197 
198 	private static IllegalArgumentException createInvalidCommentException(
199 			String newComment) {
200 		return new IllegalArgumentException(
201 				MessageFormat.format(
202 				JGitText.get().argumentIsNotAValidCommentString, newComment));
203 	}
204 
205 	/**
206 	 * Get abbreviated commit SHA-1 of commit that action will be performed on
207 	 *
208 	 * @return abbreviated commit SHA-1 of commit that action will be performed
209 	 *         on
210 	 */
211 	public AbbreviatedObjectId getCommit() {
212 		return commit;
213 	}
214 
215 	/**
216 	 * Get the first line of the commit message of the commit the action will be
217 	 * performed on.
218 	 *
219 	 * @return the first line of the commit message of the commit the action
220 	 *         will be performed on.
221 	 */
222 	public String getShortMessage() {
223 		return shortMessage;
224 	}
225 
226 	/**
227 	 * Set short message
228 	 *
229 	 * @param shortMessage
230 	 *            a short message.
231 	 */
232 	public void setShortMessage(String shortMessage) {
233 		this.shortMessage = shortMessage;
234 	}
235 
236 	/**
237 	 * Get a comment
238 	 *
239 	 * @return a comment. If the line is a comment line then the comment is
240 	 *         returned. Lines starting with # or blank lines or lines
241 	 *         containing only spaces and tabs are considered as comment lines.
242 	 *         The complete line is returned (e.g. including the '#')
243 	 */
244 	public String getComment() {
245 		return comment;
246 	}
247 
248 	/** {@inheritDoc} */
249 	@SuppressWarnings("nls")
250 	@Override
251 	public String toString() {
252 		return "Step["
253 				+ action
254 				+ ", "
255 				+ ((commit == null) ? "null" : commit)
256 				+ ", "
257 				+ ((shortMessage == null) ? "null" : shortMessage)
258 				+ ", "
259 				+ ((comment == null) ? "" : comment) + "]";
260 	}
261 }