Created
June 25, 2018 00:05
-
-
Save zacscott/1b1f38da4764706a03ce3df31c1a3eaf to your computer and use it in GitHub Desktop.
PHPCS w/ Bitbucket Pipelines helper script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import subprocess | |
import sys | |
import tempfile | |
def log(message): | |
"""Print a log message to console, will be a darker colour than normal print()""" | |
formatted = "%s%s%s" % ( | |
'\u001b[30;1m', # dark grey colour | |
message, | |
'\u001b[0m' # reset colour | |
) | |
print(formatted) | |
def hr(): | |
"""Print a horizontal line to console""" | |
log("================================================================") | |
def cmd(command): | |
""" | |
Execute the given command. | |
:param command: The command to be executed, passed to os.system() | |
""" | |
exit_code = 0 | |
lines = [] | |
command_str = ' '.join(command) | |
log(command_str) | |
hr() | |
# run the command and capture the output | |
try: | |
output = subprocess.check_output( | |
command, | |
stderr=subprocess.STDOUT, | |
universal_newlines=True | |
) | |
except subprocess.CalledProcessError as ex: | |
output = ex.output | |
exit_code = ex.returncode | |
# parse lines | |
output = output.decode('ascii') if not isinstance(output, str) else output | |
lines = output.split("\n") | |
# output command output | |
for line in lines: | |
print(line) | |
hr() | |
return (exit_code, lines) | |
_tempdir = None | |
def tempdir(): | |
"""Returns the temp working directory, where composer etc. will be installed""" | |
global _tempdir | |
if _tempdir is None: | |
_tempdir = tempfile.mkdtemp() | |
return _tempdir | |
def git_fetch(): | |
cmd(["git", "remote", "set-branches", "origin", "*"]) | |
cmd(["git", "fetch"]) | |
def git_checkout(branch): | |
"""Checkout the given branch in Git""" | |
# NOTE we have to do it in this round about way because Bitbucket only does | |
# a shallow clone, so we dont have all the branches | |
cmd([ | |
"git", | |
"checkout", | |
branch | |
]) | |
cmd([ | |
"git", "pull", "origin", branch | |
]) | |
def git_diff_files(branch): | |
""" | |
Return a list of all of the files which have changed between the current | |
branch and the given branch in Git | |
""" | |
(exit_code, changed_files) = cmd([ | |
"git", "diff", branch, "--name-only" | |
]) | |
return changed_files | |
def phpcs_build(): | |
"""Download, install and configure PHPCS""" | |
owd = os.getcwd() | |
os.chdir(tempdir()) | |
cmd([ | |
"composer", | |
"require", | |
"squizlabs/php_codesniffer", | |
"--ignore-platform-reqs" | |
]) | |
os.chdir(owd) | |
# include WP coding standards | |
cmd([ | |
"git", "clone", | |
"https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", | |
"%s/vendor/wpcs" % tempdir(), | |
"--depth", "1" | |
]) | |
cmd([ | |
"%s/vendor/bin/phpcs" % tempdir(), | |
"--config-set", | |
"installed_paths", | |
"%s/vendor/wpcs" % tempdir() | |
]) | |
def phpcs_analyse(files): | |
"""Run the PHPCS analyser on the given list of files""" | |
command = [ | |
"%s/vendor/bin/phpcs" % tempdir(), | |
"--colors" | |
] | |
(exit_code, changed_files) = cmd(command + files) | |
return exit_code | |
################################################################################################ | |
def run_phpcs(branch_from, branch_to): | |
hr() | |
log("COMPARING GIT %s => %s" % (branch_from, branch_to)) | |
log("TEMPDIR = %s" % tempdir()) | |
hr() | |
git_fetch() | |
# determine the files which have changed between the two branches | |
git_checkout(branch_from) | |
changed_files = git_diff_files(branch_to) | |
# select the PHP files only for analysis | |
changed_php_files = [] | |
for file_path in changed_files: | |
print("'%s'" % file_path) | |
if file_path.endswith("php"): | |
changed_php_files.append(file_path) | |
if len(changed_php_files): | |
# run PHPCS if there are files to update | |
# include PHPCS and analyse the changed files | |
phpcs_build() | |
exit_code = phpcs_analyse(changed_files) | |
# exit with same code as PHPCS, so pipeline fails if there are errors | |
exit(exit_code) | |
else: | |
log("NO PHP FILES TO ANALYSE") | |
if len(sys.argv) >= 2: | |
run_phpcs(sys.argv[1], sys.argv[2]) | |
else: | |
print("USAGE: %s <from branch> <to branch>" % sys.argv[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment