blob: 5372dd0016228451c68ef0d8e6c8aa5ea7a92c5f [file] [log] [blame]
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
"""
Simple Data-Driven Build System
"""
import json
import threading
import sys
import traceback
import llbuild
class SimpleRule(llbuild.Rule, llbuild.Task):
"""
asKey(*args) -> str
Return the key for computing the rule in the future.
"""
@classmethod
def asKey(klass, *args):
kind = klass.__name__
assert kind.endswith("Rule")
kind = kind[:-4]
return json.dumps({ "kind" : kind, "args" : args })
def create_task(self):
return self
###
# JSON-ify Wrappers
def is_result_valid(self, engine, result):
try:
return self.is_data_valid(engine, json.loads(result))
except:
traceback.print_exc()
return True
def is_data_valid(self, engine, result):
return True
def provide_value(self, engine, input_id, result):
try:
return self.provide_data(engine, input_id, json.loads(result))
except:
traceback.print_exc()
return None
def provide_data(self, engine, input_id, data):
raise RuntimeError("missing client override")
class SimpleAsyncRule(SimpleRule):
_async = True
def run(self):
abstract
def inputs_available(self, engine):
if self._async:
# Spawn a thread to do the actual work.
t = threading.Thread(target=self._execute, args=(engine,))
t.start()
else:
self._execute(engine)
def _execute(self, engine):
try:
result = self.run()
except:
traceback.print_exc()
result = None
engine.task_is_complete(self, result)
class DataDrivenEngine(llbuild.BuildEngine):
def __init__(self, namespace):
super(DataDrivenEngine, self).__init__(self)
self.namespace = namespace
def lookup_rule(self, name):
# Rules are encoded as a JSON dictionary.
data = json.loads(name)
rule_name = data["kind"] + "Rule"
rule_class = self.namespace.get(rule_name)
if rule_class is None:
raise RuntimeError("invalid rule: %r" % (data,))
return rule_class(*data['args'])
def task_is_complete(self, task, data, force_change=False):
value = json.dumps(data)
super(DataDrivenEngine, self).task_is_complete(
task, value, force_change)
def build(self, key):
result = super(DataDrivenEngine, self).build(key)
return json.loads(result)