source_code_file.py
Go to the documentation of this file.
00001 import re
00002 import os
00003 from ros_introspection.resource_list import is_package, get_python_dependency
00004 
00005 PKG = '([^\.;]+)(\.?[^;]*)?'
00006 PYTHON1 = '^import ' + PKG
00007 PYTHON2 = 'from ' + PKG + ' import .*'
00008 CPLUS = re.compile('#include\s*[<\\"]([^/]*)/?([^/]*)[>\\"]')          # Zero or one slash
00009 CPLUS2 = re.compile('#include\s*[<\\"]([^/]*)/([^/]*)/([^/]*)[>\\"]')  # Two slashes
00010 ROSCPP = re.compile('#include\s*<ros/ros.h>')
00011 
00012 EXPRESSIONS = [re.compile(PYTHON1), re.compile(PYTHON2), CPLUS, CPLUS2]
00013 
00014 
00015 def is_python_hashbang_line(s):
00016     return s[0:2] == '#!' and 'python' in s
00017 
00018 
00019 class SourceCodeFile:
00020     def __init__(self, rel_fn, file_path):
00021         self.rel_fn = rel_fn
00022         self.file_path = file_path
00023         self.tags = set()
00024         self.changed_contents = None
00025 
00026         self.lines = map(str.strip, self.get_contents().split('\n'))
00027         if '.py' in self.file_path or (len(self.lines) > 0 and is_python_hashbang_line(self.lines[0])):
00028             self.language = 'python'
00029         else:
00030             self.language = 'c++'
00031 
00032         parts = os.path.split(rel_fn)
00033         if parts and parts[0] == 'test':
00034             self.tags.add('test')
00035 
00036     def get_contents(self):
00037         if self.changed_contents:
00038             return self.changed_contents
00039         return open(self.file_path).read()
00040 
00041     def replace_contents(self, contents):
00042         self.changed_contents = contents
00043         self.lines = map(unicode.strip, unicode(contents).split('\n'))
00044 
00045     def search_for_patterns(self, patterns):
00046         matches = []
00047         contents = self.get_contents()
00048         for pattern in patterns:
00049             matches += pattern.findall(contents)
00050         return matches
00051 
00052     def search_lines_for_patterns(self, patterns):
00053         matches = []
00054         for line in self.lines:
00055             for pattern in patterns:
00056                 m = pattern.search(line)
00057                 if m:
00058                     matches.append(m.groups())
00059         return matches
00060 
00061     def search_lines_for_pattern(self, pattern):
00062         return self.search_lines_for_patterns([pattern])
00063 
00064     def get_import_packages(self):
00065         pkgs = set()
00066         for match in self.search_lines_for_patterns(EXPRESSIONS):
00067             pkgs.add(match[0])
00068         if len(self.search_lines_for_pattern(ROSCPP)) > 0:
00069             pkgs.add('roscpp')
00070         return sorted(list(pkgs))
00071 
00072     def get_dependencies(self):
00073         deps = []
00074         for pkg in self.get_import_packages():
00075             if is_package(pkg):
00076                 deps.append(pkg)
00077         return deps
00078 
00079     def get_external_python_dependencies(self):
00080         deps = []
00081         if self.language != 'python':
00082             return deps
00083 
00084         for pkg in self.get_import_packages():
00085             p_dep = get_python_dependency(pkg)
00086             if p_dep:
00087                 deps.append(p_dep)
00088         return deps
00089 
00090     def is_executable(self):
00091         return os.access(self.file_path, os.X_OK)
00092 
00093     def __lt__(self, other):
00094         return self.rel_fn < other.rel_fn
00095 
00096     def __repr__(self):
00097         attribs = [self.language] + list(self.tags)
00098         return '%s (%s)' % (self.rel_fn, ', '.join(attribs))
00099 
00100     def write(self):
00101         if self.changed_contents:
00102             with open(self.file_path, 'w') as f:
00103                 f.write(self.changed_contents)


ros_introspection
Author(s):
autogenerated on Wed Jun 19 2019 19:21:34