summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <michael.drake@codethink.co.uk>2015-04-14 16:01:33 +0000
committerMichael Drake <michael.drake@codethink.co.uk>2015-04-15 14:38:09 +0000
commit3721121494823889f1e0500c3ec9a4c562115451 (patch)
tree29980295ab56c75c6302f73b8163cd240c3de51c
parent8405a74e46aefc39134d912018ba9adda380cc3e (diff)
downloadmorph-3721121494823889f1e0500c3ec9a4c562115451.tar.gz
Improve version guessing.
Change-Id: I3a462f170521c4296e82ea1d2567a7ca7ed476c9
-rw-r--r--morphlib/plugins/cve_check_plugin.py73
1 files changed, 72 insertions, 1 deletions
diff --git a/morphlib/plugins/cve_check_plugin.py b/morphlib/plugins/cve_check_plugin.py
index 26bb987c..3179d797 100644
--- a/morphlib/plugins/cve_check_plugin.py
+++ b/morphlib/plugins/cve_check_plugin.py
@@ -19,6 +19,7 @@
import warnings
+import re
import cliapp
import morphlib
@@ -55,6 +56,7 @@ class CVECheckPlugin(cliapp.Plugin):
self.lrc, self.rrc = morphlib.util.new_repo_caches(self.app)
self.resolver = morphlib.artifactresolver.ArtifactResolver()
self.cve_db = CVEDataBase()
+ self.version_guesser = VersionGuesser()
for system_filename in system_filenames:
self.certify_system(repo, ref, system_filename)
@@ -100,7 +102,7 @@ class CVECheckPlugin(cliapp.Plugin):
self.lrc.cache_repo(source.repo_name)
cached = self.lrc.get_repo(source.repo_name)
- version = cached.version_guess(ref)
+ version = self.version_guesser.guess_version(cached, ref)
self.cve_db.check_vulnerability(name, version)
@@ -180,3 +182,72 @@ class CVEDataBase:
s.check_vulnerability(version)
break
+
+
+class ProjectVersionGuesser(object):
+
+ def __init__(self, interesting_files):
+ self.interesting_files = interesting_files
+
+ def file_contents(self, cached, ref, tree):
+ filenames = [x for x in self.interesting_files if x in tree]
+ if filenames:
+ for filename in filenames:
+ yield filename, cached.read_file(filename, ref)
+
+class AutotoolsVersionGuesser(ProjectVersionGuesser):
+
+ def __init__(self):
+ ProjectVersionGuesser.__init__(self, [
+ 'configure.ac',
+ 'configure.in',
+ 'configure.ac.in',
+ 'configure.in.in',
+ ])
+
+ def guess_version(self, cached, ref, tree):
+ version = None
+ for filename, data in self.file_contents(cached, ref, tree):
+ # First, try to grep for AC_INIT()
+ version = self._check_ac_init(data)
+ if version:
+ break
+
+ return version
+
+ def _check_ac_init(self, data):
+ data = data.replace('\n', ' ')
+ for macro in ['AC_INIT', 'AM_INIT_AUTOMAKE']:
+ pattern = r'.*%s\((.*?)\).*' % macro
+ if not re.match(pattern, data):
+ continue
+ acinit = re.sub(pattern, r'\1', data)
+ if acinit:
+ version = acinit.split(',')
+ if macro == 'AM_INIT_AUTOMAKE' and len(version) == 1:
+ continue
+ version = version[0] if len(version) == 1 else version[1]
+ version = re.sub('[\[\]]', '', version).strip()
+ version = version.split()[0]
+ if version:
+ if version and version[0].isdigit():
+ return version
+ return None
+
+class VersionGuesser(object):
+
+ def __init__(self):
+ self.guessers = [
+ AutotoolsVersionGuesser()
+ ]
+
+ def guess_version(self, cached, ref):
+ version = None
+ tree = cached.list_files(ref, recurse=False)
+ for guesser in self.guessers:
+ version = guesser.guess_version(cached, ref, tree)
+ if version:
+ return version
+
+ # Fall back to `git describe` which always gives something
+ return cached.version_guess(ref)