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