001package org.apache.maven.scm.provider.hg.command.branch;
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 java.io.File;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.maven.scm.ScmBranchParameters;
027import org.apache.maven.scm.ScmException;
028import org.apache.maven.scm.ScmFile;
029import org.apache.maven.scm.ScmFileSet;
030import org.apache.maven.scm.ScmFileStatus;
031import org.apache.maven.scm.ScmResult;
032import org.apache.maven.scm.command.Command;
033import org.apache.maven.scm.command.branch.AbstractBranchCommand;
034import org.apache.maven.scm.command.branch.BranchScmResult;
035import org.apache.maven.scm.provider.ScmProviderRepository;
036import org.apache.maven.scm.provider.hg.HgUtils;
037import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
038import org.apache.maven.scm.provider.hg.command.HgConsumer;
039import org.apache.maven.scm.provider.hg.command.inventory.HgListConsumer;
040import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
041import org.codehaus.plexus.util.StringUtils;
042
043/**
044 * Branch. Mercurial has weird branches. After a branch is created, it must be committed to the server, otherwise
045 * the branch does not exist (yet) in the repository.
046 *
047 * @author Henning Schmiedehausen
048 *
049 */
050public class HgBranchCommand
051    extends AbstractBranchCommand
052    implements Command
053{
054
055    protected ScmResult executeBranchCommand( ScmProviderRepository scmProviderRepository, ScmFileSet fileSet,
056                                              String branch, String message )
057        throws ScmException
058    {
059        return executeBranchCommand( scmProviderRepository, fileSet, branch, new ScmBranchParameters( message ) );
060    }
061
062    /**
063     * {@inheritDoc}
064     */
065    protected ScmResult executeBranchCommand( ScmProviderRepository scmProviderRepository, ScmFileSet fileSet,
066                                              String branch, ScmBranchParameters scmBranchParameters )
067        throws ScmException
068    {
069
070        if ( StringUtils.isBlank( branch ) )
071        {
072            throw new ScmException( "branch must be specified" );
073        }
074
075        if ( !fileSet.getFileList().isEmpty() )
076        {
077            throw new ScmException( "This provider doesn't support branchging subsets of a directory" );
078        }
079
080        File workingDir = fileSet.getBasedir();
081
082        // build the command
083        String[] branchCmd = new String[] { HgCommandConstants.BRANCH_CMD, branch };
084
085        // keep the command about in string form for reporting
086        HgConsumer branchConsumer = new HgConsumer( getLogger() )
087        {
088            public void doConsume( ScmFileStatus status, String trimmedLine )
089            {
090                // noop
091            }
092        };
093
094        ScmResult result = HgUtils.execute( branchConsumer, getLogger(), workingDir, branchCmd );
095        HgScmProviderRepository repository = (HgScmProviderRepository) scmProviderRepository;
096
097        if ( !result.isSuccess() )
098        {
099            throw new ScmException( "Error while executing command " + joinCmd( branchCmd ) );
100        }
101
102        // First commit.
103        String[] commitCmd =
104            new String[] { HgCommandConstants.COMMIT_CMD, HgCommandConstants.MESSAGE_OPTION,
105                scmBranchParameters.getMessage() };
106
107        result = HgUtils.execute( new HgConsumer( getLogger() ), getLogger(), workingDir, commitCmd );
108
109        if ( !result.isSuccess() )
110        {
111            throw new ScmException( "Error while executing command " + joinCmd( commitCmd ) );
112        }
113
114        // now push, if we should.
115
116        if ( repository.isPushChanges() )
117        {
118            if ( !repository.getURI().equals( fileSet.getBasedir().getAbsolutePath() ) )
119            {
120
121                String[] pushCmd = new String[] {
122                    HgCommandConstants.PUSH_CMD,
123                    HgCommandConstants.NEW_BRANCH_OPTION,
124                    repository.getURI()
125                };
126
127                result = HgUtils.execute( new HgConsumer( getLogger() ), getLogger(), fileSet.getBasedir(), pushCmd );
128
129                if ( !result.isSuccess() )
130                {
131                    throw new ScmException( "Error while executing command " + joinCmd( pushCmd ) );
132                }
133            }
134        }
135
136        // do an inventory to return the files branched (all of them)
137        String[] listCmd = new String[]{ HgCommandConstants.INVENTORY_CMD };
138        HgListConsumer listconsumer = new HgListConsumer( getLogger() );
139
140        result = HgUtils.execute( listconsumer, getLogger(), fileSet.getBasedir(), listCmd );
141
142        if ( !result.isSuccess() )
143        {
144            throw new ScmException( "Error while executing command " + joinCmd( listCmd ) );
145        }
146
147        List<ScmFile> files = listconsumer.getFiles();
148        List<ScmFile> fileList = new ArrayList<ScmFile>();
149        for ( ScmFile f : files )
150        {
151            fileList.add( new ScmFile( f.getPath(), ScmFileStatus.TAGGED ) );
152        }
153
154        return new BranchScmResult( fileList, result );
155    }
156
157    private String joinCmd( String[] cmd )
158    {
159        StringBuilder result = new StringBuilder();
160        for ( int i = 0; i < cmd.length; i++ )
161        {
162            String s = cmd[i];
163            result.append( s );
164            if ( i < cmd.length - 1 )
165            {
166                result.append( " " );
167            }
168        }
169        return result.toString();
170    }
171}