Skip to content

Commit

Permalink
refactor: remove remaining chalkConfig field accesses (#329)
Browse files Browse the repository at this point in the history
Continue (from past commits [1][2][3]) to prepare for the new con4m,
by reducing our usage of the autogenerated types and procs. This time,
remove nearly every remaining access of a chalkConfig field. The two
remaining field accesses are in the `get` overloads:

    $ git grep --break --heading --ignore-case --context=1 'chalkConfig\.'
    src/run_management.nim
    30:proc get*[T](chalkConfig: ChalkConfig, fqn: string): T =
    31:  get[T](chalkConfig.`@@attrscope@@`, fqn)
    32:
    33:proc getOpt*[T](chalkConfig: ChalkConfig, fqn: string): Option[T] =
    34:  getOpt[T](chalkConfig.`@@attrscope@@`, fqn)

We'll remove those later.

Refs: #214

[1] 66a5bb4, "refactor: begin to avoid autogenerated getters"
[2] 4157b58, "refactor: reduce usage of autogenerated getters, part 2"
[3] 855197e, "refactor(confload, subscan): remove chalkConfig field accesses"
  • Loading branch information
ee7 authored Jun 17, 2024
1 parent 4290bd0 commit bad5618
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 162 deletions.
2 changes: 1 addition & 1 deletion src/chalk_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ type
Plugin* = ref object
name*: string
enabled*: bool
configInfo*: PluginSpec
configInfo*: AttrScope
getChalkTimeHostInfo*: ChalkTimeHostCb
getChalkTimeArtifactInfo*: ChalkTimeArtifactCb
getRunTimeArtifactInfo*: RunTimeArtifactCb
Expand Down
20 changes: 10 additions & 10 deletions src/chalkjson.nim
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,12 @@ proc extractOneChalkJson*(chalkData: string, path: string): ChalkDict =

# Output ordering for keys.
proc orderKeys*(dict: ChalkDict,
tplate: MarkTemplate | ReportTemplate): seq[string] =
tplate: AttrScope): seq[string] =
var tmp: seq[(int, string)] = @[]
for k, _ in dict:
var order = chalkConfig.keySpecs[k].normalizedOrder
if tplate != nil and k in tplate.keys:
let orderOpt = tplate.keys[k].order
var order = get[int](getChalkScope(), "keyspec." & k & ".normalized_order")
if tplate != nil and getObjectOpt(tplate, "key." & k).isSome():
let orderOpt = getOpt[int](tplate, "key." & k & ".order")
if orderOpt.isSome():
order = orderOpt.get()
tmp.add((order, k))
Expand All @@ -460,7 +460,7 @@ proc orderKeys*(dict: ChalkDict,
# we need, which gives us a JsonNode object, that we then convert
# back to a string, with necessary quotes intact.

proc toJson*(dict: ChalkDict, tplate: MarkTemplate | ReportTemplate): string =
proc toJson*(dict: ChalkDict, tplate: AttrScope): string =
result = ""
var comma = ""
let keys = dict.orderKeys(tplate)
Expand All @@ -476,23 +476,23 @@ proc toJson*(dict: ChalkDict, tplate: MarkTemplate | ReportTemplate): string =
result = "{ " & result & " }"

proc toJson*(dict: ChalkDict): string =
return dict.toJson(MarkTemplate(nil))
return dict.toJson(AttrScope(nil))

proc prepareContents*(dict: ChalkDict,
t: MarkTemplate | ReportTemplate): string =
t: AttrScope): string =
return dict.filterByTemplate(t).toJson(t)

proc forcePrivateKeys() =
var toForce: seq[string]

for k, _ in chalkConfig.keySpecs:
for k, _ in getChalkSubsections("keyspec"):
if k.startswith("$"):
toForce.add(k)

forceChalkKeys(toForce)

proc getChalkMark*(obj: ChalkObj): ChalkDict =
trace("Creating mark using template: " & getOutputConfig().markTemplate)
trace("Creating mark using template: " & get[string](getOutputConfig(), "mark_template"))

forcePrivateKeys()

Expand All @@ -512,7 +512,7 @@ proc getChalkMarkAsStr*(obj: ChalkObj): string =
trace("Chalk cachemark " & $obj.cachedMark)
return obj.cachedMark
trace("Converting Mark to JSON. Mark template is: " &
getOutputConfig().markTemplate)
get[string](getOutputConfig(), "mark_template"))

if obj.cachedMark != "":
return obj.cachedMark
Expand Down
85 changes: 48 additions & 37 deletions src/collect.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ proc hasSubscribedKey(p: Plugin, keys: seq[string], dict: ChalkDict): bool =
# Decides whether to run a given plugin... does it export any key we
# are subscribed to, that hasn't already been provided?
for k in keys:
if k in p.configInfo.ignore: continue
if k in get[seq[string]](p.configInfo, "ignore"): continue
if k notin subscribedKeys and k != "*": continue
if k in p.configInfo.overrides: return true
if k in get[seq[string]](p.configInfo, "overrides"): return true
if k notin dict: return true

return false
Expand All @@ -27,12 +27,12 @@ proc canWrite(plugin: Plugin, key: string, decls: seq[string]): bool =
# This would all be redundant to what we can check in the config file spec,
# except that we do allow "*" fields for plugins, so we need the runtime
# check to filter out inappropriate items.
let spec = chalkConfig.keySpecs[key]
let spec = getObject(getChalkScope(), "keyspec." & key)

if key in plugin.configInfo.ignore: return false
if key in get[seq[string]](plugin.configInfo, "ignore"): return false

if spec.codec:
if plugin.configInfo.codec:
if get[bool](spec, "codec"):
if get[bool](plugin.configInfo, "codec"):
return true
else:
error("Plugin '" & plugin.name & "' can't write codec key: '" & key & "'")
Expand All @@ -41,23 +41,29 @@ proc canWrite(plugin: Plugin, key: string, decls: seq[string]): bool =
if key notin decls and "*" notin decls:
error("Plugin '" & plugin.name & "' produced undeclared key: '" & key & "'")
return false
if not spec.system:
if not get[bool](spec, "system"):
return true

case plugin.name
of "system", "metsys":
return true
of "conffile":
if spec.confAsSystem:
if get[bool](spec, "conf_as_system"):
return true
else: discard

error("Plugin '" & plugin.name & "' can't write system key: '" & key & "'")
return false

proc registerKeys(templ: MarkTemplate | ReportTemplate) =
for name, content in templ.keys:
if content.use: subscribedKeys[name] = true
proc registerKeys(templ: AttrScope) =
let keyOpt = getObjectOpt(templ, "key")
if keyOpt.isSome():
let key = keyOpt.get()
for name, content in key.contents:
if content.isA(AttrScope):
let useOpt = getOpt[bool](content.get(AttrScope), "use")
if useOpt.isSome() and useOpt.get():
subscribedKeys[name] = true

proc registerOutconfKeys() =
# We always subscribe to _VALIDATED, even if they don't want to
Expand All @@ -71,19 +77,21 @@ proc registerOutconfKeys() =

let outconf = getOutputConfig()

if outconf.markTemplate != "":
chalkConfig.markTemplates[outConf.markTemplate].registerKeys()
let markTemplate = get[string](outconf, "mark_template")
if markTemplate != "":
getObject(getChalkScope(), "mark_template." & markTemplate).registerKeys()

if outconf.reportTemplate != "":
chalkConfig.reportTemplates[outConf.reportTemplate].registerKeys()
let reportTemplate = get[string](outconf, "report_template")
if reportTemplate != "":
getObject(getChalkScope(), "report_template." & reportTemplate).registerKeys()

proc collectChalkTimeHostInfo*() =
if hostCollectionSuspended():
return

trace("Collecting chalk time artifact info")
for plugin in getAllPlugins():
let subscribed = plugin.configInfo.preRunKeys
let subscribed = get[seq[string]](plugin.configInfo, "pre_run_keys")
if chalkCollectionSuspendedFor(plugin.name): continue
if not plugin.hasSubscribedKey(subscribed, hostInfo): continue
try:
Expand All @@ -93,9 +101,9 @@ proc collectChalkTimeHostInfo*() =
continue

for k, v in dict:
if not plugin.canWrite(k, plugin.configInfo.preRunKeys):
if not plugin.canWrite(k, get[seq[string]](plugin.configInfo, "pre_run_keys")):
continue
if k notin hostInfo or k in plugin.configInfo.overrides or plugin.isSystem():
if k notin hostInfo or k in get[seq[string]](plugin.configInfo, "overrides") or plugin.isSystem():
hostInfo[k] = v
except:
warn("When collecting chalk-time host info, plugin implementation " &
Expand All @@ -116,15 +124,18 @@ proc initCollection*() =
registerOutconfKeys()

# Next, register for any custom reports.
for name, report in chalkConfig.reportSpecs:
if (getBaseCommandName() notin report.use_when and
"*" notin report.use_when):
continue

let templName = report.reportTemplate
for name, report in getChalkSubsections("custom_report"):
let useWhenOpt = getOpt[seq[string]](report, "use_when")
if useWhenOpt.isSome():
let useWhen = useWhenOpt.get()
if (getBaseCommandName() notin useWhen and "*" notin useWhen):
continue

if templName != "":
chalkConfig.reportTemplates[templName].registerKeys()
let templNameOpt = getOpt[string](report, "report_template")
if templNameOpt.isSome():
let templName = templNameOpt.get()
if templName != "":
getObject(getChalkScope(), "report_template." & templName).registerKeys()

if isChalkingOp():
collectChalkTimeHostInfo()
Expand All @@ -134,19 +145,19 @@ proc collectRunTimeArtifactInfo*(artifact: ChalkObj) =
for plugin in getAllPlugins():
let
data = artifact.collectedData
subscribed = plugin.configInfo.postChalkKeys
subscribed = get[seq[string]](plugin.configInfo, "post_chalk_keys")

if chalkCollectionSuspendedFor(plugin.name): continue
if not plugin.hasSubscribedKey(subscribed, data): continue
if plugin.configInfo.codec and plugin != artifact.myCodec: continue
if get[bool](plugin.configInfo, "codec") and plugin != artifact.myCodec: continue

trace("Running plugin: " & plugin.name)
try:
let dict = plugin.callGetRunTimeArtifactInfo(artifact, isChalkingOp())
if dict == nil or len(dict) == 0: continue
for k, v in dict:
if not plugin.canWrite(k, plugin.configInfo.postChalkKeys): continue
if k notin artifact.collectedData or k in plugin.configInfo.overrides or plugin.isSystem():
if not plugin.canWrite(k, get[seq[string]](plugin.configInfo, "post_chalk_keys")): continue
if k notin artifact.collectedData or k in get[seq[string]](plugin.configInfo, "overrides") or plugin.isSystem():
artifact.collectedData[k] = v
trace(plugin.name & ": Plugin called.")
except:
Expand Down Expand Up @@ -182,9 +193,9 @@ proc collectChalkTimeArtifactInfo*(obj: ChalkObj, override = false) =
if obj.fsRef != "":
data["PATH_WHEN_CHALKED"] = pack(resolvePath(obj.fsRef))

if plugin.configInfo.codec and plugin != obj.myCodec: continue
if get[bool](plugin.configInfo, "codec") and plugin != obj.myCodec: continue

let subscribed = plugin.configInfo.preChalkKeys
let subscribed = get[seq[string]](plugin.configInfo, "pre_chalk_keys")
if not plugin.hasSubscribedKey(subscribed, data) and not plugin.isSystem():
trace(plugin.name & ": Skipping plugin; its metadata wouldn't be used.")
continue
Expand All @@ -200,8 +211,8 @@ proc collectChalkTimeArtifactInfo*(obj: ChalkObj, override = false) =
continue

for k, v in dict:
if not plugin.canWrite(k, plugin.configInfo.preChalkKeys): continue
if k notin obj.collectedData or k in plugin.configInfo.overrides or plugin.isSystem() or override:
if not plugin.canWrite(k, get[seq[string]](plugin.configInfo, "pre_chalk_keys")): continue
if k notin obj.collectedData or k in get[seq[string]](plugin.configInfo, "overrides") or plugin.isSystem() or override:
obj.collectedData[k] = v
trace(plugin.name & ": Plugin called.")
except:
Expand All @@ -216,7 +227,7 @@ proc collectRunTimeHostInfo*() =
## artifact loop below.
trace("Collecting run time host info")
for plugin in getAllPlugins():
let subscribed = plugin.configInfo.postRunKeys
let subscribed = get[seq[string]](plugin.configInfo, "post_run_keys")
if chalkCollectionSuspendedFor(plugin.name): continue
if not plugin.hasSubscribedKey(subscribed, hostInfo): continue

Expand All @@ -226,8 +237,8 @@ proc collectRunTimeHostInfo*() =
if dict == nil or len(dict) == 0: continue

for k, v in dict:
if not plugin.canWrite(k, plugin.configInfo.postRunKeys): continue
if k notin hostInfo or k in plugin.configInfo.overrides or plugin.isSystem():
if not plugin.canWrite(k, get[seq[string]](plugin.configInfo, "post_run_keys")): continue
if k notin hostInfo or k in get[seq[string]](plugin.configInfo, "overrides") or plugin.isSystem():
hostInfo[k] = v
except:
warn("When collecting run-time host info, plugin implementation " &
Expand Down
26 changes: 14 additions & 12 deletions src/commands/cmd_help.nim
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,16 @@ proc getReportTemplateDocs(state: ConfigState): Rope =
title = atom("Report Templates"))

proc formatOneTemplate(state: ConfigState,
tmpl: MarkTemplate | ReportTemplate): Rope =
tmpl: AttrScope): Rope =
var
keysToReport: seq[string]

