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