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 org.apache.maven.scm.ScmException; 023import org.apache.maven.scm.ScmFileStatus; 024import org.apache.maven.scm.log.DefaultLog; 025import org.apache.maven.scm.provider.hg.command.HgCommandConstants; 026import org.apache.maven.scm.provider.hg.command.HgConsumer; 027import org.codehaus.plexus.util.cli.Commandline; 028 029import java.io.File; 030 031/** 032 * Check hg installation. 033 * 034 * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a> 035 * @author <a href="mailto:ryan@darksleep.com">ryan daum</a> 036 * 037 */ 038public class HgConfig 039{ 040 //Minimum version for the Hg SCM 041 private static final String HG_REQ = "0.9.2"; 042 043 // The string which indicates the beginning of the Mercurial line 044 private static final String HG_VERSION_TAG = "ercurial Distributed SCM (version "; 045 046 // URL to download mercurial from 047 private static final String HG_INSTALL_URL = "'http://www.selenic.com/mercurial/wiki/index.cgi/Download'"; 048 049 //Configuration to check with default values (not installed) 050 private HgVersionConsumer hgVersion = new HgVersionConsumer( null ); 051 052 HgConfig( File workingDir ) 053 { 054 try 055 { 056 hgVersion = getHgVersion( workingDir ); 057 } 058 catch ( ScmException e ) 059 { 060 //Ignore - is not installed. 061 //This is already recorded thus we do not generate more info. 062 } 063 064 } 065 066 /** 067 * @return True if one can run basic hg commands 068 */ 069 private boolean isInstalled() 070 { 071 return hgVersion.isVersionOk( HG_REQ ); 072 } 073 074 /** 075 * @return True if all modules for hg are installed. 076 */ 077 private boolean isComplete() 078 { 079 return isInstalled(); 080 } 081 082 // Consumer to find the Mercurial version 083 public static HgVersionConsumer getHgVersion( File workingDir ) 084 throws ScmException 085 { 086 String[] versionCmd = new String[]{HgCommandConstants.VERSION}; 087 HgVersionConsumer consumer = new HgVersionConsumer( HG_VERSION_TAG ); 088 Commandline cmd = HgUtils.buildCmd( workingDir, versionCmd ); 089 090 // Execute command 091 HgUtils.executeCmd( consumer, cmd ); 092 093 // Return result 094 return consumer; 095 } 096 097 098 /** 099 * Iterate through two dot-notation version strings, normalize them to the same length, then 100 * do alphabetic comparison 101 * 102 * @param version1 103 * @param version2 104 * @return true if version2 is greater than version1 105 */ 106 private static boolean compareVersion( String version1, String version2 ) 107 { 108 int l1, l2; 109 String v1, v2; 110 111 v1 = version1; 112 v2 = version2; 113 l1 = version1.length(); 114 l2 = version2.length(); 115 116 if ( l1 > l2 ) 117 { 118 for ( int x = l2; x >= l1; x-- ) 119 { 120 v2 += ' '; 121 } 122 } 123 if ( l2 > l1 ) 124 { 125 for ( int x = l1; x <= l2; x++ ) 126 { 127 v1 += ' '; 128 } 129 } 130 131 return v2.compareTo( v1 ) >= 0; 132 } 133 134 135 /** 136 * Get version of the executable. 137 * Version is resolved by splitting the line starting with the version tag and finding 138 * the second last word. 139 */ 140 private static class HgVersionConsumer 141 extends HgConsumer 142 { 143 144 private String versionStr = "NA"; 145 146 private String versionTag; 147 148 HgVersionConsumer( String versionTag ) 149 { 150 super( new DefaultLog() ); 151 this.versionTag = versionTag; 152 } 153 154 public void doConsume( ScmFileStatus status, String line ) 155 { 156 if ( line.startsWith( versionTag ) ) 157 { 158 String[] elements = line.split( " " ); 159 versionStr = elements[elements.length - 1].split( "\\)" )[0]; 160 } 161 } 162 163 String getVersion() 164 { 165 return versionStr; 166 } 167 168 boolean isVersionOk( String version ) 169 { 170 // build one number out of the whole version # 171 172 return compareVersion( version, versionStr ); 173 } 174 } 175 176 private String getInstalledStr() 177 { 178 if ( isComplete() ) 179 { 180 return "valid and complete."; 181 } 182 return ( isInstalled() ? "incomplete. " : "invalid. " ) + "Consult " + HG_INSTALL_URL; 183 } 184 185 public String toString( File workingDir ) 186 { 187 boolean hgOk = hgVersion.isVersionOk( HG_REQ ); 188 return "\n Your Hg installation seems to be " + getInstalledStr() + "\n Hg version: " 189 + hgVersion.getVersion() + ( hgOk ? " (OK)" : " (May be INVALID)" ) + "\n"; 190 } 191}