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