ethspecify 0.2.4__py3-none-any.whl → 0.3.2__py3-none-any.whl

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/cli.py CHANGED
@@ -3,11 +3,11 @@ import json
3
3
  import os
4
4
  import sys
5
5
 
6
- from .core import grep, replace_spec_tags, get_pyspec, get_latest_fork, get_spec_item_history, load_config, run_checks
6
+ from .core import grep, replace_spec_tags, get_pyspec, get_latest_fork, get_spec_item_history, load_config, run_checks, sort_specref_yaml, generate_specref_files, get_yaml_filename_for_spec_attr, get_spec_attr_and_name, add_missing_entries_to_yaml
7
7
 
8
8
 
9
9
  def process(args):
10
- """Process all spec tags."""
10
+ """Process all spec tags and sort specref YAML files."""
11
11
  project_dir = os.path.abspath(os.path.expanduser(args.path))
12
12
  if not os.path.isdir(project_dir):
13
13
  print(f"Error: The directory {repr(project_dir)} does not exist.")
@@ -16,23 +16,57 @@ def process(args):
16
16
  # Load config once from the project directory
17
17
  config = load_config(project_dir)
18
18
 
19
+ # Check if auto_add_missing_entries and auto_standardize_names are enabled
20
+ specrefs_config = config.get('specrefs', {})
21
+ if isinstance(specrefs_config, dict):
22
+ auto_add_missing = specrefs_config.get('auto_add_missing_entries', False)
23
+ auto_standardize_names = specrefs_config.get('auto_standardize_names', False)
24
+ specrefs_files = specrefs_config.get('files', [])
25
+ elif isinstance(specrefs_config, list):
26
+ auto_add_missing = False
27
+ auto_standardize_names = False
28
+ specrefs_files = specrefs_config
29
+ else:
30
+ auto_add_missing = False
31
+ auto_standardize_names = False
32
+ specrefs_files = []
33
+
34
+ # Process spec tags in files
19
35
  for f in grep(project_dir, r"<spec\b.*?>", args.exclude):
20
36
  print(f"Processing file: {f}")
21
37
  replace_spec_tags(f, config)
22
38
 
39
+ # Add missing spec items to YAML files if enabled
40
+ if auto_add_missing:
41
+ from .core import add_missing_spec_items_to_yaml_files
42
+ add_missing_spec_items_to_yaml_files(project_dir, config, specrefs_files)
43
+
44
+ # Update entry names to <spec_item>#<fork> format if enabled
45
+ if auto_standardize_names:
46
+ from .core import update_entry_names_in_yaml_files
47
+ update_entry_names_in_yaml_files(project_dir, specrefs_files)
48
+
49
+ # Sort specref YAML files if they exist in config
50
+ for yaml_file in specrefs_files:
51
+ yaml_path = os.path.join(project_dir, yaml_file)
52
+ if os.path.exists(yaml_path):
53
+ if not sort_specref_yaml(yaml_path):
54
+ print(f"Error sorting: {yaml_file}")
55
+
23
56
  return 0
24
57
 
25
58
 
26
59
  def list_tags(args):
27
60
  """List all available tags with their fork history."""
28
61
  preset = getattr(args, 'preset', 'mainnet')
29
- return _list_tags_with_history(args, preset)
62
+ version = getattr(args, 'version', 'nightly')
63
+ return _list_tags_with_history(args, preset, version)
30
64
 
31
65
 
32
- def _list_tags_with_history(args, preset):
66
+ def _list_tags_with_history(args, preset, version):
33
67
  """List all tags with their fork history."""
34
68
  try:
35
- history = get_spec_item_history(preset)
69
+ history = get_spec_item_history(preset, version)
36
70
  except ValueError as e:
37
71
  print(f"Error: {e}")
38
72
  return 1
@@ -89,30 +123,36 @@ def check(args):
89
123
  total_source_files = {"valid": 0, "total": 0}
90
124
 
91
125
  for section_name, section_results in results.items():
