michael-o commented on code in PR #193: URL: https://github.com/apache/maven-scm/pull/193#discussion_r1491006507
########## maven-scm-api/src/main/java/org/apache/maven/scm/command/info/InfoItem.java: ########## @@ -18,7 +18,14 @@ */ package org.apache.maven.scm.command.info; +import java.time.OffsetDateTime; +import java.time.temporal.TemporalAccessor; + /** + * Encapsulates meta information about one file (or directory) being managed with an SCM. Review Comment: about a ########## maven-scm-api/src/main/java/org/apache/maven/scm/command/info/InfoItem.java: ########## @@ -117,11 +126,31 @@ public void setLastChangedRevision(String lastChangedRevision) { this.lastChangedRevision = lastChangedRevision; } + /** + * @deprecated Use {@link #getLastModifiedDate()} instead + */ + @Deprecated public String getLastChangedDate() { return lastChangedDate; } + /** + * @deprecated Use {@link #setLastModifiedDate(TemporalAccessor)} instead + */ + @Deprecated public void setLastChangedDate(String lastChangedDate) { this.lastChangedDate = lastChangedDate; } + + /** + * + * @return the date when the file indicated via {@link #getPath()} has been changed in the SCM for the last time + */ + OffsetDateTime getLastModifiedDate() { + return lastChangedDateTime; Review Comment: The name inconsistency is intended? ########## maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/info/GitInfoConsumer.java: ########## @@ -18,50 +18,90 @@ */ package org.apache.maven.scm.provider.git.gitexe.command.info; -import java.util.ArrayList; -import java.util.List; +import java.nio.file.Path; +import java.time.format.DateTimeFormatter; import org.apache.commons.lang3.StringUtils; -import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.command.info.InfoItem; import org.apache.maven.scm.util.AbstractConsumer; +import org.codehaus.plexus.util.cli.Arg; +import org.codehaus.plexus.util.cli.Commandline; /** + * Parses output of {@code git log} with a particular format and populates a {@link InfoItem}. + * * @author Olivier Lamy * @since 1.5 + * @see <a href="https://git-scm.com/docs/git-log#_pretty_formats">Pretty Formats */ public class GitInfoConsumer extends AbstractConsumer { - // $ git show - // commit cd3c0dfacb65955e6fbb35c56cc5b1bf8ce4f767 + private final InfoItem infoItem; + private final int revisionLength; + + public GitInfoConsumer(Path path, int revisionLength) { + infoItem = new InfoItem(); + infoItem.setPath(path.toString()); + infoItem.setURL(path.toUri().toASCIIString()); + this.revisionLength = revisionLength; + } + + enum LineParts { + HASH(0), + AUTHOR_NAME(3), + AUTHOR_EMAIL(2), + AUTHOR_LAST_MODIFIED(1); - private final List<InfoItem> infoItems = new ArrayList<>(1); + private final int index; - private final ScmFileSet scmFileSet; + LineParts(int index) { + this.index = index; + } - public GitInfoConsumer(ScmFileSet scmFileSet) { - this.scmFileSet = scmFileSet; + public int getIndex() { + return index; + } } /** + * @param line the line which is supposed to have the format as specified by {@link #getFormatArgument()}. * @see org.codehaus.plexus.util.cli.StreamConsumer#consumeLine(java.lang.String) */ public void consumeLine(String line) { if (logger.isDebugEnabled()) { logger.debug("consume line " + line); } - if (infoItems.isEmpty()) { - if (!(line == null || line.isEmpty())) { - InfoItem infoItem = new InfoItem(); - infoItem.setRevision(StringUtils.trim(line)); - infoItem.setURL(scmFileSet.getBasedir().toPath().toUri().toASCIIString()); - infoItems.add(infoItem); - } + // name must be last token as it may contain separators + String[] parts = line.split("\\s", 4); + if (parts.length != 4) { + throw new IllegalArgumentException( + "Unexpected line: expecting 4 tokens separated by whitespace but got " + line); } + infoItem.setLastChangedAuthor( + parts[LineParts.AUTHOR_NAME.getIndex()] + " <" + parts[LineParts.AUTHOR_EMAIL.getIndex()] + ">"); + String revision = parts[LineParts.HASH.getIndex()]; + if (revisionLength > -1) { + // do not truncate below 4 characters + revision = StringUtils.truncate(revision, Integer.max(4, revisionLength)); + } + infoItem.setRevision(revision); + infoItem.setLastModifiedDate( + DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(parts[LineParts.AUTHOR_LAST_MODIFIED.getIndex()])); + } + + public InfoItem getInfoItem() { + return infoItem; } - public List<InfoItem> getInfoItems() { - return infoItems; + /** + * The format argument to use with {@code git log} + * @return the format argument to use {@code git log} command + * @see <a href="https://git-scm.com/docs/git-log#_pretty_formats">Pretty Formats</a> + */ + public static Arg getFormatArgument() { + Commandline.Argument arg = new Commandline.Argument(); + arg.setValue("--format=format:%H %aI %aE %aN"); + return arg; Review Comment: Should this one have a test as well? ########## maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/info/GitInfoCommand.java: ########## @@ -43,31 +49,34 @@ public class GitInfoCommand extends AbstractCommand implements GitCommand { protected ScmResult executeCommand( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { - GitInfoConsumer consumer = new GitInfoConsumer(fileSet); - CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); - - Commandline cli = createCommandLine(repository, fileSet, parameters); + Commandline baseCli = GitCommandLineUtils.getBaseGitCommandLine(fileSet.getBasedir(), "log"); + baseCli.createArg().setValue("-1"); // only most recent commit matters + baseCli.createArg().setValue("--no-merges"); // skip merge commits + baseCli.addArg(GitInfoConsumer.getFormatArgument()); - int exitCode = GitCommandLineUtils.execute(cli, consumer, stderr); - if (exitCode != 0) { - return new InfoScmResult(cli.toString(), "The git rev-parse command failed.", stderr.getOutput(), false); + List<InfoItem> infoItems = new LinkedList<>(); + if (fileSet.getFileList().isEmpty()) { + infoItems.add(executeInfoCommand(baseCli, parameters, fileSet.getBasedir())); + } else { + // iterate over files + for (File scmFile : fileSet.getFileList()) { + Commandline cliClone = (Commandline) baseCli.clone(); + cliClone.createArg().setFile(scmFile); + infoItems.add(executeInfoCommand(cliClone, parameters, scmFile)); + } } - return new InfoScmResult(cli.toString(), consumer.getInfoItems()); + return new InfoScmResult(baseCli.toString(), infoItems); } - public static Commandline createCommandLine( - ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { - Commandline cli = GitCommandLineUtils.getBaseGitCommandLine(fileSet.getBasedir(), "rev-parse"); - cli.createArg().setValue("--verify"); - final int revLength = getRevisionLength(parameters); - if (revLength > NO_REVISION_LENGTH) // set the --short key only if revision length parameter is passed and - // different from -1 - { - cli.createArg().setValue("--short=" + revLength); + protected InfoItem executeInfoCommand(Commandline cli, CommandParameters parameters, File scmFile) + throws ScmException { + GitInfoConsumer consumer = new GitInfoConsumer(scmFile.toPath(), getRevisionLength(parameters)); + CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); + int exitCode = GitCommandLineUtils.execute(cli, consumer, stderr); + if (exitCode != 0) { + throw new ScmException("The git log command failed:" + cli.toString() + " returned " + stderr.getOutput()); Review Comment: `failed: ` space missing -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@maven.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org