Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove some chalkConfig field accesses #237

Merged
merged 2 commits into from
Jun 11, 2024

Conversation

ee7
Copy link
Contributor

@ee7 ee7 commented Mar 12, 2024

Issue

#214

Description

Continue from #235 and #236, removing every remaining access of a ChalkConfig field that consists only of built-in types.

With this PR, the remaining field accesses of chalkConfig are the below:

$ git log -1 --format='%h %s'
c3d2d46 refactor(subscan): remove chalkConfig field accesses
$ git grep --break --heading --ignore-case 'chalkConfig\.'
src/chalkjson.nim
448:    var order = chalkConfig.keySpecs[k].normalizedOrder
488:  for k, _ in chalkConfig.keySpecs:

src/collect.nim
30:  let spec = chalkConfig.keySpecs[key]
75:    chalkConfig.markTemplates[outConf.markTemplate].registerKeys()
78:    chalkConfig.reportTemplates[outConf.reportTemplate].registerKeys()
119:  for name, report in chalkConfig.reportSpecs:
127:      chalkConfig.reportTemplates[templName].registerKeys()

src/commands/cmd_help.nim
377:      for k, v in chalkConfig.markTemplates:
379:      for k, v in chalkConfig.reportTemplates:
383:        if item notin chalkConfig.markTemplates and
384:           item notin chalkConfig.reportTemplates:
387:          if item in chalkConfig.markTemplates:
389:          if item in chalkConfig.reportTemplates:
397:      let theTemplate = chalkConfig.markTemplates[markTmplName]
403:      let theTemplate = chalkConfig.reportTemplates[repTmplName]

src/config.nim
58:  return chalkConfig.outputConfigs[getBaseCommandName()]
62:    outconf  = chalkConfig.outputConfigs[getBaseCommandName()]
65:  chalkConfig.markTemplates[tmplName]
69:    outconf  = chalkConfig.outputConfigs[getBaseCommandName()]
72:  chalkConfig.reportTemplates[tmplName]
116:  if name in chalkConfig.keyspecs: return some(chalkConfig.keyspecs[name])
119:  if name in chalkConfig.plugins:
120:    return some(chalkConfig.plugins[name])

src/docker/build.nim
106:    labelTemplate = chalkConfig.markTemplates[labelTemplName]
125:    labelTemplate    = chalkConfig.markTemplates[labelTemplName]

src/docker/json.nim
70:  if not boxedValue.checkAutoType(chalkConfig.keyspecs[chalkKey].`type`):

src/docker/util.nim
110:  if key notin chalkConfig.keyspecs:

src/plugins/conffile.nim
15:  for k, v in chalkConfig.keySpecs:

src/plugins/externalTool.nim
85:  for k, v in chalkConfig.tools:

src/plugins/system.nim
239:      templateToUse = chalkConfig.reportTemplates[templateName]

src/plugins/techStackGeneric.nim
282:    for langName, val in chalkConfig.linguistLanguages:
285:    for key, val in chalkConfig.techStackRules:
354:  for key, val in chalkConfig.techStackRules:

src/reporting.nim
108:  for topic, spec in chalkConfig.reportSpecs:
122:    let templateToUse = chalkConfig.reportTemplates[spec.reportTemplate]

src/run_management.nim
21:  get[T](chalkConfig.`@@attrscope@@`, fqn)
24:  getOpt[T](chalkConfig.`@@attrscope@@`, fqn)

src/sinks.nim
164:      attrRoot = chalkConfig.`@@attrscope@@`
185:    attrRoot = if attr != nil: attr else: chalkConfig.`@@attrscope@@`
233:    attrRoot = chalkConfig.`@@attrscope@@`

Just to illustrate the progress: with this PR, nimble build succeeds if we manually replace c4autoconf.nim with these ~430 lines (which is ~15% of the length of the autogenerated one):

Click to expand
import std/[options, tables]
import pkg/[con4m, nimutils/box]

type KeyConfig* = ref object
  `@@ attrscope @@`*: AttrScope
  use*: bool
  order*: Option[int]

proc loadKeyConfig(scope: AttrScope): KeyConfig =
  result = new(KeyConfig)
  result.`@@ attrscope @@` = scope
  result.use = unpack[bool](scope.attrLookup("use").get())
  result.order = none(int)
  if "order" in scope.contents:
    var tmp = scope.attrLookup("order")
    if tmp.isSome():
      result.order = some(unpack[int](tmp.get()))

type OutputConfig* = ref object
  `@@ attrscope @@`*: AttrScope
  mark_template*: string
  report_template*: string
  doc*: Option[string]

proc loadOutputConfig(scope: AttrScope): OutputConfig =
  result = new(OutputConfig)
  result.`@@ attrscope @@` = scope
  result.mark_template = unpack[string](scope.attrLookup("mark_template").get())
  result.report_template = unpack[string](scope.attrLookup("report_template").get())
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

type LinguistLanguage* = ref object
  `@@ attrscope @@`*: AttrScope
  extension*: string

proc loadLinguistLanguage(scope: AttrScope): LinguistLanguage =
  result = new(LinguistLanguage)
  result.`@@ attrscope @@` = scope
  result.extension = unpack[string](scope.attrLookup("extension").get())

proc get_extension*(self: LinguistLanguage): string =
  return self.extension

type hostScope* = ref object
  `@@ attrscope @@`*: AttrScope
  filepaths*: Option[seq[string]]
  directories*: Option[seq[string]]
  process_names*: Option[seq[string]]
  strict*: bool

proc loadhostScope(scope: AttrScope): hostScope =
  result = new(hostScope)
  result.`@@ attrscope @@` = scope
  result.filepaths = none(seq[string])
  if "filepaths" in scope.contents:
    var tmp = scope.attrLookup("filepaths")
    if tmp.isSome():
      result.filepaths = some(unpack[seq[string]](tmp.get()))
  result.directories = none(seq[string])
  if "directories" in scope.contents:
    var tmp = scope.attrLookup("directories")
    if tmp.isSome():
      result.directories = some(unpack[seq[string]](tmp.get()))
  result.process_names = none(seq[string])
  if "process_names" in scope.contents:
    var tmp = scope.attrLookup("process_names")
    if tmp.isSome():
      result.process_names = some(unpack[seq[string]](tmp.get()))
  result.strict = unpack[bool](scope.attrLookup("strict").get())

proc get_filepaths*(self: hostScope): Option[seq[string]] =
  return self.filepaths

proc get_directories*(self: hostScope): Option[seq[string]] =
  return self.directories

proc get_process_names*(self: hostScope): Option[seq[string]] =
  return self.process_names

proc get_strict*(self: hostScope): bool =
  return self.strict

type MarkTemplate* = ref object
  `@@ attrscope @@`*: AttrScope
  keys*: OrderedTableRef[string, KeyConfig]
  shortdoc*: Option[string]
  doc*: Option[string]

