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