Last active
December 13, 2022 10:13
-
-
Save jclaveau/af2271b9fdf05f7f1983f492af5592f8 to your computer and use it in GitHub Desktop.
Replace all variables between brackets like "{{ remote.origin.url }}" by their values retrieved from git
This file contains 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
#!/bin/sh | |
# https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/ | |
# git config core.hooksPath .githooks | |
# run from the root of the repo | |
.githooks/replace_by_git_vars.py readme.md README.md | |
# If your filesystem is not case-sensitive you can use | |
# .githooks/replace_by_git_vars.py README.template.md README.md | |
# Example: | |
# [![Integration Tests](https://github.com/{{ repository.name }}/actions/workflows/integration-tests.yaml/badge.svg?branch={{ current.branch }})](https://github.com/{{ repository.name }}/actions/workflows/integration-tests.yaml?query=branch%3A{{ current.branch }}) |
This file contains 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
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# Copyright: (c) 2016, [Daniel Dye (https://gist.github.com/dandye/dfe0870a6a1151c89ed9)] | |
# Copyright: (c) 2021, [Jean Claveau (https://gist.github.com/jclaveau/af2271b9fdf05f7f1983f492af5592f8)] | |
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | |
import sys | |
import os | |
import json | |
import re | |
import subprocess | |
# """ | |
# This script replaces vars written between brackets like "{{ remote.origin.url }}" by their values. | |
# Used as a pre-commit hook[2] to update the README.md file's and have badges matching the current branch | |
# | |
# [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 | |
# [4] https://gist.github.com/dandye/dfe0870a6a1151c89ed9 | |
# """ | |
argv = sys.argv | |
if len(argv) < 3: | |
print(os.path.basename(__file__) + " [input_file] [output_file] [-v]") | |
quit() | |
input_file = argv[1] | |
output_file = argv[2] | |
verbose = len(argv) == 4 and argv[3] == '-v' | |
if verbose: | |
print("Starting replacing vars in " + input_file + " to generate " + output_file) | |
git_vars = {} | |
# retrieve git config | |
config = subprocess.check_output([ | |
"git", | |
"config", | |
"--list", | |
]).strip().decode('utf-8').split('\n') | |
for config_rule in config: | |
parts = config_rule.split('=') | |
git_vars[parts[0]] = parts[1] | |
# Get the name | |
git_vars['repository.name'] = re.findall("([^:]+)\.git$", git_vars['remote.origin.url'])[0] | |
# retrieve current branch name | |
git_vars['current.branch'] = subprocess.check_output([ | |
"git", | |
"rev-parse", | |
"--abbrev-ref", | |
"HEAD", | |
]).strip().decode('utf-8') | |
# retrieve current commit hash | |
git_vars['current.commit'] = subprocess.check_output([ | |
"git", | |
"rev-parse", | |
"HEAD", | |
]).strip().decode('utf-8') | |
# retrieve tags and current version | |
git_vars['tags'] = subprocess.check_output([ | |
"git", | |
"tag", | |
"--list", | |
]).strip().decode('utf-8') | |
git_vars['current.version'] = git_vars['tags'][0] if len(git_vars['tags']) else None | |
if verbose: | |
print(json.dumps(git_vars, indent=4)) | |
lines = open(input_file).readlines() | |
changed = False | |
with open(output_file, "w") as fh: | |
fh.write('<!---\n') # https://stackoverflow.com/a/4829998/2714285 | |
fh.write("This file is auto-generate by a github hook please modify " + input_file + " if you don't want to lose your work\n") | |
fh.write('-->\n') | |
for line in lines: | |
new_line = line | |
for entry in git_vars: | |
pattern = '{{\s*' + entry + '\s*}}' | |
if len(re.findall(pattern, new_line)): | |
new_line = re.sub(pattern, git_vars[entry], new_line) | |
if verbose: | |
print("Found {{ " + entry + " }} in:\n " + line + "=> " + new_line) | |
changed = True | |
fh.write(new_line) | |
if not changed and verbose: | |
print("No variable found in " + output_file) | |
subprocess.check_output(["git", "add", output_file]) | |
# If output_file and input_file are the same only the replacement will be added for commit | |
with open(input_file, "w") as fh: | |
for line in lines: | |
fh.write(line) | |
if verbose: | |
print(output_file + " variables replaced") |
Nice little script. Typo ouput_file
to output_file
and loose
to lose
Using this nicely. Also I changed input name to README.template.md
as not all filesystems are case-sensitive.
Nice little script. Typo
ouput_file
tooutput_file
andloose
tolose
Using this nicely. Also I changed input name toREADME.template.md
as not all filesystems are case-sensitive.
Happy to see this little piece of work useful for other ones.
Also, thank you for your feedback, I added your points.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
pre-commit.com
is a framework adding a layer abovegit hooks
. I personally never used it even if it looks very interesting. So, to answer you, no, no yaml is required.As explained in githooks.com there is already a
.git/hooks/pre-commit.sample
in every repo. You just have to create a.git/hooks/pre-commit
file and call your scripts from it.Placing your scripts in
.githooks/...
will allow you to commit them contrary to.git/...
content.