maav / guix-mirror (public) (License: GPLv3+) (since 2019-11-02) (hash sha1)
Mirror of GNU Guix (https://git.savannah.gnu.org/git/guix.git) with personal branches integrated into master branch.

/guix/describe.scm (05bf99eb58e579b5f27da35b95357db31a7be7d1) (7016 bytes) (mode 100644) (type blob)

;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix 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.
;;;
;;; GNU Guix 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 GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix describe)
  #:use-module (guix memoization)
  #:use-module (guix profiles)
  #:use-module (guix packages)
  #:use-module ((guix utils) #:select (location-file))
  #:use-module ((guix store) #:select (%store-prefix store-path?))
  #:use-module ((guix config) #:select (%state-directory))
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:export (current-profile
            current-profile-date
            current-profile-entries
            package-path-entries

            package-provenance
            manifest-entry-with-provenance))

;;; Commentary:
;;;
;;; This module provides supporting code to allow a Guix instance to find, at
;;; run time, which profile it's in (profiles created by 'guix pull').  That
;;; allows it to read meta-information about itself (e.g., repository URL and
;;; commit ID) and to find other channels available in the same profile.  It's
;;; a bit like ELPA's pkg-info.el.
;;;
;;; Code:

(define initial-program-arguments
  ;; Save the initial program arguments.  This allows us to see the "real"
  ;; 'guix' program, even if 'guix repl -s' calls 'set-program-arguments'
  ;; later on.
  (program-arguments))

(define current-profile
  (mlambda ()
    "Return the profile (created by 'guix pull') the calling process lives in,
or #f if this is not applicable."
    (match initial-program-arguments
      ((program . _)
       (and (string-suffix? "/bin/guix" program)
            ;; Note: We want to do _lexical dot-dot resolution_.  Using ".."
            ;; for real would instead take us into the /gnu/store directory
            ;; that ~/.config/guix/current/bin points to, whereas we want to
            ;; obtain ~/.config/guix/current.
            (let ((candidate (dirname (dirname program))))
              (and (file-exists? (string-append candidate "/manifest"))
                   candidate)))))))

