c2e 1.dev10__tar.gz → 1.dev12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: c2e
3
- Version: 1.dev10
3
+ Version: 1.dev12
4
4
  Summary: C2E: Console Command Engine
5
5
  Author: iFamished
6
6
  License: GPL-3.0
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "c2e"
10
- version = "1-dev.10"
10
+ version = "1-dev.12"
11
11
  description = "C2E: Console Command Engine"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.14"
@@ -0,0 +1,182 @@
1
+ from mapres import res
2
+ from .dsl import COMMANDS, parse_line, help_command, help_child, help_arg
3
+
4
+
5
+ def help_cmd_arg(cmd, meta):
6
+ lines = []
7
+ a = meta.name
8
+ lines.append(res(f'<bold><aqua>{a}<reset>: <gray>Retrieve and print the {a} of the server<reset>'))
9
+
10
+ u = res(f'<aqua>Usage:<reset> <gold>{cmd.name}<reset> <aqua>{a}<reset>')
11
+ req = []
12
+ opt = []
13
+
14
+ for pn in meta.params:
15
+ ps = cmd.params.get(pn)
16
+ t = ps.type_.__name__ if ps else 'str'
17
+ if pn in meta.required_params:
18
+ req.append(res(f'<dark_gray>\\<<reset>{pn}:{t}<dark_gray>\\><reset>'))
19
+ else:
20
+ opt.append(res(f'<dark_gray>[<reset>{pn}:{t}<dark_gray>]<reset>'))
21
+
22
+ if req:
23
+ u += ' ' + ' '.join(req)
24
+ if opt:
25
+ u += ' ' + ' '.join(opt)
26
+ if meta.flags:
27
+ u += res(' <dark_gray>[<reset>--flags<dark_gray>]<reset>')
28
+ lines.append(u)
29
+
30
+ if meta.params:
31
+ lines.append('')
32
+ lines.append(res('\0 <light_purple>Params:<reset>'))
33
+ for pn in meta.params:
34
+ ps = cmd.params.get(pn)
35
+ if not ps:
36
+ continue
37
+ t = ps.type_.__name__
38
+ d = ps.desc or 'No description'
39
+ lines.append(
40
+ res(f'\0 <blue>{pn}<reset> (type=<gold>{t}<reset>, default=<gray>{ps.default}<reset>): <gray>{d}<reset>')
41
+ )
42
+
43
+ if meta.flags:
44
+ lines.append('')
45
+ lines.append(res('\0 <light_purple>Flags:<reset>'))
46
+ for fn in meta.flags:
47
+ fs = cmd.flags.get(fn)
48
+ if not fs:
49
+ continue
50
+ d = fs.desc or 'No description'
51
+ lines.append(res(f'\0 <blue>--{fn}<reset>: <gray>{d}<reset>'))
52
+
53
+ return '\n'.join(lines)
54
+
55
+
56
+ def dispatch(cli, line):
57
+ p = parse_line(line)
58
+ if not p.sub:
59
+ return
60
+
61
+ cmd = COMMANDS.get(p.sub)
62
+ if not cmd:
63
+ return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown command {p.sub}<reset>'))
64
+
65
+ # top-level help (no args)
66
+ if 'help' in p.flags and not p.pos:
67
+ return cli.safePrint(help_command(cmd))
68
+
69
+ # ------------------------------------------------------------
70
+ # CASE 1: command has children → existing child logic
71
+ # ------------------------------------------------------------
72
+ if cmd.children:
73
+ if not p.pos:
74
+ return cli.safePrint(res('<red>Error:<reset> <gray>Missing subcommand<reset>'))
75
+
76
+ cname = p.pos[0]
77
+ child = cmd.children.get(cname)
78
+ if not child:
79
+ return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown subcommand {cname}<reset>'))
80
+
81
+ if 'help' in p.flags and len(p.pos) == 1:
82
+ return cli.safePrint(help_child(child))
83
+
84
+ if 'help' in p.flags and len(p.pos) >= 2:
85
+ an = p.pos[1]
86
+ meta = child.args_meta.get(an)
87
+ if not meta:
88
+ return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown argument {an}<reset>'))
89
+ return cli.safePrint(help_arg(child, meta))
90
+
91
+ arg = p.pos[1] if len(p.pos) > 1 else None
92
+ if child.requires_arg and arg is None:
93
+ return cli.safePrint(
94
+ res(f'<red>Error:<reset> <gray>Subcommand {child.name} requires an argument<reset>')
95
+ )
96
+
97
+ g = child.func.__globals__
98
+
99
+ for n, ps in child.params.items():
100
+ if n in p.params:
101
+ try:
102
+ v = ps.type_(p.params[n])
103
+ except Exception:
104
+ v = ps.default
105
+ else:
106
+ v = ps.default
107
+
108
+ def wrap(f=ps.func, val=v):
109
+ def w():
110
+ return f(val)
111
+ return w
112
+
113
+ g[n] = wrap()
114
+
115
+ for n, fs in child.flags.items():
116
+ present = n in p.flags
117
+
118
+ def wrap(f=fs.func, pr=present):
119
+ def w():
120
+ return pr
121
+ return w
122
+
123
+ g[n] = wrap()
124
+
125
+ f = child.func
126
+ if f.__code__.co_argcount >= 2:
127
+ return f(cli, arg)
128
+ return f(cli)
129
+
130
+ # ------------------------------------------------------------
131
+ # CASE 2: command has NO children → treat like child
132
+ # ------------------------------------------------------------
133
+ arg = p.pos[0] if p.pos else None
134
+
135
+ # arg-level help for top-level commands
136
+ if 'help' in p.flags and arg is not None:
137
+ meta = cmd.args_meta.get(arg)
138
+ if not meta:
139
+ return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown argument {arg}<reset>'))
140
+ return cli.safePrint(help_cmd_arg(cmd, meta))
141
+
142
+ # command-level help (no arg)
143
+ if 'help' in p.flags and arg is None:
144
+ return cli.safePrint(help_command(cmd))
145
+
146
+ if cmd.requires_arg and arg is None:
147
+ return cli.safePrint(
148
+ res(f'<red>Error:<reset> <gray>Command {cmd.name} requires an argument<reset>')
149
+ )
150
+
151
+ g = cmd.func.__globals__
152
+
153
+ for n, ps in cmd.params.items():
154
+ if n in p.params:
155
+ try:
156
+ v = ps.type_(p.params[n])
157
+ except Exception:
158
+ v = ps.default
159
+ else:
160
+ v = ps.default
161
+
162
+ def wrap(f=ps.func, val=v):
163
+ def w():
164
+ return f(val)
165
+ return w
166
+
167
+ g[n] = wrap()
168
+
169
+ for n, fs in cmd.flags.items():
170
+ present = n in p.flags
171
+
172
+ def wrap(f=fs.func, pr=present):
173
+ def w():
174
+ return pr
175
+ return w
176
+
177
+ g[n] = wrap()
178
+
179
+ f = cmd.func
180
+ if f.__code__.co_argcount >= 2:
181
+ return f(cli, arg)
182
+ return f(cli)
@@ -48,16 +48,10 @@ class BaseSpec:
48
48
  self._parse_args_meta()
