Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
tabatkins committed Aug 16, 2024
1 parent 75fe915 commit 92e5a1f
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 186 deletions.
20 changes: 15 additions & 5 deletions bikeshed/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from isodate import Duration, parse_duration

from . import config, constants, datablocks, h, markdown, repository, t
from . import config, constants, datablocks, h, markdown, repository, status, t
from . import messages as m
from .translate import _

Expand Down Expand Up @@ -49,7 +49,7 @@ def __init__(self) -> None:
self.level: str | None = None
self.displayShortname: str | None = None
self.shortname: str | None = None
self.status: str | None = None
self.status: self.Status | None = None
self.rawStatus: str | None = None

# optional metadata
Expand Down Expand Up @@ -80,7 +80,8 @@ def __init__(self) -> None:
self.externalInfotrees: config.BoolSet = config.BoolSet(default=False)
self.favicon: str | None = None
self.forceCrossorigin: bool = False
self.group: str | None = None
self.group: status.Group | None = None
self.rawGroup: str | None = None
self.h1: str | None = None
self.ignoreCanIUseUrlFailure: list[str] = []
self.ignoreMDNFailure: list[str] = []
Expand Down Expand Up @@ -114,6 +115,8 @@ def __init__(self) -> None:
self.noEditor: bool = False
self.noteClass: str = "note"
self.opaqueElements: list[str] = ["pre", "xmp", "script", "style"]
self.org: status.Org | None = None
self.rawOrg: str | None = None
self.prepTR: bool = False
self.previousEditors: list[dict[str, str | None]] = []
self.previousVersions: list[dict[str, str]] = []
Expand Down Expand Up @@ -195,7 +198,13 @@ def computeImplicitMetadata(self, doc: t.SpecT) -> None:
and "repository-issue-tracking" in self.boilerplate
):
self.issues.append(("GitHub", self.repository.formatIssueUrl()))
self.status = config.canonicalizeStatus(self.rawStatus, self.group)

self.org, self.status, self.group = status.canonicalizeOrgStatusGroup(
doc.statuses,
self.rawOrg,
self.rawStatus,
self.rawGroup,
)

self.expires = canonicalizeExpiryDate(self.date, self.expires)

