Skip to content

Commit

Permalink
Improve Buildozer's venv handling. (#1689)
Browse files Browse the repository at this point in the history
* Improve Buildozer's venv handling.

* Rather than call a subprocess to run venv, use the built-in venv library.
* Rather than check if an attribute exists, define it in __init__ and see if it has changed.
* self.venv contained a folder name, but the folder name didn't need to be stored after the method returned. A boolean was all that was required.

Also, some trivial clean ups thrown in:
* Comment improvements.
* Copy command didn't need to be logged; buildops will do that.
* Directory's existence doesn't need to be checked; buildops will do that.

* Add reference to comment

Co-authored-by: Mirko Galimberti <[email protected]>

---------

Co-authored-by: Mirko Galimberti <[email protected]>
  • Loading branch information
Julian-O and misl6 authored Sep 10, 2023
1 parent 8490791 commit 40fbf38
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions buildozer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from sys import exit
import textwrap
import warnings
import venv

import buildozer.buildops as buildops
from buildozer.jsonstore import JsonStore
Expand All @@ -38,6 +39,7 @@ def __init__(self, filename='buildozer.spec', target=None):
self.state = None
self.build_id = None
self.config = SpecParser()
self._venv_created = False

self.logger = Logger()

Expand Down Expand Up @@ -225,19 +227,26 @@ def check_application_requirements(self):
return

# remove all the requirements that the target can compile

# TODO: Make more general - filter at the first non [a-z0-9_-] char?
onlyname = lambda x: x.split('==')[0] # noqa: E731

requirements = [x for x in requirements if onlyname(x) not in
target_available_packages]

if requirements and hasattr(sys, 'real_prefix'):
# Technique defined in venv library documentation.
# See: https://docs.python.org/3/library/venv.html#how-venvs-work
currently_in_venv = sys.prefix != sys.base_prefix

if requirements and currently_in_venv:
e = self.logger.error
e('virtualenv is needed to install pure-Python modules, but')
e('virtualenv does not support nesting, and you are running')
e('buildozer in one. Please run buildozer outside of a')
e('virtualenv instead.')
exit(1)

# did we already installed the libs ?
# did we already install the libs ?
if (
exists(self.applibs_dir) and
self.state.get('cache.applibs', '') == requirements
Expand Down Expand Up @@ -272,14 +281,14 @@ def check_garden_requirements(self):
warnings.warn("`garden_requirements` settings is deprecated, use `requirements` instead", DeprecationWarning)

def _ensure_virtualenv(self):
if hasattr(self, 'venv'):
# Only do it once.
if self._venv_created:
return
self.venv = join(self.buildozer_dir, 'venv')
if not buildops.file_exists(self.venv):
buildops.cmd(
["python3", "-m", "venv", "./venv"],
cwd=self.buildozer_dir,
env=self.environ)

venv_dir = join(self.buildozer_dir, 'venv')
if not buildops.file_exists(venv_dir):
venv.create(venv_dir)
self._venv_created = True

# read virtualenv output and parse it
assert sys.platform != "win32", "Can't call bash on Windows"
Expand All @@ -305,8 +314,6 @@ def _ensure_virtualenv(self):

def clean_platform(self):
self.logger.info('Clean the platform build directory')
if not exists(self.platform_dir):
return
buildops.rmdir(self.platform_dir)

def get_version(self):
Expand Down Expand Up @@ -446,7 +453,6 @@ def _copy_application_sources(self):
buildops.mkdir(dfn)

# copy!
self.logger.debug('Copy {0}'.format(sfn))
buildops.file_copy(sfn, rfn)

def _copy_application_libs(self):
Expand Down Expand Up @@ -695,7 +701,7 @@ def check_root(self):
sys.exit()

def cmd_init(self, *args):
'''Create a initial buildozer.spec in the current directory
'''Create an initial buildozer.spec in the current directory
'''
if exists('buildozer.spec'):
print('ERROR: You already have a buildozer.spec file.')
Expand Down

0 comments on commit 40fbf38

Please sign in to comment.