49
49
  self._infer_arg_requirement()
50
50
 
51
- # ------------------------------
52
- # Docstring extraction
53
- # ------------------------------
54
51
  def _doc(self, f):
55
52
  d = f.__doc__
56
53
  return d.strip().splitlines()[0].strip() if d else None
57
54
 
58
- # ------------------------------
59
- # __args__ block extraction
60
- # ------------------------------
61
55
  def _extract_args_block(self):
62
56
  src = inspect.getsource(self.func)
63
57
  lines = src.splitlines()
@@ -81,9 +75,6 @@ class BaseSpec:
81
75
  raw = '\n'.join(l.strip() for l in block)
82
76
  setattr(self.func, '__args__', raw)
83
77
 
84
- # ------------------------------
85
- # Parse __args__ metadata
86
- # ------------------------------
87
78
  def _parse_args_meta(self):
88
79
  raw = getattr(self.func, '__args__', None)
89
80
  if not raw:
@@ -125,9 +116,6 @@ class BaseSpec:
125
116
 
126
117
  self.args_meta[arg] = ArgMeta(arg, params, flags, req_p, req_f)
127
118
 
128
- # ------------------------------
129
- # Infer required/optional positional arg
130
- # ------------------------------
131
119
  def _infer_arg_requirement(self):
132
120
  sig = inspect.signature(self.func)
133
121
  ps = list(sig.parameters.values())
