summaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
authorRicardo Wurmus <rekado@elephly.net>2026-03-27 08:47:17 +0100
committerRicardo Wurmus <rekado@elephly.net>2026-04-13 18:12:10 +0200
commit98e7385b132e236eac9cf164f3321efdadf40d15 (patch)
tree80a7e67d737cf1340f108c6cd9bd25716936778d /etc
parente0b60a79544da84c40fccb5d515b968dfaa15f77 (diff)
etc: Add import helper script for RStudio.
* etc/rstudio-node-helper.scm: New file.
Diffstat (limited to 'etc')
-rwxr-xr-xetc/rstudio-node-helper.sh99
1 files changed, 99 insertions, 0 deletions
diff --git a/etc/rstudio-node-helper.sh b/etc/rstudio-node-helper.sh
new file mode 100755
index 0000000..a843289
--- /dev/null
+++ b/etc/rstudio-node-helper.sh
@@ -0,0 +1,99 @@
1#!/usr/bin/env bash
2exec guix repl -L . -- $0 $@
3!#
4
5;;; SPDX-License-Identifier: GPL-3.0-or-later
6
7;; Usage: ./rstudio-node-helper.sh /path/to/quarto/yarn.lock rstudio-node.scm
8
9(use-modules (ice-9 peg)
10 (ice-9 textual-ports)
11 (ice-9 match)
12 (srfi srfi-1)
13 (guix sets)
14 (guix scripts import))
15
16(define (parse-yarn.lock file)
17 (define-peg-pattern NL none "\n")
18 (define-peg-pattern colon none ":")
19 (define-peg-pattern comma none ",")
20 (define-peg-pattern WS none (or " " "\t" "\r"))
21 (define-peg-pattern comment all
22 (and (ignore "#") (* WS) (* (and (not-followed-by NL) peg-any))))
23 (define-peg-pattern EOL body (and (* WS) (? comment) NL))
24 (define-peg-pattern identifier body
25 (+ (and (not-followed-by (or NL WS comma colon)) peg-any)))
26 (define-peg-pattern string-quoted body
27 (and (ignore "\"")
28 (+ (or (and (ignore "\\") peg-any)
29 (and (not-followed-by "\"") peg-any)))
30 (ignore "\"")))
31 (define-peg-pattern string-or-ident body
32 (and (* WS) (or string-quoted identifier)))
33 (define-peg-pattern name all string-or-ident)
34 (define-peg-pattern names body
35 (and name (* (and comma WS name)) colon EOL))
36 (define-peg-pattern key all string-or-ident)
37 (define-peg-pattern value all string-or-ident)
38 (define-peg-pattern k+v body (and key WS value))
39 (define-peg-pattern indentation none (+ WS))
40 (define-peg-pattern indented-line body (and indentation k+v))
41 (define-peg-pattern indented-dict body (and indentation identifier colon EOL
42 (+ (and indented-line EOL))))
43 (define-peg-pattern block all (and names
44 (* (or (and indented-line EOL)
45 indented-dict))))
46 (define-peg-pattern yarn body (and (+ (or EOL NL block)) (* peg-any)))
47 (let ((content (call-with-input-file file get-string-all)))
48 (peg:tree (match-pattern yarn content))))
49
50(define (extract-dependencies tree)
51 (let ((deps (apply append
52 (filter-map
53 (match-lambda
54 (('block ('name name) (entries ...))
55 (let ((point (string-rindex name #\@)))
56 (and point
57 (let ((package-name (string-take name point))
58 (version-spec
59 (match (assoc-ref entries '(key "version"))
60 ((('value v)) v)
61 (_ #false))))
62 (if (and package-name (string-prefix? package-name "turbo"))
63 #false
64 (list (cons package-name version-spec)))))))
65 (_ #false))
66 tree))))
67 ;; Make sure the records are unique and don't contain weird
68 ;; records.
69 (set->list (fold (lambda (entry previous)
70 (match entry
71 ((name . version)
72 (if (string-prefix? "npm:" version)
73 previous
74 (set-insert entry previous)))))
75 (set)
76 deps))))
77
78(define (import-from-file yarn-file target-file)
79 (let ((tree (parse-yarn.lock yarn-file)))
80 (use-modules (ice-9 pretty-print))
81 (pretty-print tree)
82 (for-each (match-lambda
83 ((name . version)
84 (unless #false
85 (pk 'importing name '- version)
86 (let ((res (false-if-exception
87 (guix-import "-i" target-file
88 "npm-binary" "-r"
89 (if (string=? "*" version)
90 name
91 (string-append name "@" version)) ))))
92 (unless res
93 (pk '---failed name '- version))))))
94 (extract-dependencies tree))))
95
96(match (command-line)
97 ((command source target . _)
98 (import-from-file source target))
99 (else (error "provide a yarn.lock file and a Scheme module target to append to.")))