001 package 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
022 import org.apache.maven.scm.ScmException;
023 import org.apache.maven.scm.ScmFileStatus;
024 import org.apache.maven.scm.log.DefaultLog;
025 import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
026 import org.apache.maven.scm.provider.hg.command.HgConsumer;
027 import org.codehaus.plexus.util.cli.Commandline;
028
029 import 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 */
038 public 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 }