001    package org.apache.maven.scm.provider.hg.command.update;
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.List;
025    import java.util.Map;
026    
027    import org.apache.maven.scm.ChangeSet;
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.ScmVersion;
034    import org.apache.maven.scm.command.Command;
035    import org.apache.maven.scm.command.changelog.ChangeLogCommand;
036    import org.apache.maven.scm.command.update.AbstractUpdateCommand;
037    import org.apache.maven.scm.command.update.UpdateScmResult;
038    import org.apache.maven.scm.command.update.UpdateScmResultWithRevision;
039    import org.apache.maven.scm.provider.ScmProviderRepository;
040    import org.apache.maven.scm.provider.hg.HgUtils;
041    import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
042    import org.apache.maven.scm.provider.hg.command.HgConsumer;
043    import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand;
044    import org.apache.maven.scm.provider.hg.command.diff.HgDiffConsumer;
045    import org.codehaus.plexus.util.StringUtils;
046    
047    /**
048     * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
049     * @author Olivier Lamy
050     * @version $Id: HgUpdateCommand.java 1207290 2011-11-28 15:20:44Z olamy $
051     */
052    public class HgUpdateCommand
053        extends AbstractUpdateCommand
054        implements Command
055    {
056        /** {@inheritDoc} */
057        protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repo, ScmFileSet fileSet, ScmVersion tag )
058            throws ScmException
059        {
060            File workingDir = fileSet.getBasedir();
061    
062            String[] updateCmd;
063            // Update branch
064            if (repo.isPushChanges()) {
065                updateCmd = new String[] {
066                        HgCommandConstants.PULL_CMD,
067                        HgCommandConstants.REVISION_OPTION,
068                        tag != null && !StringUtils.isEmpty( tag.getName() ) ? tag.getName() : "tip" };
069            } else {
070                updateCmd = new String[] {
071                        HgCommandConstants.UPDATE_CMD,
072                        tag != null && !StringUtils.isEmpty( tag.getName() ) ? tag.getName() : "tip",
073                        HgCommandConstants.CLEAN_OPTION };
074            }
075            ScmResult updateResult = HgUtils.execute( new HgConsumer( getLogger() ), getLogger(), workingDir, updateCmd );
076    
077            if ( !updateResult.isSuccess() )
078            {
079                return new UpdateScmResult( null, null, updateResult );
080            }
081    
082            // Find changes from last revision
083            int currentRevision = HgUtils.getCurrentRevisionNumber( getLogger(), workingDir );
084            int previousRevision = currentRevision - 1;
085            String[] diffCmd = new String[] {
086                HgCommandConstants.DIFF_CMD,
087                HgCommandConstants.REVISION_OPTION,
088                "" + previousRevision };
089            HgDiffConsumer diffConsumer = new HgDiffConsumer( getLogger(), workingDir );
090            ScmResult diffResult = HgUtils.execute( diffConsumer, getLogger(), workingDir, diffCmd );
091    
092            // Now translate between diff and update file status
093            List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
094            List<CharSequence> changes = new ArrayList<CharSequence>();
095            List<ScmFile> diffFiles = diffConsumer.getChangedFiles();
096            Map<String, CharSequence> diffChanges = diffConsumer.getDifferences();
097            for ( ScmFile file : diffFiles )
098            {
099                changes.add( diffChanges.get( file.getPath() ) );
100                if ( file.getStatus() == ScmFileStatus.MODIFIED )
101                {
102                    updatedFiles.add( new ScmFile( file.getPath(), ScmFileStatus.PATCHED ) );
103                }
104                else
105                {
106                    updatedFiles.add( file );
107                }
108            }
109            
110            if ( repo.isPushChanges() ) {
111                    String[] hgUpdateCmd = new String[] { HgCommandConstants.UPDATE_CMD };
112                    HgUtils.execute( new HgConsumer( getLogger() ), getLogger(), workingDir, hgUpdateCmd );
113            }
114    
115            return new UpdateScmResultWithRevision( updatedFiles, new ArrayList<ChangeSet>(0), String.valueOf( currentRevision ), diffResult );
116        }
117    
118        protected ChangeLogCommand getChangeLogCommand()
119        {
120            HgChangeLogCommand command = new HgChangeLogCommand();
121            command.setLogger( getLogger() );
122            return command;
123        }
124    }