ethspecify 0.2.1__tar.gz → 0.2.2__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.
- {ethspecify-0.2.1 → ethspecify-0.2.2}/PKG-INFO +1 -1
- ethspecify-0.2.2/ethspecify/cli.py +168 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify/core.py +146 -6
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/PKG-INFO +1 -1
- {ethspecify-0.2.1 → ethspecify-0.2.2}/setup.py +1 -1
- ethspecify-0.2.1/ethspecify/cli.py +0 -205
- {ethspecify-0.2.1 → ethspecify-0.2.2}/LICENSE +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/README.md +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify/__init__.py +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/SOURCES.txt +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/dependency_links.txt +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/entry_points.txt +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/requires.txt +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/ethspecify.egg-info/top_level.txt +0 -0
- {ethspecify-0.2.1 → ethspecify-0.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from .core import grep, replace_spec_tags, get_pyspec, get_latest_fork, get_spec_item_history
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def process(args):
|
|
10
|
+
"""Process all spec tags."""
|
|
11
|
+
project_dir = os.path.abspath(os.path.expanduser(args.path))
|
|
12
|
+
if not os.path.isdir(project_dir):
|
|
13
|
+
print(f"Error: The directory {repr(project_dir)} does not exist.")
|
|
14
|
+
return 1
|
|
15
|
+
|
|
16
|
+
for f in grep(project_dir, r"<spec\b.*?>", args.exclude):
|
|
17
|
+
print(f"Processing file: {f}")
|
|
18
|
+
replace_spec_tags(f)
|
|
19
|
+
|
|
20
|
+
return 0
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def list_tags(args):
|
|
24
|
+
"""List all available tags with their fork history."""
|
|
25
|
+
preset = getattr(args, 'preset', 'mainnet')
|
|
26
|
+
return _list_tags_with_history(args, preset)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _list_tags_with_history(args, preset):
|
|
30
|
+
"""List all tags with their fork history."""
|
|
31
|
+
try:
|
|
32
|
+
history = get_spec_item_history(preset)
|
|
33
|
+
except ValueError as e:
|
|
34
|
+
print(f"Error: {e}")
|
|
35
|
+
return 1
|
|
36
|
+
|
|
37
|
+
if args.format == "json":
|
|
38
|
+
result = {
|
|
39
|
+
"preset": preset,
|
|
40
|
+
"mode": "history",
|
|
41
|
+
"history": history
|
|
42
|
+
}
|
|
43
|
+
print(json.dumps(result, indent=2))
|
|
44
|
+
else:
|
|
45
|
+
print(f"Available tags across all forks ({preset} preset):")
|
|
46
|
+
|
|
47
|
+
def _print_items_with_history(category_name, items_dict, spec_attr):
|
|
48
|
+
"""Helper to print items with their fork history."""
|
|
49
|
+
if not items_dict:
|
|
50
|
+
return
|
|
51
|
+
print(f"\n{category_name}:")
|
|
52
|
+
for item_name in sorted(items_dict.keys()):
|
|
53
|
+
if args.search is None or args.search.lower() in item_name.lower():
|
|
54
|
+
forks = items_dict[item_name]
|
|
55
|
+
fork_list = ", ".join(forks)
|
|
56
|
+
print(f" <spec {spec_attr}=\"{item_name}\" /> ({fork_list})")
|
|
57
|
+
|
|
58
|
+
_print_items_with_history("Functions", history['functions'], "fn")
|
|
59
|
+
_print_items_with_history("Constants", history['constant_vars'], "constant_var")
|
|
60
|
+
_print_items_with_history("Custom Types", history['custom_types'], "custom_type")
|
|
61
|
+
_print_items_with_history("SSZ Objects", history['ssz_objects'], "ssz_object")
|
|
62
|
+
_print_items_with_history("Dataclasses", history['dataclasses'], "dataclass")
|
|
63
|
+
_print_items_with_history("Preset Variables", history['preset_vars'], "preset_var")
|
|
64
|
+
_print_items_with_history("Config Variables", history['config_vars'], "config_var")
|
|
65
|
+
|
|
66
|
+
return 0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def list_forks(args):
|
|
72
|
+
"""List all available forks."""
|
|
73
|
+
pyspec = get_pyspec()
|
|
74
|
+
preset = args.preset
|
|
75
|
+
|
|
76
|
+
if preset not in pyspec:
|
|
77
|
+
print(f"Error: Preset '{preset}' not found.")
|
|
78
|
+
print(f"Available presets: {', '.join(pyspec.keys())}")
|
|
79
|
+
return 1
|
|
80
|
+
|
|
81
|
+
# Filter out EIP forks
|
|
82
|
+
forks = sorted(
|
|
83
|
+
[fork for fork in pyspec[preset].keys() if not fork.startswith("eip")],
|
|
84
|
+
key=lambda x: (x != "phase0", x)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if args.format == "json":
|
|
88
|
+
result = {
|
|
89
|
+
"preset": preset,
|
|
90
|
+
"forks": forks
|
|
91
|
+
}
|
|
92
|
+
print(json.dumps(result, indent=2))
|
|
93
|
+
else:
|
|
94
|
+
print(f"Available forks for {preset} preset:")
|
|
95
|
+
for fork in forks:
|
|
96
|
+
print(f" {fork}")
|
|
97
|
+
|
|
98
|
+
return 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def main():
|
|
102
|
+
parser = argparse.ArgumentParser(
|
|
103
|
+
description="Process files containing <spec> tags."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Create subparsers for different commands
|
|
107
|
+
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
|
108
|
+
|
|
109
|
+
# Parser for 'process' command
|
|
110
|
+
process_parser = subparsers.add_parser("process", help="Process spec tags in files")
|
|
111
|
+
process_parser.set_defaults(func=process)
|
|
112
|
+
process_parser.add_argument(
|
|
113
|
+
"--path",
|
|
114
|
+
type=str,
|
|
115
|
+
help="Directory to search for files containing <spec> tags",
|
|
116
|
+
default=".",
|
|
117
|
+
)
|
|
118
|
+
process_parser.add_argument(
|
|
119
|
+
"--exclude",
|
|
120
|
+
action="append",
|
|
121
|
+
help="Exclude paths matching this regex",
|
|
122
|
+
default=[],
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Parser for 'list-tags' command
|
|
126
|
+
list_tags_parser = subparsers.add_parser("list-tags", help="List available specification tags with fork history")
|
|
127
|
+
list_tags_parser.set_defaults(func=list_tags)
|
|
128
|
+
list_tags_parser.add_argument(
|
|
129
|
+
"--format",
|
|
130
|
+
type=str,
|
|
131
|
+
choices=["text", "json"],
|
|
132
|
+
default="text",
|
|
133
|
+
help="Output format (text or json)",
|
|
134
|
+
)
|
|
135
|
+
list_tags_parser.add_argument(
|
|
136
|
+
"--search",
|
|
137
|
+
type=str,
|
|
138
|
+
help="Filter tags by search term",
|
|
139
|
+
default=None,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Parser for 'list-forks' command
|
|
143
|
+
list_forks_parser = subparsers.add_parser("list-forks", help="List available forks")
|
|
144
|
+
list_forks_parser.set_defaults(func=list_forks)
|
|
145
|
+
list_forks_parser.add_argument(
|
|
146
|
+
"--preset",
|
|
147
|
+
type=str,
|
|
148
|
+
help="Preset to use (mainnet or minimal)",
|
|
149
|
+
default="mainnet",
|
|
150
|
+
)
|
|
151
|
+
list_forks_parser.add_argument(
|
|
152
|
+
"--format",
|
|
153
|
+
type=str,
|
|
154
|
+
choices=["text", "json"],
|
|
155
|
+
default="text",
|
|
156
|
+
help="Output format (text or json)",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Default to 'process' if no args are provided
|
|
160
|
+
if len(sys.argv) == 1:
|
|
161
|
+
sys.argv.insert(1, "process")
|
|
162
|
+
|
|
163
|
+
args = parser.parse_args()
|
|
164
|
+
exit(args.func(args))
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__main__":
|
|
168
|
+
main()
|
|
@@ -107,7 +107,9 @@ def get_previous_forks(fork, version="nightly"):
|
|
|
107
107
|
if key != f"{fork.upper()}_FORK_VERSION":
|
|
108
108
|
if key != "GENESIS_FORK_VERSION":
|
|
109
109
|
f = key.split("_")[0].lower()
|
|
110
|
-
|
|
110
|
+
# Skip EIP forks
|
|
111
|
+
if not f.startswith("eip"):
|
|
112
|
+
previous_forks.append(f)
|
|
111
113
|
return list(reversed(previous_forks))
|
|
112
114
|
|
|
113
115
|
|
|
@@ -201,12 +203,150 @@ def get_latest_fork(version="nightly"):
|
|
|
201
203
|
"""A helper function to get the latest non-eip fork."""
|
|
202
204
|
pyspec = get_pyspec(version)
|
|
203
205
|
forks = sorted(
|
|
204
|
-
pyspec["mainnet"].keys(),
|
|
205
|
-
key=lambda x: (x != "phase0", x
|
|
206
|
+
[fork for fork in pyspec["mainnet"].keys() if not fork.startswith("eip")],
|
|
207
|
+
key=lambda x: (x != "phase0", x)
|
|
206
208
|
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
return forks[-1] if forks else "phase0"
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def get_spec_item_changes(fork, preset="mainnet", version="nightly"):
|
|
213
|
+
"""
|
|
214
|
+
Compare spec items in the given fork with previous forks to detect changes.
|
|
215
|
+
Returns dict with categories containing items marked as (new) or (modified).
|
|
216
|
+
"""
|
|
217
|
+
pyspec = get_pyspec(version)
|
|
218
|
+
if fork not in pyspec[preset]:
|
|
219
|
+
raise ValueError(f"Fork '{fork}' not found in {preset} preset")
|
|
220
|
+
|
|
221
|
+
current_fork_data = pyspec[preset][fork]
|
|
222
|
+
previous_forks = get_previous_forks(fork, version)
|
|
223
|
+
|
|
224
|
+
changes = {
|
|
225
|
+
'functions': {},
|
|
226
|
+
'constant_vars': {},
|
|
227
|
+
'custom_types': {},
|
|
228
|
+
'ssz_objects': {},
|
|
229
|
+
'dataclasses': {},
|
|
230
|
+
'preset_vars': {},
|
|
231
|
+
'config_vars': {},
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
# Check each category of spec items
|
|
235
|
+
for category in changes.keys():
|
|
236
|
+
if category not in current_fork_data:
|
|
237
|
+
continue
|
|
238
|
+
|
|
239
|
+
for item_name, item_content in current_fork_data[category].items():
|
|
240
|
+
status = _get_item_status(item_name, item_content, category, previous_forks, pyspec, preset)
|
|
241
|
+
if status:
|
|
242
|
+
changes[category][item_name] = status
|
|
243
|
+
|
|
244
|
+
return changes
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _get_item_status(item_name, current_content, category, previous_forks, pyspec, preset):
|
|
248
|
+
"""
|
|
249
|
+
Determine if an item is new or modified compared to previous forks.
|
|
250
|
+
Returns 'new', 'modified', or None if unchanged.
|
|
251
|
+
"""
|
|
252
|
+
# Check if item exists in any previous fork
|
|
253
|
+
found_in_previous = False
|
|
254
|
+
previous_content = None
|
|
255
|
+
|
|
256
|
+
for prev_fork in previous_forks:
|
|
257
|
+
if (prev_fork in pyspec[preset] and
|
|
258
|
+
category in pyspec[preset][prev_fork] and
|
|
259
|
+
item_name in pyspec[preset][prev_fork][category]):
|
|
260
|
+
|
|
261
|
+
found_in_previous = True
|
|
262
|
+
prev_content = pyspec[preset][prev_fork][category][item_name]
|
|
263
|
+
|
|
264
|
+
# Compare content with immediate previous version
|
|
265
|
+
if prev_content != current_content:
|
|
266
|
+
return "modified"
|
|
267
|
+
else:
|
|
268
|
+
# Found unchanged version, so this is not new or modified
|
|
269
|
+
return None
|
|
270
|
+
|
|
271
|
+
# If not found in any previous fork, it's new
|
|
272
|
+
if not found_in_previous:
|
|
273
|
+
return "new"
|
|
274
|
+
|
|
275
|
+
return None
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def get_spec_item_history(preset="mainnet", version="nightly"):
|
|
279
|
+
"""
|
|
280
|
+
Get the complete history of all spec items across all forks.
|
|
281
|
+
Returns dict with categories containing items and their fork history.
|
|
282
|
+
"""
|
|
283
|
+
pyspec = get_pyspec(version)
|
|
284
|
+
if preset not in pyspec:
|
|
285
|
+
raise ValueError(f"Preset '{preset}' not found")
|
|
286
|
+
|
|
287
|
+
# Get all forks in chronological order, excluding EIP forks
|
|
288
|
+
all_forks = sorted(
|
|
289
|
+
[fork for fork in pyspec[preset].keys() if not fork.startswith("eip")],
|
|
290
|
+
key=lambda x: (x != "phase0", x)
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
# Track all unique items across all forks
|
|
294
|
+
all_items = {
|
|
295
|
+
'functions': set(),
|
|
296
|
+
'constant_vars': set(),
|
|
297
|
+
'custom_types': set(),
|
|
298
|
+
'ssz_objects': set(),
|
|
299
|
+
'dataclasses': set(),
|
|
300
|
+
'preset_vars': set(),
|
|
301
|
+
'config_vars': set(),
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Collect all item names
|
|
305
|
+
for fork in all_forks:
|
|
306
|
+
if fork not in pyspec[preset]:
|
|
307
|
+
continue
|
|
308
|
+
fork_data = pyspec[preset][fork]
|
|
309
|
+
for category in all_items.keys():
|
|
310
|
+
if category in fork_data:
|
|
311
|
+
all_items[category].update(fork_data[category].keys())
|
|
312
|
+
|
|
313
|
+
# Build history for each item
|
|
314
|
+
history = {}
|
|
315
|
+
for category in all_items.keys():
|
|
316
|
+
history[category] = {}
|
|
317
|
+
for item_name in all_items[category]:
|
|
318
|
+
item_history = _trace_item_history(item_name, category, all_forks, pyspec, preset)
|
|
319
|
+
if item_history:
|
|
320
|
+
history[category][item_name] = item_history
|
|
321
|
+
|
|
322
|
+
return history
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def _trace_item_history(item_name, category, all_forks, pyspec, preset):
|
|
326
|
+
"""
|
|
327
|
+
Trace the history of a specific item across all forks.
|
|
328
|
+
Returns a list of forks where the item was introduced or modified.
|
|
329
|
+
"""
|
|
330
|
+
history_forks = []
|
|
331
|
+
previous_content = None
|
|
332
|
+
|
|
333
|
+
for fork in all_forks:
|
|
334
|
+
if (fork in pyspec[preset] and
|
|
335
|
+
category in pyspec[preset][fork] and
|
|
336
|
+
item_name in pyspec[preset][fork][category]):
|
|
337
|
+
|
|
338
|
+
current_content = pyspec[preset][fork][category][item_name]
|
|
339
|
+
|
|
340
|
+
if previous_content is None:
|
|
341
|
+
# First appearance
|
|
342
|
+
history_forks.append(fork)
|
|
343
|
+
elif current_content != previous_content:
|
|
344
|
+
# Content changed
|
|
345
|
+
history_forks.append(fork)
|
|
346
|
+
|
|
347
|
+
previous_content = current_content
|
|
348
|
+
|
|
349
|
+
return history_forks
|
|
210
350
|
|
|
211
351
|
def parse_common_attributes(attributes):
|
|
212
352
|
try:
|
|
@@ -8,7 +8,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name="ethspecify",
|
|
11
|
-
version="0.2.
|
|
11
|
+
version="0.2.2",
|
|
12
12
|
description="A utility for processing Ethereum specification tags.",
|
|
13
13
|
long_description=long_description,
|
|
14
14
|
long_description_content_type="text/markdown",
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
from .core import grep, replace_spec_tags, get_pyspec, get_latest_fork
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def process(args):
|
|
10
|
-
"""Process all spec tags."""
|
|
11
|
-
project_dir = os.path.abspath(os.path.expanduser(args.path))
|
|
12
|
-
if not os.path.isdir(project_dir):
|
|
13
|
-
print(f"Error: The directory {repr(project_dir)} does not exist.")
|
|
14
|
-
return 1
|
|
15
|
-
|
|
16
|
-
for f in grep(project_dir, r"<spec\b.*?>", args.exclude):
|
|
17
|
-
print(f"Processing file: {f}")
|
|
18
|
-
replace_spec_tags(f)
|
|
19
|
-
|
|
20
|
-
return 0
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def list_tags(args):
|
|
24
|
-
"""List all available tags for a specific fork and preset."""
|
|
25
|
-
# Get the specification data
|
|
26
|
-
pyspec = get_pyspec()
|
|
27
|
-
fork = args.fork
|
|
28
|
-
preset = args.preset
|
|
29
|
-
|
|
30
|
-
# Validate that the fork exists
|
|
31
|
-
if fork not in pyspec[preset]:
|
|
32
|
-
print(f"Error: Fork '{fork}' not found in {preset} preset")
|
|
33
|
-
available_forks = list(pyspec[preset].keys())
|
|
34
|
-
print(f"Available forks: {', '.join(available_forks)}")
|
|
35
|
-
return 1
|
|
36
|
-
|
|
37
|
-
# Format output based on requested format
|
|
38
|
-
if args.format == "json":
|
|
39
|
-
result = {
|
|
40
|
-
"fork": fork,
|
|
41
|
-
"preset": preset,
|
|
42
|
-
"tags": {
|
|
43
|
-
"functions": list(pyspec[preset][fork]['functions'].keys()),
|
|
44
|
-
"constant_vars": list(pyspec[preset][fork]['constant_vars'].keys()),
|
|
45
|
-
"custom_types": list(pyspec[preset][fork]['custom_types'].keys()),
|
|
46
|
-
"ssz_objects": list(pyspec[preset][fork]['ssz_objects'].keys()),
|
|
47
|
-
"dataclasses": list(pyspec[preset][fork]['dataclasses'].keys()),
|
|
48
|
-
"preset_vars": list(pyspec[preset][fork]['preset_vars'].keys()),
|
|
49
|
-
"config_vars": list(pyspec[preset][fork]['config_vars'].keys()),
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
print(json.dumps(result, indent=2))
|
|
53
|
-
else:
|
|
54
|
-
# Plain text output
|
|
55
|
-
print(f"Available tags for {fork} fork ({preset} preset):")
|
|
56
|
-
maybe_fork = f' fork="{fork}"' if fork != get_latest_fork() else ""
|
|
57
|
-
|
|
58
|
-
print("\nFunctions:")
|
|
59
|
-
for fn_name in sorted(pyspec[preset][fork]['functions'].keys()):
|
|
60
|
-
if args.search is None or args.search.lower() in fn_name.lower():
|
|
61
|
-
print(f" <spec fn=\"{fn_name}\"{maybe_fork} />")
|
|
62
|
-
|
|
63
|
-
print("\nConstants:")
|
|
64
|
-
for const_name in sorted(pyspec[preset][fork]['constant_vars'].keys()):
|
|
65
|
-
if args.search is None or args.search.lower() in const_name.lower():
|
|
66
|
-
print(f" <spec constant_var=\"{const_name}\"{maybe_fork} />")
|
|
67
|
-
|
|
68
|
-
print("\nCustom Types:")
|
|
69
|
-
for type_name in sorted(pyspec[preset][fork]['custom_types'].keys()):
|
|
70
|
-
if args.search is None or args.search.lower() in type_name.lower():
|
|
71
|
-
print(f" <spec custom_type=\"{type_name}\"{maybe_fork} />")
|
|
72
|
-
|
|
73
|
-
print("\nSSZ Objects:")
|
|
74
|
-
for obj_name in sorted(pyspec[preset][fork]['ssz_objects'].keys()):
|
|
75
|
-
if args.search is None or args.search.lower() in obj_name.lower():
|
|
76
|
-
print(f" <spec ssz_object=\"{obj_name}\"{maybe_fork} />")
|
|
77
|
-
|
|
78
|
-
print("\nDataclasses:")
|
|
79
|
-
for class_name in sorted(pyspec[preset][fork]['dataclasses'].keys()):
|
|
80
|
-
if args.search is None or args.search.lower() in class_name.lower():
|
|
81
|
-
print(f" <spec dataclass=\"{class_name}\"{maybe_fork} />")
|
|
82
|
-
|
|
83
|
-
print("\nPreset Variables:")
|
|
84
|
-
for var_name in sorted(pyspec[preset][fork]['preset_vars'].keys()):
|
|
85
|
-
if args.search is None or args.search.lower() in var_name.lower():
|
|
86
|
-
print(f" <spec preset_var=\"{var_name}\"{maybe_fork} />")
|
|
87
|
-
|
|
88
|
-
print("\nConfig Variables:")
|
|
89
|
-
for var_name in sorted(pyspec[preset][fork]['config_vars'].keys()):
|
|
90
|
-
if args.search is None or args.search.lower() in var_name.lower():
|
|
91
|
-
print(f" <spec config_var=\"{var_name}\"{maybe_fork} />")
|
|
92
|
-
|
|
93
|
-
return 0
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def list_forks(args):
|
|
97
|
-
"""List all available forks."""
|
|
98
|
-
pyspec = get_pyspec()
|
|
99
|
-
preset = args.preset
|
|
100
|
-
|
|
101
|
-
if preset not in pyspec:
|
|
102
|
-
print(f"Error: Preset '{preset}' not found.")
|
|
103
|
-
print(f"Available presets: {', '.join(pyspec.keys())}")
|
|
104
|
-
return 1
|
|
105
|
-
|
|
106
|
-
forks = sorted(
|
|
107
|
-
pyspec[preset].keys(),
|
|
108
|
-
# Put phase0 at the top & EIP feature forks at the bottom
|
|
109
|
-
key=lambda x: (x != "phase0", x.startswith("eip"), x)
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
if args.format == "json":
|
|
113
|
-
result = {
|
|
114
|
-
"preset": preset,
|
|
115
|
-
"forks": forks
|
|
116
|
-
}
|
|
117
|
-
print(json.dumps(result, indent=2))
|
|
118
|
-
else:
|
|
119
|
-
print(f"Available forks for {preset} preset:")
|
|
120
|
-
for fork in forks:
|
|
121
|
-
print(f" {fork}")
|
|
122
|
-
|
|
123
|
-
return 0
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def main():
|
|
127
|
-
parser = argparse.ArgumentParser(
|
|
128
|
-
description="Process files containing <spec> tags."
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
# Create subparsers for different commands
|
|
132
|
-
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
|
133
|
-
|
|
134
|
-
# Parser for 'process' command
|
|
135
|
-
process_parser = subparsers.add_parser("process", help="Process spec tags in files")
|
|
136
|
-
process_parser.set_defaults(func=process)
|
|
137
|
-
process_parser.add_argument(
|
|
138
|
-
"--path",
|
|
139
|
-
type=str,
|
|
140
|
-
help="Directory to search for files containing <spec> tags",
|
|
141
|
-
default=".",
|
|
142
|
-
)
|
|
143
|
-
process_parser.add_argument(
|
|
144
|
-
"--exclude",
|
|
145
|
-
action="append",
|
|
146
|
-
help="Exclude paths matching this regex",
|
|
147
|
-
default=[],
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
# Parser for 'list-tags' command
|
|
151
|
-
list_tags_parser = subparsers.add_parser("list-tags", help="List available specification tags")
|
|
152
|
-
list_tags_parser.set_defaults(func=list_tags)
|
|
153
|
-
list_tags_parser.add_argument(
|
|
154
|
-
"--fork",
|
|
155
|
-
type=str,
|
|
156
|
-
help="Fork to list tags for",
|
|
157
|
-
default=get_latest_fork(),
|
|
158
|
-
)
|
|
159
|
-
list_tags_parser.add_argument(
|
|
160
|
-
"--preset",
|
|
161
|
-
type=str,
|
|
162
|
-
help="Preset to use (mainnet or minimal)",
|
|
163
|
-
default="mainnet",
|
|
164
|
-
)
|
|
165
|
-
list_tags_parser.add_argument(
|
|
166
|
-
"--format",
|
|
167
|
-
type=str,
|
|
168
|
-
choices=["text", "json"],
|
|
169
|
-
default="text",
|
|
170
|
-
help="Output format (text or json)",
|
|
171
|
-
)
|
|
172
|
-
list_tags_parser.add_argument(
|
|
173
|
-
"--search",
|
|
174
|
-
type=str,
|
|
175
|
-
help="Filter tags by search term",
|
|
176
|
-
default=None,
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
# Parser for 'list-forks' command
|
|
180
|
-
list_forks_parser = subparsers.add_parser("list-forks", help="List available forks")
|
|
181
|
-
list_forks_parser.set_defaults(func=list_forks)
|
|
182
|
-
list_forks_parser.add_argument(
|
|
183
|
-
"--preset",
|
|
184
|
-
type=str,
|
|
185
|
-
help="Preset to use (mainnet or minimal)",
|
|
186
|
-
default="mainnet",
|
|
187
|
-
)
|
|
188
|
-
list_forks_parser.add_argument(
|
|
189
|
-
"--format",
|
|
190
|
-
type=str,
|
|
191
|
-
choices=["text", "json"],
|
|
192
|
-
default="text",
|
|
193
|
-
help="Output format (text or json)",
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
# Default to 'process' if no args are provided
|
|
197
|
-
if len(sys.argv) == 1:
|
|
198
|
-
sys.argv.insert(1, "process")
|
|
199
|
-
|
|
200
|
-
args = parser.parse_args()
|
|
201
|
-
exit(args.func(args))
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if __name__ == "__main__":
|
|
205
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|