001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.git.gitexe.command.info; 020 021import java.nio.file.Path; 022import java.time.format.DateTimeFormatter; 023 024import org.apache.commons.lang3.StringUtils; 025import org.apache.maven.scm.command.info.InfoItem; 026import org.apache.maven.scm.util.AbstractConsumer; 027import org.codehaus.plexus.util.cli.Arg; 028import org.codehaus.plexus.util.cli.Commandline; 029 030/** 031 * Parses output of {@code git log} with a particular format and populates a {@link InfoItem}. 032 * 033 * @author Olivier Lamy 034 * @since 1.5 035 * @see <a href="https://git-scm.com/docs/git-log#_pretty_formats">Pretty Formats</a> 036 */ 037public class GitInfoConsumer extends AbstractConsumer { 038 039 private final InfoItem infoItem; 040 private final int revisionLength; 041 042 public GitInfoConsumer(Path path, int revisionLength) { 043 infoItem = new InfoItem(); 044 infoItem.setPath(path.toString()); 045 infoItem.setURL(path.toUri().toASCIIString()); 046 this.revisionLength = revisionLength; 047 } 048 049 enum LineParts { 050 HASH(0), 051 AUTHOR_NAME(3), 052 AUTHOR_EMAIL(2), 053 AUTHOR_LAST_MODIFIED(1); 054 055 private final int index; 056 057 LineParts(int index) { 058 this.index = index; 059 } 060 061 public int getIndex() { 062 return index; 063 } 064 } 065 066 /** 067 * @param line the line which is supposed to have the format as specified by {@link #getFormatArgument()}. 068 * @see org.codehaus.plexus.util.cli.StreamConsumer#consumeLine(java.lang.String) 069 */ 070 public void consumeLine(String line) { 071 if (logger.isDebugEnabled()) { 072 logger.debug("consume line {}", line); 073 } 074 075 // name must be last token as it may contain separators 076 String[] parts = line.split("\\s", 4); 077 if (parts.length != 4) { 078 throw new IllegalArgumentException( 079 "Unexpected line: expecting 4 tokens separated by whitespace but got " + line); 080 } 081 infoItem.setLastChangedAuthor( 082 parts[LineParts.AUTHOR_NAME.getIndex()] + " <" + parts[LineParts.AUTHOR_EMAIL.getIndex()] + ">"); 083 String revision = parts[LineParts.HASH.getIndex()]; 084 if (revisionLength > -1) { 085 // do not truncate below 4 characters 086 revision = StringUtils.truncate(revision, Integer.max(4, revisionLength)); 087 } 088 infoItem.setRevision(revision); 089 infoItem.setLastChangedDateTime( 090 DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(parts[LineParts.AUTHOR_LAST_MODIFIED.getIndex()])); 091 } 092 093 public InfoItem getInfoItem() { 094 return infoItem; 095 } 096 097 /** 098 * The format argument to use with {@code git log} 099 * @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}