3333 - python scripts execution
3434 - shell scripts execution
3535
36- On posix, posix Python and shell scripts are executed before mac or linux
36+ On posix, posix Python and shell scripts are executed before mac or linux
3737scripts.
3838
3939The base scripts or packages are always installed first before platform-
7878 raise Exception ('Unsupported OS/platform' )
7979 platform_names = tuple ()
8080
81+
8182# common file basenames for requirements and scripts
8283base = ('base' ,)
8384
9697 shell_scripts = ('win.bat' ,)
9798
9899
99- def call (cmd ):
100+ def call (cmd , root_dir ):
100101 """ Run a `cmd` command (as a list of args) with all env vars."""
101102 cmd = ' ' .join (cmd )
102- if subprocess .Popen (cmd , shell = True , env = dict (os .environ )).wait () != 0 :
103+ if subprocess .Popen (cmd , shell = True , env = dict (os .environ ), cwd = root_dir ).wait () != 0 :
103104 print ()
104- print ('Failed to execute command:\n %(cmd)s' % locals ())
105+ print ('Failed to execute command:\n %(cmd)s. Aborting... ' % locals ())
105106 sys .exit (1 )
106107
107108
109+ def find_pycache (root_dir ):
110+ """
111+ Yield __pycache__ directory paths found in root_dir as paths relative to
112+ root_dir.
113+ """
114+ for top , dirs , _files in os .walk (root_dir ):
115+ for d in dirs :
116+ if d == '__pycache__' :
117+ dir_path = os .path .join (top , d )
118+ dir_path = dir_path .replace (root_dir , '' , 1 )
119+ dir_path = dir_path .strip (os .path .sep )
120+ yield dir_path
121+
122+
108123def clean (root_dir ):
109124 """
110- Remove cleanable directories and files.
125+ Remove cleanable directories and files in root_dir .
111126 """
112127 print ('* Cleaning ...' )
113- cleanable = '''build bin lib include Scripts
128+ cleanable = '''build bin lib Lib include Include Scripts local
114129 django_background_task.log
115- develop-eggs eggs parts .installed.cfg
130+ develop-eggs eggs parts .installed.cfg
116131 .Python
117132 .cache
118- .settings
119133 pip-selfcheck.json
120134 ''' .split ()
121135
136+ # also clean __pycache__ if any
137+ cleanable .extend (find_pycache (root_dir ))
138+
122139 for d in cleanable :
123140 try :
124141 loc = os .path .join (root_dir , d )
@@ -130,19 +147,23 @@ def clean(root_dir):
130147 except :
131148 pass
132149
133- def build_pip_dirs_args (paths , option = '--extra-search-dir=' ):
150+
151+ def build_pip_dirs_args (paths , root_dir , option = '--extra-search-dir=' ):
134152 """
135- Return an iterable of pip command line arguments for the `option` pip
136- command line option using a list of `paths` to directories.
153+ Return an iterable of pip command line options for `option` of pip using a
154+ list of `paths` to directories.
137155 """
138156 for path in paths :
157+ if not os .path .isabs (path ):
158+ path = os .path .join (root_dir , path )
139159 if os .path .exists (path ):
140160 yield option + path
141161
142- def create_virtualenv (std_python , root_dir , tpp_dirs ):
162+
163+ def create_virtualenv (std_python , root_dir , tpp_dirs , quiet = False ):
143164 """
144165 Create a virtualenv in `root_dir` using the `std_python` Python
145- executable. One of the tpp_dirs must contain a vendored virtualenv.py and
166+ executable. One of the ` tpp_dirs` must contain a vendored virtualenv.py and
146167 virtualenv dependencies such as setuptools and pip packages.
147168
148169 @std_python: Path or name of the Python executable to use.
@@ -155,22 +176,28 @@ def create_virtualenv(std_python, root_dir, tpp_dirs):
155176 vendored Python distributions that pip will use to find required
156177 components.
157178 """
158- print ()
159179 print ("* Configuring Python ..." )
160180 # search virtualenv.py in the tpp_dirs. keep the first found
161181 venv_py = None
162182 for tpd in tpp_dirs :
163- venv = os .path .join (tpd , 'virtualenv.py' )
183+ venv = os .path .join (root_dir , tpd , 'virtualenv.py' )
164184 if os .path .exists (venv ):
165185 venv_py = venv
166186 break
167- # TODO: error out if venv_py not found
187+
188+ # error out if venv_py not found
189+ if not venv_py :
190+ print ("Configuration Error ... aborting." )
191+ exit (1 )
192+
168193 vcmd = [std_python , venv_py , '--never-download' ]
194+ if quiet :
195+ vcmd += ['--quiet' ]
169196 # third parties may be in more than one directory
170- vcmd .extend (build_pip_dirs_args (tpp_dirs ))
197+ vcmd .extend (build_pip_dirs_args (tpp_dirs , root_dir ))
171198 # we create the virtualenv in the root_dir
172199 vcmd .append (root_dir )
173- call (vcmd )
200+ call (vcmd , root_dir )
174201
175202
176203def activate (root_dir ):
@@ -181,36 +208,43 @@ def activate(root_dir):
181208 exec (code , dict (__file__ = activate_this ))
182209
183210
184- def install_3pp (configs , root_dir , tpp_dirs ):
185- """ Install requirements with pip."""
186- print ()
211+ def install_3pp (configs , root_dir , tpp_dirs , quiet = False ):
212+ """
213+ Install requirements from requirement files found in `configs` with pip,
214+ using the vendored components in `tpp_dirs`.
215+ """
187216 print ("* Installing components ..." )
188- for req_file in get_conf_files (configs , requirements ):
189- pcmd = ['pip' , 'install' , '--no-allow-external' ,
217+ requirement_files = get_conf_files (configs , root_dir , requirements )
218+ for req_file in requirement_files :
219+ pcmd = ['pip' , 'install' , '--no-allow-external' ,
190220 '--use-wheel' , '--no-index' ]
191- pcmd .extend (build_pip_dirs_args (tpp_dirs , '--find-links=' ))
221+ if quiet :
222+ pcmd += ['--quiet' ]
223+ pip_dir_args = list (build_pip_dirs_args (tpp_dirs , root_dir , '--find-links=' ))
224+ pcmd .extend (pip_dir_args )
192225 req_loc = os .path .join (root_dir , req_file )
193226 pcmd .extend (['-r' , req_loc ])
194- call (pcmd )
227+ call (pcmd , root_dir )
195228
196229
197230def run_scripts (configs , root_dir , configured_python ):
198- """ Run py_script and sh_script scripts."""
199- print ()
231+ """
232+ Run Python scripts and shell scripts found in `configs`.
233+ """
200234 print ("* Configuring ..." )
201235 # Run Python scripts for each configurations
202- for py_script in get_conf_files (configs , python_scripts ):
236+ for py_script in get_conf_files (configs , root_dir , python_scripts ):
203237 cmd = [configured_python , os .path .join (root_dir , py_script )]
204- call (cmd )
238+ call (cmd , root_dir )
205239
206240 # Run sh_script scripts for each configurations
207- for sh_script in get_conf_files (configs , shell_scripts ):
241+ for sh_script in get_conf_files (configs , root_dir , shell_scripts ):
208242 # we source the scripts on posix
209243 cmd = ['.' ]
210244 if on_win :
211245 cmd = []
212- cmd = cmd + [os .path .join (root_dir , sh_script )]
213- call (cmd )
246+ cmd = cmd + [os .path .join (root_dir , sh_script )]
247+ call (cmd , root_dir )
214248
215249
216250def chmod_bin (directory ):
@@ -224,16 +258,18 @@ def chmod_bin(directory):
224258 os .chmod (os .path .join (path , f ), rwx )
225259
226260
227- def get_conf_files (config_dir_paths , file_names = requirements ):
261+ def get_conf_files (config_dir_paths , root_dir , file_names = requirements ):
228262 """
229- Based on config_dir_paths return a list of collected path-prefixed file
230- paths matching names in a file_names tuple. Returned paths are posix
231- paths.
263+ Return a list of collected path-prefixed file paths matching names in a
264+ file_names tuple, based on config_dir_paths, root_dir and the types of
265+ file_names requested. Returned paths are posix paths.
232266
233267 @config_dir_paths: Each config_dir_path is a relative from the project
234268 root to a config dir. This script should always be called from the project
235269 root dir.
236270
271+ @root_dir: The project absolute root dir.
272+
237273 @file_names: get requirements, python or shell files based on list of
238274 supported file names provided as a tuple of supported file_names.
239275
@@ -247,10 +283,10 @@ def get_conf_files(config_dir_paths, file_names=requirements):
247283 """
248284 # collect files for each requested dir path
249285 collected = []
250-
251286 for config_dir_path in config_dir_paths :
252- if not os .path .exists (config_dir_path ):
253- print ('Configurtaion directory %(config_dir_path)s '
287+ abs_config_dir_path = os .path .join (root_dir , config_dir_path )
288+ if not os .path .exists (abs_config_dir_path ):
289+ print ('Configuration directory %(config_dir_path)s '
254290 'does not exists. Skipping.' % locals ())
255291 continue
256292 # Support args like enterprise or enterprise/dev
@@ -259,19 +295,18 @@ def get_conf_files(config_dir_paths, file_names=requirements):
259295 current = None
260296 for path in paths :
261297 if not current :
262- current = (path , os .path .abspath ( path ),)
298+ current = (path , os .path .join ( root_dir , path ),)
263299 else :
264300 base_path , base_loc = current
265301 current = (os .path .join (base_path , path ),
266302 os .path .join (base_loc , path ),)
267-
268303 path , loc = current
269304 # we iterate on known filenames to ensure the defined precedence
270305 # is respected (posix over mac, linux), etc
271306 for n in file_names :
272307 for f in os .listdir (loc ):
273308 if f == n :
274- f_loc = os .path .join (path , f )
309+ f_loc = os .path .join (loc , f )
275310 if f_loc not in collected :
276311 collected .append (f_loc )
277312
@@ -292,6 +327,9 @@ def get_conf_files(config_dir_paths, file_names=requirements):
292327 bin_dir = os .path .join (root_dir , 'bin' )
293328 standard_python = sys .executable
294329
330+ # you must create a CONFIGURE_QUIET env var if you want to run quietly
331+ run_quiet = 'CONFIGURE_QUIET' in os .environ
332+
295333 if on_win :
296334 configured_python = os .path .join (bin_dir , 'python.exe' )
297335 scripts_dir = os .path .join (root_dir , 'Scripts' )
@@ -300,30 +338,34 @@ def get_conf_files(config_dir_paths, file_names=requirements):
300338 os .makedirs (scripts_dir )
301339 if not os .path .exists (bin_dir ):
302340 cmd = ('mklink /J %(bin_dir)s %(scripts_dir)s' % locals ()).split ()
303- call (cmd )
341+ call (cmd , root_dir )
304342 else :
305343 configured_python = os .path .join (bin_dir , 'python' )
306344 scripts_dir = bin_dir
307345
308- # get requested configuration paths and install components and run scripts
346+ # Get requested configuration paths to collect components and scripts later
309347 configs = []
310348 for path in args [:]:
311- if os .path .exists (path ):
312- configs .append (path )
349+ if not os .path .isabs (path ):
350+ abs_path = os .path .join (root_dir , path )
351+ if os .path .exists (abs_path ):
352+ configs .append (path )
313353 else :
314354 print ()
315355 print ('WARNING: Skipping missing Configuration directory:\n '
316356 ' %(path)s does not exist.' % locals ())
317357 print ()
318358
319- # one or more third-party directories may exist
320- # as environment variables prefixed with TPP_DIR
359+ # Collect vendor directories from environment variables: one or more third-
360+ # party directories may exist as environment variables prefixed with TPP_DIR
321361 thirdparty_dirs = []
322362 for envvar , path in os .environ .items ():
323363 if not envvar .startswith ('TPP_DIR' ):
324364 continue
325- if os .path .exists (path ):
326- thirdparty_dirs .append (path )
365+ if not os .path .isabs (path ):
366+ abs_path = os .path .join (root_dir , path )
367+ if os .path .exists (abs_path ):
368+ thirdparty_dirs .append (path )
327369 else :
328370 print ()
329371 print ('WARNING: Skipping missing Python thirdparty directory:\n '
@@ -332,10 +374,13 @@ def get_conf_files(config_dir_paths, file_names=requirements):
332374 ' set %(envvar)s=%(path)s' % locals ())
333375 print ()
334376
377+ # Finally execute our three steps: venv, install and scripts
335378 if not os .path .exists (configured_python ):
336- create_virtualenv (standard_python , root_dir , thirdparty_dirs )
379+ create_virtualenv (standard_python , root_dir , thirdparty_dirs , quiet = run_quiet )
337380 activate (root_dir )
338381
339- install_3pp (configs , root_dir , thirdparty_dirs ,)
382+ install_3pp (configs , root_dir , thirdparty_dirs , quiet = run_quiet )
340383 run_scripts (configs , root_dir , configured_python )
341384 chmod_bin (bin_dir )
385+ print ("* Configuration completed." )
386+ print ()
0 commit comments