001    package 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    
022    import java.io.File;
023    import java.util.ArrayList;
024    import java.util.Iterator;
025    import java.util.List;
026    
027    import org.apache.maven.scm.ScmBranchParameters;
028    import org.apache.maven.scm.ScmException;
029    import org.apache.maven.scm.ScmFile;
030    import org.apache.maven.scm.ScmFileSet;
031    import org.apache.maven.scm.ScmFileStatus;
032    import org.apache.maven.scm.ScmResult;
033    import org.apache.maven.scm.command.Command;
034    import org.apache.maven.scm.command.branch.AbstractBranchCommand;
035    import org.apache.maven.scm.command.branch.BranchScmResult;
036    import org.apache.maven.scm.provider.ScmProviderRepository;
037    import org.apache.maven.scm.provider.hg.HgUtils;
038    import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
039    import org.apache.maven.scm.provider.hg.command.HgConsumer;
040    import org.apache.maven.scm.provider.hg.command.inventory.HgListConsumer;
041    import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
042    import org.codehaus.plexus.util.StringUtils;
043    
044    /**
045     * Branch. Mercurial has weird branches. After a branch is created, it must be committed to the server, otherwise
046     * the branch does not exist (yet) in the repository.
047     *
048     * @author Henning Schmiedehausen
049     * @version $Id: HgBranchCommand.java 1061024 2011-01-19 21:54:37Z olamy $
050     */
051    public class HgBranchCommand
052        extends AbstractBranchCommand
053        implements Command
054    {
055    
056        protected ScmResult executeBranchCommand( ScmProviderRepository scmProviderRepository, ScmFileSet fileSet, String branch,
057                                               String message )
058            throws ScmException
059        {
060            return executeBranchCommand( scmProviderRepository, fileSet, branch, new ScmBranchParameters( message ) );
061        }
062    
063        /**
064         * {@inheritDoc}
065         */
066        protected ScmResult executeBranchCommand( ScmProviderRepository scmProviderRepository, ScmFileSet fileSet, String branch,
067                                               ScmBranchParameters scmBranchParameters )
068            throws ScmException
069        {
070    
071            if ( StringUtils.isBlank( branch ) )
072            {
073                throw new ScmException( "branch must be specified" );
074            }
075    
076            if ( !fileSet.getFileList().isEmpty() )
077            {
078                throw new ScmException( "This provider doesn't support branchging subsets of a directory" );
079            }
080    
081            File workingDir = fileSet.getBasedir();
082    
083            // build the command
084            String[] branchCmd =
085                new String[]{ HgCommandConstants.BRANCH_CMD, branch };
086    
087            // keep the command about in string form for reporting
088            ;
089            HgConsumer branchConsumer = new HgConsumer( getLogger() ) {
090                public void doConsume( ScmFileStatus status, String trimmedLine )
091                {
092                }
093            };
094    
095            ScmResult result = HgUtils.execute( branchConsumer, getLogger(), workingDir, branchCmd );
096            HgScmProviderRepository repository = (HgScmProviderRepository) scmProviderRepository;
097    
098            if ( !result.isSuccess() )
099            {
100                throw new ScmException( "Error while executing command " + joinCmd( branchCmd ) );
101            }
102    
103            // First commit.
104            String[] commitCmd = new String[]{ HgCommandConstants.COMMIT_CMD, HgCommandConstants.MESSAGE_OPTION, scmBranchParameters.getMessage() };
105    
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 ( Iterator<ScmFile> i = files.iterator(); i.hasNext(); )
150            {
151                ScmFile f = i.next();
152    
153                fileList.add( new ScmFile( f.getPath(), ScmFileStatus.TAGGED ) );
154            }
155    
156            return new BranchScmResult( fileList, result );
157        }
158    
159        private String joinCmd( String[] cmd )
160        {
161            StringBuilder result = new StringBuilder();
162            for ( int i = 0; i < cmd.length; i++ )
163            {
164                String s = cmd[i];
165                result.append( s );
166                if ( i < cmd.length - 1 )
167                {
168                    result.append( " " );
169                }
170            }
171            return result.toString();
172        }
173    }