1 /* 2 * Copyright (C) 2013, Christian Halstrick <christian.halstrick@sap.com> 3 * and other copyright owners as documented in the project's IP log. 4 * 5 * This program and the accompanying materials are made available 6 * under the terms of the Eclipse Distribution License v1.0 which 7 * accompanies this distribution, is reproduced below, and is 8 * available at http://www.eclipse.org/org/documents/edl-v10.php 9 * 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials provided 22 * with the distribution. 23 * 24 * - Neither the name of the Eclipse Foundation, Inc. nor the 25 * names of its contributors may be used to endorse or promote 26 * products derived from this software without specific prior 27 * written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44 package org.eclipse.jgit.lib; 45 46 import java.text.MessageFormat; 47 48 import org.eclipse.jgit.errors.IllegalTodoFileModification; 49 import org.eclipse.jgit.internal.JGitText; 50 51 /** 52 * Describes a single line in a file formatted like the git-rebase-todo file. 53 * 54 * @since 3.2 55 */ 56 public class RebaseTodoLine { 57 /** 58 * Describes rebase actions 59 */ 60 @SuppressWarnings("nls") 61 public static enum Action { 62 /** Use commit */ 63 PICK("pick", "p"), 64 65 /** Use commit, but edit the commit message */ 66 REWORD("reword", "r"), 67 68 /** Use commit, but stop for amending */ 69 EDIT("edit", "e"), 70 71 /** Use commit, but meld into previous commit */ 72 SQUASH("squash", "s"), 73 74 /** like "squash", but discard this commit's log message */ 75 FIXUP("fixup", "f"), 76 77 /** 78 * A comment in the file. Also blank lines (or lines containing only 79 * whitespaces) are reported as comments 80 */ 81 COMMENT("comment", "#"); 82 83 private final String token; 84 85 private final String shortToken; 86 87 private Action(String token, String shortToken) { 88 this.token = token; 89 this.shortToken = shortToken; 90 } 91 92 /** 93 * @return full action token name 94 */ 95 public String toToken() { 96 return this.token; 97 } 98 99 @Override 100 public String toString() { 101 return "Action[" + token + "]"; 102 } 103 104 /** 105 * @param token 106 * @return the Action 107 */ 108 static public Action parse(String token) { 109 for (Action action : Action.values()) { 110 if (action.token.equals(token) 111 || action.shortToken.equals(token)) 112 return action; 113 } 114 throw new IllegalArgumentException(MessageFormat.format( 115 JGitText.get().unknownOrUnsupportedCommand, token, 116 Action.values())); 117 } 118 } 119 120 Action action; 121 122 final AbbreviatedObjectId commit; 123 124 String shortMessage; 125 126 String comment; 127 128 /** 129 * Create a new comment line 130 * 131 * @param newComment 132 * the new comment 133 */ 134 public RebaseTodoLine(String newComment) { 135 this.action = Action.COMMENT; 136 setComment(newComment); 137 this.commit = null; 138 this.shortMessage = null; 139 } 140 141 /** 142 * Create a new non-comment line 143 * 144 * @param action 145 * a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action} object. 146 * @param commit 147 * a {@link org.eclipse.jgit.lib.AbbreviatedObjectId} object. 148 * @param shortMessage 149 * a {@link java.lang.String} object. 150 */ 151 public RebaseTodoLine(Action action, AbbreviatedObjectId commit, 152 String shortMessage) { 153 this.action = action; 154 this.commit = commit; 155 this.shortMessage = shortMessage; 156 this.comment = null; 157 } 158 159 /** 160 * Get rebase action type 161 * 162 * @return rebase action type 163 */ 164 public Action getAction() { 165 return action; 166 } 167 168 /** 169 * Set the action. It's not allowed to set a non-comment action on a line 170 * which was a comment line before. But you are allowed to set the comment 171 * action on a non-comment line and afterwards change the action back to 172 * non-comment. 173 * 174 * @param newAction 175 * a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action} object. 176 * @throws org.eclipse.jgit.errors.IllegalTodoFileModification 177 * on attempt to set a non-comment action on a line which was a 178 * comment line before. 179 */ 180 public void setAction(Action newAction) throws IllegalTodoFileModification { 181 if (!Action.COMMENT.equals(action) && Action.COMMENT.equals(newAction)) { 182 // transforming from non-comment to comment 183 if (comment == null) 184 // no comment was explicitly set. Take the old line as comment 185 // text 186 comment = "# " + action.token + " " //$NON-NLS-1$ //$NON-NLS-2$ 187 + ((commit == null) ? "null" : commit.name()) + " " //$NON-NLS-1$ //$NON-NLS-2$ 188 + ((shortMessage == null) ? "null" : shortMessage); //$NON-NLS-1$ 189 } else if (Action.COMMENT.equals(action) && !Action.COMMENT.equals(newAction)) { 190 // transforming from comment to non-comment 191 if (commit == null) 192 throw new IllegalTodoFileModification(MessageFormat.format( 193 JGitText.get().cannotChangeActionOnComment, action, 194 newAction)); 195 } 196 this.action = newAction; 197 } 198 199 /** 200 * <p> 201 * Set a comment for this line that is used if this line's 202 * {@link org.eclipse.jgit.lib.RebaseTodoLine#action} is a {@link org.eclipse.jgit.lib.RebaseTodoLine.Action#COMMENT} 203 * </p> 204 * It's allowed to unset the comment by calling 205 * <code>setComment(null)</code> <br> 206 * A valid comment either starts with a hash (i.e. <code>'#'</code>), is an 207 * empty string, or consists of only spaces and tabs.<br> 208 * If the argument <code>newComment</code> doesn't match these requirements 209 * an Exception is thrown. 210 * 211 * @param newComment 212 * the comment 213 */ 214 public void setComment(String newComment) { 215 if (newComment == null) { 216 this.comment = null; 217 return; 218 } 219 220 if (newComment.contains("\n") || newComment.contains("\r")) //$NON-NLS-1$ //$NON-NLS-2$ 221 throw createInvalidCommentException(newComment); 222 223 if (newComment.trim().length() == 0 || newComment.startsWith("#")) { //$NON-NLS-1$ 224 this.comment = newComment; 225 return; 226 } 227 228 throw createInvalidCommentException(newComment); 229 } 230 231 private static IllegalArgumentException createInvalidCommentException( 232 String newComment) { 233 return new IllegalArgumentException( 234 MessageFormat.format( 235 JGitText.get().argumentIsNotAValidCommentString, newComment)); 236 } 237 238 /** 239 * Get abbreviated commit SHA-1 of commit that action will be performed on 240 * 241 * @return abbreviated commit SHA-1 of commit that action will be performed 242 * on 243 */ 244 public AbbreviatedObjectId getCommit() { 245 return commit; 246 } 247 248 /** 249 * Get the first line of the commit message of the commit the action will be 250 * performed on. 251 * 252 * @return the first line of the commit message of the commit the action 253 * will be performed on. 254 */ 255 public String getShortMessage() { 256 return shortMessage; 257 } 258 259 /** 260 * Set short message 261 * 262 * @param shortMessage 263 * a short message. 264 */ 265 public void setShortMessage(String shortMessage) { 266 this.shortMessage = shortMessage; 267 } 268 269 /** 270 * Get a comment 271 * 272 * @return a comment. If the line is a comment line then the comment is 273 * returned. Lines starting with # or blank lines or lines 274 * containing only spaces and tabs are considered as comment lines. 275 * The complete line is returned (e.g. including the '#') 276 */ 277 public String getComment() { 278 return comment; 279 } 280 281 /** {@inheritDoc} */ 282 @SuppressWarnings("nls") 283 @Override 284 public String toString() { 285 return "Step[" 286 + action 287 + ", " 288 + ((commit == null) ? "null" : commit) 289 + ", " 290 + ((shortMessage == null) ? "null" : shortMessage) 291 + ", " 292 + ((comment == null) ? "" : comment) + "]"; 293 } 294 }