Skip to content

Commit

Permalink
[ui] Add support for showing the values in the database.
Browse files Browse the repository at this point in the history
 - This requires maintaining a manual Python port of the
   llbuild::buildsystem::BuildValue type, but unfortunately I don't have a
   better idea currently -- and being able to see the values is really important
   to debugging complex databases.
  • Loading branch information
ddunbar committed Feb 20, 2017
1 parent 03f913f commit 848278c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
103 changes: 102 additions & 1 deletion products/ui/llbuildui/model.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import struct

from sqlalchemy import *
from sqlalchemy.orm import relation, relationship
from sqlalchemy.ext.declarative import declarative_base
Expand All @@ -22,7 +24,7 @@ class RuleResult(Base):
id = Column(Integer, nullable=False, primary_key=True)
key_id = Column(Integer, ForeignKey(KeyName.id),
nullable=False)
value = Column(Integer, nullable=False)
value_bytes = Column("value", Integer, nullable=False)
built_at = Column(Integer, nullable=False)
computed_at = Column(Integer, nullable=False)

Expand All @@ -34,6 +36,10 @@ def __repr__(self):
self.__class__.__name__, (self.id, self.key, self.value,
self.built_at, self.computed_at))

@property
def value(self):
return BuildValue(self.value_bytes)

class RuleDependency(Base):
__tablename__ = "rule_dependencies"

Expand All @@ -48,3 +54,98 @@ class RuleDependency(Base):
def __repr__(self):
return "%s%r" % (
self.__class__.__name__, (self.rule_id, self.key))

###

class BuildValue(object):
# FIXME: This is a manually Python translation of the C++
# llbuild::buildsystem::BuildValue type, which is unfortunate, but it isn't
# available via an API we can access directly yet.

kinds = [
"Invalid",
"VirtualInput", "ExistingInput", "MissingInput",
"DirectoryContents", "DirectoryTreeSignature",
"MissingOutput", "FailedInput",
"SuccessfulCommand", "FailedCommand",
"PropagatedFailureCommand", "CancelledCommand", "SkippedCommand",
"Target",
]

def __init__(self, data):
bytes = str(data)

# The first byte is the kind.
if bytes:
self.kind = self.__class__.kinds[struct.unpack("<B", bytes[0])[0]]
bytes = bytes[1:]
else:
self.kind = "Invalid"

# The next item is the signature, if used.
if self.hasCommandSignature:
self.signature = struct.unpack("<Q", bytes[:8])[0]
bytes = bytes[8:]
else:
self.signature = None

# The outputs follow, if used.
if self.hasOutputInfo:
numOutputs = struct.unpack("<I", bytes[:4])[0]
bytes = bytes[4:]
self.outputs = []
for i in range(numOutputs):
# Read the file information.
self.outputs.append(FileInfo(bytes[:48]))
bytes = bytes[48:]
else:
self.outputs = None

# The strings follow, if used.
if self.hasStringList:
stringsLength = struct.unpack("<Q", bytes[:8])[0]
bytes = bytes[8:]
stringData = bytes[:stringsLength]
bytes = bytes[stringsLength:]
assert len(stringData) == stringsLength
assert stringData[-1] == '\0'
self.strings = stringData[:-1].split("\0")
else:
self.strings = None

assert len(bytes) == 0

@property
def hasCommandSignature(self):
return self.kind in ("SuccessfulCommand", "DirectoryTreeSignature")

@property
def hasStringList(self):
return self.kind in ("DirectoryContents",)

@property
def hasOutputInfo(self):
return self.kind in ("ExistingInput", "SuccessfulCommand",
"DirectoryContents")

def __repr__(self):
output = "BuildValue(kind=%r" % self.kind
if self.signature is not None:
output += ", signature=%0x" % self.signature
if self.outputs is not None:
output += ", outputs=%r" % self.outputs
if self.strings is not None:
output += ", strings=%r" % self.strings
output += ")"
return output

class FileInfo(object):
def __init__(self, bytes):
(self.device, self.inode, self.mode, self.size,
modTimeSec, modTimeNano) = struct.unpack("<QQQQQQ", bytes)
self.modTime = (modTimeSec, modTimeNano)

def __repr__(self):
return "FileInfo(device=%r, inode=%#0x, mode=%r, size=%r, mtime=(%r, %r))" % (
self.device, self.inode, self.mode, self.size,
self.modTime[0], self.modTime[1])
3 changes: 3 additions & 0 deletions products/ui/llbuildui/templates/rule_result.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ <h4>Dependents</h4>
</a><br>
{% endfor %}

<h4>Value</h4>
{{ rule_result.value }}

{% endblock %}

0 comments on commit 848278c

Please sign in to comment.