diff --git a/build/recipes/build_pkgs/build_pkgs.py b/build/recipes/build_pkgs/build_pkgs.py index 0cafdde39f17e7689b2a2c10b01006fbb4e16fa8..7b3324ad8d465a489f0302974870a1b2fd0d8015 100644 --- a/build/recipes/build_pkgs/build_pkgs.py +++ b/build/recipes/build_pkgs/build_pkgs.py @@ -4,7 +4,7 @@ from typing import List, Dict, Any, Callable, Optional from zc.buildout.buildout import Buildout, Options -logger: logging.Logger = logging.getLogger("buildout/build_pkgs") +logger = logging.getLogger("buildout/build_pkgs") def get_dirs() -> List[str]: @@ -13,11 +13,11 @@ def get_dirs() -> List[str]: :return: List of directories as strings. """ logger.debug("Getting list of directories containing setup.py files...") - find: subprocess.CompletedProcess = subprocess.run([ + find = subprocess.run([ 'find', '.', '-name', 'setup.py', '-not', '-path', './build/recipes/*' ], stdout=subprocess.PIPE) - dirs: List[str] = find.stdout.decode('utf-8').split('\n') - dirs_cpy: List[str] = dirs + dirs = find.stdout.decode('utf-8').split('\n') + dirs_cpy = dirs for i, d in enumerate(dirs_cpy): dirs[i] = d.replace('/setup.py', '') @@ -33,10 +33,10 @@ def get_names(dirs: List[str]) -> List[str]: :return: List of names as strings. """ logger.debug("Generating list of subproject names...") - names: List[str] = [] + names = [] for d in dirs: if d != '': - name: str = d.split('/')[-1] + name = d.split('/')[-1] if name == "archive": # Case with ./services/archive having special dir structure @@ -56,9 +56,9 @@ class Recipe: :param name: (Boilerplate) Name of section that uses this recipe. :param options: (Boilerplate) Options of section that uses this recipe. """ - self.name: str = name - self.options: Options = options - self.pkg_list: List[str] = get_names(get_dirs()) + self.name = name + self.options = options + self.pkg_list = get_names(get_dirs()) def install(self) -> Any: """ @@ -69,9 +69,9 @@ class Recipe: logger.warning("WARNING: You've requested all packages to be built. This will take a long time.") logger.warning("If only one or a few packages have changed, consider specifying them " "in a comma-separated list.") - pkgs: List[str] = self.pkg_list + pkgs = self.pkg_list else: - pkgs: List[str] = self.options['name'].split(',') + pkgs = self.options['name'].split(',') for p in pkgs: if p not in self.pkg_list or p == '': @@ -85,4 +85,4 @@ class Recipe: return self.options.created() - update: Callable = install + update = install diff --git a/build/recipes/build_pkgs/test/conftest.py b/build/recipes/build_pkgs/test/conftest.py index 5d7d7756fcba3c015e1b7f68c98545d09e3fd1ec..46126efdfc2d3f2a05a8cf0e83d51c1acc8bdc3f 100644 --- a/build/recipes/build_pkgs/test/conftest.py +++ b/build/recipes/build_pkgs/test/conftest.py @@ -12,7 +12,7 @@ def recipe() -> build_pkgs.Recipe: :return: Initialized recipe object for build_pkgs """ from .. import build_pkgs - buildout: zc.buildout.testing.Buildout = zc.buildout.testing.Buildout() - options: buildout.Options = buildout.Options(buildout, 'build_pkgs', {'recipe': 'build_pkgs', 'name': 'null'}) - recipe: build_pkgs.Recipe = build_pkgs.Recipe(buildout=buildout, name=None, options=options) + buildout = zc.buildout.testing.Buildout() + options = buildout.Options(buildout, 'build_pkgs', {'recipe': 'build_pkgs', 'name': 'null'}) + recipe = build_pkgs.Recipe(buildout=buildout, name=None, options=options) return recipe diff --git a/build/recipes/build_pkgs/test/test_build_pkgs.py b/build/recipes/build_pkgs/test/test_build_pkgs.py index 10758442d4cd05151c73486d19a9e4389a7f491c..188c5e670ca796fad5dc6d275b60b6b9670b71c2 100644 --- a/build/recipes/build_pkgs/test/test_build_pkgs.py +++ b/build/recipes/build_pkgs/test/test_build_pkgs.py @@ -10,7 +10,7 @@ class TestBuildPkgs: Test that build_pkgs correctly gets the package name from :return: """ - d: str = 'apps/cli/executables/null' + d = 'apps/cli/executables/null' assert build_pkgs.get_names([d]) == ['null'] def test_get_dirs(self): @@ -20,11 +20,11 @@ class TestBuildPkgs: """ assert './apps/cli/executables/null' in build_pkgs.get_dirs() - def test_output(self, recipe): + def test_output(self, recipe: build_pkgs.Recipe): """ Test that the package specified in the recipe has been built correctly. """ - created: List[str] = recipe.install() + created = recipe.install() for path in created: if len(path) > 0: diff --git a/build/recipes/setup_to_meta/setup_to_meta.py b/build/recipes/setup_to_meta/setup_to_meta.py index b8ed067442dbf6274978054440bd87a99165b5ef..783afd3766ca01ad586f53953463bde491396c94 100644 --- a/build/recipes/setup_to_meta/setup_to_meta.py +++ b/build/recipes/setup_to_meta/setup_to_meta.py @@ -6,8 +6,8 @@ from typing import List, Any, Dict, Callable, Optional from zc.buildout.buildout import Buildout, Options -PYTHON_VERSION: str = '3.8' -logger: logging.Logger = logging.getLogger("buildout/setup_to_meta") +PYTHON_VERSION = '3.8' +logger = logging.getLogger("buildout/setup_to_meta") def write_metafile(metadata: str, filepath: str): @@ -32,15 +32,15 @@ class MetadataGenerator: Uses given info extracted from setup.py file to fill out metadata template. """ def __init__(self, setup: Dict[str, str], path: str): - self.setup: Dict[str, str] = setup - self.path: str = path + self.setup = setup + self.path = path def fmt_ep(self) -> str: """ Format entry points section of metadata. :return: Formatted string if entry points exists; else empty string. """ - ep_string: str = '' + ep_string = '' if 'entry_points' in self.setup.keys() and 'console_scripts' in self.setup['entry_points']: ep_string += 'entry_points:\n' for ep in self.setup['entry_points']['console_scripts']: @@ -53,12 +53,12 @@ class MetadataGenerator: Format requirements section of metadata. :return: Formatted string if requirements exists; else empty string. """ - reqs_string: str = '' - reqs_list: str = '' + reqs_string = '' + reqs_list = '' reqs_string += 'requirements:\n' - build_reqs: str = ' build:\n' - run_reqs: str = ' run:\n' - host_reqs: str = ' host:\n' + build_reqs = ' build:\n' + run_reqs = ' run:\n' + host_reqs = ' host:\n' reqs_list += ' - python={}\n'.format(PYTHON_VERSION) if 'install_requires' in self.setup.keys(): @@ -78,7 +78,7 @@ class MetadataGenerator: needs. For now, it's pretty dumb. :return: Formatted string if tests_require exists; else empty string. """ - test_string: str = '' + test_string = '' if 'tests_require' in self.setup.keys(): test_string += ( 'test:\n' @@ -105,17 +105,17 @@ class MetadataGenerator: except KeyError: pass - name: str = self.setup['name'] - version: str = self.setup['version'] - entry_points: str = self.fmt_ep() - pth: str = self.path.replace("./", "") - requirements: str = self.fmt_reqs() - test: str = self.fmt_test() - lic: str = self.setup['license'] - summary: str = self.setup['description'] + name = self.setup['name'] + version = self.setup['version'] + entry_points = self.fmt_ep() + pth = self.path.replace("./", "") + requirements = self.fmt_reqs() + test = self.fmt_test() + lic = self.setup['license'] + summary = self.setup['description'] with open('build/tools/metafile_template.txt', 'r') as f: - metadata: str = f.read() + metadata = f.read() logger.debug("Done generating.") return metadata.format( @@ -140,7 +140,7 @@ def parse_setup(d: str) -> Dict[str, str]: logger.debug(f"Parsing setup.py at {d}...") subprocess.run(['cp', 'build/tools/parse_setup.py', d]) os.chdir(d) - proc: subprocess.CompletedProcess = subprocess.run(['python3', 'parse_setup.py'], stdout=subprocess.PIPE) + proc = subprocess.run(['python3', 'parse_setup.py'], stdout=subprocess.PIPE) os.chdir(root) subprocess.run(['rm', '{}/parse_setup.py'.format(d)]) @@ -154,7 +154,7 @@ def get_outputs(names: List[str]) -> List[str]: :param dirs: List of dirs of all subprojects with a setup.py file. :return: List of paths to output files as strings. """ - outputs: List[str] = [] + outputs = [] for name in names: outputs.append("build/metadata/{}/meta.yaml".format(name)) @@ -166,11 +166,11 @@ def get_dirs() -> List[str]: :return: List of directories as strings. """ logger.debug("Finding list of directories containing setup.py files...") - find: subprocess.CompletedProcess = subprocess.run([ + find = subprocess.run([ 'find', '.', '-name', 'setup.py', '-not', '-path', './build/recipes/*' ], stdout=subprocess.PIPE) - dirs: List[str] = find.stdout.decode('utf-8').split('\n') - dirs_cpy: List[str] = dirs + dirs = find.stdout.decode('utf-8').split('\n') + dirs_cpy = dirs for i, d in enumerate(dirs_cpy): dirs[i] = d.replace('/setup.py', '') @@ -186,7 +186,7 @@ def get_names(dirs: List[str]) -> List[str]: :return: List of names as strings. """ logger.debug("Getting list of names...") - names: List[str] = [] + names = [] for d in dirs: if d != '': name = d.split('/')[-1] @@ -208,12 +208,12 @@ def del_substrings(s: str, substrings: List[str]): :return: Modified string. """ for replace in substrings: - s: str = s.replace(replace, '') + s = s.replace(replace, '') return s -root: str = os.getcwd() +root = os.getcwd() class Recipe: @@ -230,10 +230,10 @@ class Recipe: :param name: (Boilerplate) Name of section that uses this recipe. :param options: (Boilerplate) Options of section that uses this recipe. """ - self.dirs: List[str] = get_dirs() - self.names: List[str] = get_names(self.dirs) - self.outputs: List[str] = get_outputs(self.names) - self.options: Options = options + self.dirs = get_dirs() + self.names = get_names(self.dirs) + self.outputs = get_outputs(self.names) + self.options = options def install(self) -> Any: """ @@ -242,8 +242,8 @@ class Recipe: """ for i, d in enumerate(self.dirs): if d != '': - setup_data: Dict[str, str] = parse_setup(d) - metadata: str = MetadataGenerator(setup_data, d).generate() + setup_data = parse_setup(d) + metadata = MetadataGenerator(setup_data, d).generate() write_metafile(metadata, self.outputs[i]) # Buildout-specific operation: pass created file into options.created() self.options.created(self.outputs[i]) @@ -251,4 +251,4 @@ class Recipe: return self.options.created() # No special procedure for updating vs. installing - update: Callable = install + update = install diff --git a/build/recipes/setup_to_meta/test/conftest.py b/build/recipes/setup_to_meta/test/conftest.py index c9f4b3a9188f69eba15f65938a1750112ed1dfcd..877092d84ed217e63b96ae18f0b49205f9d70abd 100644 --- a/build/recipes/setup_to_meta/test/conftest.py +++ b/build/recipes/setup_to_meta/test/conftest.py @@ -13,13 +13,13 @@ def recipe() -> setup_to_meta.Recipe: :return: Initialized recipe object for setup_to_meta """ from .. import setup_to_meta - buildout: zc.buildout.testing.Buildout = zc.buildout.testing.Buildout() - options: buildout.Options = buildout.Options( + buildout = zc.buildout.testing.Buildout() + options = buildout.Options( buildout, 'gen_metadata', {'recipe': 'setup_to_meta'} ) - recipe: setup_to_meta.Recipe = setup_to_meta.Recipe( + recipe = setup_to_meta.Recipe( buildout=buildout, name=None, options=options diff --git a/build/recipes/setup_to_meta/test/test_setup_to_meta.py b/build/recipes/setup_to_meta/test/test_setup_to_meta.py index 4b17197cac71503b0213d58917b0a165a1b3bb3b..8cb514d110f903e577b61fdaa503fe139a9bad03 100644 --- a/build/recipes/setup_to_meta/test/test_setup_to_meta.py +++ b/build/recipes/setup_to_meta/test/test_setup_to_meta.py @@ -8,14 +8,14 @@ class TestSetupToMeta: """ Tests that del_substrings function properly deletes substrings from a given string """ - replaced: str = setup_to_meta.del_substrings('heallob, woarlcd', ['a', 'b', 'c']) + replaced = setup_to_meta.del_substrings('heallob, woarlcd', ['a', 'b', 'c']) assert replaced == 'hello, world' def test_get_names(self): """ Tests that setup_to_meta correctly gets the package name from the package path """ - d: str = 'apps/cli/executables/null' + d = 'apps/cli/executables/null' assert setup_to_meta.get_names([d]) == ['null'] def test_get_dirs(self): @@ -36,12 +36,12 @@ class TestSetupToMeta: """ Tests that parse_setup correctly parses a setup.py file into a dictionary. """ - setup_data: Dict[str, str] = setup_to_meta.parse_setup('apps/cli/executables/null') - keys: List[str] = ['name', 'version', 'description', 'license'] + setup_data = setup_to_meta.parse_setup('apps/cli/executables/null') + keys = ['name', 'version', 'description', 'license'] for key in keys: assert key in setup_data - def test_output(self, recipe): + def test_output(self, recipe: setup_to_meta.Recipe): """ Test that metadata was successfully created and contains data. @@ -49,7 +49,7 @@ class TestSetupToMeta: occur in a correct recipe. :param recipe: Fixture that initializes recipe class in setup_to_meta.py """ - created: List[str] = recipe.install() + created = recipe.install() for path in created: with open(path, 'r') as f: diff --git a/build/recipes/test_recipes/test/test_test_recipes.py b/build/recipes/test_recipes/test/test_test_recipes.py index 57034eefdff357e8e0b09ddb02c556b57b0f2fff..912bc274ba93235ccdc85c82e1949993855cafd5 100644 --- a/build/recipes/test_recipes/test/test_test_recipes.py +++ b/build/recipes/test_recipes/test/test_test_recipes.py @@ -1,5 +1,6 @@ from .. import test_recipes + class TestRecipes: def test_get_recipes(self): """ diff --git a/build/recipes/test_recipes/test_recipes.py b/build/recipes/test_recipes/test_recipes.py index 479cc05141ca024ae4db3a58f36ebf6f570100d2..fd09a2c49ee94434e2a4e6823c0be5029e3af9da 100644 --- a/build/recipes/test_recipes/test_recipes.py +++ b/build/recipes/test_recipes/test_recipes.py @@ -1,9 +1,13 @@ import subprocess import logging +from typing import Dict, Optional + +from zc.buildout.buildout import Buildout, Options logger = logging.getLogger("buildout/test_recipes") -def get_recipes(): + +def get_recipes() -> Dict[str, str]: """ Get all currently installed buildout recipes (including this one!) :return: Dictionary with format {recipe_name: recipe_path_from_root,} @@ -26,6 +30,7 @@ def get_recipes(): return recipes + class Recipe: """ Buildout Recipe class. @@ -33,7 +38,7 @@ class Recipe: http://www.buildout.org/en/latest/topics/writing-recipes.html """ - def run_test(self, recipe): + def run_test(self, recipe: str): """ Run test for given recipe. :param recipe: Name of recipe to be run. @@ -42,7 +47,7 @@ class Recipe: subprocess.run(['pytest', '-vv', '--log-level=DEBUG', '--showlocals', self.recipes[recipe]]) - def __init__(self, buildout, name, options): + def __init__(self, buildout: Optional[Buildout], name: str, options: Options): """ Initializes fields needed for recipe. :param buildout: (Boilerplate) Dictionary of options from buildout section @@ -68,4 +73,4 @@ class Recipe: self.run_test(recipe) else: if self.choice in self.recipes: - self.run_test(self.choice) \ No newline at end of file + self.run_test(self.choice) diff --git a/build/tools/parse_setup.py b/build/tools/parse_setup.py index 8acd807b95980c86bcedb4f1a2b220ea5300da79..6d1c8ab8fd78bd0096d40322fc3ca926dacf5aea 100644 --- a/build/tools/parse_setup.py +++ b/build/tools/parse_setup.py @@ -3,6 +3,8 @@ import setuptools import json data = {} + + def my_setup(*args, **kwargs): """ A replacement for setuptools.setup(). @@ -20,6 +22,7 @@ def my_setup(*args, **kwargs): for field in fields: data[field] = kwargs.get(field) + def main(): # Author of these shenanigans: Daniel Lyons (but you already knew that) @@ -36,5 +39,6 @@ def main(): # Instead of exiting, we now have populated our global variable, without doing any parsing json.dump(data, sys.stdout) + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/build/tools/transfer_to_builder.py b/build/tools/transfer_to_builder.py index fa43851a3f4ccf5312ba40249f082155b2e1e1b1..4f9b67094afb4ecaafb325c1b8b7635dffa36dca 100644 --- a/build/tools/transfer_to_builder.py +++ b/build/tools/transfer_to_builder.py @@ -1,10 +1,12 @@ -import subprocess -import paramiko -import logging +import os +import sys import fnmatch import getpass -import sys -import os +import logging +from typing import List + +import paramiko +import subprocess from scp import SCPClient @@ -12,7 +14,8 @@ logger = logging.getLogger("buildtools/transfer_to_builder") logger.setLevel(logging.INFO) hander = logging.StreamHandler(stream=sys.stdout) -def get_build_pkg_names(): + +def get_build_pkg_names() -> List[str]: """ Search through pkgs directory for built .tar.bz2 packages :return: List of package archive file names @@ -28,7 +31,8 @@ def get_build_pkg_names(): return pkg_names -def create_ssh_client(server): + +def create_ssh_client(server: str) -> paramiko.SSHClient: """ Use paramiko to load SSH keys if they exist and set up an SSH connection to a server. :param server: The server to connect to @@ -52,7 +56,8 @@ def create_ssh_client(server): return client -def transfer_packages(pkg_names): + +def transfer_packages(pkg_names: List[str]): """ Use shell commands to transfer build archives to builder and update its conda package index. :param pkg_names: Names of the .tar.bz2 files for the built packages. @@ -74,7 +79,8 @@ def transfer_packages(pkg_names): cmd_chmod]) else: logger.error("No packages found in build/pkgs/noarch. " - "Did conda build successfully build the package(s)?") + "Did conda build successfully build the package(s)?") + if __name__ == "__main__": - transfer_packages(get_build_pkg_names()) \ No newline at end of file + transfer_packages(get_build_pkg_names())