Add check-ignore
This commit is contained in:
parent
c2f8359690
commit
8fe3e19385
107
libwyag.py
107
libwyag.py
@ -957,3 +957,110 @@ def cmd_ls_files(args):
|
|||||||
print(f" uid: {e.uid} group: {e.gid}")
|
print(f" uid: {e.uid} group: {e.gid}")
|
||||||
print(f" flags: stage={e.flag_stage} assume_valid={e.flag_assume_valid}")
|
print(f" flags: stage={e.flag_stage} assume_valid={e.flag_assume_valid}")
|
||||||
|
|
||||||
|
argsp = argsubparsers.add_parser("check-ignore", help="Check path(s) against ignore rules.")
|
||||||
|
argsp.add_argument("path", nargs="+", help="Paths to check")
|
||||||
|
|
||||||
|
def cmd_check_ignore(args):
|
||||||
|
repo = repo_find()
|
||||||
|
rules = gitignore_read(repo)
|
||||||
|
for path in args.path:
|
||||||
|
if check_ignore(rules, path):
|
||||||
|
print(path)
|
||||||
|
|
||||||
|
def gitignore_parse1(raw):
|
||||||
|
raw = raw.strip()
|
||||||
|
|
||||||
|
if not raw or raw[0] == "#":
|
||||||
|
return None
|
||||||
|
elif raw[0] == "!":
|
||||||
|
return (raw[1:], False)
|
||||||
|
elif raw[0] == "\\":
|
||||||
|
return (raw[1:], True)
|
||||||
|
else:
|
||||||
|
return (raw, True)
|
||||||
|
|
||||||
|
def gitignore_parse(lines):
|
||||||
|
ret = list()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
parsed = gitignore_parse1(line)
|
||||||
|
if parsed:
|
||||||
|
ret.append(parsed)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class GitIgnore(object):
|
||||||
|
absolute = None
|
||||||
|
scoped = None
|
||||||
|
|
||||||
|
def __init__(self, absolute, scoped):
|
||||||
|
self.absolute = absolute
|
||||||
|
self.scoped = scoped
|
||||||
|
|
||||||
|
def gitignore_read(repo):
|
||||||
|
ret = GitIgnore(absolute=list(), scoped=dict())
|
||||||
|
|
||||||
|
# Read local configuration
|
||||||
|
repo_file = os.path.join(repo.gitdir, "info/exclude")
|
||||||
|
if os.path.exists(repo_file):
|
||||||
|
with open(repo_file, "r") as f:
|
||||||
|
ret.absolute.append(gitignore_parse(f.readlines()))
|
||||||
|
|
||||||
|
# Global configuration
|
||||||
|
if "XDG_CONFIG_HOME" in os.environ:
|
||||||
|
config_home == os.environ["XDG_CONFIG_HOME"]
|
||||||
|
else:
|
||||||
|
config_home = os.path.expanduser("~/.config")
|
||||||
|
global_file = os.path.join(config_home, "git/ignore")
|
||||||
|
|
||||||
|
if os.path.exists(global_file):
|
||||||
|
with open(global_file, "r") as f:
|
||||||
|
ret.absolute.append(gitignore_parse(f.readlines()))
|
||||||
|
|
||||||
|
# .gitignore files in the index
|
||||||
|
index = index_read(repo)
|
||||||
|
|
||||||
|
for entry in index.entries:
|
||||||
|
if entry.name == ".gitignore" or entry.name.endswith("/.gitignore"):
|
||||||
|
dir_name = os.path.dirname(entry.name)
|
||||||
|
contents = object_read(repo, entry.sha)
|
||||||
|
lines = contents.blobdata.decode("utf8").splitlines()
|
||||||
|
ret.scoped[dirname] = gitignore_parse(lines)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def check_ignore1(rules, path):
|
||||||
|
result = None
|
||||||
|
for (pattern, value) in rules:
|
||||||
|
if fnmatch(path, pattern):
|
||||||
|
result = value
|
||||||
|
return result
|
||||||
|
|
||||||
|
def check_ignore_scoped(rules, path):
|
||||||
|
parent = os.path.dirname(path)
|
||||||
|
while True:
|
||||||
|
if parent in rules:
|
||||||
|
result = check_ignore1(rules[parent], path)
|
||||||
|
if result != None:
|
||||||
|
return result
|
||||||
|
if parent == "":
|
||||||
|
break
|
||||||
|
parent = os.path.dirname(parent)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def check_ignore_absolute(rules, path):
|
||||||
|
parent = os.path.dirname(path)
|
||||||
|
for ruleset in rules:
|
||||||
|
result = check_ignore1(ruleset, path)
|
||||||
|
if result != None:
|
||||||
|
return result
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_ignore(rules, path):
|
||||||
|
if os.path.isabs(path):
|
||||||
|
raise Exception("This function requires path to be relative to the repository's root")
|
||||||
|
|
||||||
|
result = check_ignore_scoped(rules.scoped, path)
|
||||||
|
if result != None:
|
||||||
|
return result
|
||||||
|
|
||||||
|
return check_ignore_absolute(rules.absolute, path)
|
||||||
|
Loading…
Reference in New Issue
Block a user