forked from nim-lang/packages
-
Notifications
You must be signed in to change notification settings - Fork 0
/
package_scanner.nim
139 lines (124 loc) · 3.72 KB
/
package_scanner.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# A very simple Nim package scanner.
#
# Scans the package list from this repository.
#
# Check the packages for:
# * Missing name
# * Missing/unknown method
# * Missing/unreachable repository
# * Missing tags
# * Missing description
# * Missing/unknown license
# * Insecure git:// url on GitHub
#
# Usage: nim c -d:ssl -r package_scanner.nim
#
# Copyright 2015 Federico Ceratto <federico.ceratto@gmail.com>
# Released under GPLv3 License, see /usr/share/common-licenses/GPL-3
import httpclient
import net
import json
import os
import sets
import strutils
const
LICENSES = @[
"Allegro 4 Giftware",
"Apache License 2.0",
"BSD",
"BSD2",
"BSD3",
"CC0",
"GPL",
"GPLv2",
"GPLv3",
"LGPLv2",
"LGPLv3",
"MIT",
"MS-PL",
"MPL",
"WTFPL",
"libpng",
"zlib",
"ISC",
"Unlicense"
]
VCS_TYPES = @["git", "hg"]
proc canFetchNimbleRepository(name: string, urlJson: JsonNode): bool =
# The fetch is a lie!
# TODO: Make this check the actual repo url and check if there is a
# nimble file in it
result = true
var url: string
var client = newHttpClient(timeout=100000)
defer: client.close()
if not urlJson.isNil:
url = urlJson.str
if url.startsWith("https://github.com"):
if existsEnv("GITHUB_TOKEN"):
client.headers = newHttpHeaders({"authorization": "Bearer " & getEnv("GITHUB_TOKEN")})
try:
discard client.getContent(url)
except HttpRequestError, TimeoutError:
echo "W: ", name, ": unable to fetch repo ", url, " ",
getCurrentExceptionMsg()
except AssertionError:
echo "W: ", name, ": httpclient failed ", url, " ",
getCurrentExceptionMsg()
except:
echo "W: Another error attempting to request: ", url
echo " Error was: ", getCurrentExceptionMsg()
proc verifyAlias(pdata: JsonNode, result: var int) =
if not pdata.hasKey("name"):
echo "E: missing alias' package name"
result.inc()
# TODO: Verify that 'alias' points to a known package.
proc check(): int =
var name: string
echo ""
let pkg_list = parseJson(readFile(getCurrentDir() / "packages.json"))
var names = initSet[string]()
for pdata in pkg_list:
name = if pdata.hasKey("name"): pdata["name"].str else: ""
if pdata.hasKey("alias"):
verifyAlias(pdata, result)
else:
if name == "":
echo "E: missing package name"
result.inc()
elif not pdata.hasKey("method"):
echo "E: ", name, " has no method"
result.inc()
elif not (pdata["method"].str in VCS_TYPES):
echo "E: ", name, " has an unknown method: ", pdata["method"].str
result.inc()
elif not pdata.hasKey("url"):
echo "E: ", name, " has no URL"
result.inc()
elif pdata.hasKey("web") and not canFetchNimbleRepository(name, pdata["web"]):
result.inc()
elif not pdata.hasKey("tags"):
echo "E: ", name, " has no tags"
result.inc()
elif not pdata.hasKey("description"):
echo "E: ", name, " has no description"
result.inc()
elif not pdata.hasKey("license"):
echo "E: ", name, " has no license"
result.inc()
elif pdata["url"].str.normalize.startsWith("git://github.com/"):
echo "E: ", name, " has an insecure git:// URL instead of https://"
result.inc()
else:
# Other warnings should go here
if not (pdata["license"].str in LICENSES):
echo "W: ", name, " has an unexpected license: ", pdata["license"]
if name.normalize notin names:
names.incl(name.normalize)
else:
echo("E: ", name, ": a package by that name already exists.")
result.inc()
echo ""
echo "Problematic packages count: ", result
when isMainModule:
quit(check())