-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanager.py
executable file
·143 lines (112 loc) · 4.17 KB
/
manager.py
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
#!/usr/bin/python
import curses
from multiprocessing import Manager
from queue import Queue
import subprocess
import threading
class TerminalWindow:
def __init__(self, parent_scr: curses.window, height: int, width: int, y: int, x: int, color: int, label: str) -> None:
self.width = width
self.height = height
self.color = color
self.label = label
self.is_first_line = True
self.win = parent_scr.subwin(height, width, y, x)
self.win.border()
self.contents = self.win.subpad(height - 2, width - 2, y + 1, x + 1)
self.contents.scrollok(True)
def print(self, str: str):
str = str.strip()
if not self.is_first_line:
self.contents.addch('\n')
self.contents.addch("[")
self.contents.addstr(self.label, curses.color_pair(self.color))
self.contents.addch("]")
self.contents.addch(" ")
self.contents.addstr(str)
self.is_first_line = False
def refresh(self):
self.contents.refresh()
class ProjectRunner:
def __init__(self, target) -> None:
self.output: Queue[str] = Manager().Queue()
self.target = target
self.built = False
self.started = False
def build(self):
self.built = False
def start_build(o: ProjectRunner, queue: Queue[str]):
queue.put("Starting build..", False)
subprocess.run(f"cargo build --quiet", cwd=o.target,
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
o.built = True
queue.put("Build finished!", False)
self.build_t = threading.Thread(
target=start_build, args=(self, self.output))
self.build_t.daemon = True
self.build_t.start()
def start(self):
if not self.built:
raise ValueError("Not yet built!")
self.proc = subprocess.Popen(f"target/debug/{self.target}", cwd=self.target, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
self.started = True
def output_reader(queue: Queue[str], proc: subprocess.Popen[str]):
while True:
line = proc.stdout.readline()
if line:
queue.put(line, False)
self.t = threading.Thread(
target=output_reader, args=(self.output, self.proc))
self.t.daemon = True
self.t.start()
def terminate(self):
self.proc.terminate()
self.started = False
def __del__(self):
self.terminate()
def rebuild(self):
self.terminate()
self.build()
class ProjectManager:
def __init__(self, parent_scr: curses.window, height: int, width: int, y: int, x: int, color: int, label: str, target) -> None:
self.win = TerminalWindow(
parent_scr, height, width, y, x, color, label)
self.proc = ProjectRunner(target)
self.proc.build()
def draw(self):
if self.proc.built and not self.proc.started:
self.proc.start()
try:
self.win.print(f"Value: {self.proc.output.get(False)}")
except:
pass
self.win.refresh()
def main(stdscr: curses.window):
curses.curs_set(0)
stdscr.clear()
stdscr.border()
stdscr.nodelay(True)
curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)
[height, width] = stdscr.getmaxyx()
term_width = (width - 2) // 2
azusa = ProjectManager(stdscr, height - 3, term_width,
y=1, x=1, color=1, label="Azusa", target="azusa")
api = ProjectManager(stdscr, height - 3, term_width,
y=1, x=term_width + 1, color=3, label="API", target="api")
while(True):
try:
ch = stdscr.getkey()
if ch == 'q':
break
elif ch == 'w':
api.proc.rebuild()
elif ch == 'a':
azusa.proc.rebuild()
except:
pass
azusa.draw()
api.draw()
curses.wrapper(main)