dayhoff-tools 1.0.22__py3-none-any.whl → 1.1.1__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,197 @@ 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
396
-
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.")
394
+ subprocess.run(lock_cmd, check=True, capture_output=True)
417
395
 
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_all: bool = typer.Option(
485
425
  False,
486
- "--install-project",
487
- help="Install the local project package itself into the environment.",
488
- )
426
+ "--all",
427
+ "-a",
428
+ help="Update all dependencies instead of just dayhoff-tools.",
429
+ ),
489
430
  ):
490
- """Update uv.lock and sync dependencies based on pyproject.toml.
431
+ """Update dependencies to newer versions.
491
432
 
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.
433
+ Default Action (no flags): Updates only 'dayhoff-tools' package to latest,
434
+ updates pyproject.toml, and syncs.
435
+
436
+ Flags:
437
+ --all/-a: Updates all dependencies to latest compatible versions (`uv lock --upgrade`)
438
+ and syncs the environment. Overrides the default.
495
439
  """
496
440
  # ANSI color codes
497
441
  BLUE = "\033[94m"
498
442
  RESET = "\033[0m"
499
443
 
444
+ lock_file_path = Path("uv.lock")
445
+ pyproject_path = Path("pyproject.toml")
446
+
447
+ # Determine action based on flags
448
+ lock_cmd = ["uv", "lock"]
449
+ action_description = ""
450
+ run_pyproject_update = False
451
+
452
+ if update_all:
453
+ lock_cmd.append("--upgrade")
454
+ action_description = (
455
+ "Updating lock file for all dependencies to latest versions..."
456
+ )
457
+ else: # Default behavior: update dayhoff-tools
458
+ lock_cmd.extend(["--upgrade-package", "dayhoff-tools"])
459
+ action_description = (
460
+ "Updating dayhoff-tools lock and pyproject.toml (default behavior)..."
461
+ )
462
+ run_pyproject_update = (
463
+ True # Only update pyproject if we are doing the dayhoff update
464
+ )
465
+
500
466
  try:
501
- lock_cmd = ["uv", "lock"]
502
- # Print command in blue
467
+ # Step 1: Run the update lock command
468
+ print(action_description)
503
469
  print(f"Running command: {BLUE}{' '.join(lock_cmd)}{RESET}")
504
- subprocess.run(lock_cmd, check=True)
505
-
506
- sync_cmd = ["uv", "sync", "--all-groups"]
507
- if not install_project:
508
- sync_cmd.append("--no-install-project")
470
+ subprocess.run(lock_cmd, check=True, capture_output=True)
471
+
472
+ # Step 2: Update pyproject.toml only if doing the dayhoff update (default)
473
+ if run_pyproject_update:
474
+ print(f"Reading {lock_file_path} to find new dayhoff-tools version...")
475
+ if not lock_file_path.exists():
476
+ print(f"Error: {lock_file_path} not found after lock command.")
477
+ return
478
+ locked_version = None
479
+ try:
480
+ lock_data = toml.load(lock_file_path)
481
+ for package in lock_data.get("package", []):
482
+ if package.get("name") == "dayhoff-tools":
483
+ locked_version = package.get("version")
484
+ break
485
+ except toml.TomlDecodeError as e:
486
+ print(f"Error parsing {lock_file_path}: {e}")
487
+ return
488
+ except Exception as e:
489
+ print(f"Error reading lock file: {e}")
490
+ return
491
+
492
+ if not locked_version:
493
+ print(
494
+ f"Error: Could not find dayhoff-tools version in {lock_file_path}."
495
+ )
496
+ return
509
497
 
510
- # Print command in blue
498
+ print(f"Found dayhoff-tools version {locked_version} in lock file.")
499
+ print(f"Updating {pyproject_path} version constraint...")
500
+ try:
501
+ content = pyproject_path.read_text()
502
+ pattern = re.compile(
503
+ "^(\s*['\"])dayhoff-tools(?:[><=~^][^'\"\\[,]*)?(['\"]\S*)$",
504
+ re.MULTILINE,
505
+ )
506
+ package_name = "dayhoff-tools"
507
+ new_constraint_text = f">={locked_version}"
508
+ replacement_string = f"\g<1>{package_name}{new_constraint_text}\g<2>"
509
+ new_content, num_replacements = pattern.subn(
510
+ replacement_string, content
511
+ )
512
+ if num_replacements > 0:
513
+ pyproject_path.write_text(new_content)
514
+ print(
515
+ f"Updated dayhoff-tools constraint in {pyproject_path} to '{new_constraint_text}'"
516
+ )
517
+ else:
518
+ print(
519
+ f"Warning: Could not find dayhoff-tools dependency line in {pyproject_path} to update constraint."
520
+ )
521
+ except FileNotFoundError:
522
+ print(f"Error: {pyproject_path} not found.")
523
+ return
524
+ except Exception as e:
525
+ print(f"Error updating {pyproject_path}: {e}")
526
+ print("Proceeding with sync despite pyproject.toml update error.")
527
+
528
+ # Step 3: Sync environment
529
+ print("Syncing environment with updated lock file...")
530
+ # Always use --no-install-project for updates
531
+ sync_cmd = ["uv", "sync", "--all-groups", "--no-install-project"]
511
532
  print(f"Running command: {BLUE}{' '.join(sync_cmd)}{RESET}")
512
533
  subprocess.run(sync_cmd, check=True)
513
534
 
514
- print("Dependencies synced successfully.")
535
+ # Final status message
536
+ if update_all:
537
+ print("All dependencies updated and environment synced successfully.")
538
+ else: # Default case (dayhoff update)
539
+ print(
540
+ "dayhoff-tools updated, pyproject.toml modified, and environment synced successfully."
541
+ )
542
+
515
543
  except subprocess.CalledProcessError as e:
516
- print(f"Error occurred during dependency sync: {e}")
544
+ stderr_output = e.stderr.decode() if e.stderr else "No stderr output."
545
+ print(f"Error occurred during dependency update/sync: {e}")
546
+ print(f"Stderr: {stderr_output}")
547
+ if "NoSolution" in stderr_output:
548
+ print(
549
+ "\nHint: Could not find a compatible set of dependencies. Check constraints in pyproject.toml."
550
+ )
551
+ elif "unrecognized arguments: --upgrade" in stderr_output:
552
+ print(
553
+ "\nHint: Your version of 'uv' might be too old to support '--upgrade'. Try updating uv."
554
+ )
517
555
  sys.exit(1)
518
556
  except FileNotFoundError:
519
557
  print("Error: 'uv' command not found. Is uv installed and in PATH?")
520
558
  sys.exit(1)
559
+ except Exception as e:
560
+ print(f"An unexpected error occurred: {e}")
561
+ 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.1
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=KgF_shWIfzZyKVl9VKqhVm5WJwp0YCvYFadnN3fLZeU,21211
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.1.dist-info/METADATA,sha256=UQv5qilixD2tR0TaF5UHN22BZKPqg7L2bd9my01EyqM,2213
29
+ dayhoff_tools-1.1.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
30
+ dayhoff_tools-1.1.1.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
+ dayhoff_tools-1.1.1.dist-info/RECORD,,