puilder / puilder /

# Very basic build system. Designed to be friendly for UI generation.

from json import dumps, loads

def dump(data):
    return dumps(data, sort_keys=False, indent=2, separators=(',',':'))

class Build(object):
    """A single build file"""
    def __init__(self):
        self.targets = []
        self.options = {}

    def for_serialize(self):
        sopt = self.options.copy()
        if 'default' in sopt:
            # we only save the target name as default option, not the reference
                sopt['default'] = sopt['default'].name
                # this should happen but may happen due data inconsistency.
                # better remove
                if 'default' in sopt:
                    del sopt['default']
        return {
            'targets': [t.for_serialize() for t in self.targets],
            'options': sopt,

    def from_serialize(cls, data):
        b = Build()
        for d in data['targets']:
        if 'default' in b.options:
            b.default = b.options['default']
        return b

    def loads(cls, s):
        return cls.from_serialize(loads(s))

    def loadf(cls, filename):
        f = open(filename)
        s = cls.loads(
        return s

    def dumps(self):
        return dump(self.for_serialize())

    def dumpf(self, filename):
        f = open(filename, 'w')

    def create_new_target(self, name='', actions=()):
        t = Target() = name
        t.actions = list(actions)
        #t.dependencies = list(dependencies)
        return t

    def get_default(self):
        if 'default' in self.options:
            return self.options['default']
            # if not a default is defined, we return a target named default
            # as a fallback
            for target in self.targets:
                if == "default":
                    return target

    def set_default(self, target):
        if not isinstance(target, Target) :
            for ctar in self.targets:
                ctar.is_default = False
                if == target:
                    ctar.is_default = True
                    target = ctar
            for ctar in self.targets:
                ctar.is_default = target is ctar

        if target is None:
                del self.options['default']
            except KeyError: 
            self.options['default'] = target

    default = property(get_default, set_default)

class Target(object):
    """A single target"""

    def __init__(self): = ''
        self.is_default = False
        self.actions = []
        #self.dependencies = []

    def for_serialize(self):
        return {
            'actions': [a.for_serialize() for a in self.actions],
            #'dependencies': [d.for_serialize() for d in self.dependencies],

    def from_serialize(cls, data):
        t = Target() = data.get('name', 'unnamed')
        for act in data.get('actions', ()):
        return t

    def create_new_action(self):
        act = Action()
        act.type = 'shell'
        return act

    def action_count(self):
        return len(self.actions)

    def __str__(self):

    def __repr__(self):
        return '<Target %s>'

class Action(object):
    """A single action"""
    def __repr__(self):
        return '<puild-action %s %r>' % (self.type, self.value)

    def __init__(self):
        self.type = ''
        self.value = ''
        self.options = {
            'ignore_fail': False,

    def for_serialize(self):
        return {
            'type': self.type,
            'value': self.value,
            'options': self.options,

    def from_serialize(cls, data):
        a = Action()
        a.type = data['type']
        a.value = data['value']
        a.options = data.get('options', {})
        return a

action_types = [
    ('shell', 'Shell Command'),
    ('python', 'Python Script'),
    ('target', 'Existing Target'),
    ('external', 'External Build')

if __name__ == '__main__':
    b = get_test_build()
    b.options['name'] = 'foo'
    print b.dumps()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.