-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgitignore
More file actions
executable file
·96 lines (81 loc) · 2.97 KB
/
gitignore
File metadata and controls
executable file
·96 lines (81 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
"""Select a gitignore for the current directory"""
from pathlib import Path
from shutil import copy
import subprocess
import sys
from tempfile import NamedTemporaryFile
try:
from appdirs import user_data_dir
GI_DIR = Path(user_data_dir("gitignore"))
except ImportError:
from os import getenv
GI_DIR = Path(f"{getenv('HOME')}/templates/gitignore")
def dir_yield(path: Path):
"""recursively yield from all directories in the gitignore repo"""
for entry in path.iterdir():
if entry.is_dir() and "git" not in entry.name:
yield from dir_yield(entry.resolve())
elif not entry.name.endswith(".gitignore"):
continue
yield entry.resolve()
def get_gitignores():
"""download the gitignore repository if it doesn't exist"""
try:
# HACK: this checks if the dir: doesn't exist OR exists and is empty
if not GI_DIR.exists() or (not GI_DIR.exists() and not any(GI_DIR.iterdir())):
GI_DIR.mkdir(parents=True)
print("Cloning gitignore repository...")
subprocess.run(
["git", "clone", "https://github.com/github/gitignore", GI_DIR],
check=True,
)
print(f"gitignores cloned to '{GI_DIR}'")
except PermissionError as err:
raise NotImplementedError from err
except subprocess.CalledProcessError as err:
raise NotImplementedError from err
def select_gitignore(options: dict[str, Path]) -> str:
"""interactively select a gitignore with fzf"""
tmpfile = NamedTemporaryFile(mode="w+")
chosen: str = ""
try:
# add options to file to pipe into fzf
with open(tmpfile.name, "w+", encoding="utf-8") as tmp:
for lang in options:
tmp.write(lang + "\n")
tmp.seek(0)
# decode the output to a string and strip the newline
chosen = (
subprocess.check_output(f"cat {tmpfile.name} | fzf +m -i", shell=True)
.decode(sys.stdout.encoding)
.strip()
)
except PermissionError as err:
raise NotImplementedError from err
except subprocess.CalledProcessError as err:
if not chosen:
sys.exit()
raise NotImplementedError from err
finally:
tmpfile.close()
return chosen
def main():
"""select a gitignore"""
# dict comprehension where key is the filename w/o gitignore and value is file path
get_gitignores()
gitignores: dict[str, Path] = {
f.name.replace(".gitignore", ""): f.resolve() for f in dir_yield(GI_DIR)
}
# use argument if one is provided, otherwise choose interactively
try:
chosen: str = sys.argv[1]
except IndexError:
chosen = select_gitignore(gitignores)
try:
copy(gitignores[chosen], "./.gitignore")
except KeyError:
print(f"'{chosen}' is not a valid gitignore type.")
sys.exit(1)
if __name__ == "__main__":
main()