dayhoff-tools 1.0.22__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,156 +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
- # Regex: Find the line with "dayhoff-tools" dependency,
423
- # capture leading space/quote (1), package name, optional specifier, closing quote/rest (2).
424
- pattern = re.compile(
425
- "^(\\s*['\\\"])dayhoff-tools(?:[><=~^][^'\\\"\\[,]*)?(['\\\"].*)$",
426
- re.MULTILINE,
427
- )
428
- # Note: This pattern intentionally avoids matching extras like [full]
429
- # because the specifier part `[^'\"\[,]` excludes '['.
430
-
431
- package_name = "dayhoff-tools"
432
- new_constraint_text = f">={locked_version}"
433
-
434
- # Replace the matched line using captured groups:
435
- # group 1 (leading space/quote) + package name + new constraint + group 2 (closing quote/rest)
436
- replacement_string = f"\\g<1>{package_name}{new_constraint_text}\\g<2>"
437
- new_content, num_replacements = pattern.subn(
438
- replacement_string,
439
- content,
440
- )
441
-
442
- if num_replacements > 0:
443
- pyproject_path.write_text(new_content)
444
- print(
445
- f"Updated dayhoff-tools constraint in {pyproject_path} to '{new_constraint_text}'"
446
- )
447
- else:
448
- print(
449
- f"Warning: Could not find dayhoff-tools dependency line in {pyproject_path} to update constraint."
450
- )
451
-
452
- except FileNotFoundError:
453
- print(f"Error: {pyproject_path} not found.")
454
- return
455
- except Exception as e:
456
- print(f"Error updating {pyproject_path}: {e}")
457
- # Continue to sync step even if pyproject update fails?
458
- # For now, let's proceed to sync.
459
- print("Proceeding with sync despite pyproject.toml update error.")
460
-
461
- # Step 4: Sync environment based on updated lock file
462
- print("Syncing environment...")
463
- # Adding --all-groups to ensure dev dependencies are synced too
464
- 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")
465
401
  print(f"Running command: {BLUE}{' '.join(sync_cmd)}{RESET}")
466
402
  subprocess.run(sync_cmd, check=True)
467
403
 
468
- print(
469
- "dayhoff-tools updated, pyproject.toml modified, and environment synced successfully."
470
- )
404
+ print("Dependencies installed/synced successfully.")
471
405
 
472
406
  except subprocess.CalledProcessError as e:
473
- 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)
474
415
  except FileNotFoundError:
475
- # This catches if uv command itself is not found
476
416
  print("Error: 'uv' command not found. Is uv installed and in PATH?")
477
417
  sys.exit(1)
478
418
  except Exception as e:
479
- # Catch any other unexpected errors
480
419
  print(f"An unexpected error occurred: {e}")
420
+ sys.exit(1)
481
421
 
482
422
 
483
- def sync_dependencies(
484
- install_project: bool = typer.Option(
423
+ def update_dependencies(
424
+ update_dayhoff: bool = typer.Option(
485
425
  False,
486
- "--install-project",
487
- help="Install the local project package itself into the environment.",
488
- )
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
+ ),
489
436
  ):
490
- """Update uv.lock and sync dependencies based on pyproject.toml.
437
+ """Update dependencies to newer versions.
491
438
 
492
- By default, installs all declared dependencies without building/installing
493
- the local project itself (--no-install-project). Use --install-project to
494
- 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.
495
446
  """
496
447
  # ANSI color codes
497
448
  BLUE = "\033[94m"
498
449
  RESET = "\033[0m"
499
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
+
500
477
  try:
501
- lock_cmd = ["uv", "lock"]
502
- # Print command in blue
478
+ # Step 1: Run the update lock command
479
+ print(action_description)
503
480
  print(f"Running command: {BLUE}{' '.join(lock_cmd)}{RESET}")
504
- subprocess.run(lock_cmd, check=True)
481
+ subprocess.run(lock_cmd, check=True, capture_output=True)
505
482
 
506
- sync_cmd = ["uv", "sync", "--all-groups"]
507
- if not install_project:
508
- 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
509
489
 
510
- # 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"]
511
547
  print(f"Running command: {BLUE}{' '.join(sync_cmd)}{RESET}")
512
548
  subprocess.run(sync_cmd, check=True)
513
549
 
514
- 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
+
515
558
  except subprocess.CalledProcessError as e:
516
- 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
+ )
517
570
  sys.exit(1)
518
571
  except FileNotFoundError:
519
572
  print("Error: 'uv' command not found. Is uv installed and in PATH?")
520
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.22
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=GePENwZ6u1wjJlrAHZ_M7eaRyhD8ZraFgjpDFQqFgCk,19563
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.22.dist-info/METADATA,sha256=tHgvSVGwT3cLDSDXulJVw5Tet95g3JzJMQLNFarIr0g,2214
29
- dayhoff_tools-1.0.22.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
30
- dayhoff_tools-1.0.22.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
- dayhoff_tools-1.0.22.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,,