From 37b8c46b3b5ff0ff5dca2c5438f953f56efe41d8 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 8 Nov 2013 11:36:58 +0100 Subject: [PATCH 1/3] Adds support for optional web field. This change makes nimrod-code/packages#31 useful. --- packageinfo.nim | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packageinfo.nim b/packageinfo.nim index bdb6c07..d482086 100644 --- a/packageinfo.nim +++ b/packageinfo.nim @@ -22,14 +22,17 @@ type backend*: string TPackage* = object + # Required fields in a package. name*: string - version*: string + url*: string # Download location. license*: string - url*: string - dvcsTag*: string downloadMethod*: string - tags*: seq[string] description*: string + tags*: seq[string] # Even if empty, always a valid non nil seq. \ + # From here on, optional fields set to the emtpy string if not available. + version*: string + dvcsTag*: string + web*: string # Info url for humans. proc initPackageInfo(): TPackageInfo = result.mypath = "" @@ -168,6 +171,7 @@ proc getPackage*(pkg: string, packagesPath: string, resPkg: var TPackage): bool for t in p["tags"]: resPkg.tags.add(t.str) resPkg.description = p.requiredField("description") + resPkg.web = p.optionalField("web") return true return false @@ -186,6 +190,7 @@ proc getPackageList*(packagesPath: string): seq[TPackage] = for t in p["tags"]: pkg.tags.add(t.str) pkg.description = p.requiredField("description") + pkg.web = p.optionalField("web") result.add(pkg) proc findBabelFile*(dir: string): string = @@ -245,3 +250,5 @@ proc echoPackage*(pkg: TPackage) = echo(" tags: " & pkg.tags.join(", ")) echo(" description: " & pkg.description) echo(" license: " & pkg.license) + if pkg.web.len > 0: + echo(" website: " & pkg.web) From 292bb413d2664a57ef1df0dc4f6bfbe934f44916 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 8 Nov 2013 11:49:58 +0100 Subject: [PATCH 2/3] Rewrites requiredField on top of optionalField. --- packageinfo.nim | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packageinfo.nim b/packageinfo.nim index d482086..33376ee 100644 --- a/packageinfo.nim +++ b/packageinfo.nim @@ -140,21 +140,25 @@ proc readPackageInfo*(path: string): TPackageInfo = raise newException(EInvalidValue, "Cannot open package info: " & path) validatePackageInfo(result, path) -proc optionalField(obj: PJsonNode, name: string): string = +proc optionalField(obj: PJsonNode, name: string, default = ""): string = + ## Queries ``obj`` for the optional ``name`` string. + ## + ## Returns the value of ``name`` if it is a valid string, or aborts execution + ## if the field exists but is not of string type. If ``name`` is not present, + ## returns ``default``. if existsKey(obj, name): if obj[name].kind == JString: return obj[name].str else: quit("Corrupted packages.json file. " & name & " field is of unexpected type.") - else: return "" + else: return default proc requiredField(obj: PJsonNode, name: string): string = - if existsKey(obj, name): - if obj[name].kind == JString: - return obj[name].str - else: - quit("Corrupted packages.json file. " & name & " field is of unexpected type.") - else: + ## Queries ``obj`` for the required ``name`` string. + ## + ## Aborts execution if the field does not exist or is of invalid json type. + result = optionalField(obj, name, nil) + if result == nil: quit("Package in packages.json file does not contain a " & name & " field.") proc getPackage*(pkg: string, packagesPath: string, resPkg: var TPackage): bool = From 0a35930d4e2cfba51c2138d41e2fc5403f0597ae Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Fri, 8 Nov 2013 12:08:14 +0100 Subject: [PATCH 3/3] Puts TPackage json initialization into single proc. --- packageinfo.nim | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/packageinfo.nim b/packageinfo.nim index 33376ee..e42a55f 100644 --- a/packageinfo.nim +++ b/packageinfo.nim @@ -161,40 +161,40 @@ proc requiredField(obj: PJsonNode, name: string): string = if result == nil: quit("Package in packages.json file does not contain a " & name & " field.") +proc fromJson(obj: PJSonNode): TPackage = + ## Constructs a TPackage object from a JSON node. + ## + ## Aborts execution if the JSON node doesn't contain the required fields. + result.name = obj.requiredField("name") + result.version = obj.optionalField("version") + result.url = obj.requiredField("url") + result.downloadMethod = obj.requiredField("method") + result.dvcsTag = obj.optionalField("dvcs-tag") + result.license = obj.requiredField("license") + result.tags = @[] + for t in obj["tags"]: + result.tags.add(t.str) + result.description = obj.requiredField("description") + result.web = obj.optionalField("web") + proc getPackage*(pkg: string, packagesPath: string, resPkg: var TPackage): bool = + ## Searches ``packagesPath`` file saving into ``resPkg`` the found package. + ## + ## Pass in ``pkg`` the name of the package you are searching for. As + ## convenience the proc returns a boolean specifying if the ``resPkg`` was + ## successfully filled with good data. let packages = parseFile(packagesPath) for p in packages: - if p["name"].str != pkg: continue - resPkg.name = pkg - resPkg.url = p.requiredField("url") - resPkg.version = p.optionalField("version") - resPkg.downloadMethod = p.requiredField("method") - resPkg.dvcsTag = p.optionalField("dvcs-tag") - resPkg.license = p.requiredField("license") - resPkg.tags = @[] - for t in p["tags"]: - resPkg.tags.add(t.str) - resPkg.description = p.requiredField("description") - resPkg.web = p.optionalField("web") - return true - return false - + if p["name"].str == pkg: + resPkg = p.fromJson() + return true + proc getPackageList*(packagesPath: string): seq[TPackage] = + ## Returns the list of packages found at the specified path. result = @[] let packages = parseFile(packagesPath) for p in packages: - var pkg: TPackage - pkg.name = p.requiredField("name") - pkg.version = p.optionalField("version") - pkg.url = p.requiredField("url") - pkg.downloadMethod = p.requiredField("method") - pkg.dvcsTag = p.optionalField("dvcs-tag") - pkg.license = p.requiredField("license") - pkg.tags = @[] - for t in p["tags"]: - pkg.tags.add(t.str) - pkg.description = p.requiredField("description") - pkg.web = p.optionalField("web") + let pkg: TPackage = p.fromJson() result.add(pkg) proc findBabelFile*(dir: string): string =