001package org.apache.maven.scm.provider.git.gitexe.command;
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
022import org.apache.commons.io.FilenameUtils;
023
024import org.apache.maven.scm.ScmException;
025import org.apache.maven.scm.log.ScmLogger;
026import org.apache.maven.scm.provider.git.util.GitUtil;
027import org.apache.maven.scm.providers.gitlib.settings.Settings;
028import org.codehaus.plexus.util.cli.CommandLineException;
029import org.codehaus.plexus.util.cli.CommandLineUtils;
030import org.codehaus.plexus.util.cli.Commandline;
031import org.codehaus.plexus.util.cli.StreamConsumer;
032
033import java.io.File;
034import java.io.IOException;
035import java.util.List;
036
037/**
038 * Command line construction utility.
039 *
040 * @author Brett Porter
041 * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
042 *
043 */
044public final class GitCommandLineUtils
045{
046
047    private GitCommandLineUtils()
048    {
049    }
050
051    public static void addTarget( Commandline cl, List<File> files )
052    {
053        if ( files == null || files.isEmpty() )
054        {
055            return;
056        }
057        final File workingDirectory = cl.getWorkingDirectory();
058        try
059        {
060            final String canonicalWorkingDirectory = workingDirectory.getCanonicalPath();
061            for ( File file : files )
062            {
063                String relativeFile = file.getPath();
064
065                final String canonicalFile = file.getCanonicalPath();
066                if ( canonicalFile.startsWith( canonicalWorkingDirectory ) )
067                {
068                    // so we can omit the starting characters
069                    relativeFile = canonicalFile.substring( canonicalWorkingDirectory.length() );
070
071                    if ( relativeFile.startsWith( File.separator ) )
072                    {
073                        relativeFile = relativeFile.substring( File.separator.length() );
074                    }
075                }
076
077                // no setFile() since this screws up the working directory!
078                cl.createArg().setValue( FilenameUtils.separatorsToUnix( relativeFile ) );
079            }
080        }
081        catch ( IOException ex )
082        {
083            throw new IllegalArgumentException( "Could not get canonical paths for workingDirectory = "
084                + workingDirectory + " or files=" + files, ex );
085        }
086    }
087
088    /**
089     *
090     * @param workingDirectory
091     * @param command
092     * @return
093     */
094    public static Commandline getBaseGitCommandLine( File workingDirectory, String command )
095    {
096        return getAnonymousBaseGitCommandLine( workingDirectory, command );
097    }
098
099    /**
100     * Creates a {@link Commandline} for which the toString() do not display
101     * password.
102     *
103     * @param workingDirectory
104     * @param command
105     * @return CommandLine with anonymous output.
106     */
107    private static Commandline getAnonymousBaseGitCommandLine( File workingDirectory, String command )
108    {
109        if ( command == null || command.length() == 0 )
110        {
111            return null;
112        }
113
114        Commandline cl = new AnonymousCommandLine();
115
116        composeCommand( workingDirectory, command, cl );
117
118        return cl;
119    }
120
121    private static void composeCommand( File workingDirectory, String command, Commandline cl )
122    {
123        Settings settings = GitUtil.getSettings();
124
125        cl.setExecutable( settings.getGitCommand() );
126
127        cl.createArg().setValue( command );
128
129        if ( workingDirectory != null )
130        {
131            cl.setWorkingDirectory( workingDirectory.getAbsolutePath() );
132        }
133    }
134
135    public static int execute( Commandline cl, StreamConsumer consumer, CommandLineUtils.StringStreamConsumer stderr,
136                               ScmLogger logger )
137        throws ScmException
138    {
139        if ( logger.isInfoEnabled() )
140        {
141            logger.info( "Executing: " + cl );
142            logger.info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
143        }
144
145        int exitCode;
146        try
147        {
148            exitCode = CommandLineUtils.executeCommandLine( cl, consumer, stderr );
149        }
150        catch ( CommandLineException ex )
151        {
152            throw new ScmException( "Error while executing command.", ex );
153        }
154
155        return exitCode;
156    }
157
158    public static int execute( Commandline cl, CommandLineUtils.StringStreamConsumer stdout,
159                               CommandLineUtils.StringStreamConsumer stderr, ScmLogger logger )
160        throws ScmException
161    {
162        if ( logger.isInfoEnabled() )
163        {
164            logger.info( "Executing: " + cl );
165            logger.info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
166        }
167
168        int exitCode;
169        try
170        {
171            exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
172        }
173        catch ( CommandLineException ex )
174        {
175            throw new ScmException( "Error while executing command.", ex );
176        }
177
178        return exitCode;
179    }
180
181}