Last active
February 25, 2019 13:48
-
-
Save KaQuMiQ/cf4f5d2da80f5c774a96c673d73a128d to your computer and use it in GitHub Desktop.
Python manage environment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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