1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.scm.provider.git.gitexe.command.info;
20
21 import java.nio.file.Path;
22 import java.time.format.DateTimeFormatter;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.maven.scm.command.info.InfoItem;
26 import org.apache.maven.scm.util.AbstractConsumer;
27 import org.codehaus.plexus.util.cli.Arg;
28 import org.codehaus.plexus.util.cli.Commandline;
29
30 /**
31 * Parses output of {@code git log} with a particular format and populates a {@link InfoItem}.
32 *
33 * @author Olivier Lamy
34 * @since 1.5
35 * @see <a href="https://git-scm.com/docs/git-log#_pretty_formats">Pretty Formats</a>
36 */
37 public class GitInfoConsumer extends AbstractConsumer {
38
39 private final InfoItem infoItem;
40 private final int revisionLength;
41
42 public GitInfoConsumer(Path path, int revisionLength) {
43 infoItem = new InfoItem();
44 infoItem.setPath(path.toString());
45 infoItem.setURL(path.toUri().toASCIIString());
46 this.revisionLength = revisionLength;
47 }
48
49 enum LineParts {
50 HASH(0),
51 AUTHOR_NAME(3),
52 AUTHOR_EMAIL(2),
53 AUTHOR_LAST_MODIFIED(1);
54
55 private final int index;
56
57 LineParts(int index) {
58 this.index = index;
59 }
60
61 public int getIndex() {
62 return index;
63 }
64 }
65
66 /**
67 * @param line the line which is supposed to have the format as specified by {@link #getFormatArgument()}.
68 * @see org.codehaus.plexus.util.cli.StreamConsumer#consumeLine(java.lang.String)
69 */
70 public void consumeLine(String line) {
71 if (logger.isDebugEnabled()) {
72 logger.debug("consume line {}", line);
73 }
74
75 // name must be last token as it may contain separators
76 String[] parts = line.split("\\s", 4);
77 if (parts.length != 4) {
78 throw new IllegalArgumentException(
79 "Unexpected line: expecting 4 tokens separated by whitespace but got " + line);
80 }
81 infoItem.setLastChangedAuthor(
82 parts[LineParts.AUTHOR_NAME.getIndex()] + " <" + parts[LineParts.AUTHOR_EMAIL.getIndex()] + ">");
83 String revision = parts[LineParts.HASH.getIndex()];
84 if (revisionLength > -1) {
85 // do not truncate below 4 characters
86 revision = StringUtils.truncate(revision, Integer.max(4, revisionLength));
87 }
88 infoItem.setRevision(revision);
89 infoItem.setLastChangedDateTime(
90 DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(parts[LineParts.AUTHOR_LAST_MODIFIED.getIndex()]));
91 }
92
93 public InfoItem getInfoItem() {
94 return infoItem;
95 }
96
97 /**
98 * The format argument to use with {@code git log}
99 * @return the format argument to use {@code git log} command
100 * @see <a href="https://git-scm.com/docs/git-log#_pretty_formats">Pretty Formats</a>
101 */
102 public static Arg getFormatArgument() {
103 Commandline.Argument arg = new Commandline.Argument();
104 arg.setValue("--format=format:%H %aI %aE %aN");
105 return arg;
106 }
107 }