Skip to content

Instantly share code, notes, and snippets.

@rubeniskov
Last active May 14, 2022 17:03
Show Gist options
  • Save rubeniskov/e8aeec1bebf46696a9b9557e1a1bf936 to your computer and use it in GitHub Desktop.
Save rubeniskov/e8aeec1bebf46696a9b9557e1a1bf936 to your computer and use it in GitHub Desktop.
Create a unified diff patch, changing the version of the config files that are most commonly used in package manager
#!/usr/bin/env python
from __future__ import print_function
import os, getopt, sys, re, difflib, io, itertools, sys, time
# Globals vars
__VERBOSE__ = False
__VERSION__ = "0.0.1"
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def verbose(*args, **kwargs):
if __VERBOSE__:
eprint(time.time(), *args, **kwargs)
def gen_diff(old, new, filename):
return difflib.unified_diff(old, new, fromfile="a/"+filename, tofile="b/"+filename)
def gen_diff_package_json(version, content):
pattern = '("version"\s*:\s*").*(".*)'
substitution = r"\g<1>" + version + r"\g<2>"
content = re.sub(pattern, substitution, content, flags = re.M)
return io.BytesIO(content)
def gen_diff_setup_py(version, content):
pattern = '(version\s*=\s*[\'"]).*([\'"].*)'
substitution = r"\g<1>" + version + r"\g<2>"
content = re.sub(pattern, substitution, content, flags = re.M)
return io.BytesIO(content)
def gen_diff_plain_text(version, content = None):
return io.BytesIO(version)
def gen_diff_patch_strategy(version, strategy, filenames, cwd):
output = itertools.chain()
for filename in filenames:
full_filename = os.path.join(os.getcwd(), filename)
if os.path.isfile(full_filename):
verbose("Detected file '%s' using '%s' patch strategy" % (full_filename, strategy))
with open(full_filename, 'r') as fd:
content = fd.read()
patch = strategy(version, content)
fd.seek(0)
contgen = gen_diff(fd.readlines(), patch.readlines(), filename)
output = itertools.chain(output, contgen)
return output
def gen_diff_patch(version):
file_diff_gen_map = [
gen_diff_package_json, [ "package.json" ],
gen_diff_setup_py, [ "setup.py" ],
gen_diff_plain_text, [ "VERSION" ],
]
output = itertools.chain()
for idx in range(0, len(file_diff_gen_map), 2):
patch_generator = file_diff_gen_map[idx]
patch_filenames = file_diff_gen_map[idx + 1]
for line in gen_diff_patch_strategy(
version,
file_diff_gen_map[idx],
file_diff_gen_map[idx + 1],
os.getcwd()
):
sys.stdout.write(line)
sys.stdout.write("\n")
def show_version():
eprint("v{0} License MIT 2020".format(__VERSION__))
def usage():
eprint("""Usage: {program} [options] <version>
Create a unified diff patch, changing the version of the config files that
are most commonly used in package manager
* NPM - https://docs.npmjs.com/files/package.json
* PYPA - https://packaging.python.org/tutorials/packaging-projects/
* Oldschool - Plaintext file called VERSION
Available options:
-h, --help Show usage
-v, --verbose Enable verbose traces
-v, --version Show version
Examples
{program} 0.0.1
echo 0.0.1 | {program}
""".format(**{
"program": sys.argv[0]
}))
def main():
global __VERBOSE__
try:
opts, args = getopt.getopt(sys.argv[1:], "hvV", ["help", "version", "verbose"])
except getopt.GetoptError as err:
eprint(err)
usage(cmd)
sys.exit(2)
for opt, value in opts:
if opt in ("-V", "--verbose"):
__VERBOSE__ = True
verbose("Enabled verbose mode")
elif opt in ("-v", "--version"):
show_version()
sys.exit()
elif opt in ("-h", "--help"):
usage()
sys.exit()
else:
assert False, usage()
if not sys.stdin.isatty():
verbose("Reading version from stdin data")
args = sys.stdin.readline().split()
gen_diff_patch(args[0])
if __name__== "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment