diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/init/InitCommand.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/init/InitCommand.java
index 06ad574e..1a2b00ea 100644
--- a/zanata-client-commands/src/main/java/org/zanata/client/commands/init/InitCommand.java
+++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/init/InitCommand.java
@@ -42,6 +42,7 @@
import org.zanata.client.commands.ConsoleInteractorImpl;
import org.zanata.client.commands.OptionsUtil;
import org.zanata.client.config.ZanataConfig;
+import org.zanata.client.util.VersionComparator;
import org.zanata.rest.client.ZanataProxyFactory;
import com.google.common.annotations.VisibleForTesting;
@@ -98,6 +99,8 @@ protected void run() throws Exception {
// Search for zanata.ini
userConfigHandler.verifyUserConfig();
+ ensureServerVersion();
+
// If there's a zanata.xml, ask the user
projectConfigHandler.handleExistingProjectConfig();
@@ -132,6 +135,18 @@ protected void run() throws Exception {
displayAdviceAboutWhatIsNext(projectConfigHandler.hasOldConfig());
}
+ @VisibleForTesting
+ protected void ensureServerVersion() {
+ String serverVersion =
+ getRequestFactory().getServerVersionInfo().getVersionNo();
+
+ if (new VersionComparator().compare(serverVersion, "3.4.0") < 0) {
+ console.printfln(Warning, _("server.incompatible"));
+ console.printfln(Hint, _("server.incompatible.hint"));
+ throw new RuntimeException(_("server.incompatible"));
+ }
+ }
+
private void displayAdviceAboutWhatIsNext(boolean hasOldConfig) {
console.printfln(_("what.next"));
if (hasOldConfig) {
diff --git a/zanata-client-commands/src/main/java/org/zanata/client/util/VersionComparator.java b/zanata-client-commands/src/main/java/org/zanata/client/util/VersionComparator.java
new file mode 100644
index 00000000..74a0f3fb
--- /dev/null
+++ b/zanata-client-commands/src/main/java/org/zanata/client/util/VersionComparator.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014, Red Hat, Inc. and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.zanata.client.util;
+
+import java.util.Comparator;
+import java.util.List;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * This class will compare version strings i.e. 3.3.1 to 3.3. It can also
+ * compare maven snapshot version i.e. 3.3.1-SNAPSHOT is newer than 3.3.1.
+ * It can NOT handle version like 1.1a or 1.1.Final or 1.1.Alpha.
+ *
+ * @author Patrick Huang pahuang@redhat.com
+ */
+public class VersionComparator implements Comparator {
+
+ private static final Splitter splitter =
+ Splitter.on(".").omitEmptyStrings().trimResults();
+ public static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
+
+ @Override
+ public int compare(String left, String right) {
+ Preconditions.checkNotNull(left);
+ Preconditions.checkNotNull(right);
+
+ List leftOrdinals =
+ ImmutableList.copyOf(splitter.split(left.replace(
+ SNAPSHOT_SUFFIX, "")));
+ List rightOrdinals =
+ ImmutableList.copyOf(splitter.split(right.replace(
+ SNAPSHOT_SUFFIX, "")));
+ int compareIndex =
+ firstDiffOrdinalOrLastOrdinalInShortestVer(leftOrdinals,
+ rightOrdinals);
+ // compare first different ordinal
+ if (compareIndex < leftOrdinals.size()
+ && compareIndex < rightOrdinals.size()) {
+ Integer leftOrdinal =
+ getOrdinalAsInteger(leftOrdinals, compareIndex);
+ Integer rightOrdinal =
+ getOrdinalAsInteger(rightOrdinals, compareIndex);
+
+ int ordinalDiff = leftOrdinal.compareTo(rightOrdinal);
+ if (ordinalDiff == 0) {
+ return compareSnapshot(left, right);
+ }
+ return ordinalDiff;
+ }
+
+ // either equal or one is a substring of another
+ int sizeDiff = leftOrdinals.size() - rightOrdinals.size();
+ if (sizeDiff == 0) {
+ return compareSnapshot(left, right);
+ }
+ return Integer.signum(sizeDiff);
+ }
+
+ private static int firstDiffOrdinalOrLastOrdinalInShortestVer(
+ List ver1Ordinals,
+ List ver2Ordinals) {
+ int result = 0;
+ while (result < ver1Ordinals.size() && result < ver2Ordinals.size()
+ && ver1Ordinals.get(result).equals(ver2Ordinals.get(result))) {
+ result++;
+ }
+ return result;
+ }
+
+ private static Integer getOrdinalAsInteger(List ordinals,
+ int index) {
+ return Integer.valueOf(ordinals.get(index));
+ }
+
+ private static int compareSnapshot(String ver1, String ver2) {
+ boolean ver1IsSnapshot = ver1.endsWith(SNAPSHOT_SUFFIX);
+ boolean ver2IsSnapshot = ver2.endsWith(SNAPSHOT_SUFFIX);
+ if (ver1IsSnapshot && !ver2IsSnapshot) {
+ return -1;
+ } else if (!ver1IsSnapshot && ver2IsSnapshot) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/zanata-client-commands/src/main/resources/prompts.properties b/zanata-client-commands/src/main/resources/prompts.properties
index 73119aa3..02ff143f 100644
--- a/zanata-client-commands/src/main/resources/prompts.properties
+++ b/zanata-client-commands/src/main/resources/prompts.properties
@@ -3,6 +3,8 @@ found.servers=Found servers in %s:
which.server=Which Zanata server do you want to use?
server.selection=You have selected server %s
missing.server.url=You do not have a Zanata server URL in your user config file (zanata.ini). Please refer to http://zanata.org/help/cli/cli-configuration/ for how to add a server URL
+server.incompatible=Server version does not support this command! Contact your server administrator to upgrade.
+server.incompatible.hint=Alternatively, you could manually set up your project by referring to the Maintainer section in http://zanata.org/help/overview/workflow-overview/
project.config.exists=Project config (zanata.xml) already exists. If you continue it will be backed up.
continue.yes.no=Do you want to continue (y/n)?
@@ -45,6 +47,7 @@ no.source.doc.found=No source documents found.
found.source.docs=Found source documents:
source.doc.confirm.yes.no=Continue with these source document settings (y/n)?
more.src.options.hint=There are more advanced options available which can only be given from commandline. See help for detail.
+src.dir.not.exist=Directory %s does not exist! Please re-enter.
trans.dir.prompt=What is your base directory for translated files (eg ".", "po", "src/main/resources")?
trans.doc.preview=Zanata will put translation files as below (e.g. for locale %s):
diff --git a/zanata-client-commands/src/test/java/org/zanata/client/commands/init/InitCommandTest.java b/zanata-client-commands/src/test/java/org/zanata/client/commands/init/InitCommandTest.java
index 9653f8c2..e5788b10 100644
--- a/zanata-client-commands/src/test/java/org/zanata/client/commands/init/InitCommandTest.java
+++ b/zanata-client-commands/src/test/java/org/zanata/client/commands/init/InitCommandTest.java
@@ -1,6 +1,7 @@
package org.zanata.client.commands.init;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.when;
import static org.zanata.client.commands.HTTPMockContainer.Builder.readFromClasspath;
import java.io.BufferedWriter;
@@ -17,7 +18,10 @@
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.mockito.Answers;
+import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
import org.simpleframework.http.core.Container;
import org.simpleframework.http.core.ContainerServer;
import org.simpleframework.transport.connect.SocketConnection;
@@ -25,6 +29,9 @@
import org.slf4j.LoggerFactory;
import org.zanata.client.commands.ConsoleInteractor;
import org.zanata.client.commands.HTTPMockContainer;
+import org.zanata.client.commands.Messages;
+import org.zanata.rest.client.ZanataProxyFactory;
+import org.zanata.rest.dto.VersionInfo;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
@@ -43,11 +50,15 @@ public class InitCommandTest {
private InitCommand command;
private InitOptionsImpl opts;
private SocketConnection connection;
+ @Mock
+ private ConsoleInteractor console;
+ @Mock
+ private ZanataProxyFactory requestFactory;
@Before
public void setUp() throws IOException {
+ MockitoAnnotations.initMocks(this);
opts = new InitOptionsImpl();
- ConsoleInteractor console = Mockito.mock(ConsoleInteractor.class);
command = new InitCommand(opts, console, null);
}
@@ -119,4 +130,18 @@ public void willWriteSrcDirIncludesExcludesToConfigFile() throws Exception {
"potpo"));
}
+ @Test
+ public void willQuitIfServerApiVersionDoesNotSupportInit()
+ throws Exception {
+ expectException.expect(RuntimeException.class);
+ expectException.expectMessage(Matchers.equalTo(Messages
+ ._("server.incompatible")));
+
+ when(requestFactory.getServerVersionInfo()).thenReturn(
+ new VersionInfo("3.3.1", "unknown", "unknown"));
+ command = new InitCommand(opts, console, requestFactory);
+
+ command.ensureServerVersion();
+ }
+
}
diff --git a/zanata-client-commands/src/test/java/org/zanata/client/util/VersionComparatorTest.java b/zanata-client-commands/src/test/java/org/zanata/client/util/VersionComparatorTest.java
new file mode 100644
index 00000000..50270560
--- /dev/null
+++ b/zanata-client-commands/src/test/java/org/zanata/client/util/VersionComparatorTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2014, Red Hat, Inc. and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.zanata.client.util;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+import org.junit.Test;
+
+public class VersionComparatorTest {
+ public static final int GREATER = 1;
+ public static final int EQUAL = 0;
+ public static final int LESS = -1;
+ private VersionComparator comparator = new VersionComparator();
+
+ @Test
+ public void canCompareVersions() {
+ assertThat(comparator.compare("3.3.1", "3.3"), equalTo(GREATER));
+ assertThat(comparator.compare("3.3.1", "3.3.1"), equalTo(EQUAL));
+ assertThat(comparator.compare("3.3.1", "3.3.2"), equalTo(LESS));
+ assertThat(comparator.compare("3.3.1-SNAPSHOT", "3.3"), equalTo(GREATER));
+ assertThat(comparator.compare("3.3.1-SNAPSHOT", "3.3-SNAPSHOT"), equalTo(GREATER));
+ assertThat(comparator.compare("3.3.1-SNAPSHOT", "3.3.1"), equalTo(LESS));
+ assertThat(comparator.compare("3.3.1-SNAPSHOT", "3.3.2-SNAPSHOT"), equalTo(LESS));
+ assertThat(comparator.compare("3.3.1-SNAPSHOT", "3.3.1-SNAPSHOT"), equalTo(EQUAL));
+ }
+
+}
diff --git a/zanata-client-commands/src/test/resources/serverresponse/version.xml b/zanata-client-commands/src/test/resources/serverresponse/version.xml
index e606e0a4..be6cc0d8 100644
--- a/zanata-client-commands/src/test/resources/serverresponse/version.xml
+++ b/zanata-client-commands/src/test/resources/serverresponse/version.xml
@@ -1,6 +1,6 @@
- 3.3.1
+ 3.4.0
unknown
unknown
\ No newline at end of file
diff --git a/zanata-rest-client/src/main/java/org/zanata/rest/client/ZanataProxyFactory.java b/zanata-rest-client/src/main/java/org/zanata/rest/client/ZanataProxyFactory.java
index bcfc0b36..e4e126fa 100644
--- a/zanata-rest-client/src/main/java/org/zanata/rest/client/ZanataProxyFactory.java
+++ b/zanata-rest-client/src/main/java/org/zanata/rest/client/ZanataProxyFactory.java
@@ -138,7 +138,7 @@ public void performVersionCheck() {
warnMismatchAPIVersion(clientScm, serverScm);
}
- private VersionInfo getServerVersionInfo() {
+ public VersionInfo getServerVersionInfo() {
IVersionResource iversion = createIVersionResource();
ClientResponse versionResp;
try {