dayhoff-tools 1.0.21__py3-none-any.whl → 1.1.0__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.
dayhoff_tools/cli/main.py CHANGED
@@ -8,20 +8,28 @@ from dayhoff_tools.cli.utility_commands import (
8
8
  delete_local_branch,
9
9
  get_ancestry,
10
10
  import_from_warehouse_typer,
11
+ install_dependencies,
11
12
  rebuild_devcontainer_file,
12
13
  test_github_actions_locally,
13
- update_dayhoff_tools,
14
- sync_dependencies,
14
+ update_dependencies,
15
15
  )
16
16
 
17
17
  app = typer.Typer()
18
18
 
19
19
  # Utility commands
20
20
  app.command("clean")(delete_local_branch)
21
- app.command("deps")(sync_dependencies)
21
+
22
+ # Dependency Management
23
+ app.command(
24
+ "install", help="Install dependencies based on pyproject.toml and sync environment."
25
+ )(install_dependencies)
26
+ app.command(
27
+ "update", help="Update dependencies (--all or --dayhoff) and sync environment."
28
+ )(update_dependencies)
29
+
30
+ # Other Utilities
22
31
  app.command("gha")(test_github_actions_locally)
23
32
  app.command("rebuild")(rebuild_devcontainer_file)
24
- app.command("update")(update_dayhoff_tools)
25
33
  app.command("wadd")(add_to_warehouse_typer)
26
34
  app.command("wancestry")(get_ancestry)
27
35
  app.command("wimport")(import_from_warehouse_typer)
@@ -365,152 +365,212 @@ def build_and_upload_wheel(bump_part: str = "patch"):
365
365
  )
366
366
 
367
367
 
368
- def update_dayhoff_tools():
369
- """Update dayhoff-tools to latest, update pyproject.toml, and sync.
368
+ # --- Dependency Management Commands ---
370
369
 
371
- 1. Runs `uv lock --upgrade-package dayhoff-tools`
372
- 2. Parses uv.lock to find the new version.
373
- 3. Updates the version constraint in pyproject.toml to `>=<new_version>`.
374
- 4. Runs `uv sync --no-install-project`.
370
+
371
+ def install_dependencies(
372
+ install_project: bool = typer.Option(
373
+ False,
374
+ "--install-project",
375
+ "-p",
376
+ help="Install the local project package itself into the environment.",
377
+ ),
378
+ ):
379
+ """Install dependencies based on pyproject.toml.
380
+
381
+ Ensures uv.lock matches pyproject.toml and syncs the environment.
382
+ This is the command to run after changing pyproject.toml manually
383
+ or cloning/pulling a repository.
375
384
  """
376
385
  # ANSI color codes
377
386
  BLUE = "\033[94m"
378
387
  RESET = "\033[0m"
379
388
 
380
- lock_file_path = Path("uv.lock")
381
- pyproject_path = Path("pyproject.toml")
382
-
383
389
  try:
384
- print("Updating dayhoff-tools lock...")
385
-
386
- # Step 1: Update lock file for dayhoff-tools
387
- lock_cmd = ["uv", "lock", "--upgrade-package", "dayhoff-tools"]
390
+ # Step 1: Ensure lock file matches pyproject.toml
391
+ print("Ensuring lock file matches pyproject.toml...")
392
+ lock_cmd = ["uv", "lock"]
388
393
  print(f"Running command: {BLUE}{' '.join(lock_cmd)}{RESET}")
389
- subprocess.run(lock_cmd, check=True)
390
-
391
- # Step 2: Parse uv.lock to find the new version
392
- print(f"Reading {lock_file_path} to find new version...")
393
- if not lock_file_path.exists():
394
- print(f"Error: {lock_file_path} not found after lock command.")
395
- return
394
+ subprocess.run(lock_cmd, check=True, capture_output=True)
396
395
 
397
- locked_version = None
398
- try:
399
- lock_data = toml.load(lock_file_path)
400
- # Find dayhoff-tools in the lock file packages
401
- for package in lock_data.get("package", []):
402
- if package.get("name") == "dayhoff-tools":
403
- locked_version = package.get("version")
404
- break
405
- except toml.TomlDecodeError as e:
406
- print(f"Error parsing {lock_file_path}: {e}")
407
- return
408
- except Exception as e:
409
- print(f"Error reading lock file: {e}")
410
- return
411
-
412
- if not locked_version:
413
- print(f"Error: Could not find dayhoff-tools version in {lock_file_path}.")
414
- return
415
-
416
- print(f"Found dayhoff-tools version {locked_version} in lock file.")
417
-
418
- # Step 3: Update pyproject.toml
419
- print(f"Updating {pyproject_path} version constraint...")
420
- try:
421
- content = pyproject_path.read_text()
422
- # Simplified Regex: Capture quoted package name "dayhoff-tools" (group 1),
423
- # match operators, then match non-quote/comma chars for version.
424
- pattern = re.compile(
425
- # Capture group 1: Start, whitespace, quote, "dayhoff-tools", quote, whitespace
426
- r"(^\\s*[\'\"](dayhoff-tools)[\'\"]\\s*)" +
427
- # Match version specifiers: operators followed by non-quote/comma chars
428
- r"[><=~^]*[^\'\",]*",
429
- re.MULTILINE,
430
- )
431
- new_constraint = f">= {locked_version}"
432
- new_content, num_replacements = pattern.subn(
433
- # Replace the whole match with group 1 + new constraint
434
- rf"\\1{new_constraint}",
435
- content,
436
- )
437
-
438
- if num_replacements > 0:
439
- pyproject_path.write_text(new_content)
440
- print(
441
- f"Updated dayhoff-tools constraint in {pyproject_path} to '{new_constraint}'"
442
- )
443
- else:
444
- print(
445
- f"Warning: Could not find dayhoff-tools dependency line in {pyproject_path} to update constraint."
446
- )
447
-
448
- except FileNotFoundError:
449
- print(f"Error: {pyproject_path} not found.")
450
- return
451
- except Exception as e:
452
- print(f"Error updating {pyproject_path}: {e}")
453
- # Continue to sync step even if pyproject update fails?
454
- # For now, let's proceed to sync.
455
- print("Proceeding with sync despite pyproject.toml update error.")
456
-
457
- # Step 4: Sync environment based on updated lock file
458
- print("Syncing environment...")
459
- # Adding --all-groups to ensure dev dependencies are synced too
460
- sync_cmd = ["uv", "sync", "--all-groups", "--no-install-project"]
396
+ # Step 2: Sync environment
397
+ print("Syncing environment with lock file...")
398
+ sync_cmd = ["uv", "sync", "--all-groups"]
399
+ if not install_project:
400
+ sync_cmd.append("--no-install-project")
461
401
  print(f"Running command: {BLUE}{' '.join(sync_cmd)}{RESET}")
462
402
  subprocess.run(sync_cmd, check=True)
463
403
 
464
- print(
465
- "dayhoff-tools updated, pyproject.toml modified, and environment synced successfully."
466
- )
404
+ print("Dependencies installed/synced successfully.")
467
405
 
468
406
  except subprocess.CalledProcessError as e:
469
- print(f"Error occurred during update/sync process: {e}")
407
+ stderr_output = e.stderr.decode() if e.stderr else "No stderr output."
408
+ print(f"Error occurred during dependency installation/sync: {e}")
409
+ print(f"Stderr: {stderr_output}")
410
+ if "NoSolution" in stderr_output:
411
+ print(
412
+ "\nHint: Could not find a compatible set of dependencies. Check constraints in pyproject.toml."
413
+ )
414
+ sys.exit(1)
470
415
  except FileNotFoundError:
471
- # This catches if uv command itself is not found
472
416
  print("Error: 'uv' command not found. Is uv installed and in PATH?")
473
417
  sys.exit(1)
474
418
  except Exception as e:
475
- # Catch any other unexpected errors
476
419
  print(f"An unexpected error occurred: {e}")
420
+ sys.exit(1)
477
421
 
478
422
 
479
- def sync_dependencies(
480
- install_project: bool = typer.Option(
423
+ def update_dependencies(
424
+ update_dayhoff: bool = typer.Option(
481
425
  False,
482
- "--install-project",
483
- help="Install the local project package itself into the environment.",
484
- )
426
+ "--dayhoff",
427
+ "-d",
428
+ help="Update only the dayhoff-tools package to latest, update pyproject.toml, and sync.",
429
+ ),
430
+ update_all: bool = typer.Option(
431
+ False,
432
+ "--all",
433
+ "-a",
434
+ help="Update all dependencies to their latest compatible versions and sync.",
435
+ ),
485
436
  ):
486
- """Update uv.lock and sync dependencies based on pyproject.toml.
437
+ """Update dependencies to newer versions.
487
438
 
488
- By default, installs all declared dependencies without building/installing
489
- the local project itself (--no-install-project). Use --install-project to
490
- include the local project.
439
+ Requires specifying either --dayhoff/-d or --all/-a.
440
+
441
+ Modes:
442
+ --all/-a: Updates all dependencies to latest compatible versions (`uv lock --upgrade`)
443
+ and syncs the environment.
444
+ --dayhoff/-d: Updates only 'dayhoff-tools' to latest, updates its constraint
445
+ in pyproject.toml, and syncs the environment.
491
446
  """
492
447
  # ANSI color codes
493
448
  BLUE = "\033[94m"
494
449
  RESET = "\033[0m"
495
450
 
451
+ lock_file_path = Path("uv.lock")
452
+ pyproject_path = Path("pyproject.toml")
453
+
454
+ # Validate that either -d or -a is provided
455
+ if not update_dayhoff and not update_all:
456
+ print(
457
+ "Error: Must specify either --dayhoff (-d) or --all (-a) to update dependencies."
458
+ )
459
+ raise typer.Exit(code=1)
460
+ if update_dayhoff and update_all:
461
+ print("Error: Cannot specify both --dayhoff (-d) and --all (-a).")
462
+ raise typer.Exit(code=1)
463
+
464
+ # Determine lock command based on flags
465
+ lock_cmd = ["uv", "lock"]
466
+ action_description = ""
467
+
468
+ if update_dayhoff:
469
+ lock_cmd.extend(["--upgrade-package", "dayhoff-tools"])
470
+ action_description = "Updating dayhoff-tools lock and pyproject.toml..."
471
+ elif update_all:
472
+ lock_cmd.append("--upgrade")
473
+ action_description = (
474
+ "Updating lock file for all dependencies to latest versions..."
475
+ )
476
+
496
477
  try:
497
- lock_cmd = ["uv", "lock"]
498
- # Print command in blue
478
+ # Step 1: Run the update lock command
479
+ print(action_description)
499
480
  print(f"Running command: {BLUE}{' '.join(lock_cmd)}{RESET}")
500
- subprocess.run(lock_cmd, check=True)
481
+ subprocess.run(lock_cmd, check=True, capture_output=True)
501
482
 
502
- sync_cmd = ["uv", "sync", "--all-groups"]
503
- if not install_project:
504
- sync_cmd.append("--no-install-project")
483
+ # Step 2: If specifically updating dayhoff-tools, update pyproject.toml
484
+ if update_dayhoff:
485
+ print(f"Reading {lock_file_path} to find new dayhoff-tools version...")
486
+ if not lock_file_path.exists():
487
+ print(f"Error: {lock_file_path} not found after lock command.")
488
+ return # Changed to return instead of exit
505
489
 
506
- # Print command in blue
490
+ locked_version = None
491
+ try:
492
+ lock_data = toml.load(lock_file_path)
493
+ for package in lock_data.get("package", []):
494
+ if package.get("name") == "dayhoff-tools":
495
+ locked_version = package.get("version")
496
+ break
497
+ except toml.TomlDecodeError as e:
498
+ print(f"Error parsing {lock_file_path}: {e}")
499
+ return # Changed to return
500
+ except Exception as e:
501
+ print(f"Error reading lock file: {e}")
502
+ return # Changed to return
503
+
504
+ if not locked_version:
505
+ print(
506
+ f"Error: Could not find dayhoff-tools version in {lock_file_path}."
507
+ )
508
+ return # Changed to return
509
+
510
+ print(f"Found dayhoff-tools version {locked_version} in lock file.")
511
+
512
+ # Update pyproject.toml constraint
513
+ print(f"Updating {pyproject_path} version constraint...")
514
+ try:
515
+ content = pyproject_path.read_text()
516
+ pattern = re.compile(
517
+ "^(\s*['\"])dayhoff-tools(?:[><=~^][^'\"\\[,]*)?(['\"]\S*)$",
518
+ re.MULTILINE,
519
+ )
520
+ package_name = "dayhoff-tools"
521
+ new_constraint_text = f">={locked_version}"
522
+ replacement_string = f"\g<1>{package_name}{new_constraint_text}\g<2>"
523
+ new_content, num_replacements = pattern.subn(
524
+ replacement_string, content
525
+ )
526
+
527
+ if num_replacements > 0:
528
+ pyproject_path.write_text(new_content)
529
+ print(
530
+ f"Updated dayhoff-tools constraint in {pyproject_path} to '{new_constraint_text}'"
531
+ )
532
+ else:
533
+ print(
534
+ f"Warning: Could not find dayhoff-tools dependency line in {pyproject_path} to update constraint."
535
+ )
536
+ except FileNotFoundError:
537
+ print(f"Error: {pyproject_path} not found.")
538
+ return # Changed to return
539
+ except Exception as e:
540
+ print(f"Error updating {pyproject_path}: {e}")
541
+ print("Proceeding with sync despite pyproject.toml update error.")
542
+
543
+ # Step 3: Sync environment
544
+ print("Syncing environment with updated lock file...")
545
+ # Always use --no-install-project for updates
546
+ sync_cmd = ["uv", "sync", "--all-groups", "--no-install-project"]
507
547
  print(f"Running command: {BLUE}{' '.join(sync_cmd)}{RESET}")
508
548
  subprocess.run(sync_cmd, check=True)
509
549
 
510
- print("Dependencies synced successfully.")
550
+ # Final status message
551
+ if update_dayhoff:
552
+ print(
553
+ "dayhoff-tools updated, pyproject.toml modified, and environment synced successfully."
554
+ )
555
+ elif update_all:
556
+ print("All dependencies updated and environment synced successfully.")
557
+
511
558
  except subprocess.CalledProcessError as e:
512
- print(f"Error occurred during dependency sync: {e}")
559
+ stderr_output = e.stderr.decode() if e.stderr else "No stderr output."
560
+ print(f"Error occurred during dependency update/sync: {e}")
561
+ print(f"Stderr: {stderr_output}")
562
+ if "NoSolution" in stderr_output:
563
+ print(
564
+ "\nHint: Could not find a compatible set of dependencies. Check constraints in pyproject.toml."
565
+ )
566
+ elif "unrecognized arguments: --upgrade" in stderr_output:
567
+ print(
568
+ "\nHint: Your version of 'uv' might be too old to support '--upgrade'. Try updating uv."
569
+ )
513
570
  sys.exit(1)
514
571
  except FileNotFoundError:
515
572
  print("Error: 'uv' command not found. Is uv installed and in PATH?")
516
573
  sys.exit(1)
574
+ except Exception as e:
575
+ print(f"An unexpected error occurred: {e}")
576
+ sys.exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.0.21
3
+ Version: 1.1.0
4
4
  Summary: Common tools for all the repos at Dayhoff Labs
5
5
  Author: Daniel Martin-Alarcon
6
6
  Author-email: dma@dayhofflabs.com
@@ -3,9 +3,9 @@ dayhoff_tools/chemistry/standardizer.py,sha256=uMn7VwHnx02nc404eO6fRuS4rsl4dvSPf
3
3
  dayhoff_tools/chemistry/utils.py,sha256=jt-7JgF-GeeVC421acX-bobKbLU_X94KNOW24p_P-_M,2257
4
4
  dayhoff_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  dayhoff_tools/cli/cloud_commands.py,sha256=KiYEuD3nSg8QPWBYfrhdze2La_CJe4iqK-8uOAHyS8U,35827
6
- dayhoff_tools/cli/main.py,sha256=yorL117hknzhNybt7CTz4oKXVuQRIDXPl7huIEWga-M,3666
6
+ dayhoff_tools/cli/main.py,sha256=O-kPX0Di3_W0yBd-jSzQrOKm4K3deV_-jQhOom6Ir5g,3875
7
7
  dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
8
- dayhoff_tools/cli/utility_commands.py,sha256=jj3fpJiLXL_boxegZSXfKwlW8Yl1fOLpoOO9GWdCCE8,19373
8
+ dayhoff_tools/cli/utility_commands.py,sha256=cpxAVYeSnDJXKhxWJ75X8N1VP6qNLl0TrdYY6BBv1xw,21776
9
9
  dayhoff_tools/deployment/base.py,sha256=u-AjbtHnFLoLt33dhYXHIpV-6jcieMEHHGBGN_U9Hm0,15626
10
10
  dayhoff_tools/deployment/deploy_aws.py,sha256=O0gQxHioSU_sNU8T8MD4wSOPvWc--V8eRRZzlRu035I,16446
11
11
  dayhoff_tools/deployment/deploy_gcp.py,sha256=DxBM4sUzwPK9RWLP9bSfr38n1HHl-TVrp4TsbdN8pUA,5795
@@ -25,7 +25,7 @@ dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
25
25
  dayhoff_tools/structure.py,sha256=ufN3gAodQxhnt7psK1VTQeu9rKERmo_PhoxIbB4QKMw,27660
26
26
  dayhoff_tools/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJqE4,16456
27
27
  dayhoff_tools/warehouse.py,sha256=TqV8nex1AluNaL4JuXH5zuu9P7qmE89lSo6f_oViy6U,14965
28
- dayhoff_tools-1.0.21.dist-info/METADATA,sha256=QgU5Ai9_2CL03IkOFugN71AsAvXNzjp2S1dcEygWCKw,2214
29
- dayhoff_tools-1.0.21.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
30
- dayhoff_tools-1.0.21.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
- dayhoff_tools-1.0.21.dist-info/RECORD,,
28
+ dayhoff_tools-1.1.0.dist-info/METADATA,sha256=a1k_yMC8QdtjTmj0cYhmCG_yAilCrG5WKlnm91Ljukg,2213
29
+ dayhoff_tools-1.1.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
30
+ dayhoff_tools-1.1.0.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
+ dayhoff_tools-1.1.0.dist-info/RECORD,,