summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--tools/atlas/atlas.nim4
-rw-r--r--tools/atlas/atlas.nim.cfg1
-rw-r--r--tools/atlas/packagesjson.nim56
3 files changed, 55 insertions, 6 deletions
diff --git a/tools/atlas/atlas.nim b/tools/atlas/atlas.nim
index dfa60856e..fe070c969 100644
--- a/tools/atlas/atlas.nim
+++ b/tools/atlas/atlas.nim
@@ -248,7 +248,9 @@ proc toUrl(c: var AtlasContext; p: string): string =
     fillPackageLookupTable(c)
     result = c.p.getOrDefault(unicode.toLower p)
   if result.len == 0:
-    inc c.errors
+    result = getUrlFromGithub(p)
+    if result.len == 0:
+      inc c.errors
 
 proc toName(p: string): PackageName =
   if p.isUrl:
diff --git a/tools/atlas/atlas.nim.cfg b/tools/atlas/atlas.nim.cfg
new file mode 100644
index 000000000..fcace0579
--- /dev/null
+++ b/tools/atlas/atlas.nim.cfg
@@ -0,0 +1 @@
+--define:ssl

diff --git a/tools/atlas/packagesjson.nim b/tools/atlas/packagesjson.nim
index 0b8599769..5ceef706f 100644
--- a/tools/atlas/packagesjson.nim
+++ b/tools/atlas/packagesjson.nim
@@ -1,5 +1,5 @@
 
-import std / [json, os, sets, strutils]
+import std / [json, os, sets, strutils, httpclient, uri]
 
 type
   Package* = ref object
@@ -65,11 +65,57 @@ proc `$`*(pkg: Package): string =
   if pkg.web.len > 0:
     result &= "  website:     " & pkg.web & "\n"
 
+proc toTags(j: JsonNode): seq[string] =
+  result = @[]
+  if j.kind == JArray:
+    for elem in items j:
+      result.add elem.getStr("")
+
+proc singleGithubSearch(term: string): JsonNode =
+  # For example:
+  # https://api.github.com/search/repositories?q=weave+language:nim
+  var client = newHttpClient()
+  try:
+    let x = client.getContent("https://api.github.com/search/repositories?q=" & encodeUrl(term) & "+language:nim")
+    result = parseJson(x)
+  except:
+    discard "it's a failed search, ignore"
+  finally:
+    client.close()
+
+proc githubSearch(seen: var HashSet[string]; terms: seq[string]) =
+  for term in terms:
+    let results = singleGithubSearch(term)
+    for j in items(results.getOrDefault("items")):
+      let p = Package(
+        name: j.getOrDefault("name").getStr,
+        url: j.getOrDefault("html_url").getStr,
+        downloadMethod: "git",
+        tags: toTags(j.getOrDefault("topics")),
+        description: "<none>, not listed in packages.json",
+        web: j.getOrDefault("html_url").getStr
+      )
+      if not seen.containsOrIncl(p.url):
+        echo p
+
+proc getUrlFromGithub*(term: string): string =
+  let results = singleGithubSearch(term)
+  var matches = 0
+  result = ""
+  for j in items(results.getOrDefault("items")):
+    if cmpIgnoreCase(j.getOrDefault("name").getStr, term) == 0:
+      if matches == 0:
+        result = j.getOrDefault("html_url").getStr
+      inc matches
+  if matches != 1:
+    # ambiguous, not ok!
+    result = ""
+
 proc search*(pkgList: seq[Package]; terms: seq[string]) =
-  var found = false
+  var seen = initHashSet[string]()
   template onFound =
     echo pkg
-    found = true
+    seen.incl pkg.url
     break forPackage
 
   for pkg in pkgList:
@@ -86,8 +132,8 @@ proc search*(pkgList: seq[Package]; terms: seq[string]) =
               onFound()
     else:
       echo(pkg)
-
-  if not found and terms.len > 0:
+  githubSearch seen, terms
+  if seen.len == 0 and terms.len > 0:
     echo("No package found.")
 
 type PkgCandidates* = array[3, seq[Package]]