diff --git a/eclipse-pydev.spec b/eclipse-pydev.spec index eccb663..3e9bcca 100644 --- a/eclipse-pydev.spec +++ b/eclipse-pydev.spec @@ -6,7 +6,7 @@ Epoch: 1 Summary: Eclipse Python development plug-in Name: eclipse-pydev Version: 5.9.2 -Release: 1%{?dist} +Release: 2%{?dist} License: EPL URL: http://pydev.org @@ -39,13 +39,13 @@ Requires: ws-commons-util Requires: xmlrpc-common Requires: xmlrpc-client Requires: xmlrpc-server -Requires: jython >= 2.7.1-1 +Requires: jython >= 2.7.1-3 Requires: antlr32-java >= 3.2-12 Requires: python3-autopep8 -Requires: python3-pep8 -Requires: python3-pylint -Requires: python3-django -Requires: python3-ipython-console +Requires: python3-pycodestyle +Recommends: python3-pylint +Recommends: python3-django +Recommends: python3-ipython-console BuildRequires: tycho BuildRequires: tycho-extras BuildRequires: eclipse-mylyn @@ -56,13 +56,13 @@ BuildRequires: ws-commons-util BuildRequires: xmlrpc-common BuildRequires: xmlrpc-client BuildRequires: xmlrpc-server -BuildRequires: jython >= 2.7.1-1 +BuildRequires: jython >= 2.7.1-3 BuildRequires: lucene >= 6.1.0 BuildRequires: lucene-analysis >= 6.1.0 # Required for symlinking into the plugin BuildRequires: python3-autopep8 -BuildRequires: python3-pep8 +BuildRequires: python3-pycodestyle BuildRequires: python3-rpm-macros %description @@ -101,7 +101,7 @@ rm -r plugins/org.python.pydev/pysrc/third_party/wrapped_for_pydev rm -r plugins/org.python.pydev/pysrc/third_party/pep8/* # Symlink to system versions (cd plugins/org.python.pydev/pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/autopep8.py) -(cd plugins/org.python.pydev/pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/pep8.py) +(cd plugins/org.python.pydev/pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/pycodestyle.py) # Remove pre-built artifacts find -name '*.class' -delete @@ -111,24 +111,22 @@ find -name '*.dylib' -delete find -name '*.so' -delete rm -rf plugins/org.python.pydev.jython/Lib +# Symlink to system jython and standard library +pushd plugins/org.python.pydev.jython +ln -sf %{_datadir}/jython/jython.jar +ln -sf %{_datadir}/jython/javalib +ln -sf %{_datadir}/jython/Lib +popd + # Link to system jython # we must include all of jython's runtime dependencies on the classpath pushd plugins/org.python.pydev.jython -build-jar-repository -s -p . \ - jython/jython guava jnr-constants jnr-ffi jnr-netdb jnr-posix jffi jffi-native jline/jline jansi/jansi antlr32/antlr-runtime-3.2 \ - objectweb-asm/asm objectweb-asm/asm-commons objectweb-asm/asm-util commons-compress icu4j \ - netty/netty-buffer netty/netty-codec netty/netty-common netty/netty-handler netty/netty-transport -for j in $(ls *.jar) ; do - if [ -z "$js" ] ; then js="$j"; else js="${js},$j"; fi +for j in $(ls javalib/*.jar) ; do + sed -i -e 's/\r//' -e "/^ jython\.jar/i\ $j," META-INF/MANIFEST.MF done -sed -i -e 's/\r//' -e "s/^ jython\.jar/ $js/" META-INF/MANIFEST.MF -sed -i -e "s/ jython\.jar/ $js/" build.properties +sed -i -e "s/ jython\.jar/ jython.jar,javalib\//" build.properties popd -# Symlink to jython standard library -ln -sf %{_datadir}/jython/Lib \ - plugins/org.python.pydev.jython/Lib - # Symlinks to other system jars ln -sf $(build-classpath commons-logging) \ plugins/org.python.pydev.shared_interactive_console/commons-logging-1.1.1.jar @@ -187,21 +185,19 @@ for f in commons-logging \ done popd -# Symlink system jython and libs +# Symlink to system jython and standard library pushd $installDir/eclipse/plugins/org.python.pydev.jython_* -rm -rf Lib +rm -rf jython.jar javalib Lib +ln -sf %{_datadir}/jython/jython.jar +ln -sf %{_datadir}/jython/javalib ln -sf %{_datadir}/jython/Lib -build-jar-repository -s -p . \ - jython/jython guava jnr-constants jnr-ffi jnr-netdb jnr-posix jffi jffi-native jline/jline jansi/jansi antlr32/antlr-runtime-3.2 \ - objectweb-asm/asm objectweb-asm/asm-commons objectweb-asm/asm-util commons-compress icu4j \ - netty/netty-buffer netty/netty-codec netty/netty-common netty/netty-handler netty/netty-transport popd # Symlink system pep8 pushd $installDir/eclipse/plugins/org.python.pydev_* rm pysrc/third_party/pep8/*.py (cd pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/autopep8.py) -(cd pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/pep8.py) +(cd pysrc/third_party/pep8/ && ln -s %{python3_sitelib}/pycodestyle.py) popd # convert .py$ files from mode 0644 to mode 0755 @@ -215,6 +211,10 @@ sed -i -e '/.*\.py$/s/0644/0755/' .mfiles* %license LICENSE.txt %changelog +* Thu Sep 28 2017 Mat Booth - 1:5.9.2-2 +- Fix broken internal Jython console +- Fix pycodestyle usage, rhbz#1496452 + * Sat Sep 16 2017 Mat Booth - 1:5.9.2-1 - Update to latest upstream release diff --git a/system-jython-interpreter.patch b/system-jython-interpreter.patch index 0aa022d..970a4de 100644 --- a/system-jython-interpreter.patch +++ b/system-jython-interpreter.patch @@ -1,114 +1,253 @@ +From 41fba27ce8728722076f1c0c9f81db215c7b494a Mon Sep 17 00:00:00 2001 +From: Mat Booth +Date: Thu, 28 Sep 2017 16:13:50 +0100 +Subject: [PATCH] Better support system installed versions of Jython for Linux + distros + +--- + .../debug/ui/launching/PythonRunnerConfig.java | 4 ++- + .../python/pydev/runners/SimpleJythonRunner.java | 33 ++++++++++++++++--- + .../ui/interpreters/JythonInterpreterManager.java | 21 ++++++++++++ + .../AbstractInterpreterProviderFactory.java | 2 +- + .../pydev/ui/pythonpathconf/InterpreterInfo.java | 8 ++--- + .../JythonInterpreterProviderFactory.java | 37 +++++++++++++++++++--- + 6 files changed, 89 insertions(+), 16 deletions(-) + diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java -index 86f83ef..14cdc34 100644 +index ae4202094..6aa827837 100644 --- a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java +++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java -@@ -688,6 +688,9 @@ - throw new RuntimeException("The jython jar must be specified as the interpreter to run. Found: " - + interpreter); - } -+ if (interpreter.toOSString().endsWith("jython")) { -+ cmdArgs.add(interpreter.toOSString()); -+ } else { - cmdArgs.add(javaLoc); - - //some nice things on the classpath config: http://mindprod.com/jgloss/classpath.html -@@ -703,6 +706,7 @@ - cpath = interpreter + SimpleRunner.getPythonPathSeparator() + pythonpathUsed; +@@ -59,6 +59,7 @@ import org.python.pydev.plugin.PydevPlugin; + import org.python.pydev.plugin.nature.PythonNature; + import org.python.pydev.plugin.preferences.PydevPrefs; + import org.python.pydev.pyunit.preferences.PyUnitPrefsPage2; ++import org.python.pydev.runners.SimpleJythonRunner; + import org.python.pydev.runners.SimpleRunner; + import org.python.pydev.shared_core.io.FileUtils; + import org.python.pydev.shared_core.net.LocalHost; +@@ -700,7 +701,8 @@ public class PythonRunnerConfig { + // if (project.getNature(Constants.JAVA_NATURE) != null){ + // cpath = getClasspath(JavaCore.create(project)); + // } else { +- cpath = interpreter + SimpleRunner.getPythonPathSeparator() + pythonpathUsed; ++ cpath = SimpleJythonRunner.generateClasspath(interpreter.toString()) + SimpleRunner.getPythonPathSeparator() ++ + pythonpathUsed; // } cmdArgs.add(cpath); -+ } cmdArgs.add("-Dpython.path=" + pythonpathUsed); //will be added to the env variables in the run (check if this works on all platforms...) - - addVmArgs(cmdArgs); -@@ -714,8 +718,14 @@ - //cmdArgs.add("-Dpython.security.respectJavaAccessibility=false"); - - cmdArgs.add("org.python.util.jython"); -+ if (!interpreter.toOSString().endsWith("jython")) { -+ cmdArgs.add("org.python.util.jython"); -+ } - addDebugArgs(cmdArgs, "jython", actualRun, addWithDashMFlag, modName); - } else { -+ if (!interpreter.toOSString().endsWith("jython")) { -+ cmdArgs.add("org.python.util.jython"); -+ } - cmdArgs.add("org.python.util.jython"); - } - diff --git a/plugins/org.python.pydev/src/org/python/pydev/runners/SimpleJythonRunner.java b/plugins/org.python.pydev/src/org/python/pydev/runners/SimpleJythonRunner.java -index 1b3d84c..6214e08 100644 +index 1b3d84c2b..f5552ce68 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/runners/SimpleJythonRunner.java +++ b/plugins/org.python.pydev/src/org/python/pydev/runners/SimpleJythonRunner.java -@@ -74,19 +74,24 @@ public class SimpleJythonRunner extends SimpleRunner { - String javaLoc = javaExecutable.getCanonicalPath(); - String[] s; +@@ -11,9 +11,13 @@ package org.python.pydev.runners; + + import java.io.File; + import java.io.IOException; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import java.nio.file.Paths; + import java.util.ArrayList; + import java.util.Arrays; + import java.util.List; ++import java.util.stream.Collectors; -- //In Jython 2.5b0, if we don't set python.home, it won't be able to calculate the correct PYTHONPATH -- //(see http://bugs.jython.org/issue1214 ) -- -- String pythonHome = new File(jythonJar).getParent().toString(); -- -- if (additionalPythonpath != null) { + import org.eclipse.core.resources.IProject; + import org.eclipse.core.runtime.IProgressMonitor; +@@ -77,15 +81,15 @@ public class SimpleJythonRunner extends SimpleRunner { + //In Jython 2.5b0, if we don't set python.home, it won't be able to calculate the correct PYTHONPATH + //(see http://bugs.jython.org/issue1214 ) + ++ String classpath = generateClasspath(jythonJar); + String pythonHome = new File(jythonJar).getParent().toString(); + + if (additionalPythonpath != null) { - jythonJar += SimpleRunner.getPythonPathSeparator(); - jythonJar += additionalPythonpath; -- s = new String[] { javaLoc, "-Dpython.path=" + additionalPythonpath, "-Dpython.home=" + pythonHome, ++ classpath += SimpleRunner.getPythonPathSeparator() + additionalPythonpath; + s = new String[] { javaLoc, "-Dpython.path=" + additionalPythonpath, "-Dpython.home=" + pythonHome, - "-classpath", jythonJar, "org.python.util.jython", script }; -+ if (new File(jythonJar).getName().equals("jython")) { -+ //The system jython can simply be invoked directly -+ s = new String[] { jythonJar, script }; ++ "-classpath", classpath, "org.python.util.jython", script }; } else { - s = new String[] { javaLoc, "-Dpython.home=" + pythonHome, "-classpath", jythonJar, -- "org.python.util.jython", script }; -+ //In Jython 2.5b0, if we don't set python.home, it won't be able to calculate the correct PYTHONPATH -+ //(see http://bugs.jython.org/issue1214 ) -+ -+ String pythonHome = new File(jythonJar).getParent().toString(); -+ -+ if (additionalPythonpath != null) { -+ jythonJar += SimpleRunner.getPythonPathSeparator(); -+ jythonJar += additionalPythonpath; -+ s = new String[] { javaLoc, "-Dpython.path=" + additionalPythonpath, "-Dpython.home=" + pythonHome, -+ "-classpath", jythonJar, "org.python.util.jython", script }; -+ } else { -+ s = new String[] { javaLoc, "-Dpython.home=" + pythonHome, "-classpath", jythonJar, -+ "org.python.util.jython", script }; -+ } ++ s = new String[] { javaLoc, "-Dpython.home=" + pythonHome, "-classpath", classpath, + "org.python.util.jython", script }; } - if (args != null && args.length > 0) { -@@ -158,6 +163,19 @@ public class SimpleJythonRunner extends SimpleRunner { - cacheDir = "-Dpython.cachedir=" + cacheDir.trim(); +@@ -143,6 +147,8 @@ public class SimpleJythonRunner extends SimpleRunner { } + jythonPath.append(libs); -+ if (new File(jythonJar).getName().equals("jython")) { -+ //The system jython can simply be invoked directly -+ List asList = new ArrayList(); -+ asList.add(jythonJar); -+ if (cacheDir != null) { -+ asList.add(cacheDir); -+ } -+ asList.add("-Dpython.path=" + jythonPath.toString()); -+ asList.addAll(Arrays.asList(script)); -+ asList.addAll(Arrays.asList(args)); -+ return asList.toArray(new String[0]); -+ } ++ String classpath = generateClasspath(jythonJar); + - String[] vmArgsList = ProcessUtils.parseArguments(vmArgs); + //may have the dir or be null + String cacheDir = null; + try { +@@ -162,7 +168,7 @@ public class SimpleJythonRunner extends SimpleRunner { String[] s = new String[] { "-Dpython.path=" + jythonPath.toString(), + "-classpath", +- jythonJar + pathSeparator + jythonPath, ++ classpath + pathSeparator + jythonPath, + "org.python.util.jython", + script + }; +@@ -178,4 +184,21 @@ public class SimpleJythonRunner extends SimpleRunner { + return asList.toArray(new String[0]); + } + ++ public static String generateClasspath(String jythonJar) { ++ Path jythonPath = Paths.get(jythonJar); ++ String separator = SimpleRunner.getPythonPathSeparator(); ++ try { ++ String javalibs = Files.list(jythonPath.getParent().resolve("javalib")) ++ .filter(Files::isRegularFile) ++ .map(Path::toString) ++ .collect(Collectors.joining(separator)); ++ String classpath = jythonPath.toString(); ++ if (javalibs != null && !javalibs.isEmpty()) { ++ classpath += separator + javalibs; ++ } ++ return classpath; ++ } catch (IOException e) { ++ return jythonPath.toString(); ++ } ++ } + } +diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/interpreters/JythonInterpreterManager.java b/plugins/org.python.pydev/src/org/python/pydev/ui/interpreters/JythonInterpreterManager.java +index e9f3333d1..6970c0854 100644 +--- a/plugins/org.python.pydev/src/org/python/pydev/ui/interpreters/JythonInterpreterManager.java ++++ b/plugins/org.python.pydev/src/org/python/pydev/ui/interpreters/JythonInterpreterManager.java +@@ -12,6 +12,10 @@ + package org.python.pydev.ui.interpreters; + + import java.io.File; ++import java.io.IOException; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import java.nio.file.Paths; + import java.util.List; + + import org.eclipse.core.runtime.CoreException; +@@ -71,6 +75,23 @@ public class JythonInterpreterManager extends AbstractInterpreterManager { + } + File script = getInterpreterInfoPy(); + ++ Path path = Paths.get(executable); ++ try { ++ if (executable.endsWith(".jar")) { ++ path = path.getParent().toRealPath(); ++ } else { ++ path = path.toRealPath().getParent().getParent(); ++ } ++ if (Files.isRegularFile(path.resolve("jython.jar")) && Files.isDirectory(path.resolve("Lib"))) { ++ executable = path.resolve("jython.jar").toString(); ++ } else if (Files.isRegularFile(path.resolve("jython-dev.jar")) ++ && Files.isDirectory(path.resolve("Lib"))) { ++ executable = path.resolve("jython-dev.jar").toString(); ++ } ++ } catch (IOException e) { ++ executable = path.toString(); ++ } ++ + //gets the info for the python side + Tuple outTup = new SimpleJythonRunner().runAndGetOutputWithJar( + FileUtils.getFileAbsolutePath(script), +diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java +index 0e012a9c9..7f10e3b4f 100644 +--- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java ++++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java +@@ -72,7 +72,7 @@ public abstract class AbstractInterpreterProviderFactory implements IInterpreter + if (available != null) { + for (File afile : available) { + int priority = matchesPattern(patterns, afile); +- if (priority != INVALID) { ++ if (priority != INVALID && !afile.isDirectory()) { + if (pathSetsByPriority[priority] == null) { + pathSetsByPriority[priority] = new LinkedHashSet(); + } diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterInfo.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterInfo.java -index 9bd8d88..48ea995 100644 +index 17145cf46..c8c051bb9 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterInfo.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/InterpreterInfo.java -@@ -1462,9 +1462,9 @@ public class InterpreterInfo implements IInterpreterInfo { +@@ -14,6 +14,8 @@ package org.python.pydev.ui.pythonpathconf; + import java.io.File; + import java.io.FilenameFilter; + import java.io.StringReader; ++import java.nio.file.Path; ++import java.nio.file.Paths; + import java.util.ArrayList; + import java.util.Arrays; + import java.util.Collection; +@@ -1461,10 +1463,8 @@ public class InterpreterInfo implements IInterpreterInfo { + * @return if the executable is the jython jar. */ public static boolean isJythonExecutable(String executable) { - if (executable.endsWith("\"")) { +- if (executable.endsWith("\"")) { - return executable.endsWith(".jar\""); -+ return executable.endsWith(".jar\"") || executable.endsWith("jython\""); - } +- } - return executable.endsWith(".jar"); -+ return executable.endsWith(".jar") || executable.endsWith("jython"); ++ Path p = Paths.get(executable); ++ return p.endsWith(Paths.get("bin", "jython")) || p.getFileName().toString().endsWith(".jar"); } /** +diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java +index dc2586ce3..6b397f22d 100644 +--- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java ++++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java +@@ -12,6 +12,10 @@ + ******************************************************************************/ + package org.python.pydev.ui.pythonpathconf; + ++import java.io.IOException; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import java.nio.file.Paths; + import java.util.Arrays; + import java.util.LinkedHashSet; + import java.util.List; +@@ -55,13 +59,36 @@ public class JythonInterpreterProviderFactory extends AbstractInterpreterProvide + } catch (CoreException e) { + Log.log(e); + } ++ // The jython home location for linux packaged versions of jython ++ pathsToSearch.add("/usr/share/jython"); ++ // The standard location for jars on linux distros + pathsToSearch.add("/usr/share/java"); +- pathsToSearch.add("/usr/bin"); +- pathsToSearch.add("/usr/local/bin"); + +- String[] searchResults = searchPaths(pathsToSearch, Arrays.asList("jython.jar")); +- if (searchResults.length > 0) { +- return AlreadyInstalledInterpreterProvider.create("jython", searchResults); ++ String[] searchResults = searchPaths(pathsToSearch, Arrays.asList("jython.jar", "jython-dev.jar", "jython"), ++ false); ++ ++ LinkedHashSet paths = new LinkedHashSet<>(); ++ for (String result : searchResults) { ++ Path path = Paths.get(result); ++ try { ++ if (result.endsWith(".jar")) { ++ path = path.getParent().toRealPath(); ++ } else { ++ path = path.toRealPath().getParent().getParent(); ++ } ++ if (Files.isRegularFile(path.resolve("jython.jar")) && Files.isDirectory(path.resolve("Lib"))) { ++ paths.add(path.resolve("jython.jar").toString()); ++ } else if (Files.isRegularFile(path.resolve("jython-dev.jar")) ++ && Files.isDirectory(path.resolve("Lib"))) { ++ paths.add(path.resolve("jython-dev.jar").toString()); ++ } ++ } catch (IOException e) { ++ continue; ++ } ++ } ++ ++ if (paths.size() > 0) { ++ return AlreadyInstalledInterpreterProvider.create("jython", paths.toArray(new String[paths.size()])); + } + + return null; +-- +2.13.5 +