@@ -147,9 +135,6 @@ class BaseSpec:
147
135
  self.requires_arg = False
148
136
  self.optional_arg = False
149
137
 
150
- # ------------------------------
151
- # Param decorator
152
- # ------------------------------
153
138
  def param(self, name, type=str, default=None):
154
139
  def deco(f):
155
140
  py = name.replace('-', '_')
@@ -158,9 +143,6 @@ class BaseSpec:
158
143
  return f
159
144
  return deco
160
145
 
161
- # ------------------------------
162
- # Flag decorator
163
- # ------------------------------
164
146
  def flag(self, name):
165
147
  def deco(f):
166
148
  py = name.replace('-', '_')
@@ -170,10 +152,6 @@ class BaseSpec:
170
152
  return deco
171
153
 
172
154
 
173
- # ------------------------------------------------------------
174
- # ChildSpec (inherits BaseSpec)
175
- # ------------------------------------------------------------
176
-
177
155
  class ChildSpec(BaseSpec):
178
156
  def __init__(self, parent, name, func):
179
157
  self.parent = parent
@@ -181,10 +159,6 @@ class ChildSpec(BaseSpec):
181
159
  super().__init__(func)
182
160
 
183
161
 
184
- # ------------------------------------------------------------
185
- # CommandSpec (inherits BaseSpec)
186
- # ------------------------------------------------------------
187
-
188
162
  class CommandSpec(BaseSpec):
189
163
  def __init__(self, name, func, namespace=False):
190
164
  self.name = name
@@ -201,10 +175,6 @@ class CommandSpec(BaseSpec):
201
175
  return deco
202
176
 
203
177
 
204
- # ------------------------------------------------------------
205
- # DSL entry point
206
- # ------------------------------------------------------------
207
-
208
178
  class CommandDSL:
209
179
  def __call__(self, name, namespace=False):
210
180
  def deco(f):
@@ -216,10 +186,6 @@ class CommandDSL:
216
186
  command = CommandDSL()
217
187
 
218
188
 
219
- # ------------------------------------------------------------
220
- # ParsedArgs structure
221
- # ------------------------------------------------------------
222
-
223
189
  @dataclass
224
190
  class ParsedArgs:
225
191
  sub: str | None
@@ -228,10 +194,6 @@ class ParsedArgs:
228
194
  params: dict[str, str]
229
195
 
230
196
 
231
- # ------------------------------------------------------------
232
- # Line parser
233
- # ------------------------------------------------------------
234
-
235
197
  def parse_line(raw):
236
198
  raw = raw.strip()
237
199
  if not raw:
@@ -255,15 +217,12 @@ def parse_line(raw):
255
217
  return ParsedArgs(sub, pos, flags, params)
256
218
 
257
219
 
258
- # ------------------------------------------------------------
259
- # Help generation (unchanged)
260
- # ------------------------------------------------------------
261
-
262
220
  def help_command(cmd):
263
221
  lines = []
264
222
  d = cmd.desc or 'No description'
265
223
  lines.append(res(f'<bold><yellow>{cmd.name}<reset>: <gray>{d}<reset>'))
266
224
 
225
+ # Usage
267
226
  if cmd.children:
268
227
  if cmd.is_namespace:
269
228
  u = res(f'<aqua>Usage:<reset> <gold>{cmd.name}<reset> <dark_gray>\\<<reset>child<dark_gray>\\><reset>')
@@ -271,12 +230,38 @@ def help_command(cmd):
271
230
  u = res(f'<aqua>Usage:<reset> <gold>{cmd.name}<reset> <dark_gray>[<reset>child<dark_gray>]<reset>')
272
231
  else:
273
232
  u = res(f'<aqua>Usage:<reset> <gold>{cmd.name}<reset>')
233
+ if cmd.args_meta:
234
+ u += res(' <dark_gray>\\<<reset>arg<dark_gray>\\><reset>')
235
+ if cmd.params:
236
+ u += res(' <dark_gray>[<reset>params<dark_gray>]<reset>')
237
+ if cmd.flags:
238
+ u += res(' <dark_gray>[<reset>--flags<dark_gray>]<reset>')
239
+ lines.append(u)
274
240
 
