def minimize_js(repo_link, commit, path, row, substitutions): # minimize-js <src> [dst] src = file_operations.get_file(row['src'], path, substitutions) if 'dst' in row: dst = file_operations.get_file(row['dst'], path, substitutions) else: dst = src # check access file_operations.check_file(src[0], path) # minimize action = row.get('type').lower() print(' %s %s -> %s' % (action, src[2], dst[2])) cmd = "uglifyjs '%s' -c -m -o '%s'" % (src[0], dst[0]) print(' [%s]' % cmd) subprocess.check_call(cmd, shell=True)
def copymove(repo_link, commit, path, row, substitutions): # {copy|move} <src> <dst> [add-header-comment] [replace-keywords] src = file_operations.get_file(row['src'], path, substitutions) dst = file_operations.get_file(row['dst'], path, substitutions) # determine which file(s) should be used if 'match' in row: sources, destinations = [], [] for name in glob.glob(os.path.join(src[0], '*')): src2 = file_operations.get_file(name) basename = src2[2] if re.match(row['match'], basename) is not None: sources.append(src2) file_path = os.path.join(dst[0], basename) destinations.append(file_operations.get_file(file_path)) else: sources, destinations = [src], [dst] # apply the action to each file is_move = row.get('type').lower() == 'move' for src, dst in zip(sources, destinations): copymove_single(repo_link, commit, path, row, src, dst, is_move)
def compile_coffee(repo_link, commit, path, row, substitutions): # compile-coffee <src> [dst] src = file_operations.get_file(row['src'], path, substitutions) if 'dst' in row: dst = file_operations.get_file(row['dst'], path, substitutions) else: basename, extension = src[2:4] if extension != '': basename = basename[:-len(extension)] + 'js' else: basename += '.js' dst = file_operations.get_file(basename, src[1]) # check access file_operations.check_file(src[0], path) # compile action = row.get('type').lower() print(' %s %s -> %s' % (action, src[2], dst[2])) cmd = "coffee -c -p '%s' > '%s'" % (src[0], dst[0]) print(' [%s]' % cmd) subprocess.check_call(cmd, shell=True)
def copymove_single(repo_link, commit, path, row, src, dst, is_move): action = 'move' if is_move else 'copy' print(' %s %s -> %s' % (action, src[2], dst[2])) # check access file_operations.check_file(src[0], path) # put a big "do not edit" warning at the top of the file if row.get('add-header-comment', False) is True: src = add_header(repo_link, commit, src, dst[3]) # replace template keywords with values templates = row.get('replace-keywords') if type(templates) is str: templates = [templates] if type(templates) in (tuple, list): full_templates = [file_operations.get_file(t, path) for t in templates] src = replace_keywords(src, full_templates) # make the copy (method depends on destination) if dst[0].startswith('/var/www/html/'): # copy to staging area tmp = file_operations.get_file(src[2] + '__tmp', '/common/') print(' [%s] -> [%s]' % (src[0], tmp[0])) shutil.copy(src[0], tmp[0]) # make directory and move the file as user `webadmin` cmd = "sudo -u webadmin -s mkdir -p '%s'" % (dst[1]) print(' [%s]' % cmd) subprocess.check_call(cmd, shell=True) cmd = "sudo -u webadmin -s mv -fv '%s' '%s'" % (tmp[0], dst[0]) print(' [%s]' % cmd) subprocess.check_call(cmd, shell=True) else: # make directory and copy the file print(' [%s] -> [%s]' % (src[0], dst[0])) os.makedirs(dst[1], exist_ok=True) shutil.copy(src[0], dst[0]) # maybe delete the source file if is_move: os.remove(src[0])
def add_header(repo_link, commit, src, dst_ext): # build the header based on the source language ext = dst_ext.lower() pre_block, post_block, pre_line, post_line = '', '', '', '' blanks = '\n\n\n' if ext in ('html', 'xml'): pre_block, post_block = '<!--\n', '-->\n' + blanks elif ext in ('js', 'min.js', 'css', 'c', 'cpp', 'h', 'hpp', 'java'): pre_block, post_block = '/*\n', '*/\n' + blanks elif ext in ('py', 'r', 'coffee', 'htaccess', 'sh'): pre_line, post_line, post_block = '# ', ' #', blanks elif ext in ('php'): # be sure to not introduce whitespace (e.g. newlines) outside php tags pre_block, post_block = '<?php /*\n', '*/\n' + blanks + '?>' else: # nothing modified, return the original file print(' warning: skipped header for file extension [%s]' % dst_ext) return src # additional header lines t = round(time.time()) dt = datetime.datetime.fromtimestamp(t).isoformat(' ') lines = [ '', 'Automatically generated from sources at:', repo_link, '', ('Commit hash: %s' % commit), ('Deployed at: %s (%d)' % (dt, t)), ] # add the header to a copy of the source file tmp = file_operations.get_file(src[0] + '__header') print(' adding header [%s] -> [%s]' % (src[0], tmp[0])) with open(tmp[0], 'wb') as fout: fout.write(bytes(pre_block, 'utf-8')) for line in HEADER_LINES + [ line.center(HEADER_WIDTH) for line in lines ]: fout.write(bytes(pre_line + line + post_line + '\n', 'utf-8')) fout.write(bytes(post_block, 'utf-8')) with open(src[0], 'rb') as fin: fout.write(fin.read()) # return the new file return tmp
def replace_keywords(src, templates): # load list of (key, value) pairs pairs = [] for t in templates: with open(t[0], 'r') as f: pairs.extend(json.loads(f.read())) # make a new file to hold the results tmp = file_operations.get_file(src[0] + '__valued') print(' replacing %d keywords [%s] -> [%s]' % (len(pairs), src[0], tmp[0])) with open(tmp[0], 'w') as fout: with open(src[0], 'r') as fin: for line in fin.readlines(): for (k, v) in pairs: line = line.replace(k, v) fout.write(line) # return the new file return tmp
def py3test(repo_link, commit, path, row, substitutions): # py3test [dir] # parse arguments if 'dir' in row: location = file_operations.get_file(row['dir'], path, substitutions)[0] else: location = os.path.join(path, 'tests') pattern = '^(test_.*|.*_test)\\.py$' terminal = False # find tests test_files = p3t.find_tests(location, pattern, terminal) # run tests and gather results results = [p3t.analyze_results(p3t.run_tests(f)) for f in test_files] # check for success # TODO: show in repo badge totals = { 'good': 0, 'bad': 0, 'lines': 0, 'hits': 0, } for test in results: totals['good'] += test['unit']['summary']['pass'] totals['bad'] += test['unit']['summary']['fail'] totals['bad'] += test['unit']['summary']['error'] totals['lines'] += test['coverage']['summary']['total_lines'] totals['hits'] += test['coverage']['summary']['hit_lines'] if totals['bad'] > 0: raise Exception('%d test(s) did not pass' % totals['bad']) elif totals['good'] == 0: print('no tests found') else: print('%d test(s) passed!' % totals['good']) num = len(results) cov = 100 * totals['hits'] / totals['lines'] print('overall coverage for %d files: %.1f%%' % (num, cov))