-
Notifications
You must be signed in to change notification settings - Fork 4
/
pkg-prune.rkt
executable file
·129 lines (115 loc) · 4.8 KB
/
pkg-prune.rkt
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
#!/usr/bin/env racket
;; Copyright 2024 Kaiyang Wu
;;
;; Permission is hereby granted, free of charge, to any person obtaining a copy
;; of this software and associated documentation files (the “Software”), to
;; deal in the Software without restriction, including without limitation the
;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
;; sell copies of the Software, and to permit persons to whom the Software is
;; furnished to do so, subject to the following conditions:
;;
;; The above copyright notice and this permission notice shall be included in
;; all copies or substantial portions of the Software.
;;
;; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
;; IN THE SOFTWARE.
;; Prerequisites on AOSC OS
;; `oma install racket`
#lang racket/base
(require racket/cmdline
racket/contract
racket/list
racket/match
racket/string)
(require json
net/url
net/url-connect
openssl)
(current-https-protocol (ssl-secure-client-context))
(define/contract (extract-http-code header)
(-> string? exact-positive-integer?)
(match header
[(regexp #rx"^HTTP/... ([1-9][0-9][0-9]).*" (list _ status-code))
(string->number status-code)]
[_ (error 'extract-http-code "invalid http header: ~a" header)]))
(define/contract (packages-site-revdeps pkgname)
(-> string? (listof string?))
(define url
(string->url (format "https://packages.aosc.io/revdep/~a?type=json"
pkgname)))
(define port (get-impure-port url))
(define header (purify-port port))
(define json-res
(if (= (extract-http-code header) 200)
(read-json port)
(error 'revdeps
"failed to get reverse dependencies for ~a: status code ~a"
pkgname
(extract-http-code header))))
(flatten (for/list ([group (hash-ref json-res 'revdeps)])
(for/list ([p (hash-ref group 'deps)])
(hash-ref p 'package)))))
(define/contract (packages-site-deps pkgname)
(-> string? (listof string?))
(define url
(string->url (format "https://packages.aosc.io/packages/~a?type=json"
pkgname)))
(define port (get-impure-port url))
(define header (purify-port port))
(define json-res
(if (= (extract-http-code header) 200)
(read-json port)
(error 'revdeps
"failed to get reverse dependencies for ~a: status code ~a"
pkgname
(extract-http-code header))))
(flatten (for/list ([group (hash-ref json-res 'dependencies)])
(if (or (equal? (hash-ref group 'relationship) "Breaks")
(equal? (hash-ref group 'relationship) "Provides"))
(list)
(foldl (λ (p acc)
(define pname (list-ref p 0))
(if (member pname acc)
acc
(cons pname acc)))
(list)
(hash-ref group 'packages))))))
;; Switch implementations here
(define revdeps packages-site-revdeps)
(define deps packages-site-deps)
(define/contract (queue-foldl proc init lst)
(-> (-> any/c list? (values any/c list?)) any/c list? any/c)
(define-values (acc queue) (proc init lst))
(if (null? queue)
acc
(queue-foldl proc acc queue)))
(define/contract (prune pkgnames)
(-> (listof string?) (listof string?))
; Memoization for optimizing speed where a dep is queried more than once
(define revdeps-memo (make-hash))
(define/contract (memoized-revdeps p)
(-> string? (listof string?))
(when (not (hash-has-key? revdeps-memo p))
(hash-set! revdeps-memo p (revdeps p)))
(hash-ref revdeps-memo p))
(define res
(queue-foldl (λ (acc queue)
(define p (car queue))
(define rdeps (memoized-revdeps p))
(if (or (null? rdeps)
(and (not (member p acc))
(andmap (λ (rd) (member rd acc)) rdeps)))
; when all revdeps are in the to-be-pruned list
(values (cons p acc) (append (deps p) (cdr queue)))
(values acc (cdr queue))))
(list)
pkgnames))
res)
(define packages-to-prune
(command-line #:program "pkg-prune.rkt" #:args pkgnames pkgnames))
(for-each displayln (prune packages-to-prune))