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   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
56   */
57  public abstract class AbstractGitScmProvider extends AbstractScmProvider {
58  
59      // ----------------------------------------------------------------------
60      //
61      // ----------------------------------------------------------------------
62  
63      /**
64       * Internal class.
65       */
66      private static class ScmUrlParserResult {
67          private final List<String> messages = new ArrayList<>();
68  
69          private ScmProviderRepository repository;
70      }
71  
72      // ----------------------------------------------------------------------
73      // ScmProvider Implementation
74      // ----------------------------------------------------------------------
75  
76      /**
77       * {@inheritDoc}
78       */
79      public String getScmSpecificFilename() {
80          return ".git";
81      }
82  
83      /**
84       * {@inheritDoc}
85       */
86      public ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter)
87              throws ScmRepositoryException {
88          try {
89              ScmUrlParserResult result = parseScmUrl(scmSpecificUrl, delimiter);
90  
91              if (result.messages.size() > 0) {
92                  throw new ScmRepositoryException("The scm url " + scmSpecificUrl + " is invalid.", result.messages);
93              }
94  
95              return result.repository;
96          } catch (ScmException e) {
97              // XXX We should allow throwing of SCMException.
98              throw new ScmRepositoryException("Error creating the scm repository", e);
99          }
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 }