|
3 | 3 | ;; This code was written by Alex Shinn in 2014 and placed in the |
4 | 4 | ;; Public Domain. All warranties are disclaimed. |
5 | 5 |
|
| 6 | +(define git-repo-path ".snow-repo.scm") |
| 7 | + |
6 | 8 | (define (impl-available? cfg spec confirm?) |
7 | 9 | (if (find-in-path (cadr spec)) |
8 | 10 | (or (null? (cddr spec)) |
|
692 | 694 | (call-with-output-file repo-path |
693 | 695 | (lambda (out) (write-simple-pretty repo out))))) |
694 | 696 |
|
| 697 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 698 | +;; Git Index - add packages to a local repository file. |
| 699 | + |
| 700 | +(define (process->pair-or-null key cmd) |
| 701 | + (let ((out (process->string cmd))) |
| 702 | + (if (string=? out "") |
| 703 | + '() |
| 704 | + `(,key ,(read-line (open-input-string out)))))) |
| 705 | + |
| 706 | +(define (command/git-index cfg spec . pkg-files) |
| 707 | + (when (null? pkg-files) |
| 708 | + (error "Give at least one package .tgz file as argument")) |
| 709 | + (for-each |
| 710 | + (lambda (pkg-file) |
| 711 | + (when (not (string-suffix? ".tgz" pkg-file)) |
| 712 | + (error "All packages must be .tgz files. Use snow-chibi package command"))) |
| 713 | + pkg-files) |
| 714 | + (let* ((repo-path git-repo-path) |
| 715 | + (dir (path-directory repo-path)) |
| 716 | + ;; If git repo url is ssh, switch it to https except if requested not to |
| 717 | + (fix-git-url |
| 718 | + (lambda (cfg url-pair) |
| 719 | + (let* ((uri (string->uri (cadr url-pair))) |
| 720 | + (use-ssh-url? (conf-get cfg '(command git-index use-ssh-url)))) |
| 721 | + `(url ,(uri->string |
| 722 | + (uri-with-scheme uri |
| 723 | + (if use-ssh-url? 'ssh 'https))))))) |
| 724 | + (pkgs (filter-map |
| 725 | + (lambda (pkg-file) |
| 726 | + (let* ((pkg (package-file-meta pkg-file)) |
| 727 | + (hash (process->pair-or-null 'hash "git rev-parse HEAD")) |
| 728 | + (tag (process->pair-or-null 'tag "git describe --exact-match --tags --abbrev=0")) |
| 729 | + (url (fix-git-url cfg (process->pair-or-null 'url "git config --get remote.origin.url"))) |
| 730 | + (git (cons 'git (remove null? (list hash tag url)))) |
| 731 | + (updated (tai->rfc-3339 (current-second)))) |
| 732 | + (when (null? hash) |
| 733 | + (error "Directory is not a git repository")) |
| 734 | + (and pkg |
| 735 | + `(,(car pkg) |
| 736 | + ,git |
| 737 | + ,@(cdr pkg) (updated ,updated))))) |
| 738 | + (if (pair? pkg-files) |
| 739 | + pkg-files |
| 740 | + (filter package-file? |
| 741 | + (map |
| 742 | + (lambda (f) (make-path dir f)) |
| 743 | + (directory-files dir)))))) |
| 744 | + (repo (fold (lambda (pkg repo) |
| 745 | + (let ((name (package-name pkg)) |
| 746 | + (version (package-version pkg))) |
| 747 | + (when (not version) |
| 748 | + (error "Can not index package without a version" pkg)) |
| 749 | + `(,(car repo) |
| 750 | + ,pkg |
| 751 | + ,@(remove |
| 752 | + (lambda (x) |
| 753 | + (equal? name (package-name x)) |
| 754 | + (equal? version (package-version x)) |
| 755 | + ) |
| 756 | + (cdr repo))))) |
| 757 | + (guard (exn (else (list 'repository))) |
| 758 | + (car (file->sexp-list repo-path))) |
| 759 | + pkgs))) |
| 760 | + (call-with-output-file repo-path |
| 761 | + (lambda (out) (write-simple-pretty repo out))) |
| 762 | + (display (string-append "Updated " git-repo-path)) |
| 763 | + (newline))) |
| 764 | + |
695 | 765 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
696 | 766 | ;; Gen-key - generate a new RSA key pair. |
697 | 767 |
|
|
1190 | 1260 | (local-base (string-append "repo-" repo-id ".scm"))) |
1191 | 1261 | (make-path local-dir local-base))) |
1192 | 1262 |
|
1193 | | -(define (update-repository cfg repo-uri) |
| 1263 | +(define (update-repository cfg repo-uri uri-type) |
1194 | 1264 | (let* ((local-path (repository-local-path cfg repo-uri)) |
1195 | 1265 | (local-dir (path-directory local-path)) |
1196 | 1266 | (local-tmp (string-append local-path ".tmp." |
1197 | 1267 | (number->string (current-second)) "-" |
1198 | 1268 | (number->string (current-process-id)))) |
1199 | | - (repo-str (utf8->string (resource->bytevector cfg repo-uri))) |
| 1269 | + (repo-str |
| 1270 | + (cond |
| 1271 | + ((equal? uri-type 'http) |
| 1272 | + (utf8->string (resource->bytevector cfg repo-uri))) |
| 1273 | + ((equal? uri-type 'git) |
| 1274 | + (utf8->string (git-resource->bytevector cfg |
| 1275 | + repo-uri |
| 1276 | + git-repo-path))))) |
1200 | 1277 | (repo (guard (exn (else #f)) |
1201 | 1278 | (let ((repo (read (open-input-string repo-str)))) |
1202 | 1279 | `(,(car repo) (url ,repo-uri) ,@(cdr repo)))))) |
|
1236 | 1313 | #f))) |
1237 | 1314 |
|
1238 | 1315 | ;; returns the single repo as a sexp, updated as needed |
1239 | | -(define (maybe-update-repository cfg repo-uri) |
| 1316 | +(define (maybe-update-repository cfg repo-uri uri-type) |
1240 | 1317 | (or (guard (exn |
1241 | 1318 | (else |
1242 | 1319 | (warn "error updating remote repository: " |
1243 | 1320 | repo-uri " error: " exn) |
1244 | 1321 | #f)) |
1245 | 1322 | (and (should-update-repository? cfg repo-uri) |
1246 | | - (update-repository cfg repo-uri))) |
| 1323 | + (update-repository cfg repo-uri uri-type))) |
1247 | 1324 | (guard (exn |
1248 | 1325 | (else |
1249 | 1326 | (warn "error reading local repository: " exn) |
|
1261 | 1338 | ;; not to be confused with the current-repo util in (chibi snow fort) |
1262 | 1339 | ;; which returns the single host |
1263 | 1340 | (define (current-repositories cfg) |
1264 | | - (define (make-loc uri trust depth) (vector uri trust depth)) |
| 1341 | + (define (make-loc uri uri-type trust depth) (vector uri uri-type trust depth)) |
1265 | 1342 | (define (loc-uri loc) (vector-ref loc 0)) |
1266 | | - (define (loc-trust loc) (vector-ref loc 1)) |
1267 | | - (define (loc-depth loc) (vector-ref loc 2)) |
| 1343 | + (define (loc-uri-type loc) (vector-ref loc 1)) |
| 1344 | + (define (loc-trust loc) (vector-ref loc 2)) |
| 1345 | + (define (loc-depth loc) (vector-ref loc 3)) |
1268 | 1346 | (define (adjust-package-urls ls uri) |
1269 | 1347 | (map |
1270 | 1348 | (lambda (x) |
|
1278 | 1356 | (and (pair? x) |
1279 | 1357 | (eq? 'url (car x)))) |
1280 | 1358 | ls))) |
1281 | | - (let lp ((ls (map (lambda (x) (make-loc x 1.0 0)) |
| 1359 | + (let lp ((ls (map (lambda (x) (make-loc x 'http 1.0 0)) |
1282 | 1360 | (get-repository-list cfg))) |
1283 | 1361 | (seen '()) |
1284 | 1362 | (res '())) |
|
1294 | 1372 | (loc-uri (car ls)) (loc-trust (car ls)) ) |
1295 | 1373 | (lp (cdr ls))) |
1296 | 1374 | (else |
1297 | | - (let ((uri (uri-normalize (loc-uri (car ls))))) |
| 1375 | + (let* ((uri-type (loc-uri-type (car ls))) |
| 1376 | + (uri (if (equal? uri-type 'http) |
| 1377 | + (uri-normalize (loc-uri (car ls))) |
| 1378 | + (loc-uri (car ls))))) |
1298 | 1379 | (if (member uri seen) |
1299 | 1380 | (lp (cdr ls) seen res) |
1300 | | - (let* ((repo (maybe-update-repository cfg uri)) |
| 1381 | + (let* ((repo (maybe-update-repository cfg uri uri-type)) |
1301 | 1382 | (siblings |
1302 | 1383 | (if (and (valid-repository? repo) |
1303 | 1384 | (conf-get cfg 'follow-siblings? #t)) |
|
1309 | 1390 | (lambda (x) |
1310 | 1391 | (and (pair? x) |
1311 | 1392 | (eq? 'sibling (car x)) |
1312 | | - (assoc-get (cdr x) 'url) |
| 1393 | + (or (assoc-get (cdr x) 'url) |
| 1394 | + (assoc-get (cdr x) 'git)) |
1313 | 1395 | (make-loc |
1314 | | - (uri-resolve (assoc-get (cdr x) 'url) |
1315 | | - uri-base) |
1316 | | - (* (loc-trust (car ls)) |
1317 | | - (or (assoc-get (cdr x) 'trust) 1.0)) |
1318 | | - (+ (loc-depth (car ls)) 1)))) |
| 1396 | + (if (assq 'git (cdr x)) |
| 1397 | + (assoc-get (cdr (assoc 'git (cdr x))) 'url) |
| 1398 | + (uri-resolve (assoc-get (cdr x) 'url) uri-base)) |
| 1399 | + (if (assq 'git (cdr x)) 'git 'http) |
| 1400 | + (* (loc-trust (car ls)) |
| 1401 | + (or (assoc-get (cdr x) 'trust) 1.0)) |
| 1402 | + (+ (loc-depth (car ls)) 1)))) |
1319 | 1403 | (cdr repo))) |
1320 | 1404 | '())) |
1321 | 1405 | (res (if (valid-repository? repo) |
|
2704 | 2788 | (and (pair? x) |
2705 | 2789 | (eq? 'installed-files (car x)))) |
2706 | 2790 | pkg) |
2707 | | - (installed-files ,@installed-files))) |
2708 | | - )) |
| 2791 | + (installed-files ,@installed-files))))) |
2709 | 2792 | (preserve)))))))) |
2710 | 2793 |
|
2711 | 2794 | (define (install-package-from-file repo impl cfg file) |
|
2715 | 2798 |
|
2716 | 2799 | (define (git-fetch-package repo cfg pkg) |
2717 | 2800 | (call-with-temp-dir |
2718 | | - "pkg-git-clone" |
| 2801 | + "snow-fort-pkg-git-clone" |
2719 | 2802 | (lambda (dir preserve) |
2720 | 2803 | (let* ((git-tag (package-git-tag pkg)) |
2721 | 2804 | (git-branch (cond ((equal? git-tag 'HEAD) `()) |
2722 | 2805 | (git-tag `(--branch ,git-tag)) |
2723 | 2806 | (else `()))) |
2724 | | - (git-hash (package-git-hash pkg)) |
| 2807 | + (new-cfg |
| 2808 | + (conf-extend cfg `((version . ,(package-version pkg)) |
| 2809 | + (author . ,(package-author repo pkg)) |
| 2810 | + (maintainer . ,(package-maintainer repo pkg))))) |
| 2811 | + (git-hash |
| 2812 | + (let ((hash (package-git-hash pkg))) |
| 2813 | + (when |
| 2814 | + (and (not hash) |
| 2815 | + (not (yes-or-no? new-cfg |
| 2816 | + "Git hash missing.\nProceed anyway?"))) |
| 2817 | + (die 2 "Git hash missing" pkg)) |
| 2818 | + hash)) |
2725 | 2819 | (git-commands |
2726 | 2820 | (cond (git-tag `((git clone |
2727 | 2821 | ,(package-git-url pkg) |
|
2740 | 2834 | `((git clone |
2741 | 2835 | ,(package-git-url pkg) |
2742 | 2836 | ,dir))))) |
2743 | | - (git-outputs (map process->output+error+status git-commands)) |
2744 | | - (cloned-hash (read-line |
2745 | | - (open-input-string |
2746 | | - (process->string `(git -C ,dir rev-parse HEAD))))) |
2747 | | - (libs |
2748 | | - (map (lambda (lib) |
2749 | | - (make-path dir |
2750 | | - (string-append (library->path cfg lib) ".sld"))) |
2751 | | - (package-libraries pkg))) |
2752 | | - (new-cfg |
2753 | | - (conf-extend cfg `((version . ,(package-version pkg)) |
2754 | | - (author . ,(package-author repo pkg)) |
2755 | | - (maintainer . ,(package-maintainer repo pkg))))) |
2756 | | - (spec '()) |
2757 | | - (spec+files (package-spec+files new-cfg spec libs))) |
2758 | | - (when (not (= (list-ref (list-ref git-outputs 0) 2) 0)) |
2759 | | - (error "Git clone failed" (list-ref git-outputs 0))) |
2760 | | - (when (and (not git-hash) |
2761 | | - (not (yes-or-no? new-cfg "Git hash missing.\nProceed anyway?"))) |
2762 | | - (die 2 "Git hash missing" pkg)) |
| 2837 | + (git-outputs |
| 2838 | + (let ((outputs (map process->output+error+status git-commands))) |
| 2839 | + (when (not (= (list-ref (list-ref outputs 0) 2) 0)) |
| 2840 | + (error "Git clone failed" outputs)))) |
| 2841 | + (cloned-hash (read-line |
| 2842 | + (open-input-string |
| 2843 | + (process->string `(git -C ,dir rev-parse HEAD))))) |
| 2844 | + (libs |
| 2845 | + (map (lambda (lib) |
| 2846 | + (make-path dir |
| 2847 | + (string-append (library->path cfg lib) ".sld"))) |
| 2848 | + (package-libraries pkg))) |
| 2849 | + (spec '()) |
| 2850 | + (spec+files (package-spec+files new-cfg spec libs))) |
2763 | 2851 | (when (and git-hash |
2764 | 2852 | (not (string=? cloned-hash git-hash)) |
2765 | 2853 | (not (yes-or-no? new-cfg |
2766 | 2854 | "Package git hash did not match.\n" |
2767 | 2855 | "Proceed anyway?"))) |
2768 | 2856 | (die 2 "Git hash did not match" pkg)) |
2769 | | - (call-with-temp-file |
2770 | | - "pkg" |
2771 | | - (lambda (tmp-path out preserve) |
2772 | | - (create-package (car spec+files) (cdr spec+files) tmp-path))))))) |
| 2857 | + (create-package (car spec+files) (cdr spec+files) dir))))) |
2773 | 2858 |
|
2774 | 2859 | (define (install-package repo impl cfg pkg) |
2775 | 2860 | (cond |
|
0 commit comments