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.hg; 020 021import javax.inject.Named; 022import javax.inject.Singleton; 023 024import java.io.File; 025import java.util.ArrayList; 026import java.util.List; 027 028import org.apache.maven.scm.CommandParameters; 029import org.apache.maven.scm.ScmException; 030import org.apache.maven.scm.ScmFileSet; 031import org.apache.maven.scm.command.add.AddScmResult; 032import org.apache.maven.scm.command.blame.BlameScmResult; 033import org.apache.maven.scm.command.branch.BranchScmResult; 034import org.apache.maven.scm.command.changelog.ChangeLogScmResult; 035import org.apache.maven.scm.command.checkin.CheckInScmResult; 036import org.apache.maven.scm.command.checkout.CheckOutScmResult; 037import org.apache.maven.scm.command.diff.DiffScmResult; 038import org.apache.maven.scm.command.info.InfoScmResult; 039import org.apache.maven.scm.command.list.ListScmResult; 040import org.apache.maven.scm.command.remove.RemoveScmResult; 041import org.apache.maven.scm.command.status.StatusScmResult; 042import org.apache.maven.scm.command.tag.TagScmResult; 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.hg.command.add.HgAddCommand; 047import org.apache.maven.scm.provider.hg.command.blame.HgBlameCommand; 048import org.apache.maven.scm.provider.hg.command.branch.HgBranchCommand; 049import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand; 050import org.apache.maven.scm.provider.hg.command.checkin.HgCheckInCommand; 051import org.apache.maven.scm.provider.hg.command.checkout.HgCheckOutCommand; 052import org.apache.maven.scm.provider.hg.command.diff.HgDiffCommand; 053import org.apache.maven.scm.provider.hg.command.info.HgInfoCommand; 054import org.apache.maven.scm.provider.hg.command.inventory.HgListCommand; 055import org.apache.maven.scm.provider.hg.command.remove.HgRemoveCommand; 056import org.apache.maven.scm.provider.hg.command.status.HgStatusCommand; 057import org.apache.maven.scm.provider.hg.command.tag.HgTagCommand; 058import org.apache.maven.scm.provider.hg.command.update.HgUpdateCommand; 059import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository; 060import org.apache.maven.scm.repository.ScmRepositoryException; 061import org.apache.maven.scm.repository.UnknownRepositoryStructure; 062 063/** 064 * <a href="https://www.mercurial-scm.org/">Mercurial (HG)</a> is a decentralized revision control system. 065 * 066 * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a> 067 */ 068@Singleton 069@Named("hg") 070public class HgScmProvider extends AbstractScmProvider { 071 /** 072 * {@inheritDoc} 073 */ 074 public String getScmSpecificFilename() { 075 return ".hg"; 076 } 077 078 private static class HgUrlParserResult { 079 private final List<String> messages = new ArrayList<>(); 080 081 private ScmProviderRepository repository; 082 } 083 084 /** 085 * {@inheritDoc} 086 */ 087 public ScmProviderRepository makeProviderScmRepository(String scmSpecificUrl, char delimiter) 088 throws ScmRepositoryException { 089 HgUrlParserResult result = parseScmUrl(scmSpecificUrl); 090 091 if (result.messages.size() > 0) { 092 throw new ScmRepositoryException("The scm url is invalid.", result.messages); 093 } 094 095 return result.repository; 096 } 097 098 private HgUrlParserResult parseScmUrl(String scmSpecificUrl) { 099 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}