forked from nim-lang/packages
-
Notifications
You must be signed in to change notification settings - Fork 0
/
package_scanner.nim
151 lines (121 loc) · 3.52 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
139
140
141
142
143
144
145
146
147
148
149
150
# 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 <[email protected]>
# 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
if not urlJson.isNil:
url = urlJson.str
try:
discard getContent(url, timeout=10000)
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: nil
if pdata.hasKey("alias"):
verifyAlias(pdata, result)
else:
if name.isNil:
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())