@@ -1437,3 +1437,379 @@ helm-deploy: helm-lint
1437
1437
helm-delete :
1438
1438
@echo " 🗑 Deleting $( RELEASE_NAME) release..."
1439
1439
helm uninstall $(RELEASE_NAME ) -n $(NAMESPACE ) || true
1440
+
1441
+ # =============================================================================
1442
+ # 🏠 LOCAL PYPI SERVER
1443
+ # Currently blocked by: https://github.com/pypiserver/pypiserver/issues/630
1444
+ # =============================================================================
1445
+ # help: 🏠 LOCAL PYPI SERVER
1446
+ # help: local-pypi-install - Install pypiserver for local testing
1447
+ # help: local-pypi-start - Start local PyPI server on :8084 (no auth)
1448
+ # help: local-pypi-start-auth - Start local PyPI server with basic auth (admin/admin)
1449
+ # help: local-pypi-stop - Stop local PyPI server
1450
+ # help: local-pypi-upload - Upload existing package to local PyPI (no auth)
1451
+ # help: local-pypi-upload-auth - Upload existing package to local PyPI (with auth)
1452
+ # help: local-pypi-test - Install package from local PyPI
1453
+ # help: local-pypi-clean - Full cycle: build → upload → install locally
1454
+
1455
+ .PHONY : local-pypi-install local-pypi-start local-pypi-start-auth local-pypi-stop local-pypi-upload \
1456
+ local-pypi-upload-auth local-pypi-test local-pypi-clean
1457
+
1458
+ LOCAL_PYPI_DIR := $(HOME ) /local-pypi
1459
+ LOCAL_PYPI_URL := http://localhost:8085
1460
+ LOCAL_PYPI_PID := /tmp/pypiserver.pid
1461
+ LOCAL_PYPI_AUTH := $(LOCAL_PYPI_DIR ) /.htpasswd
1462
+
1463
+ local-pypi-install :
1464
+ @echo " 📦 Installing pypiserver..."
1465
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && pip install 'pypiserver>=2.3.0' passlib"
1466
+ @mkdir -p $(LOCAL_PYPI_DIR )
1467
+
1468
+ local-pypi-start : local-pypi-install local-pypi-stop
1469
+ @echo " 🚀 Starting local PyPI server on http://localhost:8084..."
1470
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1471
+ export PYPISERVER_BOTTLE_MEMFILE_MAX_OVERRIDE_BYTES=10485760 && \
1472
+ pypi-server run -p 8084 -a . -P . $(LOCAL_PYPI_DIR ) --hash-algo=sha256 & echo \$ ! > $(LOCAL_PYPI_PID ) "
1473
+ @sleep 2
1474
+ @echo " ✅ Local PyPI server started at http://localhost:8084"
1475
+ @echo " 📂 Package directory: $( LOCAL_PYPI_DIR) "
1476
+ @echo " 🔓 No authentication required (open mode)"
1477
+
1478
+ local-pypi-start-auth : local-pypi-install local-pypi-stop
1479
+ @echo " 🚀 Starting local PyPI server with authentication on $( LOCAL_PYPI_URL) ..."
1480
+ @echo " 🔐 Creating htpasswd file (admin/admin)..."
1481
+ @mkdir -p $(LOCAL_PYPI_DIR )
1482
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1483
+ python3 -c \" import passlib.hash; print(' admin:' + passlib.hash.sha256_crypt.hash(' admin' ))\" > $(LOCAL_PYPI_AUTH ) "
1484
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1485
+ export PYPISERVER_BOTTLE_MEMFILE_MAX_OVERRIDE_BYTES=10485760 && \
1486
+ pypi-server run -p 8085 -P $(LOCAL_PYPI_AUTH ) -a update,download,list $(LOCAL_PYPI_DIR ) --hash-algo=sha256 & echo \$ ! > $(LOCAL_PYPI_PID ) "
1487
+ @sleep 2
1488
+ @echo " ✅ Local PyPI server started at $( LOCAL_PYPI_URL) "
1489
+ @echo " 📂 Package directory: $( LOCAL_PYPI_DIR) "
1490
+ @echo " 🔐 Username: admin, Password: admin"
1491
+
1492
+ local-pypi-stop :
1493
+ @echo " 🛑 Stopping local PyPI server..."
1494
+ @if [ -f $( LOCAL_PYPI_PID) ]; then \
1495
+ kill $(cat $(LOCAL_PYPI_PID ) ) 2> /dev/null || true ; \
1496
+ rm -f $(LOCAL_PYPI_PID ) ; \
1497
+ fi
1498
+ @# Kill any pypi-server processes on ports 8084 and 8085
1499
+ @pkill -f " pypi-server.*808[45]" 2> /dev/null || true
1500
+ @# Wait a moment for cleanup
1501
+ @sleep 1
1502
+ @if lsof -i :8084 > /dev/null 2>&1 ; then \
1503
+ echo " ⚠️ Port 8084 still in use, force killing..." ; \
1504
+ sudo fuser -k 8084/tcp 2> /dev/null || true ; \
1505
+ fi
1506
+ @if lsof -i :8085 > /dev/null 2>&1 ; then \
1507
+ echo " ⚠️ Port 8085 still in use, force killing..." ; \
1508
+ sudo fuser -k 8085/tcp 2> /dev/null || true ; \
1509
+ fi
1510
+ @sleep 1
1511
+ @echo " ✅ Server stopped"
1512
+
1513
+ local-pypi-upload :
1514
+ @echo " 📤 Uploading existing package to local PyPI (no auth)..."
1515
+ @if [ ! -d " dist" ] || [ -z " $$ (ls -A dist/ 2>/dev/null)" ]; then \
1516
+ echo " ❌ No dist/ directory or files found. Run 'make dist' first." ; \
1517
+ exit 1; \
1518
+ fi
1519
+ @if ! curl -s http://localhost:8084 > /dev/null 2>&1 ; then \
1520
+ echo " ❌ Local PyPI server not running on port 8084. Run 'make local-pypi-start' first." ; \
1521
+ exit 1; \
1522
+ fi
1523
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1524
+ twine upload --verbose --repository-url http://localhost:8084 --skip-existing dist/* "
1525
+ @echo " ✅ Package uploaded to local PyPI"
1526
+ @echo " 🌐 Browse packages: http://localhost:8084"
1527
+
1528
+ local-pypi-upload-auth :
1529
+ @echo " 📤 Uploading existing package to local PyPI with auth..."
1530
+ @if [ ! -d " dist" ] || [ -z " $$ (ls -A dist/ 2>/dev/null)" ]; then \
1531
+ echo " ❌ No dist/ directory or files found. Run 'make dist' first." ; \
1532
+ exit 1; \
1533
+ fi
1534
+ @if ! curl -s $(LOCAL_PYPI_URL ) > /dev/null 2>&1 ; then \
1535
+ echo " ❌ Local PyPI server not running on port 8085. Run 'make local-pypi-start-auth' first." ; \
1536
+ exit 1; \
1537
+ fi
1538
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1539
+ twine upload --verbose --repository-url $(LOCAL_PYPI_URL ) --username admin --password admin --skip-existing dist/* "
1540
+ @echo " ✅ Package uploaded to local PyPI"
1541
+ @echo " 🌐 Browse packages: $( LOCAL_PYPI_URL) "
1542
+
1543
+ local-pypi-test :
1544
+ @echo " 📥 Installing from local PyPI..."
1545
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1546
+ pip install --index-url $(LOCAL_PYPI_URL ) /simple/ \
1547
+ --extra-index-url https://pypi.org/simple/ \
1548
+ --force-reinstall $(PROJECT_NAME ) "
1549
+ @echo " ✅ Installed from local PyPI"
1550
+
1551
+ local-pypi-clean : clean dist local-pypi-start-auth local-pypi-upload-auth local-pypi-test
1552
+ @echo " 🎉 Full local PyPI cycle complete!"
1553
+ @echo " 📊 Package info:"
1554
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && pip show $( PROJECT_NAME) "
1555
+
1556
+ # Convenience target to restart server
1557
+ local-pypi-restart : local-pypi-stop local-pypi-start
1558
+
1559
+ local-pypi-restart-auth : local-pypi-stop local-pypi-start-auth
1560
+
1561
+ # Show server status
1562
+ local-pypi-status :
1563
+ @echo " 🔍 Local PyPI server status:"
1564
+ @if [ -f $( LOCAL_PYPI_PID) ] && kill -0 $(cat $(LOCAL_PYPI_PID ) ) 2> /dev/null; then \
1565
+ echo " ✅ Server running (PID: $( cat $( LOCAL_PYPI_PID) ) )" ; \
1566
+ if curl -s http://localhost:8084 > /dev/null 2>&1 ; then \
1567
+ echo " 🌐 Server on port 8084: http://localhost:8084" ; \
1568
+ elif curl -s $(LOCAL_PYPI_URL ) > /dev/null 2>&1 ; then \
1569
+ echo " 🌐 Server on port 8085: $( LOCAL_PYPI_URL) " ; \
1570
+ fi ; \
1571
+ echo " 📂 Directory: $( LOCAL_PYPI_DIR) " ; \
1572
+ else \
1573
+ echo " ❌ Server not running" ; \
1574
+ fi
1575
+
1576
+ # Debug target - run server in foreground with verbose logging
1577
+ local-pypi-debug :
1578
+ @echo " 🐛 Running local PyPI server in debug mode (Ctrl+C to stop)..."
1579
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1580
+ export PYPISERVER_BOTTLE_MEMFILE_MAX_OVERRIDE_BYTES=10485760 && \
1581
+ export BOTTLE_CHILD=true && \
1582
+ pypi-server run -p 8085 --disable-fallback -a . -P . --server=auto $(LOCAL_PYPI_DIR ) -v"
1583
+
1584
+
1585
+ # =============================================================================
1586
+ # 🏠 LOCAL DEVPI SERVER
1587
+ # =============================================================================
1588
+ # help: 🏠 LOCAL DEVPI SERVER
1589
+ # help: devpi-install - Install devpi server and client
1590
+ # help: devpi-init - Initialize devpi server (first time only)
1591
+ # help: devpi-start - Start devpi server
1592
+ # help: devpi-stop - Stop devpi server
1593
+ # help: devpi-setup-user - Create user and dev index
1594
+ # help: devpi-upload - Upload existing package to devpi
1595
+ # help: devpi-test - Install package from devpi
1596
+ # help: devpi-clean - Full cycle: build → upload → install locally
1597
+ # help: devpi-status - Show devpi server status
1598
+ # help: devpi-web - Open devpi web interface
1599
+
1600
+ .PHONY : devpi-install devpi-init devpi-start devpi-stop devpi-setup-user devpi-upload \
1601
+ devpi-test devpi-clean devpi-status devpi-web devpi-restart
1602
+
1603
+ DEVPI_HOST := localhost
1604
+ DEVPI_PORT := 3141
1605
+ DEVPI_URL := http://$(DEVPI_HOST ) :$(DEVPI_PORT )
1606
+ DEVPI_USER := $(USER )
1607
+ DEVPI_PASS := dev123
1608
+ DEVPI_INDEX := $(DEVPI_USER ) /dev
1609
+ DEVPI_DATA_DIR := $(HOME ) /.devpi
1610
+ DEVPI_PID := /tmp/devpi-server.pid
1611
+
1612
+ devpi-install :
1613
+ @echo " 📦 Installing devpi server and client..."
1614
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1615
+ pip install devpi-server devpi-client devpi-web"
1616
+ @echo " ✅ DevPi installed"
1617
+
1618
+ devpi-init : devpi-install
1619
+ @echo " 🔧 Initializing devpi server (first time setup)..."
1620
+ @if [ -d " $( DEVPI_DATA_DIR) /server" ] && [ -f " $( DEVPI_DATA_DIR) /server/.serverversion" ]; then \
1621
+ echo " ⚠️ DevPi already initialized at $( DEVPI_DATA_DIR) " ; \
1622
+ else \
1623
+ mkdir -p $(DEVPI_DATA_DIR ) /server; \
1624
+ /bin/bash -c " source $( VENV_DIR) /bin/activate && \
1625
+ devpi-init --serverdir=$(DEVPI_DATA_DIR ) /server" ; \
1626
+ echo " ✅ DevPi server initialized at $( DEVPI_DATA_DIR) /server" ; \
1627
+ fi
1628
+
1629
+ devpi-start : devpi-init devpi-stop
1630
+ @echo " 🚀 Starting devpi server on $( DEVPI_URL) ..."
1631
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1632
+ devpi-server --serverdir=$(DEVPI_DATA_DIR ) /server \
1633
+ --host=$(DEVPI_HOST ) \
1634
+ --port=$(DEVPI_PORT ) & "
1635
+ @# Wait for server to start and get the PID
1636
+ @sleep 3
1637
+ @ps aux | grep " [d]evpi-server" | grep " $( DEVPI_PORT) " | awk ' {print $2}' > $(DEVPI_PID ) || true
1638
+ @# Wait a bit more and test if server is responding
1639
+ @sleep 2
1640
+ @if curl -s $(DEVPI_URL ) > /dev/null 2>&1 ; then \
1641
+ if [ -s $( DEVPI_PID) ]; then \
1642
+ echo " ✅ DevPi server started at $( DEVPI_URL) " ; \
1643
+ echo " 📊 PID: $( cat $( DEVPI_PID) ) " ; \
1644
+ else \
1645
+ echo " ✅ DevPi server started at $( DEVPI_URL) " ; \
1646
+ fi ; \
1647
+ echo " 🌐 Web interface: $( DEVPI_URL) " ; \
1648
+ echo " 📂 Data directory: $( DEVPI_DATA_DIR) " ; \
1649
+ else \
1650
+ echo " ❌ Failed to start devpi server or server not responding" ; \
1651
+ echo " 🔍 Check logs with: make devpi-logs" ; \
1652
+ exit 1; \
1653
+ fi
1654
+
1655
+ devpi-stop :
1656
+ @echo " 🛑 Stopping devpi server..."
1657
+ @# Kill process by PID if exists
1658
+ @if [ -f $( DEVPI_PID) ] && [ -s $( DEVPI_PID) ]; then \
1659
+ pid=$(cat $(DEVPI_PID ) ) ; \
1660
+ if kill -0 $pid 2> /dev/null; then \
1661
+ echo " 🔄 Stopping devpi server (PID: $pid )" ; \
1662
+ kill $pid 2> /dev/null || true ; \
1663
+ sleep 2; \
1664
+ kill -9 $pid 2> /dev/null || true ; \
1665
+ fi ; \
1666
+ rm -f $(DEVPI_PID ) ; \
1667
+ fi
1668
+ @# Kill any remaining devpi-server processes
1669
+ @pids=$(pgrep -f "devpi-server.*$(DEVPI_PORT ) " 2>/dev/null || true ) ; \
1670
+ if [ -n " $pids " ]; then \
1671
+ echo " 🔄 Killing remaining devpi processes: $pids " ; \
1672
+ echo " $pids " | xargs -r kill 2> /dev/null || true ; \
1673
+ sleep 1; \
1674
+ echo " $pids " | xargs -r kill -9 2> /dev/null || true ; \
1675
+ fi
1676
+ @# Force kill anything using the port
1677
+ @if lsof -ti :$(DEVPI_PORT ) > /dev/null 2>&1 ; then \
1678
+ echo " ⚠️ Port $( DEVPI_PORT) still in use, force killing..." ; \
1679
+ lsof -ti :$(DEVPI_PORT ) | xargs -r kill -9 2> /dev/null || true ; \
1680
+ sleep 1; \
1681
+ fi
1682
+ @echo " ✅ DevPi server stopped"
1683
+
1684
+ devpi-setup-user : devpi-start
1685
+ @echo " 👤 Setting up devpi user and index..."
1686
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1687
+ devpi use $(DEVPI_URL ) && \
1688
+ (devpi user -c $( DEVPI_USER) password=$( DEVPI_PASS) email=$( DEVPI_USER) @localhost.local 2> /dev/null || \
1689
+ echo ' User $(DEVPI_USER) already exists' ) && \
1690
+ devpi login $(DEVPI_USER ) --password=$(DEVPI_PASS ) && \
1691
+ (devpi index -c dev bases=root/pypi volatile=False 2> /dev/null || \
1692
+ echo ' Index dev already exists' ) && \
1693
+ devpi use $(DEVPI_INDEX ) "
1694
+ @echo " ✅ User '$( DEVPI_USER) ' and index 'dev' configured"
1695
+ @echo " 📝 Login: $( DEVPI_USER) / $( DEVPI_PASS) "
1696
+ @echo " 📍 Using index: $( DEVPI_INDEX) "
1697
+
1698
+ devpi-upload : devpi-setup-user
1699
+ @echo " 📤 Uploading existing package to devpi..."
1700
+ @if [ ! -d " dist" ] || [ -z " $$ (ls -A dist/ 2>/dev/null)" ]; then \
1701
+ echo " ❌ No dist/ directory or files found. Run 'make dist' first." ; \
1702
+ exit 1; \
1703
+ fi
1704
+ @if ! curl -s $(DEVPI_URL ) > /dev/null 2>&1 ; then \
1705
+ echo " ❌ DevPi server not running. Run 'make devpi-start' first." ; \
1706
+ exit 1; \
1707
+ fi
1708
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1709
+ devpi use $(DEVPI_INDEX ) && \
1710
+ devpi upload dist/* "
1711
+ @echo " ✅ Package uploaded to devpi"
1712
+ @echo " 🌐 Browse packages: $( DEVPI_URL) /$( DEVPI_INDEX) "
1713
+
1714
+ devpi-test :
1715
+ @echo " 📥 Installing package from devpi..."
1716
+ @if ! curl -s $(DEVPI_URL ) > /dev/null 2>&1 ; then \
1717
+ echo " ❌ DevPi server not running. Run 'make devpi-start' first." ; \
1718
+ exit 1; \
1719
+ fi
1720
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
1721
+ pip install --index-url $(DEVPI_URL ) /$(DEVPI_INDEX ) /+simple/ \
1722
+ --extra-index-url https://pypi.org/simple/ \
1723
+ --force-reinstall $(PROJECT_NAME ) "
1724
+ @echo " ✅ Installed $( PROJECT_NAME) from devpi"
1725
+
1726
+ devpi-clean : clean dist devpi-upload devpi-test
1727
+ @echo " 🎉 Full devpi cycle complete!"
1728
+ @echo " 📊 Package info:"
1729
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && pip show $( PROJECT_NAME) "
1730
+
1731
+ devpi-status :
1732
+ @echo " 🔍 DevPi server status:"
1733
+ @if curl -s $(DEVPI_URL ) > /dev/null 2>&1 ; then \
1734
+ echo " ✅ Server running at $( DEVPI_URL) " ; \
1735
+ if [ -f $( DEVPI_PID) ] && [ -s $( DEVPI_PID) ]; then \
1736
+ echo " 📊 PID: $$ (cat $( DEVPI_PID) )" ; \
1737
+ fi ; \
1738
+ echo " 📂 Data directory: $( DEVPI_DATA_DIR) " ; \
1739
+ /bin/bash -c " source $( VENV_DIR) /bin/activate && \
1740
+ devpi use $(DEVPI_URL ) > /dev/null 2>&1 && \
1741
+ devpi user --list 2> /dev/null || echo ' 📝 Not logged in' " ; \
1742
+ else \
1743
+ echo " ❌ Server not running" ; \
1744
+ fi
1745
+
1746
+ devpi-web :
1747
+ @echo " 🌐 Opening devpi web interface..."
1748
+ @if curl -s $(DEVPI_URL ) > /dev/null 2>&1 ; then \
1749
+ echo " 📱 Web interface: $( DEVPI_URL) " ; \
1750
+ which open > /dev/null 2>&1 && open $(DEVPI_URL ) || \
1751
+ which xdg-open > /dev/null 2>&1 && xdg-open $(DEVPI_URL ) || \
1752
+ echo " 🔗 Open $( DEVPI_URL) in your browser" ; \
1753
+ else \
1754
+ echo " ❌ DevPi server not running. Run 'make devpi-start' first." ; \
1755
+ fi
1756
+
1757
+ devpi-restart : devpi-stop devpi-start
1758
+ @echo " 🔄 DevPi server restarted"
1759
+
1760
+ # Advanced targets for devpi management
1761
+ devpi-reset : devpi-stop
1762
+ @echo " ⚠️ Resetting devpi server (this will delete all data)..."
1763
+ @read -p " Are you sure? This will delete all packages and users [y/N]: " confirm; \
1764
+ if [ " $$ confirm" = " y" ] || [ " $$ confirm" = " Y" ]; then \
1765
+ rm -rf $(DEVPI_DATA_DIR ) ; \
1766
+ echo " ✅ DevPi data reset. Run 'make devpi-init' to reinitialize." ; \
1767
+ else \
1768
+ echo " ❌ Reset cancelled." ; \
1769
+ fi
1770
+
1771
+ devpi-backup :
1772
+ @echo " 💾 Backing up devpi data..."
1773
+ @timestamp=$$(date +%Y%m%d-%H%M%S ) ; \
1774
+ backup_file=" $( HOME) /devpi-backup-$$ timestamp.tar.gz" ; \
1775
+ tar -czf " $$ backup_file" -C $(HOME ) .devpi 2> /dev/null && \
1776
+ echo " ✅ Backup created: $$ backup_file" || \
1777
+ echo " ❌ Backup failed"
1778
+
1779
+ devpi-logs :
1780
+ @echo " 📋 DevPi server logs:"
1781
+ @if [ -f " $( DEVPI_DATA_DIR) /server/devpi.log" ]; then \
1782
+ tail -f " $( DEVPI_DATA_DIR) /server/devpi.log" ; \
1783
+ elif [ -f " $( DEVPI_DATA_DIR) /server/.xproc/devpi-server/xprocess.log" ]; then \
1784
+ tail -f " $( DEVPI_DATA_DIR) /server/.xproc/devpi-server/xprocess.log" ; \
1785
+ elif [ -f " $( DEVPI_DATA_DIR) /server/devpi-server.log" ]; then \
1786
+ tail -f " $( DEVPI_DATA_DIR) /server/devpi-server.log" ; \
1787
+ else \
1788
+ echo " ❌ No log file found. Checking if server is running..." ; \
1789
+ ps aux | grep " [d]evpi-server" || echo " Server not running" ; \
1790
+ echo " 📂 Expected log location: $( DEVPI_DATA_DIR) /server/devpi.log" ; \
1791
+ fi
1792
+
1793
+ # Configuration helper - creates pip.conf for easy devpi usage
1794
+ devpi-configure-pip :
1795
+ @echo " ⚙️ Configuring pip to use devpi by default..."
1796
+ @mkdir -p $(HOME ) /.pip
1797
+ @echo " [global]" > $(HOME ) /.pip/pip.conf
1798
+ @echo " index-url = $( DEVPI_URL) /$( DEVPI_INDEX) /+simple/" >> $(HOME ) /.pip/pip.conf
1799
+ @echo " extra-index-url = https://pypi.org/simple/" >> $(HOME ) /.pip/pip.conf
1800
+ @echo " trusted-host = $( DEVPI_HOST) " >> $(HOME ) /.pip/pip.conf
1801
+ @echo " " >> $(HOME ) /.pip/pip.conf
1802
+ @echo " [search]" >> $(HOME ) /.pip/pip.conf
1803
+ @echo " index = $( DEVPI_URL) /$( DEVPI_INDEX) /" >> $(HOME ) /.pip/pip.conf
1804
+ @echo " ✅ Pip configured to use devpi at $( DEVPI_URL) /$( DEVPI_INDEX) "
1805
+ @echo " 📝 Config file: $( HOME) /.pip/pip.conf"
1806
+
1807
+ # Remove pip devpi configuration
1808
+ devpi-unconfigure-pip :
1809
+ @echo " 🔧 Removing devpi from pip configuration..."
1810
+ @if [ -f " $( HOME) /.pip/pip.conf" ]; then \
1811
+ rm " $( HOME) /.pip/pip.conf" ; \
1812
+ echo " ✅ Pip configuration reset to defaults" ; \
1813
+ else \
1814
+ echo " ℹ️ No pip configuration found" ; \
1815
+ fi
0 commit comments