summaryrefslogblamecommitdiff
path: root/attoconf/classy.py
blob: 33c9c40317a4793dfc190889d64736f7059a23ea (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                                                             















                                                                        
 


                                






                                                        
                                       







                                                   


                                                      


                                                                                  

                       

                           
                   
              
 
                                                                       


                                                                  
                      



                                                   
                               
                     


                         
                               
                      
                               
                    
                               
                     
                               
                   
                               
                       
                               
                       
                               


                        
                                   
                   
                               






                                                                      
                                              
                                              
                                                                                           























                                                                           
                                                             



                                                         







                                                                            



                                                        






                                                                      















                                                                         
#   Copyright 2013-2015 Ben Longbons <b.r.longbons@gmail.com>
#
#   This file is part of attoconf.
#
#   attoconf is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   attoconf is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with attoconf.  If not, see <http://www.gnu.org/licenses/>.



from .core import Project, Build

class PolymorphicSlotMergerMetaclass(type):

    def __new__(meta, name, bases, dct):
        if '__slots__' not in dct:
            s = ()
            for b in bases:
                s2 = b.__dict__.get('_merge_slots_', ())
                if isinstance(s2, str):
                    s2 = (s2,)
                s += s2
            s += dct.get('_merge_slots_', ())
            dct['__slots__'] = s
        else:
            assert dct['__slots__'] == ()
        return type.__new__(meta, name, bases, dct)

    # TODO: remove *args for 1.0
    def __call__(cls, *args, **kwargs):
        instance = type.__call__(cls, *args, **kwargs)
        if 'package' in kwargs or not isinstance(instance,
                __import__('attoconf.lib.install', fromlist=['Install']).Install):
            instance._do_jiggle()
        return instance


# TODO: remove this for 1.0
def add_slots(cls):
    return cls

class ClassyProject(Project, metaclass=PolymorphicSlotMergerMetaclass):
    ''' A more convenient, objectish, way of setting up a project.
    '''
    __slots__ = ()
    _merge_slots_ = ()

    def __init__(self, srcdir):
        super(ClassyProject, self).__init__(srcdir)

    # TODO: remove this for 1.0
    def jiggle(self):
        pass

    def _do_jiggle(self):
        self.order.append(None)
        self.general()
        self.order.append(None)
        self.paths()
        self.order.append(None)
        self.arches()
        self.order.append(None)
        self.vars()
        self.order.append(None)
        self.features()
        self.order.append(None)
        self.packages()
        self.order.append(None)

        if 0:
            self.tests()
            self.order.append(None)
        self.post()
        self.order.append(None)

    def general(self):
        ''' Registration hook for general options (usually unneeded).
        '''
        self.add_help('General:', hidden=False)
        self.add_alias('--help', ['--help=default'],
                help='display standard help, then exit', hidden=False)
        self.add_option('--help', init='none',
                type=self.do_help, check=None,
                help='just display some kind of help instead of configuring', hidden=False,
                help_var='KIND')
        self.help.add_option('--help=hidden',
                help='display help you should never ever ever care about',
                hidden=False)

    def paths(self):
        ''' Registration hook for path-related options.
            (--prefix, --bindir, etc)

            Probably only used by attoconf.lib.install.
        '''

    def arches(self):
        ''' Registration hook for arch-related options.
            (--build, --host, and sometimes --target)

            Typically this changes the prefix of the compiler.
        '''

    def vars(self):
        ''' Environment variables (usually capital, don't start with a --).

            Usually there is one or two of these for every program needed.
        '''
        self.add_help('Environment Variables:', hidden=False)

    def features(self):
        ''' Customizations for this package (--enable-*).
        '''
        self.add_help('Optional Features:', hidden=False)
        # TODO add '--disable-option-checking'
        self.help.add_option('--disable-FEATURE',
                help='do not include FEATURE (same as --enable-FEATURE=no)',
                hidden=False)
        self.help.add_option('--enable-FEATURE',
                help='include FEATURE (same as --enable-FEATURE=yes)',
                hidden=False)

    def packages(self):
        ''' Settings related to dependencies (--with-*).
        '''
        self.add_help('Optional Packages:', hidden=False)
        self.help.add_option('--with-PACKAGE',
                help='use PACKAGE (same as --with-PACKAGE=yes)',
                hidden=False)
        self.help.add_option('--without-PACKAGE',
                help='do not use PACKAGE (same as --with-PACKAGE=no)',
                hidden=False)

    if 0: # not sure if really needed
        def tests(self):
            ''' Late tests, but still before post.

            '''

    def post(self):
        ''' Special hook for things that need to be done at the very end.

            attoconf.post.make
        '''

    # okay, no more registration hooks
    def build(self, bindir):
        return Build(self, bindir)