Files
Nim/tools/atlas/packagesjson.nim
Kyle Brown 31fc0f9718 Remove unused imports, and deprecated function usage (#18663)
* clean up imports and slice to remove delete

* revert buggy code

* Replace "delete" with setlen to remove depreciation warning
2021-08-11 01:26:42 +02:00

115 lines
3.3 KiB
Nim

import std / [json, os, sets, strutils]
type
Package* = ref object
# Required fields in a package.
name*: string
url*: string # Download location.
license*: string
downloadMethod*: string
description*: string
tags*: seq[string] # \
# From here on, optional fields set to the empty string if not available.
version*: string
dvcsTag*: string
web*: string # Info url for humans.
proc optionalField(obj: JsonNode, name: string, default = ""): string =
if hasKey(obj, name) and obj[name].kind == JString:
result = obj[name].str
else:
result = default
proc requiredField(obj: JsonNode, name: string): string =
result = optionalField(obj, name, "")
proc fromJson*(obj: JSonNode): Package =
result = Package()
result.name = obj.requiredField("name")
if result.name.len == 0: return nil
result.version = obj.optionalField("version")
result.url = obj.requiredField("url")
if result.url.len == 0: return nil
result.downloadMethod = obj.requiredField("method")
if result.downloadMethod.len == 0: return nil
result.dvcsTag = obj.optionalField("dvcs-tag")
result.license = obj.optionalField("license")
result.tags = @[]
for t in obj["tags"]:
result.tags.add(t.str)
result.description = obj.requiredField("description")
result.web = obj.optionalField("web")
const PackagesDir* = "packages"
proc getPackages*(workspaceDir: string): seq[Package] =
result = @[]
var uniqueNames = initHashSet[string]()
var jsonFiles = 0
for kind, path in walkDir(workspaceDir / PackagesDir):
if kind == pcFile and path.endsWith(".json"):
inc jsonFiles
let packages = json.parseFile(path)
for p in packages:
let pkg = p.fromJson()
if pkg != nil and not uniqueNames.containsOrIncl(pkg.name):
result.add(pkg)
proc `$`*(pkg: Package): string =
result = pkg.name & ":\n"
result &= " url: " & pkg.url & " (" & pkg.downloadMethod & ")\n"
result &= " tags: " & pkg.tags.join(", ") & "\n"
result &= " description: " & pkg.description & "\n"
result &= " license: " & pkg.license & "\n"
if pkg.web.len > 0:
result &= " website: " & pkg.web & "\n"
proc search*(pkgList: seq[Package]; terms: seq[string]) =
var found = false
template onFound =
echo pkg
found = true
break forPackage
for pkg in pkgList:
if terms.len > 0:
block forPackage:
for term in terms:
let word = term.toLower
# Search by name.
if word in pkg.name.toLower:
onFound()
# Search by tag.
for tag in pkg.tags:
if word in tag.toLower:
onFound()
else:
echo(pkg)
if not found and terms.len > 0:
echo("No package found.")
type PkgCandidates* = array[3, seq[Package]]
proc determineCandidates*(pkgList: seq[Package];
terms: seq[string]): PkgCandidates =
result[0] = @[]
result[1] = @[]
result[2] = @[]
for pkg in pkgList:
block termLoop:
for term in terms:
let word = term.toLower
if word == pkg.name.toLower:
result[0].add pkg
break termLoop
elif word in pkg.name.toLower:
result[1].add pkg
break termLoop
else:
for tag in pkg.tags:
if word in tag.toLower:
result[2].add pkg
break termLoop