-
Notifications
You must be signed in to change notification settings - Fork 2
/
clamp
executable file
·115 lines (101 loc) · 3.51 KB
/
clamp
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
#!/usr/bin/python3
# PYTHON_ARGCOMPLETE_OK
import json, argparse, os, sys
import re
import shlex
import pkg_resources
import readline
try:
import argcomplete
except:
pass
try:
__version__ = str(pkg_resources.require("clamp")[0].version)
except:
__version__ = "0.0.0"
def get_vars(searchstr):
#Find variables in the form $(-x=y) or just $(-x)
#Return a list of these vars with there default values in the form ((x,y), ...)
#I looked at soem existing templating engines but did not seem to do
#exactly what I needed, and this was easy enough....
sub = re.compile('\$\((\-\w+)=?([^\)\(]*)\)')
subvars = list(set(sub.findall(searchstr)))
return subvars
def var_replace(subvars, args, searchstr):
sub = re.compile('\$\(\-\w+=?[^\(\)]*\)')
for s in subvars:
replstr = ""
if s[1]:
replstr = '$(%s=%s)'%s
else:
replstr = '$(%s)'%s[0]
arg = None
try:
arg = args[s[0].split('-')[1]]
except:
pass
searchstr = searchstr.replace(replstr, arg if arg else s[1])
return searchstr
def write_config(commands, file_name=".clamp"):
with open(file_name, "w") as f:
f.write(json.dumps(commands, sort_keys=True, indent=4, separators=(',', ': ')))
def read_config(file_name=".clamp"):
try:
with open(file_name) as f:
commands = json.load(f)
except:
commands = {}
return commands
parser = argparse.ArgumentParser(description='CLAMP')
parser.add_argument('--version', action='version', version='%(prog)s '+__version__)
parser.add_argument('--set', help="Create a new command")
parser.add_argument('-r', action="store_true", help="Read command from stdin instead of command line, may be easier for quotes")
parser.add_argument('--list', action="store_true", help="List commands")
parser.add_argument('-n', action="store_true", help="Don't escape commands when listing")
choices = read_config().keys()
parser.add_argument('--delete', help="Delete command", choices=choices)
parser.add_argument('command', nargs=argparse.REMAINDER, choices=choices, help="user defined command: {%s}"%(','.join(choices)), metavar="command")
try:
argcomplete.autocomplete(parser)
except:
pass
args = parser.parse_args()
if args.set:
commands = read_config()
#Create a new command
if args.r:
command = input().rstrip("\n")
else:
command = ' '.join(args.command[1:])
commands[args.set] = command
write_config(commands)
elif args.list:
commands = read_config()
if commands:
print()
length = len(max(commands.keys()))
for k,v in commands.items():
print("%s:%s %s"%(k, ' '*(length-len(k) + 1),v if args.n else shlex.quote(v)))
print()
elif args.delete:
commands = read_config()
if args.delete in commands:
commands.pop(args.delete, None)
write_config(commands)
elif args.command:
#Look for an existing command to run
commands = read_config()
if args.command[0] in commands:
command = commands[args.command[0]]
parser = argparse.ArgumentParser(description=args.command[0])
cmd_args = get_vars(command)
for a in cmd_args:
parser.add_argument(a[0], default=a[1], required=False if a[1] else True)
sys.argv.pop(0)
try:
argcomplete.autocomplete(parser)
except:
pass
args = parser.parse_args()
command = var_replace(cmd_args, vars(args), command)
os.system(command)