Coverage Report - org.apache.maven.scm.provider.perforce.command.tag.PerforceTagCommand
 
Classes in this File Line Coverage Branch Coverage Complexity
PerforceTagCommand
14 %
14/94
5 %
2/36
3,875
 
 1  
 package org.apache.maven.scm.provider.perforce.command.tag;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  * http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.maven.scm.ScmException;
 23  
 import org.apache.maven.scm.ScmFileSet;
 24  
 import org.apache.maven.scm.ScmResult;
 25  
 import org.apache.maven.scm.ScmTagParameters;
 26  
 import org.apache.maven.scm.command.tag.AbstractTagCommand;
 27  
 import org.apache.maven.scm.command.tag.TagScmResult;
 28  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 29  
 import org.apache.maven.scm.provider.perforce.PerforceScmProvider;
 30  
 import org.apache.maven.scm.provider.perforce.command.PerforceCommand;
 31  
 import org.apache.maven.scm.provider.perforce.command.PerforceInfoCommand;
 32  
 import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
 33  
 import org.codehaus.plexus.util.IOUtil;
 34  
 import org.codehaus.plexus.util.cli.CommandLineException;
 35  
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 36  
 import org.codehaus.plexus.util.cli.Commandline;
 37  
 
 38  
 import java.io.BufferedReader;
 39  
 import java.io.DataOutputStream;
 40  
 import java.io.File;
 41  
 import java.io.IOException;
 42  
 import java.io.InputStreamReader;
 43  
 import java.io.OutputStream;
 44  
 import java.util.List;
 45  
 
 46  
 /**
 47  
  * @author Mike Perham
 48  
  * @author Olivier Lamy
 49  
  * @version $Id: PerforceTagCommand.java 1306867 2012-03-29 13:45:10Z olamy $
 50  
  */
 51  1
 public class PerforceTagCommand
 52  
     extends AbstractTagCommand
 53  
     implements PerforceCommand
 54  
 {
 55  1
     private String actualRepoLocation = null;
 56  
 
 57  
 
 58  
     protected ScmResult executeTagCommand( ScmProviderRepository repo, ScmFileSet files, String tag, String message )
 59  
         throws ScmException
 60  
     {
 61  0
         return executeTagCommand( repo, files, tag, new ScmTagParameters( message ) );
 62  
     }
 63  
 
 64  
     /**
 65  
      * {@inheritDoc}
 66  
      */
 67  
     protected ScmResult executeTagCommand( ScmProviderRepository repo, ScmFileSet files, String tag,
 68  
                                            ScmTagParameters scmTagParameters )
 69  
         throws ScmException
 70  
     {
 71  0
         PerforceScmProviderRepository prepo = (PerforceScmProviderRepository) repo;
 72  0
         actualRepoLocation = PerforceScmProvider.getRepoPath( getLogger(), prepo, files.getBasedir() );
 73  
 
 74  0
         PerforceTagConsumer consumer = new PerforceTagConsumer();
 75  0
         createLabel( repo, files, tag, consumer, false );
 76  0
         if ( consumer.isSuccess() )
 77  
         {
 78  0
             syncLabel( repo, files, tag, consumer );
 79  
         }
 80  0
         if ( consumer.isSuccess() )
 81  
         {
 82  
             // Now update the label if we need to lock it
 83  0
             if ( shouldLock() )
 84  
             {
 85  0
                 consumer = new PerforceTagConsumer();
 86  0
                 createLabel( repo, files, tag, consumer, true );
 87  
             }
 88  
         }
 89  
 
 90  0
         if ( consumer.isSuccess() )
 91  
         {
 92  
             // Unclear what to pass as the first arg
 93  0
             return new TagScmResult( "p4 label -i", consumer.getTagged() );
 94  
         }
 95  
 
 96  
         // Unclear what to pass as the first arg
 97  0
         return new TagScmResult( "p4 label -i", "Tag failed", consumer.getOutput(), false );
 98  
     }
 99  
 
 100  
     private boolean shouldLock()
 101  
     {
 102  0
         return Boolean.valueOf( System.getProperty( "maven.scm.locktag", "true" ) ).booleanValue();
 103  
     }
 104  
 
 105  
     private void syncLabel( ScmProviderRepository repo, ScmFileSet files, String tag, PerforceTagConsumer consumer )
 106  
     {
 107  0
         Commandline cl =
 108  
             createLabelsyncCommandLine( (PerforceScmProviderRepository) repo, files.getBasedir(), files, tag );
 109  
         try
 110  
         {
 111  0
             if ( getLogger().isDebugEnabled() )
 112  
             {
 113  0
                 getLogger().debug( PerforceScmProvider.clean( "Executing: " + cl.toString() ) );
 114  
             }
 115  0
             CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
 116  0
             int exitCode = CommandLineUtils.executeCommandLine( cl, consumer, err );
 117  
 
 118  0
             if ( exitCode != 0 )
 119  
             {
 120  0
                 String cmdLine = CommandLineUtils.toString( cl.getCommandline() );
 121  
 
 122  0
                 StringBuilder msg = new StringBuilder( "Exit code: " + exitCode + " - " + err.getOutput() );
 123  0
                 msg.append( '\n' );
 124  0
                 msg.append( "Command line was:" + cmdLine );
 125  
 
 126  0
                 throw new CommandLineException( msg.toString() );
 127  
             }
 128  
         }
 129  0
         catch ( CommandLineException e )
 130  
         {
 131  0
             if ( getLogger().isErrorEnabled() )
 132  
             {
 133  0
                 getLogger().error( "CommandLineException " + e.getMessage(), e );
 134  
             }
 135  0
         }
 136  0
     }
 137  
 
 138  
     private void createLabel( ScmProviderRepository repo, ScmFileSet files, String tag, PerforceTagConsumer consumer,
 139  
                               boolean lock )
 140  
     {
 141  0
         Commandline cl = createLabelCommandLine( (PerforceScmProviderRepository) repo, files.getBasedir() );
 142  0
         DataOutputStream dos = null;
 143  0
         InputStreamReader isReader = null;
 144  0
         InputStreamReader isReaderErr = null;
 145  
         try
 146  
         {
 147  0
             if ( getLogger().isDebugEnabled() )
 148  
             {
 149  0
                 getLogger().debug( PerforceScmProvider.clean( "Executing: " + cl.toString() ) );
 150  
             }
 151  0
             Process proc = cl.execute();
 152  0
             OutputStream out = proc.getOutputStream();
 153  0
             dos = new DataOutputStream( out );
 154  0
             String label = createLabelSpecification( (PerforceScmProviderRepository) repo, tag, lock );
 155  0
             if ( getLogger().isDebugEnabled() )
 156  
             {
 157  0
                 getLogger().debug( "LabelSpec: " + NEWLINE + label );
 158  
             }
 159  0
             dos.write( label.getBytes() );
 160  0
             dos.close();
 161  0
             out.close();
 162  
             // TODO find & use a less naive InputStream multiplexer
 163  0
             isReader = new InputStreamReader( proc.getInputStream() );
 164  0
             isReaderErr = new InputStreamReader( proc.getErrorStream() );
 165  0
             BufferedReader stdout = new BufferedReader( isReader );
 166  0
             BufferedReader stderr = new BufferedReader( isReaderErr );
 167  
             String line;
 168  0
             while ( ( line = stdout.readLine() ) != null )
 169  
             {
 170  0
                 if ( getLogger().isDebugEnabled() )
 171  
                 {
 172  0
                     getLogger().debug( "Consuming stdout: " + line );
 173  
                 }
 174  0
                 consumer.consumeLine( line );
 175  
             }
 176  0
             while ( ( line = stderr.readLine() ) != null )
 177  
             {
 178  0
                 if ( getLogger().isDebugEnabled() )
 179  
                 {
 180  0
                     getLogger().debug( "Consuming stderr: " + line );
 181  
                 }
 182  0
                 consumer.consumeLine( line );
 183  
             }
 184  0
             stderr.close();
 185  0
             stdout.close();
 186  
         }
 187  0
         catch ( CommandLineException e )
 188  
         {
 189  0
             if ( getLogger().isErrorEnabled() )
 190  
             {
 191  0
                 getLogger().error( "CommandLineException " + e.getMessage(), e );
 192  
             }
 193  
         }
 194  0
         catch ( IOException e )
 195  
         {
 196  0
             if ( getLogger().isErrorEnabled() )
 197  
             {
 198  0
                 getLogger().error( "IOException " + e.getMessage(), e );
 199  
             }
 200  
         }
 201  
         finally
 202  
         {
 203  0
             IOUtil.close( dos );
 204  0
             IOUtil.close( isReader );
 205  0
             IOUtil.close( isReaderErr );
 206  0
         }
 207  0
     }
 208  
 
 209  
     public static Commandline createLabelCommandLine( PerforceScmProviderRepository repo, File workingDirectory )
 210  
     {
 211  1
         Commandline command = PerforceScmProvider.createP4Command( repo, workingDirectory );
 212  
 
 213  1
         command.createArg().setValue( "label" );
 214  1
         command.createArg().setValue( "-i" );
 215  1
         return command;
 216  
     }
 217  
 
 218  
     public static Commandline createLabelsyncCommandLine( PerforceScmProviderRepository repo, File workingDirectory,
 219  
                                                           ScmFileSet files, String tag )
 220  
     {
 221  1
         Commandline command = PerforceScmProvider.createP4Command( repo, workingDirectory );
 222  
 
 223  1
         command.createArg().setValue( "labelsync" );
 224  1
         command.createArg().setValue( "-l" );
 225  1
         command.createArg().setValue( tag );
 226  
 
 227  1
         List<File> fs = files.getFileList();
 228  1
         for ( File file : fs )
 229  
         {
 230  2
             command.createArg().setValue( file.getPath() );
 231  
         }
 232  1
         return command;
 233  
     }
 234  
 
 235  
     private static final String NEWLINE = "\r\n";
 236  
 
 237  
     /*
 238  
      * Label: foo-label
 239  
      * View: //depot/path/to/repos/...
 240  
      * Owner: mperham
 241  
      */
 242  
     public String createLabelSpecification( PerforceScmProviderRepository repo, String tag, boolean lock )
 243  
     {
 244  0
         StringBuilder buf = new StringBuilder();
 245  0
         buf.append( "Label: " ).append( tag ).append( NEWLINE );
 246  0
         buf.append( "View: " ).append( PerforceScmProvider.getCanonicalRepoPath( actualRepoLocation ) ).append(
 247  
             NEWLINE );
 248  0
         String username = repo.getUser();
 249  0
         if ( username == null )
 250  
         {
 251  
             // I have no idea why but Perforce doesn't default the owner to the current user.
 252  
             // Since the user is not explicitly set, we use 'p4 info' to query for the current user.
 253  0
             username = PerforceInfoCommand.getInfo( getLogger(), repo ).getEntry( "User name" );
 254  
         }
 255  0
         buf.append( "Owner: " ).append( username ).append( NEWLINE );
 256  0
         buf.append( "Options: " ).append( lock ? "" : "un" ).append( "locked" ).append( NEWLINE );
 257  0
         return buf.toString();
 258  
     }
 259  
 }