Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Buildozer's venv handling. #1689

Merged
merged 2 commits into from
Sep 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading