View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.git;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.maven.scm.CommandParameters;
26  import org.apache.maven.scm.ScmException;
27  import org.apache.maven.scm.ScmFileSet;
28  import org.apache.maven.scm.ScmResult;
29  import org.apache.maven.scm.command.add.AddScmResult;
30  import org.apache.maven.scm.command.blame.BlameScmResult;
31  import org.apache.maven.scm.command.branch.BranchScmResult;
32  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
33  import org.apache.maven.scm.command.checkin.CheckInScmResult;
34  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
35  import org.apache.maven.scm.command.diff.DiffScmResult;
36  import org.apache.maven.scm.command.export.ExportScmResult;
37  import org.apache.maven.scm.command.info.InfoScmResult;
38  import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
39  import org.apache.maven.scm.command.remove.RemoveScmResult;
40  import org.apache.maven.scm.command.status.StatusScmResult;
41  import org.apache.maven.scm.command.tag.TagScmResult;
42  import org.apache.maven.scm.command.untag.UntagScmResult;
43  import org.apache.maven.scm.command.update.UpdateScmResult;
44  import org.apache.maven.scm.provider.AbstractScmProvider;
45  import org.apache.maven.scm.provider.ScmProviderRepository;
46  import org.apache.maven.scm.provider.git.command.GitCommand;
47  import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
48  import org.apache.maven.scm.repository.ScmRepository;
49  import org.apache.maven.scm.repository.ScmRepositoryException;
50  import org.apache.maven.scm.repository.UnknownRepositoryStructure;
51  
52  /**
53   * SCM Provider for git
54   *
55   *
56   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
57   *
58   */
59  public abstract class AbstractGitScmProvider extends AbstractScmProvider {
60  
61      // ----------------------------------------------------------------------
62      //
63      // ----------------------------------------------------------------------
64  
65      /**
66       * Internal class
67       */
68      private static class ScmUrlParserResult {
69          private final List<String> messages = new ArrayList<>();
70  
71          private ScmProviderRepository repository;
72      }
73  
74      // ----------------------------------------------------------------------
75      // ScmProvider Implementation
76      // ----------------------------------------------------------------------
77  
78      /** {@inheritDoc} */
79      public String getScmSpecificFilename() {
80          return ".git";
81      }
82  
83      /** {@inheritDoc} */
84      public ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter)
85              throws ScmRepositoryException {
86          try {
87              ScmUrlParserResult result = parseScmUrl(scmSpecificUrl, delimiter);
88  
89              if (result.messages.size() > 0) {
90                  throw new ScmRepositoryException("The scm url " + scmSpecificUrl + " is invalid.", result.messages);
91              }
92  
93              return result.repository;
94          } catch (ScmException e) {
95              // XXX We should allow throwing of SCMException.
96              throw new ScmRepositoryException("Error creating the scm repository", e);
97          }
98      }
99  
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 }