proc loadMarkTemplate(scope: AttrScope): MarkTemplate =
  result = new(MarkTemplate)
  result.`@@ attrscope @@` = scope
  result.keys = new(OrderedTableRef[string, KeyConfig])
  if scope.contents.contains("key"):
    let objlist = scope.contents["key"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.keys[item] = loadKeyConfig(aOrS.get(AttrScope))
  result.shortdoc = none(string)
  if "shortdoc" in scope.contents:
    var tmp = scope.attrLookup("shortdoc")
    if tmp.isSome():
      result.shortdoc = some(unpack[string](tmp.get()))
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

type ReportTemplate* = ref object
  `@@ attrscope @@`*: AttrScope
  keys*: OrderedTableRef[string, KeyConfig]
  shortdoc*: Option[string]
  doc*: Option[string]

proc loadReportTemplate(scope: AttrScope): ReportTemplate =
  result = new(ReportTemplate)
  result.`@@ attrscope @@` = scope
  result.keys = new(OrderedTableRef[string, KeyConfig])
  if scope.contents.contains("key"):
    let objlist = scope.contents["key"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.keys[item] = loadKeyConfig(aOrS.get(AttrScope))
  result.shortdoc = none(string)
  if "shortdoc" in scope.contents:
    var tmp = scope.attrLookup("shortdoc")
    if tmp.isSome():
      result.shortdoc = some(unpack[string](tmp.get()))
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

type ToolInfo* = ref object
  `@@ attrscope @@`*: AttrScope
  enabled*: bool
  kind*: string
  priority*: int
  stop_on_success*: bool
  get_tool_location*: CallbackObj
  attempt_install*: CallbackObj
  get_command_args*: CallbackObj
  produce_keys*: CallbackObj
  doc*: Option[string]

proc loadToolInfo(scope: AttrScope): ToolInfo =
  result = new(ToolInfo)
  result.`@@ attrscope @@` = scope
  result.enabled = unpack[bool](scope.attrLookup("enabled").get())
  result.kind = unpack[string](scope.attrLookup("kind").get())
  result.priority = unpack[int](scope.attrLookup("priority").get())
  result.stop_on_success = unpack[bool](scope.attrLookup("stop_on_success").get())
  result.get_tool_location =
    unpack[CallbackObj](scope.attrLookup("get_tool_location").get())
  result.attempt_install =
    unpack[CallbackObj](scope.attrLookup("attempt_install").get())
  result.get_command_args =
    unpack[CallbackObj](scope.attrLookup("get_command_args").get())
  result.produce_keys = unpack[CallbackObj](scope.attrLookup("produce_keys").get())
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

type FileScope* = ref object
  `@@ attrscope @@`*: AttrScope
  regex*: string
  filepaths*: Option[seq[string]]
  excluded_filepaths*: Option[seq[string]]
  filetypes*: Option[seq[string]]
  excluded_filetypes*: Option[seq[string]]
  head*: int

proc loadFileScope(scope: AttrScope): FileScope =
  result = new(FileScope)
  result.`@@ attrscope @@` = scope
  result.regex = unpack[string](scope.attrLookup("regex").get())
  result.filepaths = none(seq[string])
  if "filepaths" in scope.contents:
    var tmp = scope.attrLookup("filepaths")
    if tmp.isSome():
      result.filepaths = some(unpack[seq[string]](tmp.get()))
  result.excluded_filepaths = none(seq[string])
  if "excluded_filepaths" in scope.contents:
    var tmp = scope.attrLookup("excluded_filepaths")
    if tmp.isSome():
      result.excluded_filepaths = some(unpack[seq[string]](tmp.get()))
  result.filetypes = none(seq[string])
  if "filetypes" in scope.contents:
    var tmp = scope.attrLookup("filetypes")
    if tmp.isSome():
      result.filetypes = some(unpack[seq[string]](tmp.get()))
  result.excluded_filetypes = none(seq[string])
  if "excluded_filetypes" in scope.contents:
    var tmp = scope.attrLookup("excluded_filetypes")
    if tmp.isSome():
      result.excluded_filetypes = some(unpack[seq[string]](tmp.get()))
  result.head = unpack[int](scope.attrLookup("head").get())

proc get_regex*(self: FileScope): string =
  return self.regex

proc get_filepaths*(self: FileScope): Option[seq[string]] =
  return self.filepaths

proc get_excluded_filepaths*(self: FileScope): Option[seq[string]] =
  return self.excluded_filepaths

proc get_filetypes*(self: FileScope): Option[seq[string]] =
  return self.filetypes

proc get_excluded_filetypes*(self: FileScope): Option[seq[string]] =
  return self.excluded_filetypes

proc get_head*(self: FileScope): int =
  return self.head

type TechStackRule* = ref object
  `@@ attrscope @@`*: AttrScope
  fileScope*: FileScope
  hostScope*: hostScope
  description*: string
  category*: string
  subcategory*: string

proc loadTechStackRule(scope: AttrScope): TechStackRule =
  result = new(TechStackRule)
  result.`@@ attrscope @@` = scope
  if scope.contents.contains("file_scope"):
    result.fileScope = loadFileScope(scope.contents["file_scope"].get(AttrScope))
  if scope.contents.contains("host_scope"):
    result.hostScope = loadhostScope(scope.contents["host_scope"].get(AttrScope))
  result.description = unpack[string](scope.attrLookup("description").get())
  result.category = unpack[string](scope.attrLookup("category").get())
  result.subcategory = unpack[string](scope.attrLookup("subcategory").get())

proc get_category*(self: TechStackRule): string =
  return self.category

proc get_subcategory*(self: TechStackRule): string =
  return self.subcategory

type PluginSpec* = ref object
  `@@ attrscope @@`*: AttrScope
  priority*: int
  ignore*: seq[string]
  codec*: bool
  pre_run_keys*: seq[string]
  artifact_keys*: seq[string]
  post_chalk_keys*: seq[string]
  post_run_keys*: seq[string]
  enabled*: bool
  overrides*: seq[string]
  doc*: Option[string]

proc loadPluginSpec(scope: AttrScope): PluginSpec =
  result = new(PluginSpec)
  result.`@@ attrscope @@` = scope
  result.priority = unpack[int](scope.attrLookup("priority").get())
  result.ignore = unpack[seq[string]](scope.attrLookup("ignore").get())
  result.codec = unpack[bool](scope.attrLookup("codec").get())
  result.pre_run_keys = unpack[seq[string]](scope.attrLookup("pre_run_keys").get())
  result.artifact_keys = unpack[seq[string]](scope.attrLookup("artifact_keys").get())
  result.post_chalk_keys =
    unpack[seq[string]](scope.attrLookup("post_chalk_keys").get())
  result.post_run_keys = unpack[seq[string]](scope.attrLookup("post_run_keys").get())
  result.enabled = unpack[bool](scope.attrLookup("enabled").get())
  result.overrides = unpack[seq[string]](scope.attrLookup("overrides").get())
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

proc get_priority*(self: PluginSpec): int =
  return self.priority

proc get_enabled*(self: PluginSpec): bool =
  return self.enabled

type ReportSpec* = ref object
  `@@ attrscope @@`*: AttrScope
  enabled*: bool
  report_template*: string
  sink_configs*: seq[string]
  use_when*: seq[string]
  doc*: Option[string]

proc loadReportSpec(scope: AttrScope): ReportSpec =
  result = new(ReportSpec)
  result.`@@ attrscope @@` = scope
  result.enabled = unpack[bool](scope.attrLookup("enabled").get())
  result.report_template = unpack[string](scope.attrLookup("report_template").get())
  result.sink_configs = unpack[seq[string]](scope.attrLookup("sink_configs").get())
  result.use_when = unpack[seq[string]](scope.attrLookup("use_when").get())
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))

type KeySpec* = ref object
  `@@ attrscope @@`*: AttrScope
  required_in_chalk_mark*: bool
  required_in_self_mark*: bool
  kind*: int
  never_early*: bool
  `type`*: Con4mType
  standard*: Option[bool]
  system*: bool
  conf_as_system*: bool
  codec*: bool
  value*: Option[Box]
  callback*: Option[CallbackObj]
  since*: Option[string]
  normalized_order*: int
  apply_substitutions*: bool
  doc*: Option[string]
  shortdoc*: Option[string]

proc loadKeySpec(scope: AttrScope): KeySpec =
  result = new(KeySpec)
  result.`@@ attrscope @@` = scope
  result.required_in_chalk_mark =
    unpack[bool](scope.attrLookup("required_in_chalk_mark").get())
  result.required_in_self_mark =
    unpack[bool](scope.attrLookup("required_in_self_mark").get())
  result.kind = unpack[int](scope.attrLookup("kind").get())
  result.never_early = unpack[bool](scope.attrLookup("never_early").get())
  result.`type` = unpack[Con4mType](scope.attrLookup("type").get())
  result.standard = none(bool)
  if "standard" in scope.contents:
    var tmp = scope.attrLookup("standard")
    if tmp.isSome():
      result.standard = some(unpack[bool](tmp.get()))
  result.system = unpack[bool](scope.attrLookup("system").get())
  result.conf_as_system = unpack[bool](scope.attrLookup("conf_as_system").get())
  result.codec = unpack[bool](scope.attrLookup("codec").get())
  result.value = none(Box)
  if "value" in scope.contents:
    var tmp = scope.attrLookup("value")
    if tmp.isSome():
      result.value = some(unpack[Box](tmp.get()))
  result.callback = none(CallbackObj)
  if "callback" in scope.contents:
    var tmp = scope.attrLookup("callback")
    if tmp.isSome():
      result.callback = some(unpack[CallbackObj](tmp.get()))
  result.since = none(string)
  if "since" in scope.contents:
    var tmp = scope.attrLookup("since")
    if tmp.isSome():
      result.since = some(unpack[string](tmp.get()))
  result.normalized_order = unpack[int](scope.attrLookup("normalized_order").get())
  result.apply_substitutions =
    unpack[bool](scope.attrLookup("apply_substitutions").get())
  result.doc = none(string)
  if "doc" in scope.contents:
    var tmp = scope.attrLookup("doc")
    if tmp.isSome():
      result.doc = some(unpack[string](tmp.get()))
  result.shortdoc = none(string)
  if "shortdoc" in scope.contents:
    var tmp = scope.attrLookup("shortdoc")
    if tmp.isSome():
      result.shortdoc = some(unpack[string](tmp.get()))

type ChalkConfig* = ref object
  `@@ attrscope @@`*: AttrScope
  keyspecs*: OrderedTableRef[string, KeySpec]
  plugins*: OrderedTableRef[string, PluginSpec]
  markTemplates*: OrderedTableRef[string, MarkTemplate]
  reportTemplates*: OrderedTableRef[string, ReportTemplate]
  outputConfigs*: OrderedTableRef[string, OutputConfig]
  reportSpecs*: OrderedTableRef[string, ReportSpec]
  tools*: OrderedTableRef[string, ToolInfo]
  techStackRules*: OrderedTableRef[string, TechStackRule]
  linguist_languages*: OrderedTableRef[string, LinguistLanguage]

proc loadChalkConfig*(scope: AttrScope): ChalkConfig =
  result = new(ChalkConfig)
  result.`@@ attrscope @@` = scope
  result.keyspecs = new(OrderedTableRef[string, KeySpec])
  if scope.contents.contains("keyspec"):
    let objlist = scope.contents["keyspec"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.keyspecs[item] = loadKeySpec(aOrS.get(AttrScope))
  result.plugins = new(OrderedTableRef[string, PluginSpec])
  if scope.contents.contains("plugin"):
    let objlist = scope.contents["plugin"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.plugins[item] = loadPluginSpec(aOrS.get(AttrScope))
  result.markTemplates = new(OrderedTableRef[string, MarkTemplate])
  if scope.contents.contains("mark_template"):
    let objlist = scope.contents["mark_template"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.markTemplates[item] = loadMarkTemplate(aOrS.get(AttrScope))
  result.reportTemplates = new(OrderedTableRef[string, ReportTemplate])
  if scope.contents.contains("report_template"):
    let objlist = scope.contents["report_template"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.reportTemplates[item] = loadReportTemplate(aOrS.get(AttrScope))
  result.outputConfigs = new(OrderedTableRef[string, OutputConfig])
  if scope.contents.contains("outconf"):
    let objlist = scope.contents["outconf"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.outputConfigs[item] = loadOutputConfig(aOrS.get(AttrScope))
  result.reportSpecs = new(OrderedTableRef[string, ReportSpec])
  if scope.contents.contains("custom_report"):
    let objlist = scope.contents["custom_report"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.reportSpecs[item] = loadReportSpec(aOrS.get(AttrScope))
  result.tools = new(OrderedTableRef[string, ToolInfo])
  if scope.contents.contains("tool"):
    let objlist = scope.contents["tool"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.tools[item] = loadToolInfo(aOrS.get(AttrScope))
  result.techStackRules = new(OrderedTableRef[string, TechStackRule])
  if scope.contents.contains("tech_stack_rule"):
    let objlist = scope.contents["tech_stack_rule"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.techStackRules[item] = loadTechStackRule(aOrS.get(AttrScope))
  result.linguist_languages = new(OrderedTableRef[string, LinguistLanguage])
  if scope.contents.contains("linguist_language"):
    let objlist = scope.contents["linguist_language"].get(AttrScope)
    for item, aOrS in objlist.contents:
      result.linguist_languages[item] = loadLinguistLanguage(aOrS.get(AttrScope))

Testing

Hopefully the existing tests are sufficient.

@ee7 ee7 force-pushed the ee7/avoid-c4autoconf-getters-part-2 branch from 3d4efd7 to 4f9a7c4 Compare March 28, 2024 16:28
Base automatically changed from ee7/avoid-c4autoconf-getters-part-2 to main April 10, 2024 11:26
@ee7 ee7 force-pushed the ee7/avoid-c4autoconf-part3 branch from ed55b2e to ddaca94 Compare April 29, 2024 10:05
@ee7 ee7 marked this pull request as ready for review April 29, 2024 10:17
@ee7 ee7 requested a review from viega as a code owner April 29, 2024 10:17
@ee7 ee7 requested a review from miki725 April 29, 2024 10:17
@ee7 ee7 force-pushed the ee7/avoid-c4autoconf-part3 branch from ddaca94 to c3d2d46 Compare June 11, 2024 10:36
src/confload.nim Show resolved Hide resolved
src/subscan.nim Show resolved Hide resolved
@ee7 ee7 merged commit 855197e into main Jun 11, 2024
4 checks passed
@ee7 ee7 deleted the ee7/avoid-c4autoconf-part3 branch June 11, 2024 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants