diff options
Diffstat (limited to 'cbc/meta.py')
-rw-r--r-- | cbc/meta.py | 326 |
1 files changed, 163 insertions, 163 deletions
diff --git a/cbc/meta.py b/cbc/meta.py index 597d2d8..bda64bc 100644 --- a/cbc/meta.py +++ b/cbc/meta.py @@ -1,163 +1,163 @@ -'''I refuse to write the same thing over and over again in meta.yaml.
-And yeah, conda supports Jinja2, but ugh... No.
-'''
-
-import os
-import conda_build.metadata
-import conda_build.environ
-import yaml
-import shutil
-from glob import glob
-from configparser import ConfigParser, ExtendedInterpolation
-from collections import OrderedDict
-from .environment import Environment
-from .exceptions import MetaDataError
-
-
-class MetaData(object):
- def __init__(self, filename, env):
-
- filename = os.path.abspath(filename)
- if not os.path.exists(filename):
- raise OSError('"{0}" does not exist.'.format(filename));
-
- self.filename = filename
- self.confdir = os.path.dirname(self.filename)
-
- if not isinstance(env, Environment):
- raise MetaDataError('Expecting instance of cbc.environment.Environment, got: "{0}"'.format(type(env)))
-
- self.env = env
- self.builtins = ['cbc_build', 'cbc_cgi', 'settings', 'environ']
-
- self.fields = self.convert_conda_fields(conda_build.metadata.FIELDS)
- #self.config = SafeConfigParser(interpolation=ExtendedInterpolation(), allow_no_value=True)
- self.config = CBCConfigParser(interpolation=ExtendedInterpolation(), allow_no_value=True)
- # Include built-in Conda metadata fields
- self.config.read_dict(self.fields)
-
- if self.env.configrc is not None:
- self.config.read_dict(self.as_dict(self.env.configrc))
-
- # Include user-defined build fields
- self.config.read(self.filename)
- # Assimilate conda environment variables
- self.config['environ'] = conda_build.environ.get_dict()
-
- # Convert ConfigParser -> generic dictionary
- self.local = self.as_dict(self.config)
-
- #Field list conversion table taken from conda_build.metadata:
- for field in ('source/patches',
- 'build/entry_points', 'build/script_env',
- 'build/features', 'build/track_features',
- 'requirements/build', 'requirements/run',
- 'requirements/conflicts', 'test/requires',
- 'test/files', 'test/commands', 'test/imports'):
- section, key = field.split('/')
- if self.local[section][key]:
- self.local[section][key] = self.config.getlist(section, key)
-
- self.local_metadata = {}
- for keyword in self.builtins:
- if keyword in self.local:
- self.local_metadata[keyword] = self.local[keyword]
-
- # Convert dict to YAML-compatible dict
- self.conda_metadata = self.scrub(self.local, self.builtins)
-
- def run(self):
- self.render_scripts()
-
- def render_scripts(self):
- '''Write all conda scripts
- '''
- for maskkey, maskval in self.env.config['script'].items():
- for metakey, metaval in self.compile().items():
- if metakey in maskkey:
- with open(maskval, 'w+') as metafile:
- metafile.write(metaval)
-
- def copy_patches(self):
- extensions = ['*.diff', '*.patch']
- for extension in extensions:
- path = os.path.join(self.confdir, extension)
- for patch in glob(path):
- shutil.copy2(patch, self.env.pkgdir)
-
- def compile(self):
- compiled = {}
- compiled['meta'] = yaml.safe_dump(self.conda_metadata, default_flow_style=False, line_break=True, indent=4)
- compiled['build_linux'] = self.local_metadata['cbc_build']['linux']
- #if 'windows' in self.local_metadata['']
- compiled['build_windows'] = self.local_metadata['cbc_build']['windows']
- return compiled
-
- def convert_conda_fields(self, fields):
- temp = OrderedDict()
- for fkey, fval in fields.items():
- temp[fkey] = { x: '' for x in fval}
-
- return temp
-
- def scrub(self, obj, force_remove=[]):
- obj_c = obj.copy()
- if isinstance(obj_c, dict):
- for key,val in obj_c.items():
- for reserved in force_remove:
- if reserved in key:
- del obj[reserved]
- continue
- if isinstance(val, dict):
- val = self.scrub(val)
- if val is None or val == {} or not val:
- del obj[key]
-
- return obj
-
-
- def as_dict(self, config):
- """
- Converts a ConfigParser object into a dictionary.
-
- The resulting dictionary has sections as keys which point to a dict of the
- sections options as key => value pairs.
- """
- the_dict = {}
- for section in config.sections():
- the_dict[section] = {}
- for key, val in config.items(section):
- for cast in (int, float, bool, str):
- try:
- the_dict[section][key] = cast(val)
- except ValueError:
- pass
-
- return the_dict
-
-
-def aslist_cronly(value):
- if isinstance(value, str):
- value = filter(None, [x.strip() for x in value.splitlines()])
- return list(value)
-
-def aslist(value, flatten=True):
- """ Return a list of strings, separating the input based on newlines
- and, if flatten=True (the default), also split on spaces within
- each line."""
- values = aslist_cronly(value)
- if not flatten:
- return values
- result = []
- for value in values:
- subvalues = value.split()
- result.extend(subvalues)
- return result
-
-class CBCConfigParser(ConfigParser):
- def getlist(self,section,option):
- value = self.get(section,option)
- return list(filter(None, (x.strip() for x in value.splitlines())))
-
- def getlistint(self,section,option):
- return [int(x) for x in self.getlist(section,option)]
+'''I refuse to write the same thing over and over again in meta.yaml. +And yeah, conda supports Jinja2, but ugh... No. +''' + +import os +import conda_build.metadata +import conda_build.environ +import yaml +import shutil +from glob import glob +from configparser import ConfigParser, ExtendedInterpolation +from collections import OrderedDict +from .environment import Environment +from .exceptions import MetaDataError + + +class MetaData(object): + def __init__(self, filename, env): + + filename = os.path.abspath(filename) + if not os.path.exists(filename): + raise OSError('"{0}" does not exist.'.format(filename)); + + self.filename = filename + self.confdir = os.path.dirname(self.filename) + + if not isinstance(env, Environment): + raise MetaDataError('Expecting instance of cbc.environment.Environment, got: "{0}"'.format(type(env))) + + self.env = env + self.builtins = ['cbc_build', 'cbc_cgi', 'settings', 'environ'] + + self.fields = self.convert_conda_fields(conda_build.metadata.FIELDS) + #self.config = SafeConfigParser(interpolation=ExtendedInterpolation(), allow_no_value=True) + self.config = CBCConfigParser(interpolation=ExtendedInterpolation(), allow_no_value=True) + # Include built-in Conda metadata fields + self.config.read_dict(self.fields) + + if self.env.configrc is not None: + self.config.read_dict(self.as_dict(self.env.configrc)) + + # Include user-defined build fields + self.config.read(self.filename) + # Assimilate conda environment variables + self.config['environ'] = conda_build.environ.get_dict() + + # Convert ConfigParser -> generic dictionary + self.local = self.as_dict(self.config) + + #Field list conversion table taken from conda_build.metadata: + for field in ('source/patches', + 'build/entry_points', 'build/script_env', + 'build/features', 'build/track_features', + 'requirements/build', 'requirements/run', + 'requirements/conflicts', 'test/requires', + 'test/files', 'test/commands', 'test/imports'): + section, key = field.split('/') + if self.local[section][key]: + self.local[section][key] = self.config.getlist(section, key) + + self.local_metadata = {} + for keyword in self.builtins: + if keyword in self.local: + self.local_metadata[keyword] = self.local[keyword] + + # Convert dict to YAML-compatible dict + self.conda_metadata = self.scrub(self.local, self.builtins) + + def run(self): + self.render_scripts() + + def render_scripts(self): + '''Write all conda scripts + ''' + for maskkey, maskval in self.env.config['script'].items(): + for metakey, metaval in self.compile().items(): + if metakey in maskkey: + with open(maskval, 'w+') as metafile: + metafile.write(metaval) + + def copy_patches(self): + extensions = ['*.diff', '*.patch'] + for extension in extensions: + path = os.path.join(self.confdir, extension) + for patch in glob(path): + shutil.copy2(patch, self.env.pkgdir) + + def compile(self): + compiled = {} + compiled['meta'] = yaml.safe_dump(self.conda_metadata, default_flow_style=False, line_break=True, indent=4) + compiled['build_linux'] = self.local_metadata['cbc_build']['linux'] + #if 'windows' in self.local_metadata[''] + compiled['build_windows'] = self.local_metadata['cbc_build']['windows'] + return compiled + + def convert_conda_fields(self, fields): + temp = OrderedDict() + for fkey, fval in fields.items(): + temp[fkey] = { x: '' for x in fval} + + return temp + + def scrub(self, obj, force_remove=[]): + obj_c = obj.copy() + if isinstance(obj_c, dict): + for key,val in obj_c.items(): + for reserved in force_remove: + if reserved in key: + del obj[reserved] + continue + if isinstance(val, dict): + val = self.scrub(val) + if val is None or val == {} or not val: + del obj[key] + + return obj + + + def as_dict(self, config): + """ + Converts a ConfigParser object into a dictionary. + + The resulting dictionary has sections as keys which point to a dict of the + sections options as key => value pairs. + """ + the_dict = {} + for section in config.sections(): + the_dict[section] = {} + for key, val in config.items(section): + for cast in (int, float, bool, str): + try: + the_dict[section][key] = cast(val) + except ValueError: + pass + + return the_dict + + +def aslist_cronly(value): + if isinstance(value, str): + value = filter(None, [x.strip() for x in value.splitlines()]) + return list(value) + +def aslist(value, flatten=True): + """ Return a list of strings, separating the input based on newlines + and, if flatten=True (the default), also split on spaces within + each line.""" + values = aslist_cronly(value) + if not flatten: + return values + result = [] + for value in values: + subvalues = value.split() + result.extend(subvalues) + return result + +class CBCConfigParser(ConfigParser): + def getlist(self,section,option): + value = self.get(section,option) + return list(filter(None, (x.strip() for x in value.splitlines()))) + + def getlistint(self,section,option): + return [int(x) for x in self.getlist(section,option)] |