pipu-cli 0.1.dev2__py3-none-any.whl → 0.1.dev4__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.
- pipu_cli/__init__.py +1 -1
- pipu_cli/internals.py +126 -80
- pipu_cli/ui/modal_dialogs.py +110 -69
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/METADATA +4 -4
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/RECORD +9 -9
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/WHEEL +0 -0
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/entry_points.txt +0 -0
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/licenses/LICENSE +0 -0
- {pipu_cli-0.1.dev2.dist-info → pipu_cli-0.1.dev4.dist-info}/top_level.txt +0 -0
pipu_cli/__init__.py
CHANGED
pipu_cli/internals.py
CHANGED
|
@@ -656,6 +656,9 @@ def update_packages_preserving_editable(
|
|
|
656
656
|
2. Use the original source directory with pip install -e
|
|
657
657
|
3. For regular packages, use normal pip install
|
|
658
658
|
|
|
659
|
+
When updating packages, constraints for those packages are temporarily excluded
|
|
660
|
+
to avoid conflicts between constraints and package dependencies.
|
|
661
|
+
|
|
659
662
|
:param packages_to_update: List of package dictionaries with keys: name, latest_version, editable
|
|
660
663
|
:param console: Optional Rich console for output
|
|
661
664
|
:param timeout: Optional timeout for pip operations
|
|
@@ -664,6 +667,10 @@ def update_packages_preserving_editable(
|
|
|
664
667
|
"""
|
|
665
668
|
import subprocess
|
|
666
669
|
import sys
|
|
670
|
+
import tempfile
|
|
671
|
+
import os
|
|
672
|
+
from packaging.utils import canonicalize_name
|
|
673
|
+
from pathlib import Path
|
|
667
674
|
|
|
668
675
|
if console is None:
|
|
669
676
|
console = Console()
|
|
@@ -671,103 +678,142 @@ def update_packages_preserving_editable(
|
|
|
671
678
|
successful_updates = []
|
|
672
679
|
failed_updates = []
|
|
673
680
|
|
|
674
|
-
#
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
process = subprocess.Popen(
|
|
678
|
-
cmd,
|
|
679
|
-
stdout=subprocess.PIPE,
|
|
680
|
-
stderr=subprocess.PIPE,
|
|
681
|
-
text=True
|
|
682
|
-
)
|
|
681
|
+
# Get all current constraints and create a filtered version that excludes packages being updated
|
|
682
|
+
from .package_constraints import read_constraints
|
|
683
|
+
all_constraints = read_constraints()
|
|
683
684
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
685
|
+
# Get canonical names of packages being updated
|
|
686
|
+
packages_being_updated = {canonicalize_name(pkg["name"]) for pkg in packages_to_update}
|
|
687
|
+
|
|
688
|
+
# Filter out constraints for packages being updated to avoid conflicts
|
|
689
|
+
filtered_constraints = {
|
|
690
|
+
pkg: constraint
|
|
691
|
+
for pkg, constraint in all_constraints.items()
|
|
692
|
+
if pkg not in packages_being_updated
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
# Create a temporary constraints file if there are any constraints to apply
|
|
696
|
+
constraint_file = None
|
|
697
|
+
constraint_file_path = None
|
|
698
|
+
try:
|
|
699
|
+
if filtered_constraints:
|
|
700
|
+
constraint_file = tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False)
|
|
701
|
+
constraint_file_path = constraint_file.name
|
|
702
|
+
for pkg, constraint in filtered_constraints.items():
|
|
703
|
+
constraint_file.write(f"{pkg}{constraint}\n")
|
|
704
|
+
constraint_file.close()
|
|
705
|
+
console.print(f"[dim]Using filtered constraints (excluding {len(packages_being_updated)} package(s) being updated)[/dim]")
|
|
706
|
+
|
|
707
|
+
# Helper function to run subprocess with cancellation support
|
|
708
|
+
def run_with_cancel(cmd, timeout=None):
|
|
709
|
+
"""Run a subprocess command that can be cancelled."""
|
|
710
|
+
# Set up environment with constraint file if available
|
|
711
|
+
env = os.environ.copy()
|
|
712
|
+
if constraint_file_path:
|
|
713
|
+
env['PIP_CONSTRAINT'] = constraint_file_path
|
|
714
|
+
|
|
715
|
+
process = subprocess.Popen(
|
|
716
|
+
cmd,
|
|
717
|
+
stdout=subprocess.PIPE,
|
|
718
|
+
stderr=subprocess.PIPE,
|
|
719
|
+
text=True,
|
|
720
|
+
env=env
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
try:
|
|
724
|
+
stdout, stderr = process.communicate(timeout=timeout)
|
|
725
|
+
return process.returncode, stdout, stderr
|
|
726
|
+
except subprocess.TimeoutExpired:
|
|
694
727
|
process.kill()
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
728
|
+
process.communicate() # Clean up
|
|
729
|
+
raise
|
|
730
|
+
except:
|
|
731
|
+
# If we're interrupted or cancelled, kill the process
|
|
732
|
+
if process.poll() is None: # Process still running
|
|
733
|
+
process.kill()
|
|
734
|
+
try:
|
|
735
|
+
process.communicate(timeout=1)
|
|
736
|
+
except:
|
|
737
|
+
pass
|
|
738
|
+
raise
|
|
700
739
|
|
|
701
|
-
|
|
702
|
-
|
|
740
|
+
# Get current editable packages to find source directories
|
|
741
|
+
editable_packages = get_editable_packages()
|
|
703
742
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
743
|
+
for package_info in packages_to_update:
|
|
744
|
+
# Check for cancellation before processing each package
|
|
745
|
+
if cancel_event and cancel_event.is_set():
|
|
746
|
+
console.print("[yellow]Update cancelled by user[/yellow]")
|
|
747
|
+
break
|
|
709
748
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
749
|
+
package_name = package_info["name"]
|
|
750
|
+
latest_version = package_info.get("latest_version")
|
|
751
|
+
is_editable = package_info.get("editable", False)
|
|
713
752
|
|
|
714
|
-
|
|
715
|
-
|
|
753
|
+
try:
|
|
754
|
+
console.print(f"Updating {package_name}...")
|
|
716
755
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
source_path = editable_packages.get(canonical_name)
|
|
756
|
+
if is_editable:
|
|
757
|
+
# Package is editable, reinstall from source directory
|
|
758
|
+
canonical_name = canonicalize_name(package_name)
|
|
759
|
+
source_path = editable_packages.get(canonical_name)
|
|
722
760
|
|
|
723
|
-
|
|
724
|
-
|
|
761
|
+
if source_path:
|
|
762
|
+
console.print(f" 📝 Reinstalling editable package from: {source_path}")
|
|
725
763
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
764
|
+
# First uninstall the current version
|
|
765
|
+
uninstall_cmd = [sys.executable, "-m", "pip", "uninstall", package_name, "-y"]
|
|
766
|
+
returncode, stdout, stderr = run_with_cancel(uninstall_cmd, timeout=timeout)
|
|
729
767
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
768
|
+
if returncode != 0:
|
|
769
|
+
console.print(f" [red]Failed to uninstall {package_name}: {stderr}[/red]")
|
|
770
|
+
failed_updates.append(package_name)
|
|
771
|
+
continue
|
|
772
|
+
|
|
773
|
+
# Then reinstall in editable mode
|
|
774
|
+
install_cmd = [sys.executable, "-m", "pip", "install", "-e", source_path]
|
|
775
|
+
returncode, stdout, stderr = run_with_cancel(install_cmd, timeout=timeout)
|
|
776
|
+
|
|
777
|
+
if returncode == 0:
|
|
778
|
+
console.print(f" [green]✓ Successfully updated editable {package_name}[/green]")
|
|
779
|
+
successful_updates.append(package_name)
|
|
780
|
+
else:
|
|
781
|
+
console.print(f" [red]Failed to reinstall editable {package_name}: {stderr}[/red]")
|
|
782
|
+
failed_updates.append(package_name)
|
|
783
|
+
else:
|
|
784
|
+
console.print(f" [yellow]Could not find source path for editable {package_name}, updating normally[/yellow]")
|
|
785
|
+
# Fall through to normal update
|
|
786
|
+
is_editable = False
|
|
787
|
+
|
|
788
|
+
if not is_editable:
|
|
789
|
+
# Regular package update
|
|
790
|
+
if latest_version:
|
|
791
|
+
install_cmd = [sys.executable, "-m", "pip", "install", f"{package_name}=={latest_version}"]
|
|
792
|
+
else:
|
|
793
|
+
install_cmd = [sys.executable, "-m", "pip", "install", "--upgrade", package_name]
|
|
734
794
|
|
|
735
|
-
# Then reinstall in editable mode
|
|
736
|
-
install_cmd = [sys.executable, "-m", "pip", "install", "-e", source_path]
|
|
737
795
|
returncode, stdout, stderr = run_with_cancel(install_cmd, timeout=timeout)
|
|
738
796
|
|
|
739
797
|
if returncode == 0:
|
|
740
|
-
console.print(f" [green]✓ Successfully updated
|
|
798
|
+
console.print(f" [green]✓ Successfully updated {package_name}[/green]")
|
|
741
799
|
successful_updates.append(package_name)
|
|
742
800
|
else:
|
|
743
|
-
console.print(f" [red]Failed to
|
|
801
|
+
console.print(f" [red]Failed to update {package_name}: {stderr}[/red]")
|
|
744
802
|
failed_updates.append(package_name)
|
|
745
|
-
else:
|
|
746
|
-
console.print(f" [yellow]Could not find source path for editable {package_name}, updating normally[/yellow]")
|
|
747
|
-
# Fall through to normal update
|
|
748
|
-
is_editable = False
|
|
749
|
-
|
|
750
|
-
if not is_editable:
|
|
751
|
-
# Regular package update
|
|
752
|
-
if latest_version:
|
|
753
|
-
install_cmd = [sys.executable, "-m", "pip", "install", f"{package_name}=={latest_version}"]
|
|
754
|
-
else:
|
|
755
|
-
install_cmd = [sys.executable, "-m", "pip", "install", "--upgrade", package_name]
|
|
756
803
|
|
|
757
|
-
|
|
804
|
+
except subprocess.TimeoutExpired:
|
|
805
|
+
console.print(f" [red]Timeout updating {package_name}[/red]")
|
|
806
|
+
failed_updates.append(package_name)
|
|
807
|
+
except Exception as e:
|
|
808
|
+
console.print(f" [red]Error updating {package_name}: {e}[/red]")
|
|
809
|
+
failed_updates.append(package_name)
|
|
758
810
|
|
|
759
|
-
|
|
760
|
-
console.print(f" [green]✓ Successfully updated {package_name}[/green]")
|
|
761
|
-
successful_updates.append(package_name)
|
|
762
|
-
else:
|
|
763
|
-
console.print(f" [red]Failed to update {package_name}: {stderr}[/red]")
|
|
764
|
-
failed_updates.append(package_name)
|
|
811
|
+
return successful_updates, failed_updates
|
|
765
812
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
return successful_updates, failed_updates
|
|
813
|
+
finally:
|
|
814
|
+
# Clean up temporary constraint file
|
|
815
|
+
if constraint_file_path and os.path.exists(constraint_file_path):
|
|
816
|
+
try:
|
|
817
|
+
os.unlink(constraint_file_path)
|
|
818
|
+
except Exception:
|
|
819
|
+
pass # Best effort cleanup
|
pipu_cli/ui/modal_dialogs.py
CHANGED
|
@@ -989,81 +989,122 @@ class PackageUpdateScreen(ModalScreen[None]):
|
|
|
989
989
|
try:
|
|
990
990
|
import subprocess
|
|
991
991
|
import sys
|
|
992
|
+
import tempfile
|
|
993
|
+
import os
|
|
994
|
+
from packaging.utils import canonicalize_name
|
|
992
995
|
|
|
993
996
|
logger.info(f"Starting batch update for {len(self.selected_packages)} packages")
|
|
994
997
|
total_packages = len(self.selected_packages)
|
|
995
998
|
|
|
996
|
-
#
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
for pkg in self.selected_packages
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
self.app.call_from_thread(self._update_status, f"Updating {total_packages} packages...")
|
|
1012
|
-
self.app.call_from_thread(self._log_message, f"{'='*70}")
|
|
1013
|
-
self.app.call_from_thread(self._log_message, f"📦 Updating {total_packages} packages: {', '.join(package_names[:5])}")
|
|
1014
|
-
if len(package_names) > 5:
|
|
1015
|
-
self.app.call_from_thread(self._log_message, f" ... and {len(package_names) - 5} more")
|
|
1016
|
-
self.app.call_from_thread(self._log_message, f"{'='*70}\n")
|
|
1017
|
-
|
|
1018
|
-
# Prepare pip command to install all packages at once with proper version specs
|
|
1019
|
-
pip_cmd = [sys.executable, "-m", "pip", "install"] + package_specs
|
|
1020
|
-
|
|
1021
|
-
# Run pip and capture output with proper cleanup
|
|
1022
|
-
from ..utils import ManagedProcess
|
|
1023
|
-
return_code = None
|
|
1024
|
-
|
|
999
|
+
# Get canonical names of packages being updated
|
|
1000
|
+
from ..package_constraints import read_constraints
|
|
1001
|
+
all_constraints = read_constraints()
|
|
1002
|
+
packages_being_updated = {canonicalize_name(pkg["name"]) for pkg in self.selected_packages}
|
|
1003
|
+
|
|
1004
|
+
# Filter out constraints for packages being updated to avoid conflicts
|
|
1005
|
+
filtered_constraints = {
|
|
1006
|
+
pkg: constraint
|
|
1007
|
+
for pkg, constraint in all_constraints.items()
|
|
1008
|
+
if pkg not in packages_being_updated
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
# Create a temporary constraints file if there are any constraints to apply
|
|
1012
|
+
constraint_file = None
|
|
1013
|
+
constraint_file_path = None
|
|
1025
1014
|
try:
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
if return_code == 0:
|
|
1052
|
-
# All packages updated successfully
|
|
1053
|
-
self.successful_updates.extend(package_names)
|
|
1054
|
-
self.app.call_from_thread(self._log_message, f"\n{'='*70}")
|
|
1055
|
-
self.app.call_from_thread(self._log_message, f"✅ Successfully updated all {total_packages} packages!")
|
|
1056
|
-
self.app.call_from_thread(self._log_message, f"{'='*70}")
|
|
1057
|
-
else:
|
|
1058
|
-
# Some packages failed - pip will have shown which ones in output
|
|
1059
|
-
self.failed_updates.extend(package_names)
|
|
1060
|
-
self.app.call_from_thread(self._log_message, f"\n{'='*70}")
|
|
1061
|
-
self.app.call_from_thread(self._log_message, "❌ Update completed with errors (see above)")
|
|
1015
|
+
if filtered_constraints:
|
|
1016
|
+
constraint_file = tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False)
|
|
1017
|
+
constraint_file_path = constraint_file.name
|
|
1018
|
+
for pkg, constraint in filtered_constraints.items():
|
|
1019
|
+
constraint_file.write(f"{pkg}{constraint}\n")
|
|
1020
|
+
constraint_file.close()
|
|
1021
|
+
self.app.call_from_thread(self._log_message, f"[dim]Using filtered constraints (excluding {len(packages_being_updated)} package(s) being updated)[/dim]")
|
|
1022
|
+
|
|
1023
|
+
# Build list of package specs to update, respecting constraints
|
|
1024
|
+
package_specs = []
|
|
1025
|
+
package_names = []
|
|
1026
|
+
for pkg in self.selected_packages:
|
|
1027
|
+
package_names.append(pkg["name"])
|
|
1028
|
+
# Check if package has a constraint that should be applied instead of latest version
|
|
1029
|
+
constraint = pkg.get('constraint')
|
|
1030
|
+
if constraint:
|
|
1031
|
+
# Apply the constraint instead of pinning to latest version
|
|
1032
|
+
spec = f"{pkg['name']}{constraint}"
|
|
1033
|
+
else:
|
|
1034
|
+
# No constraint, use latest version
|
|
1035
|
+
spec = f"{pkg['name']}=={pkg['latest_version']}"
|
|
1036
|
+
package_specs.append(spec)
|
|
1037
|
+
|
|
1038
|
+
self.app.call_from_thread(self._update_status, f"Updating {total_packages} packages...")
|
|
1062
1039
|
self.app.call_from_thread(self._log_message, f"{'='*70}")
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1040
|
+
self.app.call_from_thread(self._log_message, f"📦 Updating {total_packages} packages: {', '.join(package_names[:5])}")
|
|
1041
|
+
if len(package_names) > 5:
|
|
1042
|
+
self.app.call_from_thread(self._log_message, f" ... and {len(package_names) - 5} more")
|
|
1043
|
+
self.app.call_from_thread(self._log_message, f"{'='*70}\n")
|
|
1044
|
+
|
|
1045
|
+
# Prepare pip command to install all packages at once with proper version specs
|
|
1046
|
+
pip_cmd = [sys.executable, "-m", "pip", "install"] + package_specs
|
|
1047
|
+
|
|
1048
|
+
# Set up environment with constraint file if available
|
|
1049
|
+
env = os.environ.copy()
|
|
1050
|
+
if constraint_file_path:
|
|
1051
|
+
env['PIP_CONSTRAINT'] = constraint_file_path
|
|
1052
|
+
|
|
1053
|
+
# Run pip and capture output with proper cleanup
|
|
1054
|
+
from ..utils import ManagedProcess
|
|
1055
|
+
return_code = None
|
|
1056
|
+
|
|
1057
|
+
try:
|
|
1058
|
+
with ManagedProcess(
|
|
1059
|
+
pip_cmd,
|
|
1060
|
+
stdout=subprocess.PIPE,
|
|
1061
|
+
stderr=subprocess.STDOUT,
|
|
1062
|
+
text=True,
|
|
1063
|
+
bufsize=1,
|
|
1064
|
+
universal_newlines=True,
|
|
1065
|
+
env=env
|
|
1066
|
+
) as process:
|
|
1067
|
+
# Stream output line by line
|
|
1068
|
+
if process.stdout is None:
|
|
1069
|
+
raise RuntimeError("Failed to capture subprocess output")
|
|
1070
|
+
for line in process.stdout:
|
|
1071
|
+
if self.cancel_event.is_set():
|
|
1072
|
+
self.app.call_from_thread(self._log_message, "\n🛑 Update cancelled by user")
|
|
1073
|
+
break
|
|
1074
|
+
# Display each line of pip output
|
|
1075
|
+
self.app.call_from_thread(self._log_message, line.rstrip())
|
|
1076
|
+
|
|
1077
|
+
# Wait for process to complete
|
|
1078
|
+
return_code = process.wait()
|
|
1079
|
+
except Exception as e:
|
|
1080
|
+
logger.error(f"Error during package update: {e}")
|
|
1081
|
+
self.app.call_from_thread(self._log_message, f"\n❌ Error: {e}")
|
|
1082
|
+
return_code = 1
|
|
1083
|
+
|
|
1084
|
+
if return_code == 0:
|
|
1085
|
+
# All packages updated successfully
|
|
1086
|
+
self.successful_updates.extend(package_names)
|
|
1087
|
+
self.app.call_from_thread(self._log_message, f"\n{'='*70}")
|
|
1088
|
+
self.app.call_from_thread(self._log_message, f"✅ Successfully updated all {total_packages} packages!")
|
|
1089
|
+
self.app.call_from_thread(self._log_message, f"{'='*70}")
|
|
1090
|
+
else:
|
|
1091
|
+
# Some packages failed - pip will have shown which ones in output
|
|
1092
|
+
self.failed_updates.extend(package_names)
|
|
1093
|
+
self.app.call_from_thread(self._log_message, f"\n{'='*70}")
|
|
1094
|
+
self.app.call_from_thread(self._log_message, "❌ Update completed with errors (see above)")
|
|
1095
|
+
self.app.call_from_thread(self._log_message, f"{'='*70}")
|
|
1096
|
+
|
|
1097
|
+
# Show final results and cleanup
|
|
1098
|
+
logger.info("Update loop completed, calling _update_complete")
|
|
1099
|
+
self.app.call_from_thread(self._update_complete)
|
|
1100
|
+
|
|
1101
|
+
finally:
|
|
1102
|
+
# Clean up temporary constraint file
|
|
1103
|
+
if constraint_file_path and os.path.exists(constraint_file_path):
|
|
1104
|
+
try:
|
|
1105
|
+
os.unlink(constraint_file_path)
|
|
1106
|
+
except Exception:
|
|
1107
|
+
pass # Best effort cleanup
|
|
1067
1108
|
|
|
1068
1109
|
except Exception as e:
|
|
1069
1110
|
logger.error(f"Error in update loop: {e}", exc_info=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pipu-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev4
|
|
4
4
|
Summary: A cute Python package updater
|
|
5
5
|
Author-email: Scott Arne Johnson <scott.arne.johnson@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,9 +11,9 @@ Requires-Python: >=3.10
|
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: rich_click<2.0,>=1.7
|
|
14
|
-
Requires-Dist: rich<
|
|
15
|
-
Requires-Dist: textual<
|
|
16
|
-
Requires-Dist: packaging<
|
|
14
|
+
Requires-Dist: rich<15.0,>=13.0
|
|
15
|
+
Requires-Dist: textual<7.0,>=0.40
|
|
16
|
+
Requires-Dist: packaging<26.0,>=23.0
|
|
17
17
|
Provides-Extra: dev
|
|
18
18
|
Requires-Dist: invoke; extra == "dev"
|
|
19
19
|
Requires-Dist: build; extra == "dev"
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
pipu_cli/__init__.py,sha256=
|
|
1
|
+
pipu_cli/__init__.py,sha256=ftE6SwRQUnMZwrCU25nvb-X0ASkV_TPiqhURZfbbaPU,1190
|
|
2
2
|
pipu_cli/cli.py,sha256=aCN2Fz1bWhXs8MC7kqy5GdzJggNtTdumW4PQkxKOBpg,39993
|
|
3
3
|
pipu_cli/common.py,sha256=g5krfXFsvVJpOf87Vw4DGi5WIduDgMlRuONKXqO328M,78
|
|
4
4
|
pipu_cli/config.py,sha256=xsfNU4ORAujla_FGfsMKpxy7QTpd_bJhRF_u4IPKLW0,3635
|
|
5
|
-
pipu_cli/internals.py,sha256=
|
|
5
|
+
pipu_cli/internals.py,sha256=u8J2df2rirOSgpeX3yp3ZHRLWyiqm7cMgo6TRFE8shU,35032
|
|
6
6
|
pipu_cli/package_constraints.py,sha256=6LSFlC93HNIFym7dYkfYn0fsOic6QDe1ADyghK94Pk8,93052
|
|
7
7
|
pipu_cli/thread_safe.py,sha256=zdQyCoMVJW73MC-d1pL_4ZO-K4AwkI0JeVyQsd8x7nY,7545
|
|
8
8
|
pipu_cli/utils.py,sha256=ijSHKVuKbjmRbj2RwD9S1606PeY4oDiutzhutpX25wM,5842
|
|
9
9
|
pipu_cli/ui/__init__.py,sha256=nCb_3G_vZXy5_Or9z9r-3XhYV1ppUR1r7nMZ9_6Srwg,1432
|
|
10
10
|
pipu_cli/ui/apps.py,sha256=ltH24sg-3nqVpoomgCwhVYuAwq3hBUwYRH60JXtV2Yg,59771
|
|
11
11
|
pipu_cli/ui/constants.py,sha256=HBPf4KYWHiT18c7ciQ0HeI7gZE3VIFOT0uobLU8YxQA,445
|
|
12
|
-
pipu_cli/ui/modal_dialogs.py,sha256=
|
|
12
|
+
pipu_cli/ui/modal_dialogs.py,sha256=_Q6BIJBX9l6CpqDILH3WqPfKYMqRlDnMLNUelIhZdUM,48248
|
|
13
13
|
pipu_cli/ui/table_widgets.py,sha256=PC0CqqrK3KgMbTCYRPG01lxkEtRBz9xr9PN8EzoObz8,14322
|
|
14
|
-
pipu_cli-0.1.
|
|
15
|
-
pipu_cli-0.1.
|
|
16
|
-
pipu_cli-0.1.
|
|
17
|
-
pipu_cli-0.1.
|
|
18
|
-
pipu_cli-0.1.
|
|
19
|
-
pipu_cli-0.1.
|
|
14
|
+
pipu_cli-0.1.dev4.dist-info/licenses/LICENSE,sha256=q6TxVbSI0WMB9ulF2V0FWQfeA5om3d-T9X7QwuhdiYE,1075
|
|
15
|
+
pipu_cli-0.1.dev4.dist-info/METADATA,sha256=jSrp9kzQLwM6zr60AwSeiiZ6eqpBD1TK0IsoWLwQPSs,13200
|
|
16
|
+
pipu_cli-0.1.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
17
|
+
pipu_cli-0.1.dev4.dist-info/entry_points.txt,sha256=VSv6od00zOPblnFPflNLaci4jBtQIgLYJjL1BKxLz_o,42
|
|
18
|
+
pipu_cli-0.1.dev4.dist-info/top_level.txt,sha256=z3Yce93-jGQjGRpsGZUZvbS8osh3OyS7MVpzG0uBE5M,9
|
|
19
|
+
pipu_cli-0.1.dev4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|