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.git; 020 021import java.io.File; 022import java.util.ArrayList; 023import java.util.List; 024 025import org.apache.maven.scm.CommandParameters; 026import org.apache.maven.scm.ScmException; 027import org.apache.maven.scm.ScmFileSet; 028import org.apache.maven.scm.ScmResult; 029import org.apache.maven.scm.command.add.AddScmResult; 030import org.apache.maven.scm.command.blame.BlameScmResult; 031import org.apache.maven.scm.command.branch.BranchScmResult; 032import org.apache.maven.scm.command.changelog.ChangeLogScmResult; 033import org.apache.maven.scm.command.checkin.CheckInScmResult; 034import org.apache.maven.scm.command.checkout.CheckOutScmResult; 035import org.apache.maven.scm.command.diff.DiffScmResult; 036import org.apache.maven.scm.command.export.ExportScmResult; 037import org.apache.maven.scm.command.info.InfoScmResult; 038import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult; 039import org.apache.maven.scm.command.remove.RemoveScmResult; 040import org.apache.maven.scm.command.status.StatusScmResult; 041import org.apache.maven.scm.command.tag.TagScmResult; 042import org.apache.maven.scm.command.untag.UntagScmResult; 043import org.apache.maven.scm.command.update.UpdateScmResult; 044import org.apache.maven.scm.provider.AbstractScmProvider; 045import org.apache.maven.scm.provider.ScmProviderRepository; 046import org.apache.maven.scm.provider.git.command.GitCommand; 047import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; 048import org.apache.maven.scm.repository.ScmRepository; 049import org.apache.maven.scm.repository.ScmRepositoryException; 050import org.apache.maven.scm.repository.UnknownRepositoryStructure; 051 052/** 053 * SCM Provider for git 054 * 055 * 056 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> 057 * 058 */ 059public abstract class AbstractGitScmProvider extends AbstractScmProvider { 060 061 // ---------------------------------------------------------------------- 062 // 063 // ---------------------------------------------------------------------- 064 065 /** 066 * Internal class 067 */ 068 private static class ScmUrlParserResult { 069 private final List<String> messages = new ArrayList<>(); 070 071 private ScmProviderRepository repository; 072 } 073 074 // ---------------------------------------------------------------------- 075 // ScmProvider Implementation 076 // ---------------------------------------------------------------------- 077 078 /** {@inheritDoc} */ 079 public String getScmSpecificFilename() { 080 return ".git"; 081 } 082 083 /** {@inheritDoc} */ 084 public ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter) 085 throws ScmRepositoryException { 086 try { 087 ScmUrlParserResult result = parseScmUrl(scmSpecificUrl, delimiter); 088 089 if (result.messages.size() > 0) { 090 throw new ScmRepositoryException("The scm url " + scmSpecificUrl + " is invalid.", result.messages); 091 } 092 093 return result.repository; 094 } catch (ScmException e) { 095 // XXX We should allow throwing of SCMException. 096 throw new ScmRepositoryException("Error creating the scm repository", e); 097 } 098 } 099 100 /** {@inheritDoc} */ 101 public ScmProviderRepository makeProviderScmRepository(File path) 102 throws ScmRepositoryException, UnknownRepositoryStructure { 103 if (path == null) { 104 throw new NullPointerException("Path argument is null"); 105 } 106 107 if (!path.isDirectory()) { 108 throw new ScmRepositoryException(path.getAbsolutePath() + " isn't a valid directory."); 109 } 110 111 if (!new File(path, ".git").exists()) { 112 throw new ScmRepositoryException(path.getAbsolutePath() + " isn't a git checkout directory."); 113 } 114 115 try { 116 return makeProviderScmRepository(getRepositoryURL(path), ':'); 117 } catch (ScmException e) { 118 // XXX We should allow throwing of SCMException. 119 throw new ScmRepositoryException("Error creating the scm repository", e); 120 } 121 } 122 123 protected abstract String getRepositoryURL(File path) throws ScmException; 124 125 /** {@inheritDoc} */ 126 public List<String> validateScmUrl(String scmSpecificUrl, char delimiter) { 127 List<String> messages = new ArrayList<>(); 128 try { 129 makeProviderScmRepository(scmSpecificUrl, delimiter); 130 } catch (ScmRepositoryException e) { 131 messages = e.getValidationMessages(); 132 } 133 return messages; 134 } 135 136 /** {@inheritDoc} */ 137 public String getScmType() { 138 return "git"; 139 } 140 141 // ---------------------------------------------------------------------- 142 // 143 // ---------------------------------------------------------------------- 144 145 /** 146 * The git-submodule(1) command is available since Git 1.5.3, so modules will 147 * be activated in a later stage 148 */ 149 private ScmUrlParserResult parseScmUrl(String scmSpecificUrl, char delimiter) throws ScmException { 150 ScmUrlParserResult result = new ScmUrlParserResult(); 151 152 result.repository = new GitScmProviderRepository(scmSpecificUrl); 153 154 return result; 155 } 156 157 protected abstract GitCommand getAddCommand(); 158 159 /** {@inheritDoc} */ 160 public AddScmResult add(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 161 throws ScmException { 162 return (AddScmResult) executeCommand(getAddCommand(), repository, fileSet, parameters); 163 } 164 165 protected abstract GitCommand getBranchCommand(); 166 167 /** {@inheritDoc} */ 168 protected BranchScmResult branch(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 169 throws ScmException { 170 return (BranchScmResult) executeCommand(getBranchCommand(), repository, fileSet, parameters); 171 } 172 173 protected abstract GitCommand getChangeLogCommand(); 174 175 /** {@inheritDoc} */ 176 public ChangeLogScmResult changelog( 177 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 178 return (ChangeLogScmResult) executeCommand(getChangeLogCommand(), repository, fileSet, parameters); 179 } 180 181 protected abstract GitCommand getCheckInCommand(); 182 183 /** {@inheritDoc} */ 184 public CheckInScmResult checkin(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 185 throws ScmException { 186 return (CheckInScmResult) executeCommand(getCheckInCommand(), repository, fileSet, parameters); 187 } 188 189 protected abstract GitCommand getCheckOutCommand(); 190 191 /** {@inheritDoc} */ 192 public CheckOutScmResult checkout( 193 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 194 return (CheckOutScmResult) executeCommand(getCheckOutCommand(), repository, fileSet, parameters); 195 } 196 197 protected abstract GitCommand getDiffCommand(); 198 199 /** {@inheritDoc} */ 200 public DiffScmResult diff(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 201 throws ScmException { 202 return (DiffScmResult) executeCommand(getDiffCommand(), repository, fileSet, parameters); 203 } 204 205 protected abstract GitCommand getExportCommand(); 206 207 /** {@inheritDoc} */ 208 protected ExportScmResult export(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 209 throws ScmException { 210 return (ExportScmResult) executeCommand(getExportCommand(), repository, fileSet, parameters); 211 } 212 213 protected abstract GitCommand getRemoveCommand(); 214 215 /** {@inheritDoc} */ 216 public RemoveScmResult remove(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 217 throws ScmException { 218 return (RemoveScmResult) executeCommand(getRemoveCommand(), repository, fileSet, parameters); 219 } 220 221 protected abstract GitCommand getStatusCommand(); 222 223 /** {@inheritDoc} */ 224 public StatusScmResult status(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 225 throws ScmException { 226 return (StatusScmResult) executeCommand(getStatusCommand(), repository, fileSet, parameters); 227 } 228 229 protected abstract GitCommand getTagCommand(); 230 231 /** {@inheritDoc} */ 232 public TagScmResult tag(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 233 throws ScmException { 234 return (TagScmResult) executeCommand(getTagCommand(), repository, fileSet, parameters); 235 } 236 237 protected abstract GitCommand getUntagCommand(); 238 239 /** {@inheritDoc} */ 240 public UntagScmResult untag(ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters) 241 throws ScmException { 242 return (UntagScmResult) 243 executeCommand(getUntagCommand(), repository.getProviderRepository(), fileSet, parameters); 244 } 245 246 protected abstract GitCommand getUpdateCommand(); 247 248 /** {@inheritDoc} */ 249 public UpdateScmResult update(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 250 throws ScmException { 251 return (UpdateScmResult) executeCommand(getUpdateCommand(), repository, fileSet, parameters); 252 } 253 254 protected ScmResult executeCommand( 255 GitCommand command, ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 256 throws ScmException { 257 return command.execute(repository, fileSet, parameters); 258 } 259 260 protected abstract GitCommand getInfoCommand(); 261 262 public InfoScmResult info(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 263 throws ScmException { 264 GitCommand cmd = getInfoCommand(); 265 266 return (InfoScmResult) executeCommand(cmd, repository, fileSet, parameters); 267 } 268 269 /** {@inheritDoc} */ 270 protected BlameScmResult blame(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 271 throws ScmException { 272 GitCommand cmd = getBlameCommand(); 273 274 return (BlameScmResult) executeCommand(cmd, repository, fileSet, parameters); 275 } 276 277 protected abstract GitCommand getBlameCommand(); 278 279 /** {@inheritDoc} */ 280 public RemoteInfoScmResult remoteInfo( 281 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 282 GitCommand cmd = getRemoteInfoCommand(); 283 284 return (RemoteInfoScmResult) executeCommand(cmd, repository, fileSet, parameters); 285 } 286 287 protected abstract GitCommand getRemoteInfoCommand(); 288}