001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm.provider.hg.command.tag;
020
021import java.io.File;
022import java.util.ArrayList;
023import java.util.List;
024
025import org.apache.commons.lang3.StringUtils;
026import org.apache.maven.scm.ScmException;
027import org.apache.maven.scm.ScmFile;
028import org.apache.maven.scm.ScmFileSet;
029import org.apache.maven.scm.ScmFileStatus;
030import org.apache.maven.scm.ScmResult;
031import org.apache.maven.scm.ScmTagParameters;
032import org.apache.maven.scm.command.Command;
033import org.apache.maven.scm.command.tag.AbstractTagCommand;
034import org.apache.maven.scm.command.tag.TagScmResult;
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;
041
042/**
043 * Tag
044 *
045 * @author <a href="mailto:ryan@darksleep.com">ryan daum</a>
046 * @author Olivier Lamy
047 *
048 */
049public class HgTagCommand extends AbstractTagCommand implements Command {
050
051    protected ScmResult executeTagCommand(
052            ScmProviderRepository scmProviderRepository, ScmFileSet fileSet, String tag, String message)
053            throws ScmException {
054        return executeTagCommand(scmProviderRepository, fileSet, tag, new ScmTagParameters(message));
055    }
056
057    /**
058     * {@inheritDoc}
059     */
060    protected ScmResult executeTagCommand(
061            ScmProviderRepository scmProviderRepository,
062            ScmFileSet fileSet,
063            String tag,
064            ScmTagParameters scmTagParameters)
065            throws ScmException {
066
067        if (tag == null || StringUtils.isEmpty(tag.trim())) {
068            throw new ScmException("tag must be specified");
069        }
070
071        if (!fileSet.getFileList().isEmpty()) {
072            throw new ScmException(
073                    "This provider doesn't support tagging subsets of a directory : " + fileSet.getFileList());
074        }
075
076        File workingDir = fileSet.getBasedir();
077
078        // build the command
079        String[] tagCmd = new String[] {
080            HgCommandConstants.TAG_CMD, HgCommandConstants.MESSAGE_OPTION, scmTagParameters.getMessage(), tag
081        };
082
083        // keep the command about in string form for reporting
084        StringBuilder cmd = joinCmd(tagCmd);
085        HgTagConsumer consumer = new HgTagConsumer();
086        ScmResult result = HgUtils.execute(consumer, workingDir, tagCmd);
087        HgScmProviderRepository repository = (HgScmProviderRepository) scmProviderRepository;
088        if (result.isSuccess()) {
089            // now push
090            // Push to parent branch if any
091
092            if (repository.isPushChanges()) {
093                if (!repository.getURI().equals(fileSet.getBasedir().getAbsolutePath())) {
094                    String branchName = HgUtils.getCurrentBranchName(workingDir);
095                    boolean differentOutgoingBranch = HgUtils.differentOutgoingBranchFound(workingDir, branchName);
096
097                    String[] pushCmd = new String[] {
098                        HgCommandConstants.PUSH_CMD,
099                        differentOutgoingBranch ? HgCommandConstants.REVISION_OPTION + branchName : null,
100                        repository.getURI()
101                    };
102
103                    result = HgUtils.execute(new HgConsumer(), fileSet.getBasedir(), pushCmd);
104                }
105            }
106        } else {
107            throw new ScmException("Error while executing command " + cmd.toString());
108        }
109
110        // do an inventory to return the files tagged (all of them)
111        String[] listCmd = new String[] {HgCommandConstants.INVENTORY_CMD};
112        HgListConsumer listconsumer = new HgListConsumer();
113        result = HgUtils.execute(listconsumer, fileSet.getBasedir(), listCmd);
114        if (result.isSuccess()) {
115            List<ScmFile> files = listconsumer.getFiles();
116            List<ScmFile> fileList = new ArrayList<ScmFile>();
117            for (ScmFile f : files) {
118                if (!f.getPath().endsWith(".hgtags")) {
119                    fileList.add(new ScmFile(f.getPath(), ScmFileStatus.TAGGED));
120                }
121            }
122
123            return new TagScmResult(fileList, result);
124        } else {
125            throw new ScmException("Error while executing command " + cmd.toString());
126        }
127    }
128
129    private StringBuilder joinCmd(String[] cmd) {
130        StringBuilder result = new StringBuilder();
131        for (int i = 0; i < cmd.length; i++) {
132            String s = cmd[i];
133            result.append(s);
134            if (i < cmd.length - 1) {
135                result.append(" ");
136            }
137        }
138        return result;
139    }
140}