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.hg;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.io.File;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.maven.scm.CommandParameters;
29  import org.apache.maven.scm.ScmException;
30  import org.apache.maven.scm.ScmFileSet;
31  import org.apache.maven.scm.command.add.AddScmResult;
32  import org.apache.maven.scm.command.blame.BlameScmResult;
33  import org.apache.maven.scm.command.branch.BranchScmResult;
34  import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
35  import org.apache.maven.scm.command.checkin.CheckInScmResult;
36  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
37  import org.apache.maven.scm.command.diff.DiffScmResult;
38  import org.apache.maven.scm.command.info.InfoScmResult;
39  import org.apache.maven.scm.command.list.ListScmResult;
40  import org.apache.maven.scm.command.remove.RemoveScmResult;
41  import org.apache.maven.scm.command.status.StatusScmResult;
42  import org.apache.maven.scm.command.tag.TagScmResult;
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.hg.command.add.HgAddCommand;
47  import org.apache.maven.scm.provider.hg.command.blame.HgBlameCommand;
48  import org.apache.maven.scm.provider.hg.command.branch.HgBranchCommand;
49  import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand;
50  import org.apache.maven.scm.provider.hg.command.checkin.HgCheckInCommand;
51  import org.apache.maven.scm.provider.hg.command.checkout.HgCheckOutCommand;
52  import org.apache.maven.scm.provider.hg.command.diff.HgDiffCommand;
53  import org.apache.maven.scm.provider.hg.command.info.HgInfoCommand;
54  import org.apache.maven.scm.provider.hg.command.inventory.HgListCommand;
55  import org.apache.maven.scm.provider.hg.command.remove.HgRemoveCommand;
56  import org.apache.maven.scm.provider.hg.command.status.HgStatusCommand;
57  import org.apache.maven.scm.provider.hg.command.tag.HgTagCommand;
58  import org.apache.maven.scm.provider.hg.command.update.HgUpdateCommand;
59  import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
60  import org.apache.maven.scm.repository.ScmRepositoryException;
61  import org.apache.maven.scm.repository.UnknownRepositoryStructure;
62  
63  /**
64   * <a href="https://www.mercurial-scm.org/">Mercurial (HG)</a> is a decentralized revision control system.
65   *
66   * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
67   */
68  @Singleton
69  @Named("hg")
70  public class HgScmProvider extends AbstractScmProvider {
71      /**
72       * {@inheritDoc}
73       */
74      public String getScmSpecificFilename() {
75          return ".hg";
76      }
77  
78      private static class HgUrlParserResult {
79          private final List<String> messages = new ArrayList<>();
80  
81          private ScmProviderRepository repository;
82      }
83  
84      /**
85       * {@inheritDoc}
86       */
87      public ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter)
88              throws ScmRepositoryException {
89          HgUrlParserResult result = parseScmUrl(scmSpecificUrl);
90  
91          if (result.messages.size() > 0) {
92              throw new ScmRepositoryException("The scm url is invalid.", result.messages);
93          }
94  
95          return result.repository;
96      }
97  
98      private HgUrlParserResult parseScmUrl(String scmSpecificUrl) {
99          HgUrlParserResult result = new HgUrlParserResult();
100 
101         // ----------------------------------------------------------------------
102         // Do some sanity checking of the SVN url
103         // ----------------------------------------------------------------------
104 
105         if (scmSpecificUrl.startsWith("file")) {
106             if (!scmSpecificUrl.startsWith("file:///") && !scmSpecificUrl.startsWith("file://localhost/")) {
107                 result.messages.add("An hg 'file' url must be on the form 'file:///' or 'file://localhost/'.");
108 
109                 return result;
110             }
111         } else if (scmSpecificUrl.startsWith("https")) {
112             if (!scmSpecificUrl.startsWith("https://")) {
113                 result.messages.add("An hg 'http' url must be on the form 'https://'.");
114 
115                 return result;
116             }
117         } else if (scmSpecificUrl.startsWith("http")) {
118             if (!scmSpecificUrl.startsWith("http://")) {
119                 result.messages.add("An hg 'http' url must be on the form 'http://'.");
120 
121                 return result;
122             }
123         } else {
124             try {
125                 new File(scmSpecificUrl);
126             } catch (Throwable e) {
127                 result.messages.add("The filename provided is not valid");
128 
129                 return result;
130             }
131         }
132 
133         result.repository = new HgScmProviderRepository(scmSpecificUrl);
134 
135         return result;
136     }
137 
138     /**
139      * {@inheritDoc}
140      */
141     public ScmProviderRepository makeProviderScmRepository(File path)
142             throws ScmRepositoryException, UnknownRepositoryStructure {
143         if (path == null) {
144             throw new NullPointerException("Path argument is null");
145         }
146 
147         if (!path.isDirectory()) {
148             throw new ScmRepositoryException(path.getAbsolutePath() + " isn't a valid directory.");
149         }
150 
151         File hgDir = new File(path, ".hg");
152 
153         if (!hgDir.exists()) {
154             throw new ScmRepositoryException(path.getAbsolutePath() + " isn't a hg directory.");
155         }
156 
157         return makeProviderScmRepository(path.getAbsolutePath(), ':');
158     }
159 
160     /**
161      * {@inheritDoc}
162      */
163     public List<String> validateScmUrl(String scmSpecificUrl, char delimiter) {
164         HgUrlParserResult result = parseScmUrl(scmSpecificUrl);
165 
166         return result.messages;
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     public String getScmType() {
173         return "hg";
174     }
175 
176     /**
177      * {@inheritDoc}
178      */
179     public AddScmResult add(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
180             throws ScmException {
181         HgAddCommand command = new HgAddCommand();
182 
183         return (AddScmResult) command.execute(repository, fileSet, parameters);
184     }
185 
186     /**
187      * {@inheritDoc}
188      */
189     public ChangeLogScmResult changelog(
190             ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
191         HgChangeLogCommand command = new HgChangeLogCommand();
192 
193         return (ChangeLogScmResult) command.execute(repository, fileSet, parameters);
194     }
195 
196     /**
197      * {@inheritDoc}
198      */
199     public CheckInScmResult checkin(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
200             throws ScmException {
201         HgCheckInCommand command = new HgCheckInCommand();
202 
203         return (CheckInScmResult) command.execute(repository, fileSet, parameters);
204     }
205 
206     /**
207      * {@inheritDoc}
208      */
209     public CheckOutScmResult checkout(
210             ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
211         HgCheckOutCommand command = new HgCheckOutCommand();
212 
213         return (CheckOutScmResult) command.execute(repository, fileSet, parameters);
214     }
215 
216     /**
217      * {@inheritDoc}
218      */
219     public TagScmResult tag(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
220             throws ScmException {
221         HgTagCommand command = new HgTagCommand();
222 
223         return (TagScmResult) command.execute(repository, fileSet, parameters);
224     }
225 
226     /**
227      * {@inheritDoc}
228      */
229     public DiffScmResult diff(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
230             throws ScmException {
231         HgDiffCommand command = new HgDiffCommand();
232 
233         return (DiffScmResult) command.execute(repository, fileSet, parameters);
234     }
235 
236     /**
237      * {@inheritDoc}
238      */
239     public RemoveScmResult remove(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
240             throws ScmException {
241         HgRemoveCommand command = new HgRemoveCommand();
242 
243         return (RemoveScmResult) command.execute(repository, fileSet, parameters);
244     }
245 
246     /**
247      * {@inheritDoc}
248      */
249     public StatusScmResult status(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
250             throws ScmException {
251         HgStatusCommand command = new HgStatusCommand();
252 
253         return (StatusScmResult) command.execute(repository, fileSet, parameters);
254     }
255 
256     /**
257      * {@inheritDoc}
258      */
259     public UpdateScmResult update(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
260             throws ScmException {
261         HgUpdateCommand command = new HgUpdateCommand();
262 
263         return (UpdateScmResult) command.execute(repository, fileSet, parameters);
264     }
265 
266     /**
267      * {@inheritDoc}
268      */
269     protected BlameScmResult blame(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
270             throws ScmException {
271         HgBlameCommand command = new HgBlameCommand();
272 
273         return (BlameScmResult) command.execute(repository, fileSet, parameters);
274     }
275 
276     /**
277      * {@inheritDoc}
278      */
279     public BranchScmResult branch(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
280             throws ScmException {
281         HgBranchCommand command = new HgBranchCommand();
282 
283         return (BranchScmResult) command.execute(repository, fileSet, parameters);
284     }
285 
286     /**
287      * @since 1.5
288      */
289     @Override
290     protected ListScmResult list(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
291             throws ScmException {
292         HgListCommand hgListCommand = new HgListCommand();
293 
294         return (ListScmResult) hgListCommand.executeCommand(repository, fileSet, parameters);
295     }
296 
297     /**
298      * Returns result of hg id -i.
299      *
300      * @see org.apache.maven.scm.provider.AbstractScmProvider#info(org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet, org.apache.maven.scm.CommandParameters)
301      * @since 1.5
302      */
303     @Override
304     public InfoScmResult info(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
305             throws ScmException {
306         HgInfoCommand infoCommand = new HgInfoCommand();
307 
308         return (InfoScmResult) infoCommand.execute(repository, fileSet, parameters);
309     }
310 }