[ https://issues.apache.org/jira/browse/SCM-914?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17817788#comment-17817788 ]
ASF GitHub Bot commented on SCM-914: ------------------------------------ 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 > InfoItem.lastChangedDate is leaky abstraction > --------------------------------------------- > > Key: SCM-914 > URL: https://issues.apache.org/jira/browse/SCM-914 > Project: Maven SCM > Issue Type: Bug > Components: maven-scm-api > Reporter: Tobias Gruetzmacher > Assignee: Konrad Windszus > Priority: Minor > > I was looking into implementing > [https://github.com/mojohaus/buildnumber-maven-plugin/pull/16] in a sane way, > but had to conclude that InfoItem.lastChangedDate is unfortunately just a > string and not a Data, so will leak the console output of different providers > to the user. > Does anybody see a sane way to fix this API and create a sane abstraction for > different SCMs? If yes, I would try to go ahead with the following tasks: > # Fix InfoItem, so that lastChangedDate is a Date > # Fix the current providers filling this field (svnexe and svnjava AFAICS - > aside: why is svnjava not part of the maven-scm repository?) > # Implement this feature for at least gitexe (and maybe jgit) so I can use > it for my usecase > Ideas, comments? -- This message was sent by Atlassian Jira (v8.20.10#820010)