-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplate
executable file
·163 lines (133 loc) · 5.01 KB
/
template
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/python3
import sys
import json
import subprocess
import os
from collections import namedtuple, defaultdict
from functools import partial
PROGRAM_NAME = "template"
AUTHOR = "Nic Hodlofski"
VERSION = "1.0"
BASE_URI = os.path.expanduser("~/.template")
CONFIG_FILE = "template.json"
COPY_DIRECTORY = "files"
SHELL = "bash"
class TemplateEngine:
def __init__(self, name, args):
self.name = name
self.args = args
self.dir = os.path.join(BASE_URI, self.name)
if not os.path.isdir(self.dir):
raise SystemExit(f"{self.name}: {self.dir} does not exist")
try:
with open(os.path.join(self.dir, CONFIG_FILE)) as f:
self.data = json.load(f)
except OSError:
raise SystemExit(f"{self.name}: template.json not found")
except json.decoder.JSONDecodeError:
raise SystemExit("{self.name}: template.json incorrectly formatted")
if "cwd" in self.data.keys():
self.cwd = os.path.expanduser(self.data["cwd"])
#attempt to make directory in case it doesn't exist
try:
os.makedirs(self.cwd, exist_ok=True)
except OSError:
raise SystemExit(f"{self.name}: could not find or create {self.cwd}")
except PermissionError:
raise SystemExit(
f"{self.name}: insufficient permission permissions to \
create {self.cwd}"
)
except FileExistsError:
raise SystemExit(f"{self.name}: {self.cwd} is a file, not a directory")
else:
self.cwd = "."
def _copy_files(self):
files_uri = os.path.join(self.dir, COPY_DIRECTORY)
if not os.path.isdir(files_uri):
return;
#make sure files directory isn't empty
def iterator_empty(i):
Sentinel = namedtuple('Sentinel', [])
return type(next(i, Sentinel())) is Sentinel
if iterator_empty(os.scandir(files_uri)):
return
command = " ".join(["cp", "-r", "-n", files_uri + "/*", self.cwd])
if subprocess.run(command, shell=True).returncode != 0:
raise SystemExit(f"{self.name}: file copy failed")
def _exec_shell(self):
if "shell" not in self.data.keys():
return
command = [SHELL, os.path.join(self.dir, self.data["shell"])] \
+ self.args
if subprocess.run(command, cwd=self.cwd).returncode != 0:
raise SystemExit(f"{self.name}: shell command failed")
def _config(self):
if "config" not in self.data.keys():
return
command = [os.path.join(self.dir, self.data["config"])] + self.args;
if subprocess.run(command, cwd=self.cwd).returncode != 0:
raise SystemExit(f"{self.name}: config script failed")
def new(self):
self._copy_files();
self._exec_shell();
self._config();
def new_command(sliced_argv):
name = sliced_argv[0]
args = sliced_argv[1:]
TemplateEngine(name, args).new()
def list_command(sliced_argv):
#check each subfolder for valid files/ and template.json
subfolders = [f for f in os.scandir(BASE_URI) if f.is_dir()]
templates = [
s.name for s in subfolders
if (COPY_DIRECTORY in (f.name for f in os.scandir(s.path) if f.is_dir()))
and (CONFIG_FILE in (f.name for f in os.scandir(s.path) if f.is_file()))
]
print("\n".join(templates))
def usage_command(sliced_argv, extended=False):
if extended:
print(
"""\
Usage: {0} [COMMAND] [ARGS...]
Generate content from templates.
Supported Commands:
new [NAME] [ARGS...] create new instance of template NAME
list list all installed templates
help display this help and exit
version output version information and exit
Examples:
template new cproj use the cproj template to generate a c project.
template new template f use the 'template' template to create a template
called f.
Extended documentation on templates: <http://github.com/macuser47/template>
If you're using this and you're not me, god help you.\
""".format(PROGRAM_NAME)
)
else:
print(
"""\
Usage: {0} [COMMAND] [ARGS]
Try '{0} help' for more information\
""".format(PROGRAM_NAME)
)
def version_command(sliced_argv):
print(
"""\
{} v{}
Written by {}\
""".format(PROGRAM_NAME, VERSION, AUTHOR)
)
if __name__ == "__main__":
if len(sys.argv) < 2:
usage_command([])
raise SystemExit
commands = defaultdict(lambda: partial(usage_command, extended=False))
commands["new"] = new_command
commands["list"] = list_command
commands["help"] = partial(usage_command, extended=True)
commands["version"] = version_command
sliced_argv = sys.argv[2:]
command = sys.argv[1]
commands[command](sliced_argv)
print("\nThank you for playing Wing Commander!")