275
- if cmd.flags:
276
- u += res(' <dark_gray>[<reset>--flags<dark_gray>]<reset>')
241
+ # Args (for commands without children)
242
+ if cmd.args_meta:
243
+ lines.append('')
244
+ lines.append(res('\0 <light_purple>Args:<reset>'))
245
+ for a, m in cmd.args_meta.items():
246
+ parts = [res(f'<green>{a}<reset>')]
247
+ for pn in m.params:
248
+ parts.append(res(f'<dark_gray>[<reset>{pn}<dark_gray>]<reset>'))
249
+ for fn in m.flags:
250
+ parts.append(res(f'<dark_gray>[<reset>--{fn}<dark_gray>]<reset>'))
251
+ lines.append('\0 ' + ' '.join(parts))
277
252
 
278
- lines.append(u)
253
+ # Params
254
+ if cmd.params:
255
+ lines.append('')
256
+ lines.append(res('\0 <light_purple>Params:<reset>'))
257
+ for n, ps in cmd.params.items():
258
+ t = ps.type_.__name__
259
+ d = ps.desc or 'No description'
260
+ lines.append(
261
+ res(f'\0 <blue>{n}<reset> (type=<gold>{t}<reset>, default=<gray>{ps.default}<reset>): <gray>{d}<reset>')
262
+ )
279
263
 
264
+ # Flags
280
265
  if cmd.flags:
281
266
  lines.append('')
282
267
  lines.append(res('\0 <light_purple>Flags:<reset>'))
@@ -284,6 +269,7 @@ def help_command(cmd):
284
269
  d = fs.desc or 'No description'
285
270
  lines.append(res(f'\0 <blue>--{fs.name}<reset>: <gray>{d}<reset>'))
286
271
 
272
+ # Children
287
273
  if cmd.children:
288
274
  lines.append('')
289
275
  lines.append(res('\0 <light_purple>Children:<reset>'))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: c2e
3
- Version: 1.dev10
3
+ Version: 1.dev12
4
4
  Summary: C2E: Console Command Engine
5
5
  Author: iFamished
6
6
  License: GPL-3.0
@@ -1,72 +0,0 @@
1
- from mapres import res
2
- from .dsl import COMMANDS, parse_line, help_command, help_child, help_arg
3
-
4
-
5
- def dispatch(cli, line):
6
- p = parse_line(line)
7
- if not p.sub:
8
- return
9
-
10
- cmd = COMMANDS.get(p.sub)
11
- if not cmd:
12
- return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown command {p.sub}<reset>'))
13
-
14
- if 'help' in p.flags and not p.pos:
15
- return cli.safePrint(help_command(cmd))
16
-
17
- if cmd.children:
18
- if not p.pos:
19
- return cli.safePrint(res('<red>Error:<reset> <gray>Missing subcommand<reset>'))
20
- else:
21
- return cmd.func(cli)
22
-
23
- cname = p.pos[0]
24
- child = cmd.children.get(cname)
25
- if not child:
26
- return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown subcommand {cname}<reset>'))
27
-
28
- if 'help' in p.flags and len(p.pos) == 1:
29
- return cli.safePrint(help_child(child))
30
-
31
- if 'help' in p.flags and len(p.pos) >= 2:
32
- an = p.pos[1]
33
- meta = child.args_meta.get(an)
34
- if not meta:
35
- return cli.safePrint(res(f'<red>Error:<reset> <gray>Unknown argument {an}<reset>'))
36
- return cli.safePrint(help_arg(child, meta))
37
-
38
- arg = p.pos[1] if len(p.pos) > 1 else None
39
- if child.requires_arg and arg is None:
40
- return cli.safePrint(res(f'<red>Error:<reset> <gray>Subcommand {child.name} requires an argument<reset>'))
41
-
42
- g = child.func.__globals__
43
- for n, ps in child.params.items():
44
- if n in p.params:
45
- try:
46
- v = ps.type_(p.params[n])
47
- except:
48
- v = ps.default
49
- else:
50
- v = ps.default
51
-
52
- def wrap(f=ps.func, val=v):
53
- def w():
54
- return f(val)
55
- return w
56
-
57
- g[n] = wrap()
58
-
59
- for n, fs in child.flags.items():
60
- present = n in p.flags
61
-
62
- def wrap(f=fs.func, pr=present):
63
- def w():
64
- return pr
65
- return w
66
-
67
- g[n] = wrap()
68
-
69
- f = child.func
70
- if f.__code__.co_argcount >= 2:
71
- return f(cli, arg)
72
- return f(cli)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes