|
40 | 40 | if os.path.exists("boards.local.txt"): |
41 | 41 | boards_local_txt = "boards.local.txt" |
42 | 42 | else: |
43 | | - sys.stderr.write("Error: --boards-local-txt option requires a path to boards.local.txt file\n") |
| 43 | + sys.stderr.write("Error: --boards-local-txt option requires a path to boards.local.txt file or to be present in current directory\n") |
44 | 44 | sys.exit(1) |
45 | 45 | else: |
46 | 46 | # get the boards.local.txt file from the command line |
@@ -450,6 +450,88 @@ def test_examples_in_folder(platform, folderpath): |
450 | 450 | success = 1 |
451 | 451 |
|
452 | 452 |
|
| 453 | +def install_boards_local_txt(core_fqbn, boards_local_txt): |
| 454 | + """Copies boards.local.txt to the appropriate folder for the given core_fqbn. |
| 455 | + :param str core_fqbn: The first two segments of fully qualified board |
| 456 | + name, vendor:architecture (e.g., "adafruit:samd"). |
| 457 | + :param str boards_local_txt: The path to the boards.local.txt file. |
| 458 | + """ |
| 459 | + try: |
| 460 | + local_app_data_dir = os.environ.get('HOME', '') |
| 461 | + data_dir = None |
| 462 | + if os.path.exists(os.path.join(local_app_data_dir, 'Arduino')): |
| 463 | + data_dir = os.path.join(local_app_data_dir, 'Arduino') |
| 464 | + elif os.path.exists(os.path.join(local_app_data_dir, '.arduino15')): |
| 465 | + data_dir = os.path.join(local_app_data_dir, '.arduino15') |
| 466 | + elif os.path.exists(os.path.join(local_app_data_dir, '.arduino')): |
| 467 | + data_dir = os.path.join(local_app_data_dir, '.arduino') |
| 468 | + |
| 469 | + # Get arduino-cli data directory |
| 470 | + import json |
| 471 | + if data_dir: |
| 472 | + config_output = subprocess.check_output(["arduino-cli", "config", "dump", "--format", "json", "--config-dir", data_dir]).decode() |
| 473 | + else: |
| 474 | + config_output = subprocess.check_output(["arduino-cli", "config", "dump", "--format", "json"]).decode() |
| 475 | + config = json.loads(config_output) |
| 476 | + ColorPrint.print_info(f"Using arduino-cli config: {config_output.strip()}") |
| 477 | + |
| 478 | + # Extract data directory, with fallback to default |
| 479 | + data_dir = config.get("directories", {}).get("data", data_dir) |
| 480 | + if not data_dir: |
| 481 | + ColorPrint.print_warn("No valid data directory found, cannot copy boards.local.txt") |
| 482 | + return |
| 483 | + |
| 484 | + ColorPrint.print_info(f"Using data directory: {data_dir}") |
| 485 | + |
| 486 | + # Parse platform vendor and architecture from core_fqbn (e.g., "adafruit:samd") |
| 487 | + parts = core_fqbn.split(':') |
| 488 | + if len(parts) >= 2: |
| 489 | + vendor = parts[0] |
| 490 | + architecture = parts[1] |
| 491 | + else: |
| 492 | + vendor = core_fqbn |
| 493 | + architecture = vendor |
| 494 | + |
| 495 | + ColorPrint.print_info(f"Using vendor: {vendor}, architecture: {architecture}") |
| 496 | + |
| 497 | + # Construct base platform path, fall back to architecture if vendor rebadged BSP. |
| 498 | + platform_base = os.path.join(data_dir, "packages", vendor, "hardware", architecture) if \ |
| 499 | + os.path.exists(os.path.join(data_dir, "packages", vendor, "hardware", architecture)) else \ |
| 500 | + os.path.join(data_dir, "packages", architecture, "hardware", architecture) if \ |
| 501 | + os.path.exists(os.path.join(data_dir, "packages", architecture, "hardware", architecture)) else \ |
| 502 | + os.path.join(data_dir, "hardware", vendor, architecture) if \ |
| 503 | + os.path.exists(os.path.join(data_dir, "hardware", vendor, architecture)) else \ |
| 504 | + os.path.join(data_dir, "hardware", |
| 505 | + architecture, architecture) |
| 506 | + |
| 507 | + # Find the latest version directory |
| 508 | + if os.path.exists(platform_base): |
| 509 | + if os.path.exists(os.path.join(platform_base, "boards.txt")): |
| 510 | + shutil.copyfile(boards_local_txt, os.path.join(platform_base, "boards.local.txt")) |
| 511 | + ColorPrint.print_info(f"Copied boards.local.txt to {os.path.join(platform_base, 'boards.local.txt')}") |
| 512 | + else: |
| 513 | + versions = [d for d in os.listdir(platform_base) if os.path.isdir(os.path.join(platform_base, d))] |
| 514 | + ColorPrint.print_info(f"Found versions: {versions}") |
| 515 | + # Filter out non-version directories (e.g., 'tools', 'libraries') while supporting 1.0-dev 1.0.0-offline-mode.102 etc |
| 516 | + versions = [v for v in versions if re.match(r'^(v)?\d+\.\d+(\.\d+(-\w+)?)?(\.\d+)?$', v)] |
| 517 | + if versions: |
| 518 | + # Sort versions and take the latest (could be improved with proper version sorting) |
| 519 | + latest_version = sorted(versions)[-1] |
| 520 | + platform_path = os.path.join(platform_base, latest_version) |
| 521 | + |
| 522 | + dest_path = os.path.join(platform_path, "boards.local.txt") |
| 523 | + shutil.copyfile(boards_local_txt, dest_path) |
| 524 | + ColorPrint.print_info(f"Copied boards.local.txt to {dest_path}") |
| 525 | + |
| 526 | + else: |
| 527 | + ColorPrint.print_warn(f"No version directories found in {platform_base}") |
| 528 | + else: |
| 529 | + ColorPrint.print_warn(f"Platform path {platform_base} does not exist") |
| 530 | + |
| 531 | + except Exception as e: |
| 532 | + ColorPrint.print_fail(f"Error injecting boards.local.txt for {core_fqbn}: {e}") |
| 533 | + |
| 534 | + |
453 | 535 | def main(): |
454 | 536 | # Test platforms |
455 | 537 | platforms = [] |
@@ -478,80 +560,7 @@ def main(): |
478 | 560 |
|
479 | 561 | # Inject boards.local.txt if requested |
480 | 562 | if COPY_BOARDS_LOCAL_TXT and boards_local_txt: |
481 | | - try: |
482 | | - local_app_data_dir = os.environ.get('HOME', '') |
483 | | - data_dir = None |
484 | | - if os.path.exists(os.path.join(local_app_data_dir, 'Arduino')): |
485 | | - data_dir = os.path.join(local_app_data_dir, 'Arduino') |
486 | | - elif os.path.exists(os.path.join(local_app_data_dir, '.arduino15')): |
487 | | - data_dir = os.path.join(local_app_data_dir, '.arduino15') |
488 | | - elif os.path.exists(os.path.join(local_app_data_dir, '.arduino')): |
489 | | - data_dir = os.path.join(local_app_data_dir, '.arduino') |
490 | | - |
491 | | - # Get arduino-cli data directory |
492 | | - import json |
493 | | - if data_dir: |
494 | | - config_output = subprocess.check_output(["arduino-cli", "config", "dump", "--format", "json", "--config-dir", data_dir]).decode() |
495 | | - else: |
496 | | - config_output = subprocess.check_output(["arduino-cli", "config", "dump", "--format", "json"]).decode() |
497 | | - config = json.loads(config_output) |
498 | | - ColorPrint.print_info(f"Using arduino-cli config: {config_output.strip()}") |
499 | | - |
500 | | - # Extract data directory, with fallback to default |
501 | | - data_dir = config.get("directories", {}).get("data", data_dir) |
502 | | - if not data_dir: |
503 | | - ColorPrint.print_warn("No valid data directory found, cannot copy boards.local.txt") |
504 | | - continue |
505 | | - |
506 | | - ColorPrint.print_info(f"Using data directory: {data_dir}") |
507 | | - |
508 | | - # Parse platform vendor and architecture from core_fqbn (e.g., "adafruit:samd") |
509 | | - parts = core_fqbn.split(':') |
510 | | - if len(parts) >= 2: |
511 | | - vendor = parts[0] |
512 | | - architecture = parts[1] |
513 | | - else: |
514 | | - vendor = core_fqbn |
515 | | - architecture = vendor |
516 | | - |
517 | | - ColorPrint.print_info(f"Using vendor: {vendor}, architecture: {architecture}") |
518 | | - |
519 | | - # Construct base platform path, fall back to architecture if vendor rebadged BSP. |
520 | | - platform_base = os.path.join(data_dir, "packages", vendor, "hardware", architecture) if \ |
521 | | - os.path.exists(os.path.join(data_dir, "packages", vendor, "hardware", architecture)) else \ |
522 | | - os.path.join(data_dir, "packages", architecture, "hardware", architecture) if \ |
523 | | - os.path.exists(os.path.join(data_dir, "packages", architecture, "hardware", architecture)) else \ |
524 | | - os.path.join(data_dir, "hardware", vendor, architecture) if \ |
525 | | - os.path.exists(os.path.join(data_dir, "hardware", vendor, architecture)) else \ |
526 | | - os.path.join(data_dir, "hardware", |
527 | | - architecture, architecture) |
528 | | - |
529 | | - # Find the latest version directory |
530 | | - if os.path.exists(platform_base): |
531 | | - if os.path.exists(os.path.join(platform_base, "boards.txt")): |
532 | | - shutil.copyfile(boards_local_txt, os.path.join(platform_base, "boards.local.txt")) |
533 | | - ColorPrint.print_info(f"Copied boards.local.txt to {os.path.join(platform_base, 'boards.local.txt')}") |
534 | | - else: |
535 | | - versions = [d for d in os.listdir(platform_base) if os.path.isdir(os.path.join(platform_base, d))] |
536 | | - ColorPrint.print_info(f"Found versions: {versions}") |
537 | | - # Filter out non-version directories (e.g., 'tools', 'libraries') while supporting 1.0-dev 1.0.0-offline-mode.102 etc |
538 | | - versions = [v for v in versions if re.match(r'^(v)?\d+\.\d+(\.\d+(-\w+)?)?(\.\d+)?$', v)] |
539 | | - if versions: |
540 | | - # Sort versions and take the latest (could be improved with proper version sorting) |
541 | | - latest_version = sorted(versions)[-1] |
542 | | - platform_path = os.path.join(platform_base, latest_version) |
543 | | - |
544 | | - dest_path = os.path.join(platform_path, "boards.local.txt") |
545 | | - shutil.copyfile(boards_local_txt, dest_path) |
546 | | - ColorPrint.print_info(f"Copied boards.local.txt to {dest_path}") |
547 | | - |
548 | | - else: |
549 | | - ColorPrint.print_warn(f"No version directories found in {platform_base}") |
550 | | - else: |
551 | | - ColorPrint.print_warn(f"Platform path {platform_base} does not exist") |
552 | | - |
553 | | - except Exception as e: |
554 | | - ColorPrint.print_fail(f"Error injecting boards.local.txt for {core_fqbn}: {e}") |
| 563 | + install_boards_local_txt(core_fqbn, boards_local_txt) |
555 | 564 | print('#'*80) |
556 | 565 |
|
557 | 566 | # Test examples in the platform folder |
|
0 commit comments