Expand Down Expand Up @@ -1369,7 +1378,7 @@ def parseLiteralList(key: str, val: str, lineNum: str | int | None) -> list[str]
"Favicon": Metadata("Favicon", "favicon", joinValue, parseLiteral),
"Force Crossorigin": Metadata("Force Crossorigin", "forceCrossorigin", joinValue, parseBoolean),
"Former Editor": Metadata("Former Editor", "previousEditors", joinList, parseEditor),
"Group": Metadata("Group", "group", joinValue, parseLiteral),
"Group": Metadata("Group", "rawGroup", joinValue, parseLiteral),
"H1": Metadata("H1", "h1", joinValue, parseLiteral),
"Ignore Can I Use Url Failure": Metadata(
"Ignore Can I Use Url Failure",
Expand Down Expand Up @@ -1418,6 +1427,7 @@ def parseLiteralList(key: str, val: str, lineNum: str | int | None) -> list[str]
"No Editor": Metadata("No Editor", "noEditor", joinValue, parseBoolean),
"Note Class": Metadata("Note Class", "noteClass", joinValue, parseLiteral),
"Opaque Elements": Metadata("Opaque Elements", "opaqueElements", joinList, parseCommaSeparated),
"Org": Metadata("Org", "rawOrg", joinValue, parseLiteral),
"Prepare For Tr": Metadata("Prepare For Tr", "prepTR", joinValue, parseBoolean),
"Previous Version": Metadata("Previous Version", "previousVersions", joinList, parsePreviousVersion),
"Remove Multiple Links": Metadata("Remove Multiple Links", "removeMultipleLinks", joinValue, parseBoolean),
Expand Down
3 changes: 2 additions & 1 deletion bikeshed/status/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .GroupStatusManager import GroupStatusManager
from .manager import Group, GroupStatusManager, GroupW3C, Org, Status, StatusW3C
from .utils import canonicalizeOrgStatusGroup
104 changes: 60 additions & 44 deletions bikeshed/status/GroupStatusManager.py → bikeshed/status/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@dataclasses.dataclass
class GroupStatusManager:
genericStatuses: dict[str, Status] = dataclasses.field(default_factory=dict)
standardsBodies: dict[str, StandardsBody] = dataclasses.field(default_factory=dict)
orgs: dict[str, Org] = dataclasses.field(default_factory=dict)

@staticmethod
def fromKdlStr(data: str) -> GroupStatusManager:
Expand All @@ -23,58 +23,74 @@ def fromKdlStr(data: str) -> GroupStatusManager:
status = Status.fromKdlNode(node)
self.genericStatuses[status.shortName] = status

for node in kdlDoc.getAll("standards-body"):
sb = StandardsBody.fromKdlNode(node)
self.standardsBodies[sb.name] = sb
for node in kdlDoc.getAll("org"):
org = Org.fromKdlNode(node)
self.orgs[org.name] = org

return self

def getStatuses(name: str) -> list[Status]:
def getStatuses(self, name: str) -> list[Status]:
statuses = []
if name in self.genericStatuses:
statuses.append(self.genericStatuses[name])
for sb in self.standardsBodies:
if name in sb.statuses:
statuses.append(sb.statuses[name])
for org in self.orgs.values():
if name in org.statuses:
statuses.append(org.statuses[name])
return statuses

def getStatus(sbName: str|None, statusName: str) -> Status|None:
# Note that a None sbName does *not* indicate we don't care,
# it's specifically statuses *not* restricted to a standards body.
if sbName is None:
def getStatus(self, orgName: str | None, statusName: str, allowGeneric: bool = False) -> Status | None:
# Note that a None orgName does *not* indicate we don't care,
# it's specifically statuses *not* restricted to an org.
if orgName is None:
return self.genericStatuses.get(statusName)
elif sbName in self.standardsBodies:
return self.standardsBodies[sbName].statuses.get(statusName)
elif orgName in self.orgs:
statusInOrg = self.orgs[orgName].statuses.get(statusName)
if statusInOrg:
return statusInOrg
elif allowGeneric:
return self.genericStatuses.get(statusName)
else:
return None
else:
return None

def getGroup(groupName: str) -> Group|None:
for sb in self.standardsBodies:
if groupName in sb.groups:
return sb.groups[groupName]
return None

def getStandardsBody(sbName: str) -> StandardsBody|None:
return self.standardsBodies.get(sbName)

def getGroups(self, orgName: str | None, groupName: str) -> list[Group]:
# Unlike Status, if org is None we'll just grab whatever group matches.
groups = []
for org in self.orgs.values():
if orgName is not None and org.name != orgName:
continue
if groupName in org.groups:
groups.append(org.groups[groupName])
return groups

def getGroup(self, orgName: str | None, groupName: str) -> Group | None:
# If Org is None, and there are multiple groups with that name, fail to find.
groups = self.getGroups(orgName, groupName)
if len(groups) == 1:
return groups[0]
else:
return None

def getOrg(self, orgName: str) -> Org | None:
return self.orgs.get(orgName)


@dataclasses.dataclass
class StandardsBody:
class Org:
name: str
groups: dict[str, Group] = dataclasses.field(default_factory=dict)
statuses: dict[str, Status] = dataclasses.field(default_factory=dict)

@staticmethod
def fromKdlNode(node: kdl.Node) -> StandardsBody:
def fromKdlNode(node: kdl.Node) -> Org:
name = t.cast(str, node.args[0])
self = StandardsBody(name)
self = Org(name)
for child in node.getAll("group"):
g = Group.fromKdlNode(child, sb=self)
g = Group.fromKdlNode(child, org=self)
self.groups[g.name] = g
for child in node.getAll("status"):
s = Status.fromKdlNode(child, sb=self)
s = Status.fromKdlNode(child, org=self)
self.statuses[s.shortName] = s
return self

Expand All @@ -83,49 +99,49 @@ def fromKdlNode(node: kdl.Node) -> StandardsBody:
class Group:
name: str
privSec: bool
sb: StandardsBody | None = None
org: Org

@staticmethod
def fromKdlNode(node: kdl.Node, sb: StandardsBody | None = None) -> Group:
if sb.name == "w3c":
return GroupW3C.fromKdlNode(node, sb)
def fromKdlNode(node: kdl.Node, org: Org) -> Group:
if org.name == "w3c":
return GroupW3C.fromKdlNode(node, org)
name = t.cast(str, node.args[0])
privSec = node.get("priv-sec") is not None
return Group(name, privSec, sb)
return Group(name, privSec, org)


@dataclasses.dataclass
class GroupW3C(Group):
type: str | None = None

@staticmethod
def fromKdlNode(node: kdl.Node, sb: StandardsBody | None = None) -> GroupW3C:
def fromKdlNode(node: kdl.Node, org: Org) -> GroupW3C:
name = t.cast(str, node.args[0])
privSec = node.get("priv-sec") is not None
groupType = t.cast("str|None", node.props["type"])
return GroupW3C(name, privSec, sb, groupType)
return GroupW3C(name, privSec, org, groupType)


@dataclasses.dataclass
class Status:
shortName: str
longName: str
sb: StandardsBody | None = None
org: Org | None = None
requires: list[str] = dataclasses.field(default_factory=list)

def fullShortname(self) -> str:
if self.sb.name is None:
if self.org is None:
return self.shortName
else:
return self.sb.name + "/" + self.shortName
return self.org.name + "/" + self.shortName

@staticmethod
def fromKdlNode(node: kdl.Node, sb: StandardsBody | None = None) -> Status:
if sb.name == "w3c":
return StatusW3C.fromKdlNode(node, sb)
def fromKdlNode(node: kdl.Node, org: Org | None = None) -> Status:
if org and org.name == "w3c":
return StatusW3C.fromKdlNode(node, org)
shortName = t.cast(str, node.args[0])
longName = t.cast(str, node.args[1])
self = Status(shortName, longName, sb)
self = Status(shortName, longName, org)
requiresNode = node.get("requires")
if requiresNode:
self.requires = t.cast("list[str]", list(node.getArgs((..., str))))
Expand All @@ -137,10 +153,10 @@ class StatusW3C(Status):
groupTypes: list[str] = dataclasses.field(default_factory=list)

@staticmethod
def fromKdlNode(node: kdl.Node, sbName: str | None = None) -> StatusW3C:
def fromKdlNode(node: kdl.Node, org: Org | None = None) -> StatusW3C:
shortName = t.cast(str, node.args[0])
longName = t.cast(str, node.args[1])
self = StatusW3C(shortName, longName, sbName)
self = StatusW3C(shortName, longName, org)
requiresNode = node.get("requires")
if requiresNode:
self.requires = t.cast("list[str]", list(node.getArgs((..., str))))
Expand Down
Loading

0 comments on commit 92e5a1f

Please sign in to comment.