001package org.apache.maven.scm.provider.hg;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.maven.scm.CommandParameters;
027import org.apache.maven.scm.ScmException;
028import org.apache.maven.scm.ScmFileSet;
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.info.InfoScmResult;
037import org.apache.maven.scm.command.list.ListScmResult;
038import org.apache.maven.scm.command.remove.RemoveScmResult;
039import org.apache.maven.scm.command.status.StatusScmResult;
040import org.apache.maven.scm.command.tag.TagScmResult;
041import org.apache.maven.scm.command.update.UpdateScmResult;
042import org.apache.maven.scm.provider.AbstractScmProvider;
043import org.apache.maven.scm.provider.ScmProviderRepository;
044import org.apache.maven.scm.provider.hg.command.add.HgAddCommand;
045import org.apache.maven.scm.provider.hg.command.blame.HgBlameCommand;
046import org.apache.maven.scm.provider.hg.command.branch.HgBranchCommand;
047import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand;
048import org.apache.maven.scm.provider.hg.command.checkin.HgCheckInCommand;
049import org.apache.maven.scm.provider.hg.command.checkout.HgCheckOutCommand;
050import org.apache.maven.scm.provider.hg.command.diff.HgDiffCommand;
051import org.apache.maven.scm.provider.hg.command.info.HgInfoCommand;
052import org.apache.maven.scm.provider.hg.command.inventory.HgListCommand;
053import org.apache.maven.scm.provider.hg.command.remove.HgRemoveCommand;
054import org.apache.maven.scm.provider.hg.command.status.HgStatusCommand;
055import org.apache.maven.scm.provider.hg.command.tag.HgTagCommand;
056import org.apache.maven.scm.provider.hg.command.update.HgUpdateCommand;
057import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
058import org.apache.maven.scm.repository.ScmRepositoryException;
059import org.apache.maven.scm.repository.UnknownRepositoryStructure;
060
061/**
062 * Mercurial (HG) is a decentralized revision control system.
063 * <a href="http://www.selenic.com/mercurial">http://www.selenic.com/mercurial</a>
064 *
065 * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
066 *
067 * @plexus.component role="org.apache.maven.scm.provider.ScmProvider"
068 * role-hint="hg"
069 */
070public class HgScmProvider
071    extends AbstractScmProvider
072{
073    /** {@inheritDoc} */
074    public String getScmSpecificFilename()
075    {
076        return ".hg";
077    }
078
079    private static class HgUrlParserResult
080    {
081        private List<String> messages = new ArrayList<String>();
082
083        private ScmProviderRepository repository;
084    }
085
086    /** {@inheritDoc} */
087    public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
088        throws ScmRepositoryException
089    {
090        HgUrlParserResult result = parseScmUrl( scmSpecificUrl );
091
092        if ( result.messages.size() > 0 )
093        {
094            throw new ScmRepositoryException( "The scm url is invalid.", result.messages );
095        }
096
097        return result.repository;
098    }
099
100    private HgUrlParserResult parseScmUrl( String scmSpecificUrl )
101    {
102        HgUrlParserResult result = new HgUrlParserResult();
103
104        // ----------------------------------------------------------------------
105        // Do some sanity checking of the SVN url
106        // ----------------------------------------------------------------------
107
108        if ( scmSpecificUrl.startsWith( "file" ) )
109        {
110            if ( !scmSpecificUrl.startsWith( "file:///" ) && !scmSpecificUrl.startsWith( "file://localhost/" ) )
111            {
112                result.messages.add( "An hg 'file' url must be on the form 'file:///' or 'file://localhost/'." );
113
114                return result;
115            }
116        }
117        else if ( scmSpecificUrl.startsWith( "https" ) )
118        {
119            if ( !scmSpecificUrl.startsWith( "https://" ) )
120            {
121                result.messages.add( "An hg 'http' url must be on the form 'https://'." );
122
123                return result;
124            }
125        }
126        else if ( scmSpecificUrl.startsWith( "http" ) )
127        {
128            if ( !scmSpecificUrl.startsWith( "http://" ) )
129            {
130                result.messages.add( "An hg 'http' url must be on the form 'http://'." );
131
132                return result;
133            }
134        }
135        else
136        {
137            try
138            {
139                @SuppressWarnings( "unused" )
140                File file = new File( scmSpecificUrl );
141            }
142            catch ( Throwable e )
143            {
144                result.messages.add( "The filename provided is not valid" );
145
146                return result;
147            }
148
149        }
150
151        result.repository = new HgScmProviderRepository( scmSpecificUrl );
152
153        return result;
154    }
155
156    /** {@inheritDoc} */
157    public ScmProviderRepository makeProviderScmRepository( File path )
158        throws ScmRepositoryException, UnknownRepositoryStructure
159    {
160        if ( path == null )
161        {
162            throw new NullPointerException( "Path argument is null" );
163        }
164
165        if ( !path.isDirectory() )
166        {
167            throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
168        }
169
170        File hgDir = new File( path, ".hg" );
171
172        if ( !hgDir.exists() )
173        {
174            throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a hg directory." );
175        }
176
177        return makeProviderScmRepository( path.getAbsolutePath(), ':' );
178    }
179
180    /** {@inheritDoc} */
181    public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
182    {
183        HgUrlParserResult result = parseScmUrl( scmSpecificUrl );
184
185        return result.messages;
186    }
187
188    /** {@inheritDoc} */
189    public String getScmType()
190    {
191        return "hg";
192    }
193
194    /** {@inheritDoc} */
195    public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
196        throws ScmException
197    {
198        HgAddCommand command = new HgAddCommand();
199
200        command.setLogger( getLogger() );
201
202        return (AddScmResult) command.execute( repository, fileSet, parameters );
203    }
204
205    /** {@inheritDoc} */
206    public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
207                                         CommandParameters parameters )
208        throws ScmException
209    {
210        HgChangeLogCommand command = new HgChangeLogCommand();
211
212        command.setLogger( getLogger() );
213
214        return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
215    }
216
217    /** {@inheritDoc} */
218    public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
219                                     CommandParameters parameters )
220        throws ScmException
221    {
222        HgCheckInCommand command = new HgCheckInCommand();
223
224        command.setLogger( getLogger() );
225
226        return (CheckInScmResult) command.execute( repository, fileSet, parameters );
227    }
228
229    /** {@inheritDoc} */
230    public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
231                                       CommandParameters parameters )
232        throws ScmException
233    {
234        HgCheckOutCommand command = new HgCheckOutCommand();
235
236        command.setLogger( getLogger() );
237
238        return (CheckOutScmResult) command.execute( repository, fileSet, parameters );
239    }
240
241    /** {@inheritDoc} */
242    public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
243        throws ScmException
244    {
245        HgTagCommand command = new HgTagCommand();
246
247        command.setLogger( getLogger() );
248
249        return (TagScmResult) command.execute( repository, fileSet, parameters );
250    }
251
252    /** {@inheritDoc} */
253    public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
254        throws ScmException
255    {
256        HgDiffCommand command = new HgDiffCommand();
257
258        command.setLogger( getLogger() );
259
260        return (DiffScmResult) command.execute( repository, fileSet, parameters );
261    }
262
263    /** {@inheritDoc} */
264    public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet,
265                                   CommandParameters parameters )
266        throws ScmException
267    {
268        HgRemoveCommand command = new HgRemoveCommand();
269
270        command.setLogger( getLogger() );
271
272        return (RemoveScmResult) command.execute( repository, fileSet, parameters );
273    }
274
275    /** {@inheritDoc} */
276    public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet,
277                                   CommandParameters parameters )
278        throws ScmException
279    {
280        HgStatusCommand command = new HgStatusCommand();
281
282        command.setLogger( getLogger() );
283
284        return (StatusScmResult) command.execute( repository, fileSet, parameters );
285    }
286
287    /** {@inheritDoc} */
288    public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet,
289                                   CommandParameters parameters )
290        throws ScmException
291    {
292        HgUpdateCommand command = new HgUpdateCommand();
293
294        command.setLogger( getLogger() );
295
296        return (UpdateScmResult) command.execute( repository, fileSet, parameters );
297    }
298
299    /** {@inheritDoc} */
300    protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet,
301                                    CommandParameters parameters )
302        throws ScmException
303    {
304        HgBlameCommand command = new HgBlameCommand();
305
306        command.setLogger( getLogger() );
307
308        return (BlameScmResult) command.execute( repository, fileSet, parameters );
309    }
310
311    /** {@inheritDoc} */
312    public BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
313        throws ScmException
314    {
315        HgBranchCommand command = new HgBranchCommand();
316
317        command.setLogger( getLogger() );
318
319        return (BranchScmResult) command.execute( repository, fileSet, parameters );
320    }
321
322    /**
323     * @since 1.5
324     */
325    @Override
326    protected ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
327        throws ScmException
328    {
329        HgListCommand hgListCommand = new HgListCommand();
330        hgListCommand.setLogger( getLogger() );
331        return (ListScmResult) hgListCommand.executeCommand( repository, fileSet, parameters );
332
333    }
334
335    /**
336     * returns result of hg id -i
337     * @since 1.5
338     * @see org.apache.maven.scm.provider.AbstractScmProvider#info(org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet, org.apache.maven.scm.CommandParameters)
339     */
340    @Override
341    public InfoScmResult info( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
342        throws ScmException
343    {
344        HgInfoCommand infoCommand = new HgInfoCommand();
345        infoCommand.setLogger( getLogger() );
346        return (InfoScmResult) infoCommand.execute( repository, fileSet, parameters );
347    }
348}