#!/usr/bin/env python """ Referencing current branch in github README.md [1] This pre-commit hook [2] updates the README.md file's CI badge [3] with the current branch. Based on [4]. [1] http://stackoverflow.com/questions/18673694/referencing-current-branch-in-github-readme-md [2] http://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks [3] https://github.com/xoseperez/espurna/actions [4] https://gist.github.com/dandye/dfe0870a6a1151c89ed9 Copy this file to .git/hooks/ """ import os import re import string import sys import argparse from subprocess import call, check_output try: from urllib.parse import urlparse except ImportError: from urlparse import urlparse from fileinput import FileInput # TODO: drop after platform.io supports python 3 # https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672 if sys.version_info[0] < 3: class FileInputCtx(FileInput): def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() FileInput = FileInputCtx class CustomFormatter(string.Formatter): def format_field(self, value, spec): if spec == "escape_hyphen": return value.replace("-", "--") else: return super(CustomFormatter, self).format_field(value, spec) def run(cmd, cwd=None): out = check_output(cmd, cwd=cwd) out = out.decode("latin1").strip() return out def parse_h_string(define, r_quotes=re.compile("\"(.*)\"")): string = r_quotes.search(define).group(1) return string def git_parse_remote(cwd=None, remote="origin"): remote_url = run([ "git", "config", "--local", "--get", "remote.{}.url".format(remote)], cwd) if remote_url.startswith("git"): _, _, repo = remote_url.partition(":") path = repo.replace(".git", "") elif remote_url.startswith("https"): parsed = urlparse(remote_url) path = parsed.path[1:] return path.split("/") def git_branch(cwd=None): return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd) def espurna_get_version(base, version_h="code/espurna/config/version.h"): version = "unknown" path = os.path.join(base, version_h) with open(path, "r") as version_f: for line in version_f: if line.startswith("#define") and "APP_VERSION" in line: version = parse_h_string(line) break return version TEMPLATES = { "![ci]": "![ci](https://github.com/{USER}/{REPO}/workflows/ESPurna%20build/badge.svg?branch={BRANCH})\n" "![version]": "[![version](https://img.shields.io/badge/version-{VERSION:escape_hyphen}-brightgreen.svg)]" "(CHANGELOG.md)\n", "![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH:escape_hyphen}-orange.svg)]" "(https://github.com/{USER}/{REPO}/tree/{BRANCH}/)\n", } README = "README.md" if __name__ == "__main__": base = os.getcwd() user, repo = git_parse_remote() parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("-b", "--branch", help="git branch name", default=git_branch()) parser.add_argument("-u", "--user", help="git user name", default=user) parser.add_argument("-r", "--repo", help="git repo name", default=repo) parser.add_argument("-v", "--version", help="ESPurna version", default=espurna_get_version(base)) args = parser.parse_args() fmt = { "USER": args.user, "REPO": args.repo, "BRANCH": args.branch, "VERSION": args.version } formatter = CustomFormatter() templates = [ (k, formatter.format(tmpl, **fmt)) for k, tmpl in TEMPLATES.items() ] def fmt_line(line): for match, tmpl in templates: if match in line: return tmpl return line path = os.path.join(base, README) with FileInput(path, inplace=True) as readme: for line in readme: sys.stdout.write(fmt_line(line)) if call(["git", "add", README]): sys.exit(1) sys.exit(0)