You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ma...@apache.org on 2018/08/02 20:09:38 UTC

[incubator-netbeans] branch master updated: Adds Version parsing to svn output.

This is an automated email from the ASF dual-hosted git repository.

matthiasblaesing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new c9d53a6  Adds Version parsing to svn output.
c9d53a6 is described below

commit c9d53a66c0518a3ee8008b781a1940c079808585
Author: pokebadgerswithspoon <la...@icantfeelmylegs.com>
AuthorDate: Thu Aug 2 23:09:36 2018 +0300

    Adds Version parsing to svn output.
    
    Comparing version numbers should be based on numbers, not strings.
    I.e. its possible to determine if 1.2.2 and 1.2.123 have same MAJOR.MINOR version.
    
    Fixes NETBEANS-771.
---
 .../client/cli/commands/VersionCommand.java        | 150 ++++++++++++++++++---
 .../client/cli/commands/VersionCommandTest.java    |  98 ++++++++++++++
 2 files changed, 227 insertions(+), 21 deletions(-)

diff --git a/subversion/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommand.java b/subversion/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommand.java
index f8f6db0..81ef659 100644
--- a/subversion/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommand.java
+++ b/subversion/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommand.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Level;
+import java.util.regex.Pattern;
 import org.netbeans.modules.subversion.Subversion;
 import org.netbeans.modules.subversion.client.cli.SvnCommand;
 import org.tigris.subversion.svnclientadapter.ISVNNotifyListener;
@@ -37,20 +38,22 @@ public class VersionCommand extends SvnCommand {
     private List<String> output = new ArrayList<String>();
     private boolean unsupportedVersion = false;
     private boolean supportedMetadataFormat = false;
-    
+    static final Version VERSION_15 = Version.parse("1.5");
+    static final Version VERSION_16 = Version.parse("1.6");
+
     @Override
     protected int getCommand() {
         return ISVNNotifyListener.Command.UNDEFINED;
     }
-    
+
     @Override
     public void prepareCommand(Arguments arguments) throws IOException {
-        arguments.add("--version");                
+        arguments.add("--version");
     }
 
     @Override
     protected void config(File configDir, String username, String password, Arguments arguments) {
-        arguments.addConfigDir(configDir);        
+        arguments.addConfigDir(configDir);
     }
 
     @Override
@@ -61,7 +64,7 @@ public class VersionCommand extends SvnCommand {
         output.add(lineString);
         super.outputText(lineString);
     }
-    
+
     public boolean checkForErrors() {
         Integer exitCode = getExitCode();
         if ((exitCode == null) || !exitCode.equals(Integer.valueOf(0))) {
@@ -79,20 +82,16 @@ public class VersionCommand extends SvnCommand {
 
             int pos = string.indexOf(" version ");
             if (pos > -1) {
-                Subversion.LOG.log(Level.INFO, "Commandline client version: {0}", string.substring(pos + 9));
-            }
-
-            if(string.indexOf("version 0.")  > -1 ||
-               string.indexOf("version 1.0") > -1 ||
-               string.indexOf("version 1.1") > -1 ||
-               string.indexOf("version 1.2") > -1 ||
-               string.indexOf("version 1.3") > -1 ||
-               string.indexOf("version 1.4") > -1) {
-                unsupportedVersion = true;
-                return false;
-            } else if(string.indexOf("version 1.5")  > -1 
-                    || string.indexOf("version 1.6") > -1) {
-                supportedMetadataFormat = true;
+                String vString = string.substring(pos + 9);
+                Subversion.LOG.log(Level.INFO, "Commandline client version: {0}", vString);
+                Version version = Version.parse(vString);
+                if (version.lowerThan(VERSION_15)) {
+                    unsupportedVersion = true;
+                    return false;
+                } else if (version.sameMinor(VERSION_15)
+                        || version.sameMinor(VERSION_16)) {
+                    supportedMetadataFormat = true;
+                }
             }
         }
         return outputProduced;
@@ -105,7 +104,7 @@ public class VersionCommand extends SvnCommand {
     public boolean isMetadataFormatSupported() {
         return supportedMetadataFormat;
     }
-    
+
     public String getOutput() {
         StringBuffer sb = new StringBuffer();
         for (String string : output) {
@@ -113,5 +112,114 @@ public class VersionCommand extends SvnCommand {
             sb.append('\n');
         }
         return sb.toString();
-    }    
+    }
+
+    /**
+     * Version holder with semantic verioning support.
+     *
+     * Keep svn --version output in mind. The container is compatible with
+     * MAJOR.MINOR.PATCH format plus some remainder as it happens in svn
+     * --version. I.e. "svn, version 1.10.0 (r1827917)" is supported. Regular
+     * 1.10.1 is supported too.
+     *
+     */
+    public static class Version implements Comparable<Version> {
+
+        final int[] parts;
+        final String remainder;
+
+        private Version(int[] parts, String remainder) {
+            this.parts = parts;
+            this.remainder = remainder;
+        }
+
+        /**
+         * Parse version string into container. String must be in
+         * "MAJOR.MINOR.PATCH reminder" format. Reminder part is optional.
+         *
+         * @param version non null string with version, say "1.10.0 (r1827917)"
+         * @return non null version
+         * @throws NumberFormatException should parse error occur
+         * @throws IllegalArgumentException if one of parameters was null
+         */
+        public static Version parse(String version) throws NumberFormatException, IllegalArgumentException {
+            return parse(version, " ");
+        }
+
+        /**
+         * Parse version string into container. String must be in
+         * "MAJOR.MINOR.PATCH-reminder" format. Reminder part is optional.
+         *
+         * @param version non null string with version, say 1.1.1-SNAPSHOT
+         * @param remainderDelimiter a symbol to separate semantic version from
+         * reminder, say "-" for "1.1.1-SNAPSHOT"
+         * @return non null version
+         * @throws NumberFormatException should parse error occur
+         * @throws IllegalArgumentException if one of parameters was null
+         */
+        public static Version parse(String version, String remainderDelimiter) throws NumberFormatException, IllegalArgumentException {
+            assertNotNullArg(version, "Version parameter must not be null");
+            assertNotNullArg(remainderDelimiter, "reminderDelimiter parameter must not be null");
+            String[] versionMajorParts = version.split(Pattern.quote(remainderDelimiter), 2);
+
+            String[] stringParts = versionMajorParts[0].split("\\.");
+            int[] parts = new int[stringParts.length];
+            for (int i = 0; i < stringParts.length; i++) {
+                parts[i] = Integer.parseInt(stringParts[i]);
+            }
+
+            return new Version(parts, versionMajorParts.length > 1 ? versionMajorParts[1] : "");
+        }
+
+        private static void assertNotNullArg(Object value, String errMessage) throws IllegalArgumentException {
+            if (value == null) {
+                throw new IllegalArgumentException(errMessage);
+            }
+        }
+
+        @Override
+        public int compareTo(Version t) {
+            if (t == null) {
+                return 1;
+            } else {
+                for (int i = 0; i < parts.length; i++) {
+                    if (t.parts.length < i) {
+                        return 1;
+                    }
+                    int a = parts[i];
+                    int b = t.parts[i];
+                    if (a < b) {
+                        return -1;
+                    } else if (a > b) {
+                        return +1;
+                    }
+                }
+                return t.parts.length > parts.length ? -1 : 0;
+            }
+        }
+
+        public boolean lowerThan(Version that) {
+            return compareTo(that) < 0;
+        }
+
+        /**
+         * Check if MAJOR and MINOR parts are equal
+         *
+         * @param that can be null
+         * @return
+         */
+        public boolean sameMinor(Version that) {
+            return that != null && trim(2).compareTo(that.trim(2)) == 0;
+        }
+
+        private Version trim(int level) {
+            int[] newParts = new int[level];
+            System.arraycopy(parts, 0, newParts, 0, Math.min(level, parts.length));
+            return new Version(newParts, this.remainder);
+        }
+
+        public boolean greaterThan(Version that) {
+            return compareTo(that) > 0;
+        }
+    }
 }
diff --git a/subversion/test/unit/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommandTest.java b/subversion/test/unit/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommandTest.java
new file mode 100644
index 0000000..6f58265
--- /dev/null
+++ b/subversion/test/unit/src/org/netbeans/modules/subversion/client/cli/commands/VersionCommandTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.netbeans.modules.subversion.client.cli.commands;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.netbeans.modules.subversion.client.cli.commands.VersionCommand.Version;
+
+public class VersionCommandTest {
+
+    @Test
+    public void testVersionParse() {
+        assertNotNull(Version.parse("1.2"));
+        assertNotNull(Version.parse("1.10.0 (r1827917)"));
+    }
+
+    @Test
+    public void testComparison() {
+        assertTrue(Version.parse("1.2").lowerThan(Version.parse("1.3")));
+        assertTrue(Version.parse("1.2").lowerThan(Version.parse("1.3")));
+        assertTrue(Version.parse("1.2").lowerThan(Version.parse("1.2.1")));
+        assertTrue(Version.parse("1.2").lowerThan(Version.parse("2")));
+        assertTrue(Version.parse("2").greaterThan(Version.parse("1.2")));
+        assertTrue(Version.parse("2").greaterThan(Version.parse("1.2.1")));
+        assertTrue(Version.parse("1.5").greaterThan(Version.parse("1.2.1")));
+        assertTrue(Version.parse("1.10.0 (r1827917)").greaterThan(Version.parse("1.5")));
+
+        assertTrue(Version.parse("1.10.0 (r1827917)").sameMinor(Version.parse("1.10")));
+        assertFalse(Version.parse("1.10.0 (r1827917)").sameMinor(Version.parse("1")));
+        assertFalse(Version.parse("1.10.0 (r1827917)").sameMinor(Version.parse("1")));
+    }
+
+    @Test
+    public void testRemainder() {
+        assertEquals("(r1827917)", Version.parse("1.10.0 (r1827917)").remainder);
+        assertEquals("SNAPSHOT", Version.parse("1.1.1-SNAPSHOT", "-").remainder);
+    }
+
+    @Test
+    public void testArguments() {
+        try {
+            Version.parse(null);
+            fail("Null argument should not be accepted");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            Version.parse(null, null);
+            fail("Null argument should not be accepted");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            Version.parse("1.1.1", null);
+            fail("Null argument should not be accepted");
+        } catch (IllegalArgumentException ex) {
+        }
+        try {
+            Version.parse("a.b.c");
+            fail("Number parsing exception is expected");
+        } catch (NumberFormatException ex) {
+        }
+        try {
+            Version.parse("not a version");
+            fail("Number parsing exception is expected");
+        } catch (NumberFormatException ex) {
+        }
+    }
+
+    @Test
+    public void testNETBEANS_771() {
+
+        String line = "svn, version 1.10.0 (r1827917)";
+        Version v110 = Version.parse(line.substring(line.indexOf(" version ") + 9)); // this similar to what happens in VersionCommand.java checkForErrors()
+
+        assertTrue(VersionCommand.VERSION_15.lowerThan(v110));
+        assertFalse(v110.lowerThan(VersionCommand.VERSION_15));
+        assertTrue(VersionCommand.VERSION_15.lowerThan(v110));
+        assertTrue(VersionCommand.VERSION_16.lowerThan(v110));
+        assertFalse(VersionCommand.VERSION_15.sameMinor(v110));
+        assertFalse(VersionCommand.VERSION_16.sameMinor(v110));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists