Skip to content

Instantly share code, notes, and snippets.

@KaQuMiQ
Last active February 25, 2019 13:48
Show Gist options
  • Save KaQuMiQ/cf4f5d2da80f5c774a96c673d73a128d to your computer and use it in GitHub Desktop.
Save KaQuMiQ/cf4f5d2da80f5c774a96c673d73a128d to your computer and use it in GitHub Desktop.
Python manage environment
import sys
import os
import subprocess
import venv
import runpy
import logging
import requirements
def run(dev_env: bool):
if not dev_env and __debug__:
logging.error("Release run requires optimized build")
exit(-1)
else:
if __debug__:
logging.info("Running debug...")
else:
logging.info("Running release...")
#TODO: define how to run yourself
logging.error('You have to define run function')
result = -9
if (result != 0):
exit(result)
def test():
args_tmp = sys.argv
sys.argv = ['-v']
try:
runpy.run_module(mod_name='pytest', run_name='__main__')
except SystemExit as e:
if e.code != 0:
raise e
finally:
sys.argv = args_tmp
def parse_arguments():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'--setup',
help='Setup environment',
action='store_true'
)
parser.add_argument(
'--install',
help='Install or update dependencies',
action='store_true'
)
parser.add_argument(
'--novenv',
help='Skip using virtual environment',
action='store_true'
)
parser.add_argument(
'--dev',
help='Use development environment',
action='store_true'
)
parser.add_argument(
'--run',
help='Run application',
action='store_true'
)
parser.add_argument(
'--test',
help='Run tests',
action='store_true'
)
return parser.parse_args()
def check_runtime_version():
if sys.version_info < requirements.PYTHON_VERSION:
logging.error(
'You have to use python {} or newer to in this environment'
.format('.'.join(map(str, requirements.PYTHON_VERSION)))
)
exit(-1)
def is_venv_used() -> bool:
if sys.executable.endswith("venv/bin/python"):
return True
else:
return False
def setup_venv():
logging.info("Preparing virtual environment...")
env_builder = venv.EnvBuilder(
system_site_packages=False,
clear=True,
symlinks=False,
with_pip=True
)
env_builder.create('venv')
os.system('venv/bin/pip install --upgrade pip')
logging.info(
'Virtual environment ready, use `source ./venv/bin/activate` to activate it.'
)
def install_dependencies(include_dev: bool):
logging.info('Installing dependencies...')
if include_dev:
logging.info("...including dev dependencies...")
package_list = requirements.PACKAGES + requirements.DEV_PACKAGES
else:
package_list = requirements.PACKAGES
if len(package_list) == 0:
logging.info(
'...no dependencies selected to install. Skipping...'
)
return
result = os.system(
('pip install {}')
.format(" ".join(package_list))
)
if (result != 0):
exit(result)
def check_dependencies(include_dev: bool):
logging.info('Checking dependencies...')
if include_dev:
logging.info("...including dev dependencies...")
package_list = requirements.PACKAGES + requirements.DEV_PACKAGES
else:
package_list = requirements.PACKAGES
if len(package_list) == 0:
logging.info(
'...no dependencies required...'
)
return
installed = subprocess.check_output(
['pip', 'freeze'], stderr=subprocess.STDOUT).decode()
#TODO: find better comparation
for required in package_list:
if required in installed:
continue
else:
logging.error(
'Missing dependencies, please run manage with --install'
)
exit(-1)
logging.info(
'...OK!'
)
def rerun_in_venv():
logging.info('Rerunning with activated venv...')
args = ' '.join([str(a) for a in sys.argv])
if not __debug__:
args = '-O ' + args
return os.system(
f'/bin/bash -c "source ./venv/bin/activate\npython {args}"'
)
def main():
if __debug__:
logging.basicConfig(format='# %(message)s', level=logging.DEBUG)
else:
logging.basicConfig(format='# %(message)s', level=logging.INFO)
check_runtime_version()
args = parse_arguments()
if args.setup:
if args.novenv or is_venv_used():
install_dependencies(args.dev)
else:
setup_venv()
result = rerun_in_venv()
exit(result)
elif args.install and (args.novenv or is_venv_used()):
install_dependencies(args.dev)
if not args.novenv and not is_venv_used():
logging.error(
'You have to use associated venv. Use --setup to make setup or activate it. You can ignore venv by using --novenv flag.'
)
result = rerun_in_venv()
exit(result)
check_dependencies(args.dev)
if args.test:
test()
if args.run:
run(args.dev)
if __name__ == '__main__':
main()
PYTHON_VERSION = (3, 7)
PACKAGES = \
[
# i.e. "aiohttp==3.5.1",
]
DEV_PACKAGES = \
[
'pytest',
'pylint'
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment