Skip to content

Instantly share code, notes, and snippets.

@PavelPolyakov
Created February 16, 2020 14:37
Show Gist options
  • Save PavelPolyakov/b25cf59456a4f5a9b842274bf383a2d0 to your computer and use it in GitHub Desktop.
Save PavelPolyakov/b25cf59456a4f5a9b842274bf383a2d0 to your computer and use it in GitHub Desktop.
format repo using git-filter-repo
#!/usr/bin/env python3
"""
This script is meant to format all java files in your repo using maven-formatter-plugin
"""
import argparse
import os
import sys
import subprocess
import tempfile
import uuid
try:
import git_filter_repo as fr
except ImportError:
raise SystemExit("Error: Couldn't find git_filter_repo.py. Did you forget to make a symlink to git-filter-repo named git_filter_repo.py or did you forget to put the latter in your PYTHONPATH?")
tmpdir = None
blobs_handled = {}
cat_file_process = None
def lint_with_real_filenames(commit, metadata):
filenames_to_tmp_map = {}
for change in commit.file_changes:
if change.type == b'D':
continue
elif not change.filename.lower().endswith(b".java"):
continue
else:
# Get the old blob contents
cat_file_process.stdin.write(change.blob_id + b'\n')
cat_file_process.stdin.flush()
objhash, objtype, objsize = cat_file_process.stdout.readline().split()
contents_plus_newline = cat_file_process.stdout.read(int(objsize)+1)
# Write it out to a file with the same basename
filename = os.path.join(tmpdir, os.fsencode(str(uuid.uuid4()) + ".java"))
filenames_to_tmp_map[change.filename] = filename
with open(filename, "wb") as f:
f.write(contents_plus_newline[:-1])
files_to_format = []
for filename in filenames_to_tmp_map:
files_to_format.append(os.path.basename(filenames_to_tmp_map[filename]).decode("utf-8"))
# Format the file
separator = ","
subprocess.check_call(["mvn",
# "-X"
"net.revelc.code.formatter:formatter-maven-plugin:2.11.0:format",
"\"-Dconfigfile=/Users/%USERNAME%/Desktop/style.xml\"",
"\"-DsourceDirectory=" + tmpdir.decode('utf-8') + "/\"",
"\"-Dformatter.includes="+ separator.join(files_to_format) +"\""])
# update history
for change in commit.file_changes:
if change.blob_id in blobs_handled:
change.blob_id = blobs_handled[change.blob_id]
elif change.type == b'D':
continue
elif not change.filename.lower().endswith(b".java"):
continue
else:
filename = filenames_to_tmp_map[change.filename]
# Get the new contents
with open(filename, "rb") as f:
blob = fr.Blob(f.read())
# Insert the new file into the filter's stream, and remove the tempfile
filter.insert(blob)
os.remove(filename)
# Record our handling of the blob and use it for this change
blobs_handled[change.blob_id] = blob.id
change.blob_id = blob.id
args = fr.FilteringOptions.default_options()
args.force = True
# actually start formatting procedure
tmpdir = tempfile.mkdtemp().encode()
cat_file_process = subprocess.Popen(['git', 'cat-file', '--batch'],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE)
filter = fr.RepoFilter(args, commit_callback=lint_with_real_filenames)
filter.run()
cat_file_process.stdin.close()
cat_file_process.wait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment