From: Alex Kost <alezost@gmail.com>
To: guix-devel@gnu.org
Subject: [PATCH 3/3] emacs: Add "Source" field to 'guix-info' buffers.
Date: Sun, 09 Nov 2014 11:40:11 +0300 [thread overview]
Message-ID: <87egtcbwd0.fsf@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 291 bytes --]
This patch adds URL of a package source and 2 buttons ("Show" and
"Download") to an ‘info’ buffer (see the attached screenshot).
Pushing the "Show" button displays a store path of the package source.
Pushing the "Download" button has the same meaning as “guix build -S …”.
[-- Attachment #2: 0003-emacs-Add-Source-field-to-guix-info-buffers.patch --]
[-- Type: text/x-diff, Size: 13765 bytes --]
From c879b5520718726366a5afd83143315a16ab29a7 Mon Sep 17 00:00:00 2001
From: Alex Kost <alezost@gmail.com>
Date: Sun, 9 Nov 2014 11:03:39 +0300
Subject: [PATCH 3/3] emacs: Add "Source" field to 'guix-info' buffers.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Suggested by Ludovic Courtès.
* emacs/guix-info.el (guix-info-insert-methods, guix-info-displayed-params):
Add 'source' parameter.
(guix-package-info-source): New face.
(guix-package-info-find-source-p): New variable.
(guix-package-source): New button type.
(guix-info-redisplay-entries, guix-package-info-insert-source-url,
guix-package-info-show-source, guix-package-info-insert-source): New
procedures.
* emacs/guix-base.el (guix-param-titles): Add 'source' parameter.
(guix-package-source-path, guix-package-source-build-derivation): New
procedures.
* emacs/guix-main.scm (%package-param-alist): Add 'source' parameter.
(package-source-names, package-source-derivation->store-path,
package-source-path, package-source-build-derivation): New procedures.
---
emacs/guix-base.el | 20 +++++++++
emacs/guix-info.el | 116 +++++++++++++++++++++++++++++++++++++++++++++++++---
emacs/guix-main.scm | 49 ++++++++++++++++++++++
3 files changed, 179 insertions(+), 6 deletions(-)
diff --git a/emacs/guix-base.el b/emacs/guix-base.el
index 784474e..a542a0c 100644
--- a/emacs/guix-base.el
+++ b/emacs/guix-base.el
@@ -82,6 +82,7 @@ Interactively, prompt for PATH. With prefix, use
(id . "ID")
(name . "Name")
(version . "Version")
+ (source . "Source")
(license . "License")
(synopsis . "Synopsis")
(description . "Description")
@@ -100,6 +101,7 @@ Interactively, prompt for PATH. With prefix, use
(id . "ID")
(name . "Name")
(version . "Version")
+ (source . "Source")
(license . "License")
(synopsis . "Synopsis")
(description . "Description")
@@ -1008,6 +1010,24 @@ Each element from GENERATIONS is a generation number."
'switch-to-generation profile generation)
operation-buffer)))
+(defun guix-package-source-path (package-id)
+ "Return a store file path to a source of a package PACKAGE-ID."
+ (message "Calculating the source derivation ...")
+ (guix-eval-read
+ (guix-make-guile-expression
+ 'package-source-path package-id)))
+
+(defun guix-package-source-build-derivation (package-id)
+ "Build source derivation of a package PACKAGE-ID."
+ (when (or (not guix-operation-confirm)
+ (guix-operation-prompt))
+ (guix-eval-in-repl
+ (guix-make-guile-expression
+ 'package-source-build-derivation
+ package-id
+ :use-substitutes? (or guix-use-substitutes 'f)
+ :dry-run? (or guix-dry-run 'f)))))
+
\f
;;; Pull
diff --git a/emacs/guix-info.el b/emacs/guix-info.el
index edb4450..bd56937 100644
--- a/emacs/guix-info.el
+++ b/emacs/guix-info.el
@@ -1,4 +1,4 @@
-;;; guix-info.el --- Info buffers for displaying entries
+;;; guix-info.el --- Info buffers for displaying entries -*- lexical-binding: t -*-
;; Copyright © 2014 Alex Kost <alezost@gmail.com>
@@ -24,7 +24,6 @@
;;; Code:
-(require 'guix-history)
(require 'guix-base)
(require 'guix-utils)
@@ -107,6 +106,8 @@ number of characters, it will be split into several lines.")
guix-info-insert-title-simple)
(outputs guix-package-info-insert-outputs
guix-info-insert-title-simple)
+ (source guix-package-info-insert-source
+ guix-info-insert-title-simple)
(home-url guix-info-insert-url)
(inputs guix-package-info-insert-inputs)
(native-inputs guix-package-info-insert-native-inputs)
@@ -121,6 +122,8 @@ number of characters, it will be split into several lines.")
(name guix-package-info-name)
(version guix-output-info-insert-version)
(output guix-output-info-insert-output)
+ (source guix-package-info-insert-source
+ guix-info-insert-title-simple)
(path guix-package-info-insert-output-path
guix-info-insert-title-simple)
(dependencies guix-package-info-insert-output-dependencies
@@ -157,10 +160,11 @@ is a function, this function is called with parameter title as
argument.")
(defvar guix-info-displayed-params
- '((package name version synopsis outputs location home-url
+ '((package name version synopsis outputs source location home-url
license inputs native-inputs propagated-inputs description)
- (output name version output synopsis path dependencies location home-url
- license inputs native-inputs propagated-inputs description)
+ (output name version output synopsis source path dependencies location
+ home-url license inputs native-inputs propagated-inputs
+ description)
(installed path dependencies)
(generation number prev-number current time path))
"List of displayed entry parameters.
@@ -190,6 +194,17 @@ LEVEL is 1 by default."
"Insert `guix-info-indent' spaces LEVEL times (1 by default)."
(insert (guix-info-get-indent level)))
+(defun guix-info-redisplay-entries (entries)
+ "Display entries in the current info buffer.
+Substitute `guix-entries' with ENTRIES."
+ (let ((point (point))
+ (window-start (window-start)))
+ (guix-set-buffer guix-profile entries guix-buffer-type
+ guix-entry-type guix-search-type
+ guix-search-vals t t)
+ (goto-char point)
+ (set-window-start nil window-start)))
+
(defun guix-info-insert-entries (entries entry-type)
"Display ENTRIES of ENTRY-TYPE in the current info buffer.
ENTRIES should have a form of `guix-entries'."
@@ -334,7 +349,10 @@ VAL is a list, call the function on each element of this list."
'face 'guix-info-file-path
'help-echo "Find file"
'action (lambda (btn)
- (find-file (button-label btn))))
+ (let ((file (button-label btn)))
+ (if (file-exists-p file)
+ (find-file file)
+ (message "File does not exist.")))))
(define-button-type 'guix-url
:supertype 'guix
@@ -652,6 +670,92 @@ ENTRY is an alist with package info."
'guix-package-info-insert-output-path)
\f
+;;; Inserting source
+
+(defface guix-package-info-source
+ '((t :inherit link :underline nil))
+ "Face used for a source URL of a package."
+ :group 'guix-package-info)
+
+(defcustom guix-package-info-find-source-p nil
+ "If non-nil, find a source file after pressing \"Show\" button.
+If nil, just display the source file path without finding."
+ :type 'boolean
+ :group 'guix-package-info)
+
+(define-button-type 'guix-package-source
+ :supertype 'guix
+ 'face 'guix-package-info-source
+ 'help-echo ""
+ 'action (lambda (_)
+ ;; As a source may not be a real URL (e.g., "mirror://..."),
+ ;; no action is bound to a source button.
+ (message "Yes, this is the source URL. What did you expect?")))
+
+(defun guix-package-info-insert-source-url (url &optional _)
+ "Make button from source URL and insert it at point."
+ (guix-insert-button url 'guix-package-source))
+
+(defun guix-package-info-show-source (entry-id package-id)
+ "Show file name of a package source in the current info buffer.
+Find the file if needed (see `guix-package-info-find-source-p').
+ENTRY-ID is an ID of the current entry (package or output).
+PACKAGE-ID is an ID of the package which source to show."
+ (let* ((entry (guix-get-entry-by-id entry-id guix-entries))
+ (file (guix-get-key-val entry 'source-file)))
+ ;; Do not request a source file name if it has already been received.
+ (unless file
+ (setq file (guix-package-source-path package-id))
+ (or file
+ (error "Couldn't define file path of the package source"))
+ (let* ((new-entry (cons (cons 'source-file file)
+ entry))
+ (entries (cl-substitute-if
+ new-entry
+ (lambda (entry)
+ (equal (guix-get-key-val entry 'id) entry-id))
+ guix-entries
+ :count 1)))
+ (guix-info-redisplay-entries entries)))
+ (if (file-exists-p file)
+ (if guix-package-info-find-source-p
+ (find-file file)
+ (message "The source store path is displayed."))
+ (message "The source does not exist in the store."))))
+
+(defun guix-package-info-insert-source (source entry)
+ "Insert SOURCE from package ENTRY at point.
+SOURCE is a list of URLs."
+ (guix-info-insert-indent)
+ (if (null source)
+ (guix-format-insert nil)
+ (let* ((entry-id (guix-get-key-val entry 'id))
+ (package-id (or (guix-get-key-val entry 'package-id)
+ entry-id)))
+ (guix-info-insert-action-button
+ "Show"
+ (lambda (btn)
+ (guix-package-info-show-source (button-get btn 'entry-id)
+ (button-get btn 'package-id)))
+ "Show the source store path of the current package"
+ 'entry-id entry-id
+ 'package-id package-id)
+ (guix-info-insert-indent)
+ (guix-info-insert-action-button
+ "Download"
+ (lambda (btn)
+ (guix-package-source-build-derivation
+ (button-get btn 'package-id)))
+ "Build the source derivation (download the source if needed)"
+ 'package-id package-id)
+ (let ((file (guix-get-key-val entry 'source-file)))
+ (when file
+ (guix-info-insert-val-simple file
+ #'guix-info-insert-file-path)))
+ (guix-info-insert-val-simple source
+ #'guix-package-info-insert-source-url))))
+
+\f
;;; Displaying outputs
(guix-define-buffer-type info output
diff --git a/emacs/guix-main.scm b/emacs/guix-main.scm
index 62eeabb..e0bdccb 100644
--- a/emacs/guix-main.scm
+++ b/emacs/guix-main.scm
@@ -46,10 +46,12 @@
(ice-9 vlist)
(ice-9 match)
(srfi srfi-1)
+ (srfi srfi-2)
(srfi srfi-11)
(srfi srfi-19)
(srfi srfi-26)
(guix)
+ (guix git-download)
(guix packages)
(guix profiles)
(guix licenses)
@@ -252,6 +254,18 @@ Example:
(license-name license)))
(list-maybe (package-license package))))
+(define (package-source-names package)
+ "Return a list of source names (URLs) of the PACKAGE."
+ (let ((source (package-source package)))
+ (and (origin? source)
+ (filter-map (lambda (uri)
+ (cond ((string? uri)
+ uri)
+ ((git-reference? uri)
+ (git-reference-url uri))
+ (else #f)))
+ (list-maybe (origin-uri source))))))
+
(define (package-unique? package)
"Return #t if PACKAGE is a single package with such name/version."
(null? (cdr (packages-by-name (package-name package)
@@ -263,6 +277,7 @@ Example:
(name . ,package-name)
(version . ,package-version)
(license . ,package-license-names)
+ (source . ,package-source-names)
(synopsis . ,package-synopsis)
(description . ,package-description)
(home-url . ,package-home-page)
@@ -867,3 +882,37 @@ OUTPUTS is a list of package outputs (may be an empty list)."
GENERATIONS is a list of generation numbers."
(with-store store
(delete-generations store profile generations)))
+
+(define (package-source-derivation->store-path derivation)
+ "Return a store path of the package source DERIVATION."
+ (match (derivation-outputs derivation)
+ ;; Source derivation is always (("out" . derivation)).
+ (((_ . output-drv))
+ (derivation-output-path output-drv))
+ (_ #f)))
+
+(define (package-source-path package-id)
+ "Return a store file path to a source of a package PACKAGE-ID."
+ (and-let* ((package (package-by-id package-id))
+ (source (package-source package)))
+ (with-store store
+ (package-source-derivation->store-path
+ (package-source-derivation store source)))))
+
+(define* (package-source-build-derivation package-id #:key dry-run?
+ (use-substitutes? #t))
+ "Build source derivation of a package PACKAGE-ID."
+ (and-let* ((package (package-by-id package-id))
+ (source (package-source package)))
+ (with-store store
+ (let* ((derivation (package-source-derivation store source))
+ (derivations (list derivation)))
+ (set-build-options store
+ #:use-substitutes? use-substitutes?)
+ (show-what-to-build store derivations
+ #:use-substitutes? use-substitutes?
+ #:dry-run? dry-run?)
+ (unless dry-run?
+ (build-derivations store derivations))
+ (format #t "The source store path: ~a~%"
+ (package-source-derivation->store-path derivation))))))
--
2.1.2
[-- Attachment #3: 2014-11-09_11:29:42.png --]
[-- Type: image/png, Size: 89154 bytes --]
next reply other threads:[~2014-11-09 8:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-09 8:40 Alex Kost [this message]
2014-11-09 17:45 ` [PATCH 3/3] emacs: Add "Source" field to 'guix-info' buffers Ludovic Courtès
2014-11-09 18:48 ` Alex Kost
2014-11-09 22:43 ` Ludovic Courtès
2014-11-10 13:18 ` Alex Kost
2014-11-10 23:29 ` Ludovic Courtès
2014-11-11 19:13 ` Alex Kost
2014-11-11 19:57 ` Ludovic Courtès
2014-11-12 6:56 ` Alex Kost
2014-11-12 9:55 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87egtcbwd0.fsf@gmail.com \
--to=alezost@gmail.com \
--cc=guix-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.