[bug#33448] describe: Add json format.

Message ID 20181121070051.12041-1-go.wigust@gmail.com
State Accepted
Headers show
Series [bug#33448] describe: Add json format. | expand

Checks

Context Check Description
cbaines/applying patch fail Apply failed

Commit Message

Oleg Pykhalov Nov. 21, 2018, 7 a.m. UTC
* guix/scripts/describe.scm: Add json format.
---
 guix/scripts/describe.scm | 69 +++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 25 deletions(-)

Comments

Ludovic Courtès Nov. 21, 2018, 10:53 a.m. UTC | #1
Oleg Pykhalov <go.wigust@gmail.com> skribis:

> * guix/scripts/describe.scm: Add json format.

Please describe the modified and added variables/procedures.

> +  (define (channels format)
> +    (map (lambda (entry)
> +           (match (assq 'source (manifest-entry-properties entry))
> +             (('source ('repository ('version 0)
> +                                    ('url url)
> +                                    ('branch branch)
> +                                    ('commit commit)
> +                                    _ ...))
> +              (case format
> +                ((scm)
> +                 `(channel (name ',(string->symbol
> +                                    (manifest-entry-name entry)))
> +                           (url ,url)
> +                           (commit ,commit)))
> +                ((json)
> +                 `((name . ,(string->symbol
> +                             (manifest-entry-name entry)))
> +                   (url . ,url)
> +                   (commit . ,commit)))))
> +
> +             ;; Pre-0.15.0 Guix does not provide that information,
> +             ;; so there's not much we can do in that case.
> +             (_ '???)))
> +
> +         ;; Show most recently installed packages last.
> +         (reverse
> +          (manifest-entries
> +           (profile-manifest
> +            (if (zero? number)
> +                profile
> +                (generation-file-name profile number)))))))

How about turning this into a list of <channel> objects, and then,
separately have ‘channels->sexp’ and ‘channels->json’?  That would avoid
having dealing with the format in two different places.

Also, could you mention the new format in the manual?

Last question: what use case do you have in mind regarding the JSON
format?  I’m asking because we don’t have tools that can consume it so
far.

Thanks,
Ludo’.
Oleg Pykhalov Nov. 21, 2018, 2:10 p.m. UTC | #2
Hello Ludovic,

Apologies for created previously separate bug reports of same patch
series.

ludo@gnu.org (Ludovic Courtès) writes:

> Oleg Pykhalov <go.wigust@gmail.com> skribis:
>
>> * guix/scripts/describe.scm: Add json format.
>
> Please describe the modified and added variables/procedures.
>
>> +  (define (channels format)
>> +    (map (lambda (entry)
>> +       …
>> +                (generation-file-name profile number)))))))

Ups, I'll do this in followign patch series.

> How about turning this into a list of <channel> objects, and then,
> separately have ‘channels->sexp’ and ‘channels->json’?  That would avoid
> having dealing with the format in two different places.
>
> Also, could you mention the new format in the manual?
>
> Last question: what use case do you have in mind regarding the JSON
> format?  I’m asking because we don’t have tools that can consume it so
> far.

Well, I wanted to get a command line way to select things in ‘guix
channel’ output, e.g. to get a current ‘guix’ channel commit:
--8<---------------cut here---------------start------------->8---
./pre-inst-env guix describe --profile=$HOME/.config/guix/current --format=json | jq --raw-output 'map(select(.name == "guix"))'[0].commit
--8<---------------cut here---------------end--------------->8---

I didn't think that ‘recsel’ actually could be used in the same way:
--8<---------------cut here---------------start------------->8---
./pre-inst-env guix describe --profile=$HOME/.config/guix/current --format=recutils | recsel -e 'name = "guix"' -P commit
--8<---------------cut here---------------end--------------->8---

I'll send new patch series following current message.
Ludovic Courtès Nov. 21, 2018, 9:36 p.m. UTC | #3
Oleg Pykhalov <go.wigust@gmail.com> skribis:

> ludo@gnu.org (Ludovic Courtès) writes:

[...]

>> Last question: what use case do you have in mind regarding the JSON
>> format?  I’m asking because we don’t have tools that can consume it so
>> far.
>
> Well, I wanted to get a command line way to select things in ‘guix
> channel’ output, e.g. to get a current ‘guix’ channel commit:
>
> ./pre-inst-env guix describe --profile=$HOME/.config/guix/current --format=json | jq --raw-output 'map(select(.name == "guix"))'[0].commit
>
>
> I didn't think that ‘recsel’ actually could be used in the same way:
>
> ./pre-inst-env guix describe --profile=$HOME/.config/guix/current --format=recutils | recsel -e 'name = "guix"' -P commit

I see, that makes sense.  It’s OK to have both JSON and recutils.

Thank you!

Ludo’.

Patch

diff --git a/guix/scripts/describe.scm b/guix/scripts/describe.scm
index d3203e992..53195b423 100644
--- a/guix/scripts/describe.scm
+++ b/guix/scripts/describe.scm
@@ -23,6 +23,7 @@ 
   #:use-module (guix profiles)
   #:use-module ((guix scripts pull) #:select (display-profile-content))
   #:use-module (git)
+  #:use-module (json)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-37)
   #:use-module (ice-9 match)
@@ -38,7 +39,7 @@ 
   ;; Specifications of the command-line options.
   (list (option '(#\f "format") #t #f
                 (lambda (opt name arg result)
-                  (unless (member arg '("human" "channels"))
+                  (unless (member arg '("human" "channels" "json"))
                     (leave (G_ "~a: unsupported output format~%") arg))
                   (alist-cons 'format (string->symbol arg) result)))
         (option '(#\h "help") #f #f
@@ -101,7 +102,12 @@  within a Git checkout."
        (pretty-print `(list (channel
                              (name 'guix)
                              (url ,(dirname directory))
-                             (commit ,commit))))))
+                             (commit ,commit)))))
+      ('json
+       (display (scm->json-string `((name . guix)
+                                    (url . ,(dirname directory))
+                                    (commit . ,commit))))
+       (newline)))
     (display-package-search-path fmt)))
 
 (define (display-profile-info profile fmt)
@@ -110,34 +116,47 @@  in the format specified by FMT."
   (define number
     (generation-number profile))
 
+  (define (channels format)
+    (map (lambda (entry)
+           (match (assq 'source (manifest-entry-properties entry))
+             (('source ('repository ('version 0)
+                                    ('url url)
+                                    ('branch branch)
+                                    ('commit commit)
+                                    _ ...))
+              (case format
+                ((scm)
+                 `(channel (name ',(string->symbol
+                                    (manifest-entry-name entry)))
+                           (url ,url)
+                           (commit ,commit)))
+                ((json)
+                 `((name . ,(string->symbol
+                             (manifest-entry-name entry)))
+                   (url . ,url)
+                   (commit . ,commit)))))
+
+             ;; Pre-0.15.0 Guix does not provide that information,
+             ;; so there's not much we can do in that case.
+             (_ '???)))
+
+         ;; Show most recently installed packages last.
+         (reverse
+          (manifest-entries
+           (profile-manifest
+            (if (zero? number)
+                profile
+                (generation-file-name profile number)))))))
+
   (match fmt
     ('human
      (display-profile-content profile number))
     ('channels
      (pretty-print
-      `(list ,@(map (lambda (entry)
-                      (match (assq 'source (manifest-entry-properties entry))
-                        (('source ('repository ('version 0)
-                                               ('url url)
-                                               ('branch branch)
-                                               ('commit commit)
-                                               _ ...))
-                         `(channel (name ',(string->symbol
-                                            (manifest-entry-name entry)))
-                                   (url ,url)
-                                   (commit ,commit)))
-
-                        ;; Pre-0.15.0 Guix does not provide that information,
-                        ;; so there's not much we can do in that case.
-                        (_ '???)))
-
-                    ;; Show most recently installed packages last.
-                    (reverse
-                     (manifest-entries
-                      (profile-manifest
-                       (if (zero? number)
-                           profile
-                           (generation-file-name profile number))))))))))
+      `(list ,@(channels 'scm))))
+    ('json
+     (display (scm->json-string (channels 'json)))
+     (newline)))
   (display-package-search-path fmt))