summaryrefslogtreecommitdiff
path: root/lab/set_env.py
blob: c87fa48a2a96fa30bc52b6ba59343c79016696d3 (plain)
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
#!/usr/bin/env python3
#
# Run this like:
#
#   $ $(lab/set_env.py)
#

import functools
import glob
import itertools
import os
import re
import sys

pstderr = functools.partial(print, file=sys.stderr)

SETTINGS = []

line_pattern = r"\$set_env.py: (\w+) - (.*)"
globs = "*/*.py *.py"

filenames = itertools.chain.from_iterable(glob.glob(g) for g in globs.split())
files = 0
for filename in filenames:
    files += 1
    with open(filename) as f:
        for line in f:
            m = re.search(line_pattern, line)
            if m:
                SETTINGS.append(m.groups())
pstderr("Read {} files".format(files))


def read_them():
    values = {}
    for name, _ in SETTINGS:
        values[name] = os.environ.get(name)
    return values

def show_them(values):
    for i, (name, description) in enumerate(SETTINGS, start=1):
        value = values[name]
        if value is None:
            eq = ' '
            value = ''
        else:
            eq = '='
            value = repr(value)
        pstderr("{:2d}: {:>30s} {} {:12s}   {}".format(i, name, eq, value, description))

def set_by_num(values, n, value):
    setting_name = SETTINGS[int(n)-1][0]
    values[setting_name] = value

PROMPT = "(<N> val | x <N> | q) ::> "
def get_new_values(values):
    show = True
    while True:
        if show:
            show_them(values)
            show = False
            pstderr("")
        pstderr(PROMPT, end='')
        sys.stderr.flush()
        try:
            cmd = input("").strip().split()
        except EOFError:
            pstderr("\n")
            break
        if not cmd:
            continue
        if cmd[0] == 'q':
            break
        if cmd[0] == 'x':
            if len(cmd) < 2:
                pstderr("Need numbers of entries to delete")
                continue
            try:
                nums = map(int, cmd[1:])
            except ValueError:
                pstderr("Need numbers of entries to delete")
                continue
            else:
                for num in nums:
                    set_by_num(values, num, None)
        else:
            try:
                num = int(cmd[0])
            except ValueError:
                pstderr("Don't understand option {!r}".format(cmd[0]))
                continue
            else:
                if len(cmd) >= 2:
                    set_by_num(values, num, " ".join(cmd[1:]))
                else:
                    pstderr("Need a value to set")
                    continue
        show = True

    return values

def as_exports(values):
    exports = []
    for name, value in values.items():
        if value is None:
            exports.append("export -n {}".format(name))
        else:
            exports.append("export {}={!r}".format(name, value))
    return "eval " + "; ".join(exports)

print(as_exports(get_new_values(read_them())))