1+ import argparse
12import pathlib
23import random
34import shutil
45import string
56import subprocess
7+ from typing import Optional
68
7- import click
9+ import compas
810
11+ executable = "python" if compas .WINDOWS else "python3.9"
912rhinocode = pathlib .Path ().home () / ".rhinocode"
10- rhinopython = rhinocode / "py39-rh8" / "python3.9"
13+ rhinopython = rhinocode / "py39-rh8" / executable
1114site_envs = rhinocode / "py39-rh8" / "site-envs"
1215
1316
@@ -22,10 +25,6 @@ def find_full_env_name(name: str) -> str:
2225 raise ValueError (f"No environment with this name exists: { name } " )
2326
2427
25- def default_env_name () -> str :
26- return find_full_env_name ("default" )
27-
28-
2928def ensure_site_env (name : str ) -> str :
3029 try :
3130 fullname = find_full_env_name (name )
@@ -34,60 +33,31 @@ def ensure_site_env(name: str) -> str:
3433 return fullname
3534
3635
37- @click .command ()
38- @click .argument ("package" )
39- @click .option ("--env" , default = "default" , help = "Name of the site env, without the random suffix..." )
40- @click .option ("--upgrade/--no-upgrade" , default = False )
41- @click .option ("--deps/--no-deps" , default = True )
42- @click .option ("--clear/--no-clear" , default = False )
4336def install_package (
44- package : str ,
37+ packages : list [str ],
38+ requirements : Optional [str ] = None ,
4539 env : str = "default" ,
4640 upgrade : bool = False ,
4741 deps : bool = True ,
4842 clear : bool = False ,
4943):
50- """Install a package with Rhino's CPython pip.
51-
52- Parameters
53- ----------
54- package : str
55- If a package name is provided, the package will be installed from PyPI.
56- If `.` or `..` is specified, the package will be installed from the source in the current or parent folder, respectively.
57- env : str, optional
58- The name of the virtual (site) environment in Rhino, without the random suffix.
59- If no environment name is provided, the default environment will be used.
60- If the environment doesn't exist, it will be created automatically.
61- upgrade : bool, optional
62- Attempt to upgrade packages that were already installed.
63- The default is False.
64- deps : bool, optional
65- Attempt to install the package dependencies.
66- Default is True.
67-
68- Returns
69- -------
70- str
71- The output of the call to pip.
72-
73- Examples
74- --------
75- When COMPAS is installed, the function is registered as an executable command with the name `install_in_rhino`.
76-
77- $ cd path/to/local/compas/repo
78- $ install_in_rhino .
79-
80- $ cd path/to/local/compas/repo
81- $ install_in_rhino . --env=compas-dev
82-
83- $ cd path/to/local/compas/repo
84- $ install_in_rhino . --env=compas-dev --upgrade --no-deps
85-
86- """
87- if package == "." :
88- package = str (pathlib .Path ().cwd ())
89- elif package == ".." :
90- package = str (pathlib .Path ().cwd ().parent )
44+ """Install a package with Rhino's CPython pip."""
45+
46+ if requirements and packages :
47+ raise ValueError ("You must provide either packages or a requirements file, not both." )
48+
49+ if requirements :
50+ params = ["-r" , str (pathlib .Path (requirements ).resolve ())]
51+ elif packages :
52+ params = []
53+ for p in packages :
54+ if p == "." :
55+ p = str (pathlib .Path ().cwd ())
56+ elif p == ".." :
57+ p = str (pathlib .Path ().cwd ().parent )
58+ params .append (p )
59+ else :
60+ raise ValueError ("You must provide either packages or a requirements file." )
9161
9262 env = env or "default"
9363
@@ -108,24 +78,40 @@ def install_package(
10878 "-m" ,
10979 "pip" ,
11080 "install" ,
111- package ,
81+ * params ,
11282 "--target" ,
113- target ,
83+ str ( target ) ,
11484 "--no-warn-script-location" ,
11585 ]
11686
11787 if upgrade :
11888 args .append ("--upgrade" )
119-
12089 if not deps :
12190 args .append ("--no-deps" )
12291
12392 return subprocess .check_call (args )
12493
12594
126- # =============================================================================
127- # Main
128- # =============================================================================
95+ def main ():
96+ parser = argparse .ArgumentParser (description = "Install a package with Rhino's CPython pip." )
97+ parser .add_argument ("packages" , help = "The package(s) to install (PyPI names or local package paths)" , nargs = "*" )
98+ parser .add_argument ("-r" , "--requirements" , help = "Path to a requirements file" )
99+ parser .add_argument ("--env" , default = "default" , help = "Name of the site env, without the random suffix" )
100+ parser .add_argument ("--upgrade" , action = "store_true" , help = "Attempt to upgrade packages already installed" )
101+ parser .add_argument ("--no-deps" , dest = "deps" , action = "store_false" , help = "Do not install dependencies" )
102+ parser .add_argument ("--clear" , action = "store_true" , help = "Clear the environment before installing" )
103+ parser .set_defaults (deps = True )
104+ args = parser .parse_args ()
105+
106+ install_package (
107+ packages = args .packages ,
108+ requirements = args .requirements ,
109+ env = args .env ,
110+ upgrade = args .upgrade ,
111+ deps = args .deps ,
112+ clear = args .clear ,
113+ )
114+
129115
130116if __name__ == "__main__" :
131- install_package ()
117+ main ()
0 commit comments