92
- # Determine the type prefix from section name
93
- if "Config Variables" in section_name:
94
- type_prefix = "config_var"
95
- elif "Preset Variables" in section_name:
96
- type_prefix = "preset_var"
97
- elif "Ssz Objects" in section_name:
98
- type_prefix = "ssz_object"
99
- elif "Dataclasses" in section_name:
100
- type_prefix = "dataclass"
101
- else:
102
- type_prefix = section_name.lower().replace(" ", "_")
103
-
104
126
  # Collect source file errors
105
127
  source = section_results['source_files']
106
128
  total_source_files["valid"] += source["valid"]
107
129
  total_source_files["total"] += source["total"]
108
130
  all_errors.extend(source["errors"])
109
131
 
110
- # Collect missing items with type prefix
132
+ # Collect missing items
111
133
  coverage = section_results['coverage']
112
134
  total_coverage["found"] += coverage["found"]
113
135
  total_coverage["expected"] += coverage["expected"]
114
- for missing in coverage['missing']:
115
- all_missing.append(f"MISSING: {type_prefix}.{missing}")
136
+
137
+ # For Project Coverage, items already have the proper prefix
138
+ if section_name == "Project Coverage":
139
+ for missing in coverage['missing']:
140
+ all_missing.append(f"MISSING: {missing}")
141
+ else:
142
+ # Determine the type prefix from section name for YAML-based checks
143
+ if "Config Variables" in section_name:
144
+ type_prefix = "config_var"
145
+ elif "Preset Variables" in section_name:
146
+ type_prefix = "preset_var"
147
+ elif "Ssz Objects" in section_name:
148
+ type_prefix = "ssz_object"
149
+ elif "Dataclasses" in section_name:
150
+ type_prefix = "dataclass"
151
+ else:
152
+ type_prefix = section_name.lower().replace(" ", "_")
153
+
154
+ for missing in coverage['missing']:
155
+ all_missing.append(f"MISSING: {type_prefix}.{missing}")
116
156
 
117
157
  # Display only errors and missing items
118
158
  for error in all_errors:
@@ -159,6 +199,28 @@ def list_forks(args):
159
199
  return 0
160
200
 
161
201
 
202
+ def init(args):
203
+ """Initialize a specrefs directory with basic configuration and empty source mappings."""
204
+ output_dir = args.path or "specrefs"
205
+ version = args.version
206
+
207
+ # Check if output directory already exists
208
+ if os.path.exists(output_dir):
209
+ print(f"Error: directory {repr(output_dir)} already exists.")
210
+ print("Please specify a different directory or remove the existing one.")
211
+ return 1
212
+
213
+ try:
214
+ # Generate the specref files
215
+ print(f"Initializing specrefs directory: {version}")
216
+ generate_specref_files(output_dir, version, "mainnet")
217
+ print(f"Successfully created specrefs directory at: {output_dir}")
218
+ return 0
219
+ except Exception as e:
220
+ print(f"Error: {e}")
221
+ return 1
222
+
223
+
162
224
  def main():
163
225
  parser = argparse.ArgumentParser(
164
226
  description="Process files containing <spec> tags."
@@ -199,6 +261,12 @@ def main():
199
261
  help="Filter tags by search term",
200
262
  default=None,
201
263
  )
264
+ list_tags_parser.add_argument(
265
+ "--version",
266
+ type=str,
267
+ help="Specification version to use (default: nightly)",
268
+ default="nightly",
269
+ )
202
270
 
203
271
  # Parser for 'check' command
204
272
  check_parser = subparsers.add_parser("check", help="Check spec reference coverage and validity")
@@ -227,6 +295,21 @@ def main():
227
295
  help="Output format (text or json)",
228
296
  )
229
297
 
298
+ # Parser for 'init' command
299
+ init_parser = subparsers.add_parser("init", help="Initialize a specrefs directory")
300
+ init_parser.set_defaults(func=init)
301
+ init_parser.add_argument(
302
+ "version",
303
+ type=str,
304
+ help="Specification version (e.g., 'nightly' or 'v1.6.0-alpha.5')",
305
+ )
306
+ init_parser.add_argument(
307
+ "--path",
308
+ type=str,
309
+ help="Output directory for specrefs (default: specrefs)",
310
+ default="specrefs",
311
+ )
312
+
230
313
  # Default to 'process' if no args are provided
231
314
  if len(sys.argv) == 1:
232
315
  sys.argv.insert(1, "process")