Skip to content

Commit 1b9ab49

Browse files
committed
feat: requirements.txt support 🎯
1 parent 45609a8 commit 1b9ab49

3 files changed

Lines changed: 56 additions & 9 deletions

File tree

omnipkg/cli.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import sys
66
import argparse
77
from .core import omnipkg, ConfigManager
8+
from pathlib import Path
89

910
def print_header(title):
1011
"""Prints a consistent, pretty header for CLI sections."""
@@ -36,7 +37,14 @@ def create_parser():
3637
subparsers = parser.add_subparsers(dest='command', help='All available commands:', required=True)
3738

3839
install_parser = subparsers.add_parser('install', help='Install packages (with downgrade protection)')
39-
install_parser.add_argument('packages', nargs='+', help='Packages to install (e.g., "requests==2.25.1")')
40+
# Make 'packages' optional (nargs='*') to allow using -r instead
41+
install_parser.add_argument('packages', nargs='*', help='Packages to install (e.g., "requests==2.25.1")')
42+
# Add the new -r/--requirement flag
43+
install_parser.add_argument(
44+
'-r', '--requirement',
45+
help='Install from the given requirements file.',
46+
metavar='FILE'
47+
)
4048

4149
uninstall_parser = subparsers.add_parser('uninstall', help='Uninstall packages from main env or bubbles')
4250
uninstall_parser.add_argument('packages', nargs='+', help='Packages to uninstall (e.g., "requests" or "requests==2.25.1")')
@@ -95,8 +103,43 @@ def main():
95103
# Now, create the main instance, PASSING IN the loaded config
96104
pkg_instance = omnipkg(cm.config)
97105
try:
106+
# In omnipkg/cli.py -> main()
107+
98108
if args.command == 'install':
99-
return pkg_instance.smart_install(args.packages)
109+
packages_to_process = []
110+
111+
if args.requirement:
112+
# User provided a requirements file
113+
req_path = Path(args.requirement)
114+
if not req_path.is_file():
115+
print(f"❌ Error: Requirements file not found at '{req_path}'")
116+
return 1
117+
118+
print(f"📄 Reading packages from {req_path.name}...")
119+
# In omnipkg/cli.py -> main()
120+
121+
with open(req_path, 'r') as f:
122+
# Parse the file, handling inline comments and empty lines
123+
packages_to_process = []
124+
for line in f:
125+
# Get the part before any comment and strip whitespace
126+
clean_line = line.split('#')[0].strip()
127+
# Only add it to our list if it's not an empty string
128+
if clean_line:
129+
packages_to_process.append(clean_line)
130+
131+
elif args.packages:
132+
# User provided packages directly on the command line
133+
packages_to_process = args.packages
134+
135+
else:
136+
# No packages or file provided
137+
print("❌ Error: You must either specify packages to install or use the -r flag.")
138+
print(" Example: `omnipkg install requests` or `omnipkg install -r requirements.txt`")
139+
return 1
140+
141+
# The magic happens here: pass the list to your existing core logic
142+
return pkg_instance.smart_install(packages_to_process)
100143
elif args.command == 'uninstall':
101144
return pkg_instance.smart_uninstall(args.packages, force=args.yes)
102145

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "omnipkg"
7-
version = "1.0.6"
7+
version = "1.0.7"
88
authors = [
99
{ name = "1minds3t", email = "omnipkg@proton.me" },
1010
]

requirements.txt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
redis
2-
zstandard
3-
psycopg2-binary
4-
python-dotenv
5-
packaging>=25.0
6-
requests>=2.32.4
1+
# Test requirements for omnipkg v1.0.7
2+
# We are intentionally mixing the order to test the sorting logic.
3+
4+
poetry==1.7.1 # Legacy poetry version
5+
6+
uv==0.8.5
7+
poetry==1.8.0 # The newer version of poetry
8+
9+
# And a legacy version of uv
10+
uv==0.7.13

0 commit comments

Comments
 (0)