View Javadoc
1   package org.apache.maven.scm.provider.hg;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.ScmException;
23  import org.apache.maven.scm.ScmFileStatus;
24  import org.apache.maven.scm.log.DefaultLog;
25  import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
26  import org.apache.maven.scm.provider.hg.command.HgConsumer;
27  import org.codehaus.plexus.util.cli.Commandline;
28  
29  import java.io.File;
30  
31  /**
32   * Check hg installation.
33   *
34   * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
35   * @author <a href="mailto:ryan@darksleep.com">ryan daum</a>
36   *
37   */
38  public class HgConfig
39  {
40      //Minimum version for the Hg SCM
41      private static final String HG_REQ = "0.9.2";
42  
43      // The string which indicates the beginning of the Mercurial line
44      private static final String HG_VERSION_TAG = "ercurial Distributed SCM (version ";
45  
46      // URL to download mercurial from
47      private static final String HG_INSTALL_URL = "'http://www.selenic.com/mercurial/wiki/index.cgi/Download'";
48  
49      //Configuration to check with default values (not installed)
50      private HgVersionConsumer hgVersion = new HgVersionConsumer( null );
51  
52      HgConfig( File workingDir )
53      {
54          try
55          {
56              hgVersion = getHgVersion( workingDir );
57          }
58          catch ( ScmException e )
59          {
60              //Ignore -  is not installed.
61              //This is already recorded thus we do not generate more info.
62          }
63  
64      }
65  
66      /**
67       * @return True if one can run basic hg commands
68       */
69      private boolean isInstalled()
70      {
71          return hgVersion.isVersionOk( HG_REQ );
72      }
73  
74      /**
75       * @return True if all modules for hg are installed.
76       */
77      private boolean isComplete()
78      {
79          return isInstalled();
80      }
81  
82      // Consumer to find the Mercurial version
83      public static HgVersionConsumer getHgVersion( File workingDir )
84          throws ScmException
85      {
86          String[] versionCmd = new String[]{HgCommandConstants.VERSION};
87          HgVersionConsumer consumer = new HgVersionConsumer( HG_VERSION_TAG );
88          Commandline cmd = HgUtils.buildCmd( workingDir, versionCmd );
89  
90          // Execute command
91          HgUtils.executeCmd( consumer, cmd );
92  
93          // Return result
94          return consumer;
95      }
96  
97  
98      /**
99       * 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 }