Eclipseplugins
CheckPythonModules.java
1 package com.proalpha.pds.paconnector.utils;
2 
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.io.Reader;
7 import java.lang.ProcessBuilder.Redirect;
8 import java.util.HashMap;
9 import java.util.regex.Matcher;
10 import java.util.regex.Pattern;
11 
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 
15 public class CheckPythonModules {
16  private final Logger logger = LoggerFactory.getLogger(CheckPythonModules.class);
17  HashMap<String, String> pyModuleVersions = new HashMap<String, String>();
18 
19  public CheckPythonModules() {
20 
21  this.pyModuleVersions.put("pa-installer", "0.0.27");
22  }
23 
24  private HashMap<String, String> getPythonModules() {
25 
26  // return a hash map of 2 Strings with modul an version
27  ProcessBuilder builder = new ProcessBuilder();
28  HashMap<String, String> resultLines = new HashMap<String, String>();
29  // pattern for result lines
30  final String regex = "([a-zA-Z0-9-]{1,}\\s*)([0-9]{1,4}(\\.[0-9]+){0,3})";
31  final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
32 
33  // exec python pip
34  builder.command("python", "-m", "pip", "list");
35  builder.redirectErrorStream(true);
36  builder.redirectInput(Redirect.PIPE);
37  builder.redirectOutput(Redirect.PIPE);
38 
39  try {
40  // exec python
41  final Process p = builder.start();
42  logger.info("query python modules. call '{}'", builder.command());
43  // scan output lines
44  try (Reader rOut = new InputStreamReader(p.getInputStream());
45  BufferedReader inOut = new BufferedReader(rOut)) {
46  // content of read line
47  String line;
48  do {
49  // reed in one line
50  line = inOut.readLine();
51  // if line got values
52  if (line != null) {
53  // trim trailing spaces
54  line = line.trim();
55  // check line match regexp
56  Matcher m = pattern.matcher(line);
57  if (m.matches()) {
58  // line match add groups into resultlist.
59  resultLines.put(m.group(1).trim(), m.group(2).trim());
60  logger.debug("add modulinfo " + line);
61  } else
62  logger.debug("skip line " + line);
63 
64  }
65  } while (line != null);
66  }
67 
68  // if result of call is an error clear result list
69  Integer callExitValue = p.waitFor();
70  if (callExitValue != 0)
71  resultLines.clear();
72 
73  } catch (IOException | InterruptedException e) {
74  // on any error clear list
75  resultLines.clear();
76  }
77  // return the list. In case of errors list is empty
78  return resultLines;
79 
80  }
81 
82  public Boolean pythonVersionsMatch() {
83 
84  Boolean pyVersionsMatch = true;
85  // get current module versions from python
86  HashMap<String, String> currentPythonModules = getPythonModules();
87  // check the defined module / version list against list from python
88  for (String pymodname : pyModuleVersions.keySet()) {
89 
90  String moduleversion = currentPythonModules.get(pymodname);
91 
92  if (moduleversion == null)
93  pyVersionsMatch = false;
94  else {
95  // check version against needed
96  String[] currentVersion = currentPythonModules.get(pymodname).split("\\.");
97  String[] neededVersion = pyModuleVersions.get(pymodname).split("\\.");
98 
99  if (currentVersion.length != neededVersion.length)
100  pyVersionsMatch = false;
101  else {
102  // go over all numbers
103  // watch out for 2.0.0 is higher than 1.9999.9999
104  for (Integer i = 0; i < currentVersion.length; i++) {
105 
106  Integer current = Integer.parseInt(currentVersion[i]);
107  Integer needed = Integer.parseInt(neededVersion[i]);
108  // if a leading number is higher version match
109  if (current > needed)
110  break;
111  if (current < needed)
112  pyVersionsMatch = false;
113  // same number check next number
114  }
115  }
116 
117  }
118  logger.debug(String.format("module %s got version %s. needed version is %s", pymodname,
119  currentPythonModules.get(pymodname), pyModuleVersions.get(pymodname)));
120  // if first version dosen't match update needed
121  if (!pyVersionsMatch)
122  break;
123 
124  }
125 
126  return pyVersionsMatch;
127 
128  }
129 
130 }