result = markdown(tmpl.doc.getOrElse("No description available."))
let docOpt = getOpt[string](tmpl, "doc")
let doc = if docOpt.isSome(): docOpt.get() else: "No description available."
result = markdown(doc)

for k, v in tmpl.keys:
if v.use == true:
for k, v in getInstantiations(tmpl, "key"):
if get[bool](v, "use") == true:
keysToReport.add(k)

if len(keysToReport) == 0:
Expand All @@ -374,33 +376,33 @@ See `chalk help reporting` for more information on templates.
reportTemplates: seq[string]

if "all" in args:
for k, v in chalkConfig.markTemplates:
for k, v in getChalkSubsections("mark_template"):
markTemplates.add(k)
for k, v in chalkConfig.reportTemplates:
for k, v in getChalkSubsections("report_template"):
reportTemplates.add(k)
else:
for item in args:
if item notin chalkConfig.markTemplates and
item notin chalkConfig.reportTemplates:
if item notin getContents(getChalkScope().getObject("mark_template")) and
item notin getContents(getChalkScope().getObject("report_template")):
result += h3("No template found named: " & item )
else:
if item in chalkConfig.markTemplates:
if item in getContents(getChalkScope().getObject("mark_template")):
markTemplates.add(item)
if item in chalkConfig.reportTemplates:
if item in getContents(getChalkScope().getObject("report_template")):
reportTemplates.add(item)

if len(markTemplates) + len(reportTemplates) == 0:
result += h1("No matching templates found.")
return

for markTmplName in markTemplates:
let theTemplate = chalkConfig.markTemplates[markTmplName]
let theTemplate = getObject(getChalkScope(), "mark_template." & markTmplName)

result += h2("Mark Template: " & markTmplName)
result += state.formatOneTemplate(theTemplate)

for repTmplName in reportTemplates:
let theTemplate = chalkConfig.reportTemplates[repTmplName]
let theTemplate = getObject(getChalkScope(), "report_template." & repTmplName)

result += h2("Report Template: " & repTmplName)
result += state.formatOneTemplate(theTemplate)
Expand Down
Loading

0 comments on commit bad5618

Please sign in to comment.