(define-module (ruther environment) #:use-module (ruther modules) #:use-module (guix profiles) #:use-module (gnu packages) #:use-module (guix gexp) #:use-module (guix store) #:use-module (guix packages) #:use-module (guix build-system trivial) #:use-module (gnu packages bash) #:use-module (gnu packages python) #:use-module (gnu packages guile) #:use-module (gnu packages file) #:export (make-environment make-interpreted-environment make-python-environment make-guile-environment package->application-environment)) ;; Makes a package that uses the given environment, and wraps the binaries in it. ;; TODO: replace the paths (only in text files!!! not in binaries...) in all extra-paths files, ;; so instead of symlinking some of the files might have to be just copied and substituted. ;; this also means it might come in handy to create all directories instead and symlink only the files. (define* (make-environment manifest #:key (name "environment") (binary-paths '("bin")) (extra-paths '("share/info" "share/man" "share/doc" "share/applications")) (rename-function #~identity) (filter-function #~(const #t))) "Takes a manifest, makes a package that will have all the binaries the profile has, wrapped to use etc/profile " (let ((profile (profile (content manifest)))) (package (name name) (version "0") (source #f) (build-system trivial-build-system) (native-inputs (list file)) (inputs (list bash)) (arguments (list #:modules (source-module-closure '((guix build utils) (ruther build environment)) #:select? ruther-module-name?) #:builder #~(begin (use-modules (guix build utils) (ruther build environment) (ice-9 ftw) (srfi srfi-1)) (mkdir-p #$output) ;; Iterate all binary-paths under profile and make scripts in output (let* ((profile-path #$profile) (not-directory? (lambda (base-path) (lambda (path) (let ((s (stat (string-append base-path "/" path)))) (not (eq? (stat:type s) 'directory)))))) (binary-folders (list #$@binary-paths)) (profile-binary-folders (map (lambda (folder) (string-append profile-path "/" folder)) binary-folders)) (output-binary-folders (map (lambda (folder) (string-append #$output "/" folder)) binary-folders)) (binaries (apply append (map (lambda (folder) (map (lambda (file) (string-append folder "/" file)) (scandir (string-append profile-path "/" folder) (not-directory? (string-append profile-path "/" folder))))) binary-folders))) (profile-binaries (map (lambda (binary) (string-append profile-path "/" binary)) binaries)) (output-binaries (map (lambda (binary) (string-append #$output "/" (dirname binary) "/" (#$rename-function (basename binary)))) binaries)) (profile-binaries-realpaths (map canonicalize-path profile-binaries)) (extra-folders (list #$@extra-paths))) (set-path-environment-variable "PATH" '("bin" "sbin") (list #$@(map (compose car cdr) (package-native-inputs this-package)))) (set-path-environment-variable "TARGET" '("bin" "sbin") (list #$@(map (compose car cdr) (package-inputs this-package)))) (copy-binary-files #$output output-binary-folders profile-path binaries #:filter-function #$filter-function #:rename-function #$rename-function) ;; Iterate all extra-paths and symlink them to output. (copy-extra-files #$output profile-path extra-folders) (patch-extra-files #$output (zip profile-binaries-realpaths output-binaries)))))) (synopsis #f) (description #f) (home-page #f) (license #f)))) (define* (make-interpreted-environment target-name interpreter-package interpreter-binary-name packages-specifications) (make-environment (concatenate-manifests (list (specifications->manifest packages-specifications) (packages->manifest (list interpreter-package)))) #:name target-name #:extra-paths '() #:rename-function #~(lambda (file) #$target-name) #:filter-function #~(lambda (file) (string=? (string-append "bin/" #$interpreter-binary-name) file)))) (define* (make-python-environment target-name python-packages #:key (python python)) (make-interpreted-environment target-name python "python3" python-packages)) (define* (make-guile-environment target-name guile-packages #:key (guile guile)) (make-interpreted-environment target-name python "guile" guile-packages)) (define* (package->application-environment application) (make-environment (package->manifest application) #:name (string-append(package-name application) "environment")))