11from __future__ import print_function
22
3- from os .path import (join , realpath , dirname , expanduser , exists ,
4- split , isdir )
3+ from os .path import (
4+ abspath , join , realpath , dirname , expanduser , exists ,
5+ split , isdir
6+ )
57from os import environ
68import copy
79import os
@@ -590,6 +592,120 @@ def project_has_setup_py(project_dir):
590592 return False
591593
592594
595+ def run_setuppy_install (ctx , project_dir , env = None ):
596+ if env is None :
597+ env = dict ()
598+
599+ with current_directory (project_dir ):
600+ info ('got setup.py or similar, running project install. ' +
601+ '(disable this behavior with --ignore-setup-py)' )
602+
603+ # Compute & output the constraints we will use:
604+ info ('Contents that will be used for constraints.txt:' )
605+ constraints = subprocess .check_output ([
606+ join (
607+ ctx .build_dir , "venv" , "bin" , "pip"
608+ ),
609+ "freeze"
610+ ], env = copy .copy (env ))
611+ try :
612+ constraints = constraints .decode ("utf-8" , "replace" )
613+ except AttributeError :
614+ pass
615+ info (constraints )
616+
617+ # Make sure all packages found are fixed in version
618+ # by writing a constraint file, to avoid recipes being
619+ # upgraded & reinstalled:
620+ with open ('._tmp_p4a_recipe_constraints.txt' , 'wb' ) as fileh :
621+ fileh .write (constraints .encode ("utf-8" , "replace" ))
622+ try :
623+
624+ info ('Populating venv\' s site-packages with '
625+ 'ctx.get_site_packages_dir()...' )
626+
627+ # Copy dist contents into site-packages for discovery.
628+ # Why this is needed:
629+ # --target is somewhat evil and messes with discovery of
630+ # packages in PYTHONPATH if that also includes the target
631+ # folder. So we need to use the regular virtualenv
632+ # site-packages folder instead.
633+ # Reference:
634+ # https://github.com/pypa/pip/issues/6223
635+ ctx_site_packages_dir = os .path .normpath (
636+ os .path .abspath (ctx .get_site_packages_dir ())
637+ )
638+ venv_site_packages_dir = os .path .normpath (os .path .join (
639+ ctx .build_dir , "venv" , "lib" , [
640+ f for f in os .listdir (os .path .join (
641+ ctx .build_dir , "venv" , "lib"
642+ )) if f .startswith ("python" )
643+ ][0 ], "site-packages"
644+ ))
645+ copied_over_contents = []
646+ for f in os .listdir (ctx_site_packages_dir ):
647+ full_path = os .path .join (ctx_site_packages_dir , f )
648+ if not os .path .exists (os .path .join (
649+ venv_site_packages_dir , f
650+ )):
651+ if os .path .isdir (full_path ):
652+ shutil .copytree (full_path , os .path .join (
653+ venv_site_packages_dir , f
654+ ))
655+ else :
656+ shutil .copy2 (full_path , os .path .join (
657+ venv_site_packages_dir , f
658+ ))
659+ copied_over_contents .append (f )
660+
661+ # Get listing of virtualenv's site-packages, to see the
662+ # newly added things afterwards & copy them back into
663+ # the distribution folder / build context site-packages:
664+ previous_venv_contents = os .listdir (
665+ venv_site_packages_dir
666+ )
667+
668+ # Actually run setup.py:
669+ info ('Launching package install...' )
670+ shprint (sh .bash , '-c' , (
671+ "'" + join (
672+ ctx .build_dir , "venv" , "bin" , "pip"
673+ ).replace ("'" , "'\" '\" '" ) + "' " +
674+ "install -c ._tmp_p4a_recipe_constraints.txt -v ."
675+ ).format (ctx .get_site_packages_dir ().
676+ replace ("'" , "'\" '\" '" )),
677+ _env = copy .copy (env ))
678+
679+ # Go over all new additions and copy them back:
680+ info ('Copying additions resulting from setup.py back '
681+ 'into ctx.get_site_packages_dir()...' )
682+ new_venv_additions = []
683+ for f in (set (os .listdir (venv_site_packages_dir )) -
684+ set (previous_venv_contents )):
685+ new_venv_additions .append (f )
686+ full_path = os .path .join (venv_site_packages_dir , f )
687+ if os .path .isdir (full_path ):
688+ shutil .copytree (full_path , os .path .join (
689+ ctx_site_packages_dir , f
690+ ))
691+ else :
692+ shutil .copy2 (full_path , os .path .join (
693+ ctx_site_packages_dir , f
694+ ))
695+
696+ # Undo all the changes we did to the venv-site packages:
697+ info ('Reverting additions to '
698+ 'virtualenv\' s site-packages...' )
699+ for f in set (copied_over_contents + new_venv_additions ):
700+ full_path = os .path .join (venv_site_packages_dir , f )
701+ if os .path .isdir (full_path ):
702+ shutil .rmtree (full_path )
703+ else :
704+ os .remove (full_path )
705+ finally :
706+ os .remove ("._tmp_p4a_recipe_constraints.txt" )
707+
708+
593709def run_pymodules_install (ctx , modules , project_dir = None ,
594710 ignore_setup_py = False ):
595711 """ This function will take care of all non-recipe things, by:
@@ -605,6 +721,10 @@ def run_pymodules_install(ctx, modules, project_dir=None,
605721 info ('*** PYTHON PACKAGE / PROJECT INSTALL STAGE ***' )
606722 modules = list (filter (ctx .not_has_package , modules ))
607723
724+ # We change current working directory later, so this
725+ # has to be an absolute path:
726+ project_dir = abspath (project_dir )
727+
608728 # Bail out if no python deps and no setup.py to process:
609729 if not modules and (
610730 ignore_setup_py or
@@ -697,107 +817,7 @@ def run_pymodules_install(ctx, modules, project_dir=None,
697817 if project_dir is not None and (
698818 project_has_setup_py (project_dir ) and not ignore_setup_py
699819 ):
700- with current_directory (project_dir ):
701- info ('got setup.py or similar, running project install. ' +
702- '(disable this behavior with --ignore-setup-py)' )
703-
704- # Compute & output the constraints we will use:
705- info ('Contents that will be used for constraints.txt:' )
706- constraints = subprocess .check_output ([
707- join (
708- ctx .build_dir , "venv" , "bin" , "pip"
709- ),
710- "freeze"
711- ], env = copy .copy (env ))
712- try :
713- constraints = constraints .decode ("utf-8" , "replace" )
714- except AttributeError :
715- pass
716- info (constraints )
717-
718- # Make sure all packages found are fixed in version
719- # by writing a constraint file, to avoid recipes being
720- # upgraded & reinstalled:
721- with open ('constraints.txt' , 'wb' ) as fileh :
722- fileh .write (constraints .encode ("utf-8" , "replace" ))
723-
724- info ('Populating venv\' s site-packages with '
725- 'ctx.get_site_packages_dir()...' )
726-
727- # Copy dist contents into site-packages for discovery.
728- # Why this is needed:
729- # --target is somewhat evil and messes with discovery of
730- # packages in PYTHONPATH if that also includes the target
731- # folder. So we need to use the regular virtualenv
732- # site-packages folder instead.
733- # Reference:
734- # https://github.com/pypa/pip/issues/6223
735- ctx_site_packages_dir = os .path .normpath (
736- os .path .abspath (ctx .get_site_packages_dir ())
737- )
738- venv_site_packages_dir = os .path .normpath (os .path .join (
739- ctx .build_dir , "venv" , "lib" , [
740- f for f in os .listdir (os .path .join (
741- ctx .build_dir , "venv" , "lib"
742- )) if f .startswith ("python" )
743- ][0 ], "site-packages"
744- ))
745- copied_over_contents = []
746- for f in os .listdir (ctx_site_packages_dir ):
747- full_path = os .path .join (ctx_site_packages_dir , f )
748- if not os .path .exists (os .path .join (
749- venv_site_packages_dir , f
750- )):
751- if os .path .isdir (full_path ):
752- shutil .copytree (full_path , os .path .join (
753- venv_site_packages_dir , f
754- ))
755- else :
756- shutil .copy2 (full_path , os .path .join (
757- venv_site_packages_dir , f
758- ))
759- copied_over_contents .append (f )
760-
761- # Get listing of virtualenv's site-packages, to see the
762- # newly added things afterwards & copy them back into
763- # the distribution folder / build context site-packages:
764- previous_venv_contents = os .listdir (venv_site_packages_dir )
765-
766- # Actually run setup.py:
767- info ('Launching package install...' )
768- shprint (sh .bash , '-c' , (
769- "'" + join (
770- ctx .build_dir , "venv" , "bin" , "pip"
771- ).replace ("'" , "'\" '\" '" ) + "' " +
772- "install -c constraints.txt -v ."
773- ).format (ctx .get_site_packages_dir ().replace ("'" , "'\" '\" '" )),
774- _env = copy .copy (env ))
775-
776- # Go over all new additions and copy them back:
777- info ('Copying additions resulting from setup.py back ' +
778- 'into ctx.get_site_packages_dir()...' )
779- new_venv_additions = []
780- for f in (set (os .listdir (venv_site_packages_dir )) -
781- set (previous_venv_contents )):
782- new_venv_additions .append (f )
783- full_path = os .path .join (venv_site_packages_dir , f )
784- if os .path .isdir (full_path ):
785- shutil .copytree (full_path , os .path .join (
786- ctx_site_packages_dir , f
787- ))
788- else :
789- shutil .copy2 (full_path , os .path .join (
790- ctx_site_packages_dir , f
791- ))
792-
793- # Undo all the changes we did to the venv-site packages:
794- info ('Reverting additions to virtualenv\' s site-packages...' )
795- for f in set (copied_over_contents + new_venv_additions ):
796- full_path = os .path .join (venv_site_packages_dir , f )
797- if os .path .isdir (full_path ):
798- shutil .rmtree (full_path )
799- else :
800- os .remove (full_path )
820+ run_setuppy_install (ctx , project_dir , env )
801821 elif not ignore_setup_py :
802822 info ("No setup.py found in project directory: " +
803823 str (project_dir )
0 commit comments