def client(source, packages, output, target, config=None): '''Client side to call PyLint''' # Get the exchange path exchange = os.path.join(target, nconst.AUDIT_EXCHANGE_FILE) # Get the context context = ntools.expand(os.environ.copy()) # Add exchange configuration context[nconst.AUDIT_EXCHANGE_ENTRY] = exchange # Store the test entries listing = {} # Go threw the packages for package in packages: # Get the data entries = (package, output, target, config) # Save data ntools.exchange(exchange, entries) # Get line line = [ sys.executable, '-c', 'import %s ; %s.server()' % (__name__, __name__) ] # Call subprocess p = subprocess.Popen(line, cwd=source, env=context, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # Get the output display = p.stdout.read() # Wait till the end p.wait() # Check return code if p.returncode != 0: # Log the output logger.error(display) # Raise raise nexcepts.AuditError( 'failed to call PyLint in a distinct process: %s returned' % p.returncode) # Get the wrapper data, error = ntools.exchange(exchange) # Check if errors if error is not None: # Log the error logger.error(error) # Step out raise nexcepts.AuditError('failed to audit %s' % package) # Add to errors listing[package] = data # Return results return listing
def set_output(self, fd=None): '''Override the method to store the files in the target folder''' # Check if output specified if fd is None: raise nexcepts.AuditError('file expected for output') # Check that output is a real file if not fd.fileno() > 2: raise nexcepts.AuditError('real file expected for output: got %s' % fd.name) # Get the base bn = fd.name # Close the file fd.close() # Drop it os.remove(bn) # Check if default reporter if not self.default(): # Check if target folder exists ntools.create(self.target) # Get the file self.reporter.set_output(open(os.path.join(self.target, bn), 'w'))
def audit(source, packages, output, target, config=None): '''Start PyLint''' # Check PyLint configuration file check_pylintrc() # Check output if output not in outputs(): raise nexcepts.AuditError("specified output doesn't exist: %s" % output) # Call PyLint listing = client(source, packages, output, target, config=config) # Generate sources and test cases sources, cases = generate(listing) # Create report report(target, sources) # Return the cases return cases
def check_pylintrc(path=None): ''' Check that the PyLint configuration file doesn't contain parameters that override the NoseXUnit configuration ''' # Get the forbidden options forbid = { 'REPORTS': [ 'output-format', 'include-ids', 'files-output', 'reports', ], 'MASTER': [ 'rcfile', ], } # Check if path is specified if not path: path = pylint.config.PYLINTRC # Check if path is is defined if path: # Get the absolute path path = os.path.abspath(path) # Check if the file exists if os.path.isfile(path): # Get a parser parser = configparser.ConfigParser() # Parse the file parser.read(path) # Go threw the sections for section in list(forbid.keys()): # Check if has the section if parser.has_section(section): # Go threw the options for option in forbid[section]: # Check if has the option if parser.has_option(section, option): # Forbidden option raise nexcepts.AuditError( "%s of [%s] can't be on following PyLint's configuration file: %s" % (option, section, path))
def get(self, path, desc): '''Get a source given its path and description''' # Get the right description by ignoring __init__ desc = desc.replace('.__init__', '') # Get package deep count = desc.count('.') # Start from head package current = self # Store current deep pos = 0 # Go deeper and deeper in package tree for part in desc.split('.'): # Get the path c_path = path # Step out until package is reached for i in range(count - pos): c_path = os.path.dirname(c_path) # Check if source already defined if part not in current: # Source not already defined, create it. Here this is a module. if count - pos == 0: current.set(Source(c_path, part)) # Here this is a package else: current.set( Source(os.path.join(c_path, '__init__.py'), part)) # Set the current source current = current[part] # Go deeper pos += 1 # Check the path if not ntools.identical(current.path(), path): # pylint: disable-msg=E1103 # Invalid path raise nexcepts.AuditError( 'two path for %s, only one expected:\n- %s\n- %s' % (current.full(), current.path(), path)) # pylint: disable-msg=E1103 # Return the source return current