def main(args, options=None): from openbases.main import Client params = None repo = args.repo if repo is None: repo = os.getcwd() repo = os.path.abspath(repo) if os.path.exists(repo): bot.info("repo: %s" % repo) os.environ['OPENBASESENV_REPO_BASE'] = repo os.putenv('OPENBASESENV_REPO_BASE', repo) else: bot.warning('%s does not exist.' % repo) # Ensure that paper exists paper = args.infile if not paper: bot.exit('You must specify a paper with --infile') if not os.path.exists(paper): bot.exit('%s does not exist.' % paper) paper = os.path.abspath(paper) if args.basic is True: validator = Client.BasicValidator(infile=paper) else: validator = Client.PaperValidator(infile=paper) validator.validate_criteria(criteria=args.criteria, params=params)
def load_criteria(self, criteria=None): '''load a criteria.yml file. If not specified, load (or reload) default provided by package. Parameters ========== criteria: a yml specification for criteria. If not provided, use default at criteria/specification.yml. If you need help creating a new criteria (that might be added to defaults) please open an issue ''' # First pass - criteria file defined, and exists if criteria is not None: if os.path.exists(criteria): criteria = self.validate_exists(criteria) # Second pass, use default provided by library if criteria is None: criteria = self.default_criteria # Attempt to load (and validate) the criteria (returns YamlManager) self.criteria = validate_loads(criteria) # Again fall back to default if error loading user-provided if self.criteria is None: self.criteria = validate_loads(default_criteria) basename = os.path.basename(self.criteria.infile) bot.info('[criteria:%s]' % basename) return self.criteria.load()
def check_install(software=None, quiet=True): '''check_install will attempt to run some command, and return True if installed. The command line utils will not run without this check. ''' if software == None: bot.error("Please enter the name of the software!") cmd = [software, '--version'] found = False try: version = run_command(cmd, quiet=True) except: # FileNotFoundError return found if version is not None: if version['return_code'] == 0: found = True if quiet is False: version = version['message'] bot.info("Found %s version %s" % (software.upper(), version)) return found
def test_contributing(spec, envar='OPENBASESENV_REPO_BASE', **kwargs): '''look for CONTRIBUTING.md or similar contributing: - name: Software has CONTRIBUTING.md - level: error - function: openbases.main.papers.tests.test_contributing - environment: - OPENBASESENV_REPO_BASE: null Templates taken from https://github.com/licenses/license-templates ''' # By default, not found. found = False repo_base = os.environ.get(envar) if repo_base is not None: if os.path.exists(repo_base): contenders = find_files(repo_base, 'LICENSE|license|License') if len(contenders) > 0: bot.info('Found CONTRIBUTING file(s) in repository!') found = True return found
def test_references(spec, envar="OPENBASESENV_BIBFILE", **kwargs): '''required_structure looks for a schema's required fields, and issues an exit if doesn't exist. To implement this in a criteria.yml: references: - name: References are included and complete - level: warning - function: openbases.main.papers.tests.test_references Templates taken from https://github.com/licenses/license-templates ''' from openbases.utils import read_bibtex complete = True bibfile = os.environ.get(envar) # We must have a bibfile if not "bibfile" and "bibfile" not in kwargs: bot.warning('Bibfile not provided as argument, skipping test') return complete required_fields = ['title', 'month', 'year'] bib = read_bibtex(bibfile) for entryid, entry in bib.items(): bot.info('Testing bibliography entry %s' % entryid) bot.info(' type: %s' % entry.type) for field in entry.fields: if field not in entry.fields: bot.error(' %s is missing field %s' % (entryid, field)) complete = False if entry.fields[field] in [None, '']: bot.error(' %s has empty field %s' % (entryid, field)) complete = False bot.info(' title: %s' % entry.fields['title']) return complete
def test_license(spec, envar='OPENBASESENV_REPO_BASE', **kwargs): '''required_structure looks for a schema's required fields, and issues an exit if doesn't exist. To implement this in a criteria.yml: license: - name: An OSI license is included in the repository - level: error - function: openbases.main.papers.tests.test_license - environment: - OPENBASESENV_REPO_BASE: null Templates taken from https://github.com/licenses/license-templates ''' # By default, not found. found = False # A list of terms to indicate open source licenses LICENSE_FLAGS = [ "GNU Affero General Public License", "MIT License", "Apache", "Creative Commons", "CC0", # Creative Commans 1.0 "CC1", "General Public License", "The GNU General Public License", "GPL-2.0", "Free Software Foundation", "GNU LESSER GENERAL PUBLIC", "GPL-3.0", "Mozilla Public License", "free and unencumbered software released into the public", "www.gnu.org", "This program is free software", "www.wtfpl.net", "COMMON DEVELOPMENT AND DISTRIBUTION", # CCDL '"AS IS"', # bsd 22 'as-is' ] # zlib repo_base = os.environ.get(envar) if repo_base is not None: if os.path.exists(repo_base): licenses = find_files(repo_base, 'LICENSE') for license in licenses: content = read_file(license, readlines=False) matches = [ x for x in LICENSE_FLAGS if re.search(x.lower(), content.lower()) ] if len(matches) > 0: message = 'Found Open Source license flags! %s' bot.info(message % ','.join(matches)) print(content) found = True else: bot.error('%s does not exist! Skipping test.' % repo_base) else: bot.error('''Did not find %s export for repository base! Skipping license check''' % envar) return found
def validate_criteria(self, criteria=None, infile=None, params=None): '''validate an infile (or already loaded one) against criteria. Parameters ========== infile: an input specification file criteria: a loaded (json/dict) or criteria, or html/yml file ''' from openbases.utils import load_module # If criteria not set, use default if criteria is None: self.load_criteria() # Update environment with params for validation if params is not None: bot.info('Updating custom params with %s' % params) self.params.update(params) # Update the environment update_environment(params=self.params, prefix='OPENBASESENV_') # Read in the criteria - any errors will fall back to default if not isinstance(criteria, dict): criteria = self.load_criteria(criteria) # Case 1: input file provided at runtime if infile is not None: self.load(infile) # Case 2: Didn't successfully load, fall back to previously loaded if not hasattr(self, 'spec'): # infile didn't load successfully if hasattr(self, 'infile'): self.load(infile) # Case 3: Still no infile! Exit if not hasattr(self, 'spec'): bot.error('Please provide an infile to function, or load()') if "checks" not in criteria: bot.error('criteria is missing "checks" section, exiting.') # Default missing function missing_function = 'openbases.main.validate.criteria.base.missing' # Turn status into meaningful message for user lookup = {True: 'pass', False: 'fail', None: 'null'} # Loop through checks, run against specification file for group, checks in criteria['checks'].items(): print('[group|start:%s]' % group) values = dict() [values.update(dict(check)) for check in checks] # Obtain values, the only required is the function name = values.get('name', self.robot.generate()) level = values.get('level', 'warning').upper() function = values.get('function', missing_function) kwargs = values.get('kwargs') envars_list = values.get('environment') envars = dict() # If we have environment vars from criteria, export them if envars_list is not None: [update_environment(e) for e in envars_list] # If we have a function provided in the configuration yaml function_name = function function = load_module(function) if kwargs is None: valid = function(self.spec) else: values = dict() [values.update(dict(kwarg)) for kwarg in kwargs] valid = function(self.spec, **values) print('[check:%s]' % name) print(' test:function %s' % function_name) print(' test:result %s' % lookup[valid]) if valid: bot.test("PASSED %s" % function_name) else: print(' test:level %s' % level) bot.named(level, function_name) if not valid: sys.exit(1) print('[group|end:%s]' % group) print('ALL TESTS PASSING')
def test_validation(self): """Test that the markdown is loaded fully""" repo = os.path.join(test_dir, '../../') bot.info("repo: %s" % repo) os.environ['OPENBASESENV_REPO_BASE'] = repo self.validator.validate_criteria()