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.provider.hg.command.HgCommandConstants;
25  import org.apache.maven.scm.provider.hg.command.HgConsumer;
26  import org.codehaus.plexus.util.cli.Commandline;
27  
28  import java.io.File;
29  
30  /**
31   * Check hg installation.
32   *
33   * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
34   * @author <a href="mailto:ryan@darksleep.com">ryan daum</a>
35   *
36   */
37  public class HgConfig
38  {
39      //Minimum version for the Hg SCM
40      private static final String HG_REQ = "0.9.2";
41  
42      // The string which indicates the beginning of the Mercurial line
43      private static final String HG_VERSION_TAG = "Mercurial Distributed SCM (version ";
44  
45      // URL to download mercurial from
46      private static final String HG_INSTALL_URL = "'http://www.selenic.com/mercurial/wiki/index.cgi/Download'";
47  
48      //Configuration to check with default values (not installed)
49      private HgVersionConsumer hgVersion = new HgVersionConsumer( null );
50  
51      HgConfig( File workingDir )
52      {
53          try
54          {
55              hgVersion = getHgVersion( workingDir );
56          }
57          catch ( ScmException e )
58          {
59              //Ignore -  is not installed.
60              //This is already recorded thus we do not generate more info.
61          }
62  
63      }
64  
65      /**
66       * @return True if one can run basic hg commands
67       */
68      private boolean isInstalled()
69      {
70          return hgVersion.isVersionOk( HG_REQ );
71      }
72  
73      /**
74       * @return True if all modules for hg are installed.
75       */
76      private boolean isComplete()
77      {
78          return isInstalled();
79      }
80  
81      // Consumer to find the Mercurial version
82      public static HgVersionConsumer getHgVersion( File workingDir )
83          throws ScmException
84      {
85          String[] versionCmd = new String[]{ HgCommandConstants.VERSION };
86          HgVersionConsumer consumer = new HgVersionConsumer( HG_VERSION_TAG );
87          Commandline cmd = HgUtils.buildCmd( workingDir, versionCmd );
88  
89          // Execute command
90          HgUtils.executeCmd( consumer, cmd );
91  
92          // Return result
93          return consumer;
94      }
95  
96  
97      /**
98       * Iterate through two dot-notation version strings, normalize them to the same length, then
99       * do alphabetic comparison
100      *
101      * @param version1
102      * @param version2
103      * @return true if version2 is greater than version1
104      */
105     private static boolean compareVersion( String version1, String version2 )
106     {
107         int l1, l2;
108         String v1, v2;
109 
110         v1 = version1;
111         v2 = version2;
112         l1 = version1.length();
113         l2 = version2.length();
114 
115         if ( l1 > l2 )
116         {
117             for ( int x = l2; x >= l1; x-- )
118             {
119                 v2 += ' ';
120             }
121         }
122         if ( l2 > l1 )
123         {
124             for ( int x = l1; x <= l2; x++ )
125             {
126                 v1 += ' ';
127             }
128         }
129 
130         return v2.compareTo( v1 ) >= 0;
131     }
132 
133 
134     /**
135      * Get version of the executable.
136      * Version is resolved by splitting the line starting with the version tag and finding
137      * the second last word.
138      */
139     private static class HgVersionConsumer
140         extends HgConsumer
141     {
142 
143         private String versionStr = "NA";
144 
145         private String versionTag;
146 
147         HgVersionConsumer( String versionTag )
148         {
149             this.versionTag = versionTag;
150         }
151 
152         public void doConsume( ScmFileStatus status, String line )
153         {
154             if ( line.startsWith( versionTag ) )
155             {
156                 String[] elements = line.split( " " );
157                 versionStr = elements[elements.length - 1].split( "\\)" )[0];
158             }
159         }
160 
161         String getVersion()
162         {
163             return versionStr;
164         }
165 
166         boolean isVersionOk( String version )
167         {
168             // build one number out of the whole version #
169 
170             return compareVersion( version, versionStr );
171         }
172     }
173 
174     private String getInstalledStr()
175     {
176         if ( isComplete() )
177         {
178             return "valid and complete.";
179         }
180         return ( isInstalled() ? "incomplete. " : "invalid. " ) + "Consult " + HG_INSTALL_URL;
181     }
182 
183     public String toString( File workingDir )
184     {
185         boolean hgOk = hgVersion.isVersionOk( HG_REQ );
186         return "\n  Your Hg installation seems to be " + getInstalledStr() + "\n    Hg version: "
187             + hgVersion.getVersion() + ( hgOk ? " (OK)" : " (May be INVALID)" ) + "\n";
188     }
189 }