guix-graph.el 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. ;;; guix-graph.el --- Making and viewing Guix graphs -*- lexical-binding: t -*-
  2. ;; Copyright © 2017 Alex Kost <alezost@gmail.com>
  3. ;; This file is part of Emacs-Guix.
  4. ;; Emacs-Guix is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;;
  9. ;; Emacs-Guix is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with Emacs-Guix. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; This file provides the code to make and view Guix graphs.
  18. ;;; Code:
  19. (require 'cl-lib)
  20. (require 'guix-external)
  21. (require 'guix-utils)
  22. (require 'guix-read)
  23. (require 'guix-repl)
  24. (require 'guix-guile)
  25. (defun guix-graph-backend->graph-type (backend)
  26. "Convert Guix graph BACKEND (string) to a graph type.
  27. The graph type is used internally by Emacs-Guix; it can be one of
  28. the following symbols: `dot', `html'."
  29. (if (stringp backend)
  30. (cond ((string= backend "graphviz") 'dot)
  31. ((string= backend "d3js") 'html)
  32. (t (error "Unsupported graph backend: %s" backend)))
  33. (error "Graph backend should be a string: %S" backend)))
  34. (declare-function browse-url-file-url "browse-url" (file))
  35. (defun guix-view-graph (graph-type graph-file)
  36. "View graph from GRAPH-FILE.
  37. See `guix-graph-backend->graph-type' for the meaning of GRAPH-TYPE."
  38. (cl-case graph-type
  39. (dot (guix-find-file graph-file))
  40. (html
  41. (require 'browse-url)
  42. (browse-url (browse-url-file-url graph-file)))))
  43. (defun guix-make-view-graph (backend graph-maker)
  44. "Make graph using GRAPH-MAKER procedure and view it.
  45. GRAPH-MAKER is called with GRAPH-TYPE and GRAPH-FILE arguments.
  46. It should return non-nil on success.
  47. See `guix-graph-backend->graph-type' for the meaning of GRAPH-TYPE."
  48. (let* ((graph-type (guix-graph-backend->graph-type backend))
  49. (graph-file (cl-case graph-type
  50. (dot (guix-dot-file-name))
  51. (html (guix-html-file-name)))))
  52. (if (funcall graph-maker graph-type graph-file)
  53. (guix-view-graph graph-type graph-file)
  54. (error "Couldn't create a graph"))))
  55. ;;;###autoload
  56. (defun guix-package-graph (package backend node-type)
  57. "Show BACKEND/NODE-TYPE graph for a PACKAGE.
  58. PACKAGE can be either a package name or a package ID.
  59. Interactively, prompt for arguments."
  60. (interactive
  61. (list (guix-read-package-name)
  62. (guix-read-graph-backend)
  63. (guix-read-graph-node-type)))
  64. (guix-make-view-graph
  65. backend
  66. (lambda (graph-type graph-file)
  67. (guix-eval-read
  68. (guix-make-guile-expression
  69. 'make-package-graph package
  70. (cl-case graph-type
  71. (dot (guix-dot-arguments graph-file))
  72. (html graph-file))
  73. :node-type-name node-type
  74. :backend-name backend)))))
  75. (provide 'guix-graph)
  76. ;;; guix-graph.el ends here