diff options
| author | bdunahu <bdunahu@operationnull.com> | 2026-04-27 22:16:12 -0400 |
|---|---|---|
| committer | bdunahu <bdunahu@operationnull.com> | 2026-04-28 00:15:09 -0400 |
| commit | 9e143d1d84817ec7e6d139d234f0fff07749621c (patch) | |
| tree | 7565eac131cc3528d33d5ea3597cdd8006fdb968 /src/crawl-lockfiles.scm | |
Diffstat (limited to 'src/crawl-lockfiles.scm')
| -rwxr-xr-x | src/crawl-lockfiles.scm | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/crawl-lockfiles.scm b/src/crawl-lockfiles.scm new file mode 100755 index 0000000..2ab37a0 --- /dev/null +++ b/src/crawl-lockfiles.scm @@ -0,0 +1,98 @@ +;; kenku --- crawl and reproduce github actions +;; Copyright © 2026 bdunahu <bdunahu@operationnull.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. +;; +;; +;; This file reads from standard in a list of repo identifiers and commits: +;; +;; 1fexd/gh-create-release-notes 0.0.18 +;; 1password/load-secrets-action 92467eb28f72e8255933372f1e0707c567ce2259 +;; 1password/load-secrets-action v3 +;; 2428392/gh-truncate-string-action b3ff790d21cf42af3ca7579146eedb93c8fb0757 +;; 2428392/gh-truncate-string-action v1.0.0 +;; 3ru/gpt-translate master +;; 8398a7/action-slack 77eaa4f1c608a7d68b38af4e3f739dcd8cba273e +;; +;; It only cares about the first two columns, but writes a third. What does it +;; write? It writes where it found a lockfile in the associated repo, if any. +;; I did this because I noticed some repos were putting the lockfiles in a sub- +;; directory with the action.yml. Repos can put it anywhere they want if they're +;; mean, but I will not be downloading the repo at this phase or spending my +;; tokens on a recursive find. + +;; The detected types of lockfiles are for npm, pnpm, and yarn. +;; +;; Depending on what it finds, it filters the result to a different output file +;; automatically. Like the other files, since we're using the github REST API, +;; set your $TOKEN env variable. + +(define-module (src crawl-lockfiles) + #:use-module ((src utils) #:prefix util:) + #:use-module ((src config) #:prefix conf:) + #:use-module ((src crawl-type-wrapper) #:prefix types:) + #:use-module ((ice-9 rdelim)) + #:export (npm-file + crawl-lockfiles)) + +(define outdir (in-vicinity conf:cache-dir "lock-friend")) +(define npm-file (in-vicinity outdir "npm.txt")) +(define github-api-template + "https://api.github.com/repos/~a/~a/contents/~a?ref=~a") +(define lockfiles-to-outfile '(("package-lock.json" . "npm.txt") + ("yarn.lock" . "alt-pm.txt") + ("pnpm-lock.yaml" . "alt-pm.txt") + ("pnpm-lock.yml" . "alt-pm.txt") + ("" . "no-lock.txt"))) + +(define (search-for-lockfiles owner name rest sha) + (define (search files) + (let* ((file (car files)) + (remain (cdr files)) + (url (format #f github-api-template owner name file sha))) + (if (util:url-exists? url) + file + (and (not (null? remain)) + (search remain))))) + (let* ((lockfiles (map car lockfiles-to-outfile)) + (to-try (append lockfiles (map (lambda (f) (in-vicinity rest f)) + lockfiles)))) + (search to-try))) + +(define (filter-to-file line) + (let* ((parts (string-split line char-set:whitespace)) + (paths (car parts)) + (sha (cadr parts)) + (seg (string-split paths #\/)) + (owner (car seg)) + (name (cadr seg)) + (rest (string-join (list-tail seg 2) "/")) + (lock (search-for-lockfiles owner name rest sha)) + (output (open-file (in-vicinity outdir + (assoc-ref lockfiles-to-outfile + lock)) + "a"))) + ;; stream output + (format output "~a ~a ~a\n" paths sha lock) + (close output))) + +(define (crawl-lockfiles) + (util:mkdir-p outdir) + (call-with-input-file types:node-file + (lambda (port) + (let loop () + (let ((line (read-line port))) + (unless (eof-object? line) + (filter-to-file line) + (loop))))))) |