(define (current-profile-date)
  "Return the creation date of the current profile (produced by 'guix pull'),
as a number of seconds since the Epoch, or #f if it could not be determined."
  ;; Normally 'current-profile' will return ~/.config/guix/current.  We need
  ;; to 'readlink' once to get '/var/guix/…/guix-profile', whose mtime is the
  ;; piece of information we're looking for.
  (let loop ((profile (current-profile)))
    (match profile
      (#f #f)
      ((? store-path?) #f)
      (file
       (if (string-prefix? %state-directory file)
           (and=> (lstat file) stat:mtime)
           (catch 'system-error
             (lambda ()
               (let ((target (readlink file)))
                 (loop (if (string-prefix? "/" target)
                           target
                           (string-append (dirname file) "/" target)))))
             (const #f)))))))

(define current-profile-entries
  (mlambda ()
    "Return the list of entries in the 'guix pull' profile the calling process
lives in, or #f if this is not applicable."
    (match (current-profile)
      (#f '())
      (profile
       (let ((manifest (profile-manifest profile)))
         (manifest-entries manifest))))))

(define current-channel-entries
  (mlambda ()
    "Return manifest entries corresponding to extra channels--i.e., not the
'guix' channel."
    (remove (lambda (entry)
              (string=? (manifest-entry-name entry) "guix"))
            (current-profile-entries))))

(define (package-path-entries)
  "Return two values: the list of package path entries to be added to the
package search path, and the list to be added to %LOAD-COMPILED-PATH.  These
entries are taken from the 'guix pull' profile the calling process lives in,
when applicable."
  ;; Filter out Guix itself.
  (unzip2 (map (lambda (entry)
                 (list (string-append (manifest-entry-item entry)
                                      "/share/guile/site/"
                                      (effective-version))
                       (string-append (manifest-entry-item entry)
                                      "/lib/guile/" (effective-version)
                                      "/site-ccache")))
               (current-channel-entries))))

(define (package-provenance package)
  "Return the provenance of PACKAGE as an sexp for use as the 'provenance'
property of manifest entries, or #f if it could not be determined."
  (define (entry-source entry)
    (match (assq 'source
                 (manifest-entry-properties entry))
      (('source value) value)
      (_ #f)))

  (match (and=> (package-location package) location-file)
    (#f #f)
    (file
     (let ((file (if (string-prefix? "/" file)
                     file
                     (search-path %load-path file))))
       (and file
            (string-prefix? (%store-prefix) file)

            ;; Always store information about the 'guix' channel and
            ;; optionally about the specific channel FILE comes from.
            (or (let ((main  (and=> (find (lambda (entry)
                                            (string=? "guix"
                                                      (manifest-entry-name entry)))
                                          (current-profile-entries))
                                    entry-source))
                      (extra (any (lambda (entry)
                                    (let ((item (manifest-entry-item entry)))
                                      (and (string-prefix? item file)
                                           (entry-source entry))))
                                  (current-profile-entries))))
                  (and main
                       `(,main
                         ,@(if extra (list extra) '()))))))))))

(define (manifest-entry-with-provenance entry)
  "Return ENTRY with an additional 'provenance' property if it's not already
there."
  (let ((properties (manifest-entry-properties entry)))
    (if (assq 'properties properties)
        entry
        (let ((item (manifest-entry-item entry)))
          (manifest-entry
            (inherit entry)
            (properties
             (match (and (package? item) (package-provenance item))
               (#f   properties)
               (sexp `((provenance ,@sexp)
                       ,@properties)))))))))


Mode Type Size Ref File
100644 blob 6139 7f310d2612983845551d0a641b730a269a180a3f .dir-locals.el
100644 blob 2533 e2f745b42a5a1591a93a3e9a7ccfc107a6178eff .gitignore
100644 blob 6179 ee164083c8379d90c6e7ab3b38576266f458f40c .guix-authorizations
100644 blob 182 b852180cf2563ec7b74b93c954de38d77237f23f .guix-channel
100644 blob 4499 146e65184a2f987b0307d0ec7300c93e84110625 .mailmap
100644 blob 472 1e30a74a64f51ec735dcc44ff4dfe5fa4fa13c6f AUTHORS
100644 blob 3273 ef90330cdacb9ecf7dbf38a03cdb490db131a4ad CODE-OF-CONDUCT
100644 blob 35147 94a9ed024d3859793618152ea559a168bbcbb5e2 COPYING
100644 blob 163 d6ea6943261fcae51c095ad39fe59140fc62de22 ChangeLog
100644 blob 749 aaa673fc93b0bb74feca4783ae427b9ea1b604ea HACKING
100644 blob 33109 a75d9c1ffc4237c0478b62a235b9b521fd840517 Makefile.am
100644 blob 359348 bb1de1e93802064ff44392db56d05cd0a11fcc15 NEWS
100644 blob 5260 5e9069f80f58d3946cdd588f30919a177eaccb55 README
100644 blob 3237 2475cb637ceb6eb43f54d080c56e5793041b76e5 ROADMAP
100644 blob 2381 af7afd3576f2e6aa5cbafc3c6354bbab1ae00774 THANKS
100644 blob 4360 f854f7fa98e09c7b512f3efb702c290b615186a0 TODO
100755 blob 906 a47269d87f1d6fd27bbaf634ac7439b38b32cca3 bootstrap
040000 tree - b15b9ede344760715e240528bc322c7b0194bbe7 build-aux
100644 blob 4808 50ead355a81edebf5c9419bd76a1dd69e85f5adf config-daemon.ac
100644 blob 8760 6861112eafaed85e107f8976f12e0ddb795571b7 configure.ac
100644 blob 339545 d234c4ec8668cead20279d903589d29c513b4cb6 d3.v3.js
040000 tree - ad0dbfb1b2956f33070d044c3cb173030dd3c5f1 doc
040000 tree - 8cc2bd0b87d4ef774820c72703a0b3ae914e8601 etc
100644 blob 5289 f139531ef3ecf56a790ae73934e2d91016c1aba4 gnu.scm
040000 tree - 34d1107337432fed7fa3f18c9affd932681e9b6a gnu
100644 blob 4207 ad8279395d8eb1fe5a836d54ec563a4577f4d135 graph.js
100644 blob 1357 8753c21e423f880e7a6d9f7f6f6ff1139f8b7254 guix.scm
040000 tree - 9c3a3e887916002138b68277e856e1f0e6416659 guix
040000 tree - 8df9aaabfb400159e2559fd4331fb861cb0a5adc m4
040000 tree - 84cedf0076fb8362febdffa59ba83b63e8c3f9e8 nix
040000 tree - 8dac6dd305591d733ef087c35eee3b3acb1daee2 po
040000 tree - 8c4db11917d51c4d71a841813cf8951000b76687 scripts
040000 tree - 867e6957c2eed1c47764e42093bb26ae37b221e3 tests
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/maav/guix-mirror

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/maav/guix-mirror

Clone this repository using git:
git clone git://git.rocketgit.com/user/maav/guix-mirror

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main