@@ -235,25 +235,52 @@ jobs:
235235 # Create Python script to extract specs
236236 cat > /tmp/extract_specs.py << 'PYTHON_EOF'
237237 import re
238+ import sys
238239
239240 # Read the OpenSCAD file
240- with open('mechanical_design/openscad/lifetrac_v25.scad', 'r') as f:
241- content = f.read()
242-
243- # Extract key dimensions
244- def extract_value(pattern, content):
245- match = re.search(pattern, content)
246- if match:
247- return float(match.group(1))
248- return None
249-
250- MACHINE_WIDTH = extract_value(r'MACHINE_WIDTH\s*=\s*(\d+)', content)
251- MACHINE_LENGTH = extract_value(r'MACHINE_LENGTH\s*=\s*(\d+)', content)
252- MACHINE_HEIGHT = extract_value(r'MACHINE_HEIGHT\s*=\s*(\d+)', content)
253- WHEEL_DIAMETER = extract_value(r'WHEEL_DIAMETER\s*=\s*(\d+)', content)
254- GROUND_CLEARANCE = extract_value(r'GROUND_CLEARANCE\s*=\s*(\d+)', content)
255- HYDRAULIC_PRESSURE_PSI = extract_value(r'HYDRAULIC_PRESSURE_PSI\s*=\s*(\d+)', content)
256- LIFT_CYLINDER_BORE = extract_value(r'LIFT_CYLINDER_BORE\s*=\s*([\d.]+)', content)
241+ try:
242+ with open('mechanical_design/openscad/lifetrac_v25.scad', 'r') as f:
243+ content = f.read()
244+ except FileNotFoundError:
245+ print("ERROR: OpenSCAD file not found", file=sys.stderr)
246+ sys.exit(1)
247+
248+ # Extract key dimensions with error handling
249+ def extract_value(pattern, content, name):
250+ try:
251+ match = re.search(pattern, content)
252+ if match:
253+ return float(match.group(1))
254+ print(f"WARNING: Could not find {name} in OpenSCAD file", file=sys.stderr)
255+ return None
256+ except (ValueError, AttributeError) as e:
257+ print(f"ERROR: Failed to extract {name}: {e}", file=sys.stderr)
258+ return None
259+
260+ MACHINE_WIDTH = extract_value(r'MACHINE_WIDTH\s*=\s*(\d+)', content, 'MACHINE_WIDTH')
261+ MACHINE_LENGTH = extract_value(r'MACHINE_LENGTH\s*=\s*(\d+)', content, 'MACHINE_LENGTH')
262+ MACHINE_HEIGHT = extract_value(r'MACHINE_HEIGHT\s*=\s*(\d+)', content, 'MACHINE_HEIGHT')
263+ WHEEL_DIAMETER = extract_value(r'WHEEL_DIAMETER\s*=\s*(\d+)', content, 'WHEEL_DIAMETER')
264+ GROUND_CLEARANCE = extract_value(r'GROUND_CLEARANCE\s*=\s*(\d+)', content, 'GROUND_CLEARANCE')
265+ HYDRAULIC_PRESSURE_PSI = extract_value(r'HYDRAULIC_PRESSURE_PSI\s*=\s*(\d+)', content, 'HYDRAULIC_PRESSURE_PSI')
266+ LIFT_CYLINDER_BORE = extract_value(r'LIFT_CYLINDER_BORE\s*=\s*([\d.]+)', content, 'LIFT_CYLINDER_BORE')
267+
268+ # Validate that all required values were found
269+ required_values = {
270+ 'MACHINE_WIDTH': MACHINE_WIDTH,
271+ 'MACHINE_LENGTH': MACHINE_LENGTH,
272+ 'MACHINE_HEIGHT': MACHINE_HEIGHT,
273+ 'WHEEL_DIAMETER': WHEEL_DIAMETER,
274+ 'GROUND_CLEARANCE': GROUND_CLEARANCE,
275+ 'HYDRAULIC_PRESSURE_PSI': HYDRAULIC_PRESSURE_PSI,
276+ 'LIFT_CYLINDER_BORE': LIFT_CYLINDER_BORE
277+ }
278+
279+ missing_values = [k for k, v in required_values.items() if v is None]
280+ if missing_values:
281+ print(f"ERROR: Missing required values: {', '.join(missing_values)}", file=sys.stderr)
282+ print("Skipping README update to avoid breaking existing content", file=sys.stderr)
283+ sys.exit(0) # Exit gracefully without updating
257284
258285 # Conservative lift capacity estimate based on typical loader geometry
259286 ESTIMATED_LIFT_CAPACITY_KG = 1200
@@ -279,28 +306,62 @@ jobs:
279306 | **Drive Configuration** | All-wheel drive (4 hydraulic motors) |
280307 | **Cylinder Bore (Lift)** | {LIFT_CYLINDER_BORE} mm ({LIFT_CYLINDER_BORE/25.4:.1f}") |"""
281308
282- # Update the specs in README using regex
309+ # Update the specs in README using regex with validation
310+ original_readme = readme
311+
283312 # Update technical specifications table
284- readme = re.sub(
285- r'\| Specification \| Value \(mm\) \| Value \(inches\) \| Value \(meters\) \|.*?\n\| \*\*Wheel Diameter\*\* \|[^\n]+',
313+ updated_readme = re.sub(
314+ r'( \| Specification \| Value \(mm\) \| Value \(inches\) \| Value \(meters\) \|.*?\n)( \| \*\*Wheel Diameter\*\* \|[^\n]+) ',
286315 specs_table,
287316 readme,
317+ count=1,
288318 flags=re.DOTALL
289319 )
290320
321+ if updated_readme == readme:
322+ print("WARNING: Technical specifications table pattern not found, trying alternative pattern", file=sys.stderr)
323+ # Try simpler pattern that looks for the table header
324+ pattern_start = readme.find('### Technical Specifications')
325+ if pattern_start != -1:
326+ # Find the end of the table
327+ table_start = readme.find('| Specification | Value (mm)', pattern_start)
328+ if table_start != -1:
329+ # Find next section header or blank line after table
330+ table_end = readme.find('\n\n###', table_start)
331+ if table_end == -1:
332+ table_end = readme.find('\n\n| Specification | Value |', table_start)
333+ if table_end != -1:
334+ # Extract table and replace
335+ old_table = readme[table_start:readme.find('\n', readme.rfind('|', table_start, table_end))+1]
336+ updated_readme = readme.replace(old_table, specs_table + '\n', 1)
337+
338+ readme = updated_readme
339+
291340 # Update performance specifications table
292- readme = re.sub(
293- r'### Performance Specifications\s*\n\n\| Specification \| Value \|.*?\n\| \*\*Cylinder Bore \(Lift\)\*\* \|[^\n]+',
341+ updated_readme = re.sub(
342+ r'( ### Performance Specifications\s*\n\n\| Specification \| Value \|.*?\n)( \| \*\*Cylinder Bore \(Lift\)\*\* \|[^\n]+) ',
294343 f'### Performance Specifications\n\n{perf_table}',
295344 readme,
345+ count=1,
296346 flags=re.DOTALL
297347 )
298348
299- # Write updated README
300- with open('README.md', 'w') as f:
301- f.write(readme)
302-
303- print("✓ README specifications updated successfully")
349+ if updated_readme == readme:
350+ print("WARNING: Performance specifications table pattern not found", file=sys.stderr)
351+ else:
352+ readme = updated_readme
353+
354+ # Only write if changes were made
355+ if readme != original_readme:
356+ try:
357+ with open('README.md', 'w') as f:
358+ f.write(readme)
359+ print("✓ README specifications updated successfully")
360+ except IOError as e:
361+ print(f"ERROR: Failed to write README: {e}", file=sys.stderr)
362+ sys.exit(1)
363+ else:
364+ print("INFO: No changes needed to README specifications")
304365 print(f" Width: {int(MACHINE_WIDTH)} mm")
305366 print(f" Length: {int(MACHINE_LENGTH)} mm")
306367 print(f" Height: {int(MACHINE_HEIGHT)} mm")
0 commit comments