001 package org.apache.maven.scm.provider.perforce.command.blame;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.maven.scm.ScmException;
023 import org.apache.maven.scm.ScmFileSet;
024 import org.apache.maven.scm.command.blame.AbstractBlameCommand;
025 import org.apache.maven.scm.command.blame.BlameLine;
026 import org.apache.maven.scm.command.blame.BlameScmResult;
027 import org.apache.maven.scm.provider.ScmProviderRepository;
028 import org.apache.maven.scm.provider.perforce.PerforceScmProvider;
029 import org.apache.maven.scm.provider.perforce.command.PerforceCommand;
030 import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
031 import org.codehaus.plexus.util.cli.CommandLineException;
032 import org.codehaus.plexus.util.cli.CommandLineUtils;
033 import org.codehaus.plexus.util.cli.Commandline;
034
035 import java.io.File;
036 import java.util.List;
037
038 /**
039 * @author Evgeny Mandrikov
040 * @author Olivier Lamy
041 * @since 1.4
042 */
043 public class PerforceBlameCommand
044 extends AbstractBlameCommand
045 implements PerforceCommand
046 {
047 public BlameScmResult executeBlameCommand( ScmProviderRepository repo, ScmFileSet workingDirectory, String filename )
048 throws ScmException
049 {
050 // Call annotate command
051 PerforceScmProviderRepository p4repo = (PerforceScmProviderRepository) repo;
052 String clientspec = PerforceScmProvider.getClientspecName( getLogger(), p4repo, workingDirectory.getBasedir() );
053 Commandline cl = createCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(),
054 filename, clientspec);
055
056 PerforceBlameConsumer blameConsumer = new PerforceBlameConsumer( getLogger() );
057
058 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
059
060 int exitCode;
061
062 try
063 {
064 exitCode = CommandLineUtils.executeCommandLine( cl, blameConsumer, stderr );
065 }
066 catch ( CommandLineException ex )
067 {
068 throw new ScmException( "Error while executing command.", ex );
069 }
070 if ( exitCode != 0 )
071 {
072 return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
073 }
074
075 // Call filelog command
076
077 cl = createFilelogCommandLine( (PerforceScmProviderRepository) repo, workingDirectory.getBasedir(), filename, clientspec );
078
079 PerforceFilelogConsumer filelogConsumer = new PerforceFilelogConsumer( getLogger() );
080
081 try
082 {
083 exitCode = CommandLineUtils.executeCommandLine( cl, filelogConsumer, stderr );
084 }
085 catch ( CommandLineException ex )
086 {
087 throw new ScmException( "Error while executing command.", ex );
088 }
089 if ( exitCode != 0 )
090 {
091 return new BlameScmResult( cl.toString(), "The perforce command failed.", stderr.getOutput(), false );
092 }
093
094 // Combine results
095
096 List<BlameLine> lines = blameConsumer.getLines();
097 for ( int i = 0; i < lines.size(); i++ )
098 {
099 BlameLine line = lines.get( i );
100 String revision = line.getRevision();
101 line.setAuthor( filelogConsumer.getAuthor( revision ) );
102 line.setDate( filelogConsumer.getDate( revision ) );
103 }
104
105 return new BlameScmResult( cl.toString(), lines );
106 }
107
108 public static Commandline createCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
109 String filename, final String clientspec )
110 {
111 Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
112 if(clientspec != null)
113 {
114 cl.createArg().setValue( "-c" );
115 cl.createArg().setValue( clientspec );
116 }
117 cl.createArg().setValue( "annotate" );
118 cl.createArg().setValue( "-q" ); // quiet
119 cl.createArg().setValue( filename );
120 return cl;
121 }
122
123 public static Commandline createFilelogCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
124 String filename, final String clientspec )
125 {
126 Commandline cl = PerforceScmProvider.createP4Command( repo, workingDirectory );
127 if(clientspec != null)
128 {
129 cl.createArg().setValue( "-c" );
130 cl.createArg().setValue( clientspec );
131 }
132 cl.createArg().setValue( "filelog" );
133 cl.createArg().setValue( filename );
134 return cl;
135 }
136 }