Skip to content
Snippets Groups Projects
setup_to_meta.py 4.51 KiB
Newer Older
import setuptools, importlib, subprocess, os, re

def write_metafile(metadata, filename):
    try:
        os.makedirs(filename[:-10])
    except FileExistsError:

    with open(filename, 'w') as f:
        f.write(metadata)

def generate_metafile(setup_dict, path):
    metadata = (
        '{{% set name = "{name}" %}}\n'
        '{{% set version = "{version}" %}}\n'
        '\n'
        'package:\n'
        '  name: "{{{{ name|lower }}}}"\n'
        '  version: "{{{{ version }}}}"\n'
        '\n'
        'build:\n'
    ).format(
        name=setup_dict["name"],
        version=setup_dict["version"]
    )

    if 'entry_points' in setup_dict.keys():
        metadata += '  entry_points:\n'
        for ep in setup_dict['entry_points']:
            metadata += '    - {}\n'.format(ep)

    metadata += ('  script: {{{{PYTHON}}}} setup.py install\n'
                 '\n'
                 'source:\n'
                 '  path: {}\n'.format(path))
    metadata += '\n'

    if 'install_requires' in setup_dict.keys():
        metadata += 'requirements:\n'
        build_reqs = '  build:\n'
        run_reqs = '  run:\n'
        for req in setup_dict['install_requires'].split(', '):
            build_reqs += '    - {}\n'.format(req)
            run_reqs += '    - {}\n'.format(req)

        metadata += build_reqs
        metadata += run_reqs

    if 'tests_require' in setup_dict.keys():
        metadata += ('test:\n'
                     '  source_files:\n'
                     '    - test/\n'
                     '  requires:\n')

        for req in setup_dict['tests_require'].split(', '):
            metadata += '    - {}\n'.format(req)

        metadata += ('  commands:\n'
                     '    - pytest -vv --log-level=DEBUG --showlocals\n')

    metadata += ('\n'
                 'about:\n'
                 '  license: "{0}"\n'
                 '  license_family: "{0}"\n'
                 '  summary: "{1}"'.format(setup_dict['license'], setup_dict['description']))

    return metadata

def data_to_dict(setup_data):
    data_dict = {}
    r_entry = r"([a-z-_]+): "
    r_id = r"[a-zA-Z0-9-_]"
    r_ep = r"{{(?:[a-zA-Z0-9-_.]+):\s*(?P<values>(?:{0}+\s*=\s*[a-zA-Z0-9-_.]+:{0}+(?:,\s*)?)*)}}".format(r_id)

    for d in setup_data:
        result = re.match(r_entry, d)
        if result:
            substrings = [result.group(0), '[', ']', '\'', '"']
            field = result.group(1)
            value = del_substrings(d, substrings)
            if value == "None":
                continue
            if re.match(r_ep, value):
                # Parse entry points
                value = re.match(r_ep, value).group('values')
                value = re.split(',\s*', value)
            data_dict[field] = value
            # print("{}: {}".format(field, value))
def get_outputs(names):
    outputs = []
    for name in names:
        outputs.append("support/conda/{}/meta.yaml".format(name))

    return outputs

def get_dirs():
    find = subprocess.run(['find', '.', '-name', 'setup.py'], stdout=subprocess.PIPE)
    dirs = find.stdout.decode('utf-8').split('\n')

    for i, d in enumerate(dirs):
        if d.find("./src") >= 0:
            dirs.remove(d)
            continue
        dirs[i] = d.replace('/setup.py', '')

    return dirs

def get_names(dirs):
    names = []
    for d in dirs:
        if d != '':
            name = d.split('/')[-1]

            if name == "archive":
                # Case with ./services/archive having special dir structure
                name = "services"
            names.append(name)

    return names

def del_substrings(s, substrings):
    for replace in substrings:
        s = s.replace(replace, '')

    return s

class Recipe:
    def __init__(self, buildout, name, options):
        self.dirs = get_dirs()
        self.names = get_names(self.dirs)
        self.outputs = get_outputs(self.names)
    # TODO: Keep track of path in setup_dict
            if d != '':
                os.chdir(d)
                proc = subprocess.run(['python3', 'parse_setup.py'], stdout=subprocess.PIPE)
                os.chdir(root)
                setup_data = (proc.stdout.decode('utf-8')).split('\n')
                data_dict = data_to_dict(setup_data)
                metadata = generate_metafile(data_dict, d)
                write_metafile(metadata, self.outputs[i])
                self.options.created(self.outputs[i])