Compare commits

...

8 Commits

Author SHA1 Message Date
Magali Lemes
c215307e0c scripts: git: log: Add '--grep'.
* guix/scripts/git/log.scm (show-help, %options): Add '--grep'.
* Makefile.am (MODULES): Add 'guix/scripts/git/log.scm'.
2022-07-04 10:34:52 +02:00
Magali Lemes
754157f50b scripts: git: log: Add docstring.
* guix/scripts/git/log.scm (%options, list-channels, information-placeholders,
replace-regex, procedure-list, pretty-show-commit, show-channel-cache-path,
show-commit, get-commits): Add docstring.
* guix/scripts/git/log.scm: (%options, show-help): Add '--version'.
2022-07-04 10:34:52 +02:00
Magali Lemes
b8270a11d6 scripts: git: log: Add '--pretty'.
* guix/scripts/git/log.scm (%options, show-help): Add '--pretty'.
(placeholders-regex, information-placeholders): New variables.
(replace-regex, procedure-list, pretty-show-commit): New procedures.
2022-07-04 10:34:52 +02:00
Magali Lemes
7b912bae6f scripts: git: log: Manage with different channels.
* guix/scripts/git/log.scm (list-channels): New procedure.
(get-commits): Retrieve commits from all channels, instead of just one.
(%options): By default '--channel-cache-path' lists the paths of all channels.
2022-07-04 10:34:52 +02:00
Magali Lemes
99edf7e5ea git: Export commit-closure.
* guix/git.scm (commit-closure): Export it.
2022-07-04 10:34:52 +02:00
Magali Lemes
38f088544c scripts: git: log: Add '--format'.
* guix/scripts/git/log.scm (%formats): New variable.
(show-help, %options): Add '--format' option.
(show-commit): Adjust adding new arguments.
(get-commits): Return a list of all commits.
2022-07-04 10:34:52 +02:00
Magali Lemes
fa61849b40 Add 'guix git log'.
* guix/scripts/git/log.scm: New file.
* guix/scripts/git.scm (%sub-commands): Add "log".
2022-07-04 10:34:52 +02:00
Ludovic Courtès
2a4de119d0 .guix-authorizations: Add magali.
* .guix-authorizations: Add magali to the committers.
2022-07-04 10:34:46 +02:00
5 changed files with 251 additions and 1 deletions

View File

@@ -64,6 +64,8 @@
(;; primary: "4F71 6F9A 8FA2 C80E F1B5 E1BA 5E35 F231 DE1A C5E0"
"B051 5948 F1E7 D3C1 B980 38A0 2646 FA30 BACA 7F08"
(name "lfam"))
("925C 8EBD F446 931D 1B64 4498 2D58 A112 6E2D FC90"
(name "magali"))
("CBF5 9755 CBE7 E7EF EF18 3FB1 DD40 9A15 D822 469D"
(name "marusich"))
("BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"

View File

@@ -341,6 +341,7 @@ MODULES = \
guix/scripts/size.scm \
guix/scripts/git.scm \
guix/scripts/git/authenticate.scm \
guix/scripts/git/log.scm \
guix/scripts/graph.scm \
guix/scripts/weather.scm \
guix/scripts/container.scm \

View File

@@ -59,6 +59,7 @@
update-cached-checkout
url+commit->name
latest-repository-commit
commit-closure
commit-difference
commit-relation
commit-descendant?

View File

@@ -38,7 +38,7 @@ Operate on Git repositories.\n"))
(newline)
(show-bug-report-information))
(define %sub-commands '("authenticate"))
(define %sub-commands '("authenticate" "log"))
(define (resolve-sub-command name)
(let ((module (resolve-interface

246
guix/scripts/git/log.scm Normal file
View File

@@ -0,0 +1,246 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020, 2021 Magali Lemes <magalilemes00@gmail.com>
;;;
;;; 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 scripts git log)
#:use-module (git)
#:use-module (guix channels)
#:use-module (guix git)
#:use-module (guix scripts)
#:use-module (guix scripts pull)
#:use-module (guix sets)
#:use-module (guix ui)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
#:use-module (ice-9 regex)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-19)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-37)
#:export (guix-git-log))
(define %formats
'("oneline" "medium" "full"))
(define %options
;; Specifications of the command-line options.
(list (option '(#\h "help") #f #f
(lambda args
(show-help)
(exit 0)))
(option '(#\V "version") #f #f
(lambda args
(show-version-and-exit "guix git log")))
(option '("channel-cache-path") #f #t
(lambda (opt name arg result)
(if arg
(alist-cons 'channel-cache-path
(string->symbol arg) result)
(list-channels))))
(option '("format") #t #f
(lambda (opt name arg result)
(unless (member arg %formats)
(leave (G_ "~a: invalid format~%") arg))
(alist-cons 'format (string->symbol arg) result)))
(option '("grep") #t #f
(lambda (opt name arg result)
(alist-cons 'grep arg result)))
(option '("oneline") #f #f
(lambda (opt name arg result)
(alist-cons 'oneline? #t result)))
(option '("pretty") #t #f
(lambda (opt name arg result)
(alist-cons 'pretty arg result)))))
(define %default-options
'())
(define (list-channels)
"List channels and their checkout path"
(define channels (channel-list '()))
(for-each (lambda (channel)
(format #t "~a~% ~a~%"
(channel-name channel)
(url-cache-directory (channel-url channel))))
channels))
(define (show-help)
(display (G_ "Usage: guix git log [OPTIONS...]
Show Guix commit logs.\n"))
(display (G_ "
--channel-cache-path[=CHANNEL]
show checkout path from CHANNEL"))
(display (G_ "
--format=FORMAT show log according to FORMAT"))
(display (G_ "
--grep=REGEXP show commits whose message matches REGEXP"))
(display (G_ "
--oneline show short hash and summary of commits"))
(display (G_ "
--pretty=<string> show log according to string"))
(newline)
(display (G_ "
-h, --help display this help and exit"))
(display (G_ "
-V, --version display version information and exit"))
(newline)
(show-bug-report-information))
(define commit-short-id
(compose (cut string-take <> 7) oid->string commit-id))
(define placeholders-regex "%([Hhsb]|(an)|(cn))")
(define information-placeholders
;; Alist of placeholders and their corresponding procedure.
`(("%b" . ,commit-body)
("%H" . ,(compose oid->string commit-id))
("%h" . ,commit-short-id)
("%s" . ,commit-summary)
("%an" . ,(compose signature-name commit-author))))
(define (replace-regex string)
"Return a string replacing all information placeholders with ~a"
(regexp-substitute/global #f placeholders-regex string 'pre "~a" 'post))
(define (procedure-list string)
"Return a list of procedures according to the placeholders contained in
string, in the order they appear"
(let* ((placeholders-in-the-string
(map match:substring (list-matches placeholders-regex string))))
(map (lambda (commit)
(assoc-ref information-placeholders commit))
placeholders-in-the-string)))
(define (pretty-show-commit string commit)
"Display commit according to string"
(format #t "~?~%" (replace-regex string) (map
(lambda (f) (f commit))
(procedure-list string))))
(define (show-channel-cache-path channel)
"Display channel checkout path."
(define channels (channel-list '()))
(let ((found-channel (find (lambda (element)
(equal? channel (channel-name element)))
channels)))
(if found-channel
(format #t "~a~%" (url-cache-directory (channel-url found-channel)))
(leave (G_ "~a: channel not found~%") (symbol->string channel)))))
(define (show-commit commit fmt abbrev-commit)
"Display commit according to fmt. If abbrev-commit is #t, then show short hash
id instead of the 40-character one."
(match fmt
('oneline
(format #t "~a ~a~%"
(if abbrev-commit
(commit-short-id commit)
(oid->string (commit-id commit)))
(commit-summary commit)))
('medium
(let ((author (commit-author commit))
(merge-commit (if (> (commit-parentcount commit) 1) #t #f)))
(format #t "commit ~a~[~%Merge:~]~{ ~a~}~%Author: ~a <~a>~%Date: ~a~%~%~a~%"
(if abbrev-commit
(commit-short-id commit)
(oid->string (commit-id commit)))
(if merge-commit 0 1) ;; show "Merge:"
(if merge-commit (map commit-short-id (commit-parents commit)) '())
(signature-name author)
(signature-email author)
(date->string
(time-utc->date
(make-time time-utc 0
(time-time (signature-when author)))
(* 60 (time-offset (signature-when author))))
"~a ~b ~e ~H:~M:~S ~Y ~z")
(commit-message commit))))
('full
(let ((merge-commit (if (> (commit-parentcount commit) 1) #t #f))
(author (commit-author commit))
(committer (commit-committer commit)))
(format #t "commit ~a~[~%Merge:~]~{ ~a~}~%Author: ~a <~a>~%Commit: ~a <~a>~%~%~a~%"
(if abbrev-commit
(commit-short-id commit)
(oid->string (commit-id commit)))
(if merge-commit 0 1) ;; show "Merge:"
(if merge-commit (map commit-short-id (commit-parents commit)) '())
(signature-name author)
(signature-email author)
(signature-name committer)
(signature-email committer)
(commit-message commit))))))
(define %channels-repositories
(make-hash-table))
(define (get-commits)
"Return a list with commits from all channels."
(define channels (channel-list '()))
(fold (lambda (channel commit-list)
(let* ((channel-path (url-cache-directory (channel-url channel)))
(repository (repository-open channel-path))
(latest-commit
(commit-lookup repository
(object-id
(revparse-single
repository "origin/master")))))
(begin
(hashq-set! %channels-repositories channel-path repository)
(append (set->list (commit-closure latest-commit))
commit-list)))) '() channels))
(define (guix-git-log . args)
(define options
(parse-command-line args %options (list %default-options)))
(let ((channel-cache (assoc-ref options 'channel-cache-path))
(oneline? (assoc-ref options 'oneline?))
(format-type (assoc-ref options 'format))
(pretty-string (assoc-ref options 'pretty))
(regexp (assoc-ref options 'grep)))
(with-error-handling
(cond
(channel-cache
(show-channel-cache-path channel-cache))
(oneline?
(leave-on-EPIPE
(for-each (lambda (commit)
(when (or (not regexp)
(string-match regexp (commit-message commit)))
(show-commit commit 'oneline #t)))
(get-commits))))
(format-type
(leave-on-EPIPE
(for-each (lambda (commit)
(when (or (not regexp)
(string-match regexp (commit-message commit)))
(show-commit commit format-type #f)))
(get-commits))))
(pretty-string
(let ((pretty-show (cut pretty-show-commit pretty-string <>)))
(leave-on-EPIPE
(for-each (lambda (commit)
(when (or (not regexp)
(string-match regexp (commit-message commit)))
(pretty-show commit)))
(get-commits)))))))))