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 @Override 190 public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters) 191 throws ScmException { 192 return (CheckInScmResult) getCheckInCommand().execute(repository.getProviderRepository(), fileSet, parameters); 193 } 194 195 protected abstract GitCommand getCheckOutCommand(); 196 197 /** {@inheritDoc} */ 198 public CheckOutScmResult checkout( 199 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 200 return (CheckOutScmResult) executeCommand(getCheckOutCommand(), repository, fileSet, parameters); 201 } 202 203 protected abstract GitCommand getDiffCommand(); 204 205 /** {@inheritDoc} */ 206 public DiffScmResult diff(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 207 throws ScmException { 208 return (DiffScmResult) executeCommand(getDiffCommand(), repository, fileSet, parameters); 209 } 210 211 protected abstract GitCommand getExportCommand(); 212 213 /** {@inheritDoc} */ 214 protected ExportScmResult export(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 215 throws ScmException { 216 return (ExportScmResult) executeCommand(getExportCommand(), repository, fileSet, parameters); 217 } 218 219 protected abstract GitCommand getRemoveCommand(); 220 221 /** {@inheritDoc} */ 222 public RemoveScmResult remove(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 223 throws ScmException { 224 return (RemoveScmResult) executeCommand(getRemoveCommand(), repository, fileSet, parameters); 225 } 226 227 protected abstract GitCommand getStatusCommand(); 228 229 /** {@inheritDoc} */ 230 public StatusScmResult status(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 231 throws ScmException { 232 return (StatusScmResult) executeCommand(getStatusCommand(), repository, fileSet, parameters); 233 } 234 235 protected abstract GitCommand getTagCommand(); 236 237 /** {@inheritDoc} */ 238 public TagScmResult tag(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 239 throws ScmException { 240 return (TagScmResult) executeCommand(getTagCommand(), repository, fileSet, parameters); 241 } 242 243 protected abstract GitCommand getUntagCommand(); 244 245 /** {@inheritDoc} */ 246 public UntagScmResult untag(ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters) 247 throws ScmException { 248 return (UntagScmResult) 249 executeCommand(getUntagCommand(), repository.getProviderRepository(), fileSet, parameters); 250 } 251 252 protected abstract GitCommand getUpdateCommand(); 253 254 /** {@inheritDoc} */ 255 public UpdateScmResult update(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 256 throws ScmException { 257 return (UpdateScmResult) executeCommand(getUpdateCommand(), repository, fileSet, parameters); 258 } 259 260 protected ScmResult executeCommand( 261 GitCommand command, ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 262 throws ScmException { 263 return command.execute(repository, fileSet, parameters); 264 } 265 266 protected abstract GitCommand getInfoCommand(); 267 268 public InfoScmResult info(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 269 throws ScmException { 270 GitCommand cmd = getInfoCommand(); 271 272 return (InfoScmResult) executeCommand(cmd, repository, fileSet, parameters); 273 } 274 275 /** {@inheritDoc} */ 276 protected BlameScmResult blame(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) 277 throws ScmException { 278 GitCommand cmd = getBlameCommand(); 279 280 return (BlameScmResult) executeCommand(cmd, repository, fileSet, parameters); 281 } 282 283 protected abstract GitCommand getBlameCommand(); 284 285 /** {@inheritDoc} */ 286 public RemoteInfoScmResult remoteInfo( 287 ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException { 288 GitCommand cmd = getRemoteInfoCommand(); 289 290 return (RemoteInfoScmResult) executeCommand(cmd, repository, fileSet, parameters); 291 } 292 293 protected abstract GitCommand getRemoteInfoCommand(); 294}