166 lines
5.5 KiB
Python
Executable File
166 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os, argparse, sys, csv, subprocess
|
|
|
|
|
|
def eprint(*all):
|
|
print(*all, file=sys.stderr)
|
|
|
|
|
|
STORAGE_LOC = os.environ['GIT_ME_STORE'] if 'GIT_ME_STORE' in os.environ else os.environ['HOME'] + '/.config/git-me'
|
|
|
|
eprint("git-me identity store: " + STORAGE_LOC)
|
|
|
|
STCOL_LEN = 3
|
|
STCOL_SLUG = 0
|
|
STCOL_NAME = 1
|
|
STCOL_EMAIL = 2
|
|
|
|
|
|
def add(args):
|
|
slug = args.slug.lower()
|
|
name = args.name
|
|
email = args.email
|
|
|
|
try:
|
|
with open(STORAGE_LOC, 'r') as fstore:
|
|
tsvin = csv.reader(fstore, delimiter='\t')
|
|
|
|
for row in tsvin:
|
|
if len(row) < STCOL_LEN:
|
|
continue
|
|
if row[STCOL_SLUG].lower() == slug:
|
|
eprint("An identity with that slug already exists!")
|
|
eprint(f" Slug: {row[STCOL_SLUG]}")
|
|
eprint(f" Name: {row[STCOL_NAME]}")
|
|
eprint(f" E-mail: {row[STCOL_EMAIL]}")
|
|
return False
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
# now add it
|
|
with open(STORAGE_LOC, 'a+') as fstore:
|
|
fstore.write(f"\n{slug}\t{name}\t{email}\n")
|
|
|
|
return True
|
|
|
|
|
|
def list_idents(args):
|
|
print("# Slug\t\tName\t\tE-mail Address")
|
|
with open(STORAGE_LOC, 'r') as fstore:
|
|
tsvin = csv.reader(fstore, delimiter='\t')
|
|
|
|
for row in tsvin:
|
|
if len(row) < STCOL_LEN:
|
|
continue
|
|
print(f"{row[STCOL_SLUG]}\t\t{row[STCOL_NAME]}\t\t{row[STCOL_EMAIL]}")
|
|
return True
|
|
|
|
|
|
def assert_hook(args):
|
|
result_name = subprocess.run(['git', 'config', '--local', '--get', 'user.name'], stdout=subprocess.PIPE)
|
|
so_name = result_name.stdout.decode().strip()
|
|
result_email = subprocess.run(['git', 'config', '--local', '--get', 'user.email'], stdout=subprocess.PIPE)
|
|
so_email = result_email.stdout.decode().strip()
|
|
|
|
if result_email.returncode + result_name.returncode > 0:
|
|
if result_name.returncode > 0:
|
|
eprint("git-me: No user.name specified!")
|
|
else:
|
|
eprint(f"git-me: user.name OK = {so_name}")
|
|
|
|
if result_email.returncode > 0:
|
|
eprint("git-me: No user.email specified!")
|
|
else:
|
|
eprint(f"git-me: user.email OK = {so_email}")
|
|
|
|
eprint("git-me: Either specify a config manually or use `git me use <id>`.")
|
|
return False
|
|
else:
|
|
eprint(f"git-me: OK. (user.name = {so_name}, user.email = {so_email})")
|
|
return True
|
|
|
|
|
|
def remove(args):
|
|
slug = args.idslug
|
|
os.rename(STORAGE_LOC, STORAGE_LOC + "~tmp")
|
|
|
|
with open(STORAGE_LOC + "~tmp", 'r') as tsvin, open(STORAGE_LOC, 'w') as tsvout:
|
|
tsvin = csv.reader(tsvin, delimiter='\t')
|
|
tsvout = csv.writer(tsvout, delimiter='\t')
|
|
|
|
for row in tsvin:
|
|
if len(row) < STCOL_LEN:
|
|
continue
|
|
if row[STCOL_SLUG].lower() == slug:
|
|
# delete; ignore
|
|
pass
|
|
else:
|
|
tsvout.writerow(row)
|
|
|
|
os.unlink(STORAGE_LOC + "~tmp")
|
|
return True
|
|
|
|
|
|
def switch_identity(args):
|
|
slug = args.idslug
|
|
with open(STORAGE_LOC, 'r') as fstore:
|
|
tsvin = csv.reader(fstore, delimiter='\t')
|
|
|
|
for row in tsvin:
|
|
if len(row) < STCOL_LEN:
|
|
continue
|
|
if row[STCOL_SLUG].lower() == slug:
|
|
proc_name = subprocess.run(["git", "config", "--local", "user.name", row[STCOL_NAME]])
|
|
if proc_name.returncode != 0:
|
|
eprint("git-me: Failed to set user.name! (non-zero exit code. Are you in a git repo?)")
|
|
return False
|
|
else:
|
|
proc_email = subprocess.run(["git", "config", "--local", "user.email", row[STCOL_EMAIL]])
|
|
if proc_name.returncode != 0:
|
|
eprint("git-me: Failed to set user.email! (non-zero exit code.)")
|
|
return False
|
|
return True
|
|
else:
|
|
eprint(f"git-me: Unable to find identity with {slug}")
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description='Manages repository identities. Environment variable GIT_ME_STORE can be used to override location of identity store.',
|
|
)
|
|
|
|
subparser = parser.add_subparsers(help='sub-command help', dest='cmd')
|
|
subparser.required = True
|
|
|
|
parser_assert = subparser.add_parser('assert', aliases=['check', 'hook', 'ck'])
|
|
parser_assert.set_defaults(func=assert_hook)
|
|
|
|
parser_add = subparser.add_parser('add', aliases=['mk'])
|
|
parser_add.add_argument('slug', type=str, help='A short, easy-to-type code to represent this id')
|
|
parser_add.add_argument('name', type=str, help='Your display name')
|
|
parser_add.add_argument('email', type=str, help='Your e-mail address')
|
|
parser_add.set_defaults(func=add)
|
|
|
|
parser_list = subparser.add_parser('list', aliases=['ls'])
|
|
parser_list.set_defaults(func=list_idents)
|
|
|
|
parser_remove = subparser.add_parser('remove', aliases=['rm'])
|
|
parser_remove.add_argument('idslug', type=str, help='The slug of the identity to remove.')
|
|
parser_remove.set_defaults(func=remove)
|
|
|
|
parser_switch = subparser.add_parser('use', aliases=['switch', 'choose', 'enable'])
|
|
parser_switch.add_argument('idslug', type=str, help='The slug of the identity to enable.')
|
|
parser_switch.set_defaults(func=switch_identity)
|
|
|
|
args = parser.parse_args(sys.argv[1:])
|
|
if 'func' in args:
|
|
if args.func(args):
|
|
exit(0)
|
|
else:
|
|
exit(1)
|
|
else:
|
|
print("git-me: Please specify a command!", file=sys.stderr)
|
|
exit(2)
|