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.maven.scm.ScmException;
026import org.apache.maven.scm.ScmFile;
027import org.apache.maven.scm.ScmFileSet;
028import org.apache.maven.scm.ScmFileStatus;
029import org.apache.maven.scm.ScmResult;
030import org.apache.maven.scm.ScmTagParameters;
031import org.apache.maven.scm.command.Command;
032import org.apache.maven.scm.command.tag.AbstractTagCommand;
033import org.apache.maven.scm.command.tag.TagScmResult;
034import org.apache.maven.scm.provider.ScmProviderRepository;
035import org.apache.maven.scm.provider.hg.HgUtils;
036import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
037import org.apache.maven.scm.provider.hg.command.HgConsumer;
038import org.apache.maven.scm.provider.hg.command.inventory.HgListConsumer;
039import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
040
041/**
042 * Tag
043 *
044 * @author <a href="mailto:ryan@darksleep.com">ryan daum</a>
045 * @author Olivier Lamy
046 *
047 */
048public class HgTagCommand extends AbstractTagCommand implements Command {
049
050    protected ScmResult executeTagCommand(
051            ScmProviderRepository scmProviderRepository, ScmFileSet fileSet, String tag, String message)
052            throws ScmException {
053        return executeTagCommand(scmProviderRepository, fileSet, tag, new ScmTagParameters(message));
054    }
055
056    /**
057     * {@inheritDoc}
058     */
059    protected ScmResult executeTagCommand(
060            ScmProviderRepository scmProviderRepository,
061            ScmFileSet fileSet,
062            String tag,
063            ScmTagParameters scmTagParameters)
064            throws ScmException {
065
066        if (tag == null || tag.trim().isEmpty()) {
067            throw new ScmException("tag must be specified");
068        }
069
070        if (!fileSet.getFileList().isEmpty()) {
071            throw new ScmException(
072                    "This provider doesn't support tagging subsets of a directory : " + fileSet.getFileList());
073        }
074
075        File workingDir = fileSet.getBasedir();
076
077        // build the command
078        String[] tagCmd = new String[] {
079            HgCommandConstants.TAG_CMD, HgCommandConstants.MESSAGE_OPTION, scmTagParameters.getMessage(), tag
080        };
081
082        // keep the command about in string form for reporting
083        StringBuilder cmd = joinCmd(tagCmd);
084        HgTagConsumer consumer = new HgTagConsumer();
085        ScmResult result = HgUtils.execute(consumer, workingDir, tagCmd);
086        HgScmProviderRepository repository = (HgScmProviderRepository) scmProviderRepository;
087        if (result.isSuccess()) {
088            // now push
089            // Push to parent branch if any
090
091            if (repository.isPushChanges()) {
092                if (!repository.getURI().equals(fileSet.getBasedir().getAbsolutePath())) {
093                    String branchName = HgUtils.getCurrentBranchName(workingDir);
094                    boolean differentOutgoingBranch = HgUtils.differentOutgoingBranchFound(workingDir, branchName);
095
096                    String[] pushCmd = new String[] {
097                        HgCommandConstants.PUSH_CMD,
098                        differentOutgoingBranch ? HgCommandConstants.REVISION_OPTION + branchName : null,
099                        repository.getURI()
100                    };
101
102                    result = HgUtils.execute(new HgConsumer(), fileSet.getBasedir(), pushCmd);
103                }
104            }
105        } else {
106            throw new ScmException("Error while executing command " + cmd.toString());
107        }
108
109        // do an inventory to return the files tagged (all of them)
110        String[] listCmd = new String[] {HgCommandConstants.INVENTORY_CMD};
111        HgListConsumer listconsumer = new HgListConsumer();
112        result = HgUtils.execute(listconsumer, fileSet.getBasedir(), listCmd);
113        if (result.isSuccess()) {
114            List<ScmFile> files = listconsumer.getFiles();
115            List<ScmFile> fileList = new ArrayList<>();
116            for (ScmFile f : files) {
117                if (!f.getPath().endsWith(".hgtags")) {
118                    fileList.add(new ScmFile(f.getPath(), ScmFileStatus.TAGGED));
119                }
120            }
121
122            return new TagScmResult(fileList, result);
123        } else {
124            throw new ScmException("Error while executing command " + cmd.toString());
125        }
126    }
127
128    private StringBuilder joinCmd(String[] cmd) {
129        StringBuilder result = new StringBuilder();
130        for (int i = 0; i < cmd.length; i++) {
131            String s = cmd[i];
132            result.append(s);
133            if (i < cmd.length - 1) {
134                result.append(" ");
135            }
136        }
137        return result;
138    }
139}