From: Csepp <raingloom@riseup.net>
To: jgart <jgart@dismail.de>
Cc: Julien Lepiller <julien@lepiller.eu>, help-guix@gnu.org
Subject: Re: committer.scm
Date: Wed, 02 Nov 2022 10:19:32 +0100 [thread overview]
Message-ID: <874jvhiudt.fsf@riseup.net> (raw)
In-Reply-To: <20221101171932.GB13253@dismail.de>
[-- Attachment #1: Type: text/plain, Size: 580 bytes --]
jgart <jgart@dismail.de> writes:
> On Tue, 01 Nov 2022 07:57:28 +0100 Julien Lepiller <julien@lepiller.eu> wrote:
>> Try calling it with pre-inst-env.
>
> Ohhh, yes that was it. I stopped calling it with pre-inst-env for some reason ;()
>
> THNX
>
> Now I just need to see how I am going to sort these 150+ crates in an automated fashion...
If you have some graph theory and Guix know-how you might be able to get
my commit sorter script working. Currently it's broken, as in it does
not sort commits in the way they should be sorted, but it has a lot of
useful bits already.
[-- Attachment #2: commit sorter guile script --]
[-- Type: text/plain, Size: 7818 bytes --]
(use-modules
(gnu installer utils)
(graph topological-sort)
(guix build utils)
(ice-9 exceptions)
(ice-9 hash-table)
(ice-9 match)
(ice-9 popen)
(ice-9 rdelim)
(oop goops)
(srfi srfi-1)
(srfi srfi-13)
(srfi srfi-2)
(srfi srfi-26)
(gnu packages)
(guix packages))
(with-exception-handler
exception-irritants
(lambda ()
(package-propagated-inputs
(module-ref
(reload-module (resolve-module '(gnu packages ocaml-mirage) #:ensure #f))
'ocaml-ppx-cstruct)))
#:unwind? #t
#:unwind-for-type &undefined-variable)
(define from-commit "raingloom/mirageos-rebase")
(define to-commit "after-dune")
;; The set (sorted list) of variables (symbols) we care about.
(define variables-of-interest
;; starts out as #f to catch errors
(make-parameter #f))
(define variable->commit-mapping
(make-parameter #f))
(define dependency-digraph
(make-parameter #f))
(define commit->log-index
(make-parameter #f))
(define (with-input-from-make thunk)
(lambda _
(with-input-from-port
(open-pipe* OPEN_READ "make")
thunk)))
(define (set-current-commit! commit)
(invoke "git" "checkout" commit))
(define (missing-variable-on-line line)
(and-let*
((words (string-split line #\space))
(prefixed-var (find-tail (cut string=? "variable" <>) words))
;; so cadr doesn't error
(prefixed-var-ok? (equal? 2 (length prefixed-var)))
(var-quoted (cadr prefixed-var))
(var-quoted-ok? (and (string-suffix? "'" var-quoted)
(string-prefix? "`" var-quoted)))
(var (string-drop-right (string-drop var-quoted 1) 1)))
var))
(define (with-input-from-command thunk command)
;; TODO this is ugly, but run-external-command-with-handler does not return
;; the value that the handler returns, only the command's exit status
(define ret #f)
(define (handler port)
(set! ret (with-input-from-port port thunk)))
(run-external-command-with-handler handler command)
ret)
(define (current-commit-missing-definitions)
(define (go)
(let ((line (read-line)))
(if (eof-object? line)
'()
(let ((variable (missing-variable-on-line line)))
(if variable
(cons variable (go))
(go))))))
(map string->symbol
(with-input-from-command go '("make"))))
(define (name->commit name)
(define (go)
(define hash (read-line))
(unless (eof-object? (read-line))
(error "unexpected additional output"))
hash)
(with-input-from-command
go
`("git" "show" "--format=%H" "--quiet" ,name)))
(define (current-commit)
(name->commit "HEAD"))
(define (commits-since commit-name)
(define commit (name->commit commit-name))
(define (go)
(let ((line (read-line)))
(cond
((eof-object? line) (error "ancestor commit does not exist"))
((string=? line commit) '())
(else (cons line (go))))))
(reverse (with-input-from-command go '("git" "log" "--format=%H"))))
(define (files-changed commit)
(cdr (with-input-from-command
read-lines
`("git" "show" "--oneline" "--name-only" ,commit))))
(define (module-file? file)
(string-suffix? ".scm" file))
(define (path->module path)
"Assumes PATH is a valid Scheme file."
(let* ((components-rev (reverse (string-split path #\/)))
(base (car components-rev))
(last-component (string-drop-right base (string-length ".scm"))))
(map string->symbol (reverse (cons last-component (cdr components-rev))))))
(define (modules-changed commit)
(map path->module
(filter module-file?
(files-changed commit))))
(define (touch-changed-files! commit)
(apply invoke (cons "touch" (files-changed commit))))
(define (commits+missing-definitions commits)
(map (lambda (commit)
(set-current-commit! commit)
(touch-changed-files! commit)
(cons commit (current-commit-missing-definitions)))
commits))
(define (set-insert set x)
"Insert element X into the sorted list SET."
(match set
(() (list x))
((a) (if (< a x)
(list a x)
(list x a)))
((a b . rest)
(cond
((and (< a x) (< x b)) (cons* a x b rest))
((equal? a x) set)
((< x a) (cons* x a (cdr set)))
(else (cons a (set-insert (cdr set) x)))))))
(define (add-dependent! dependency-graph commit dependent)
(assoc-set! dependency-graph commit
(set-insert dependent
(or (assoc-ref dependency-graph commit)
'()))))
(define (deduplicate lst)
(define ret '())
(for-each (lambda (x) (set! ret (assoc-set! ret x #t))) lst)
(map car ret))
(define (current-commit-defined-vars-of-interest)
(let ((vars-of-interest (variables-of-interest)))
(deduplicate
(concatenate
(filter identity
(map (lambda (module-name)
(let ((module (reload-module
(resolve-module module-name))))
(map (lambda (var)
(and (module-variable
module var) var))
vars-of-interest)))
(modules-changed (current-commit))))))))
;; : alist symbol (list string)
(define (compute-variable->commit-mapping! commits)
(fold
(lambda (commit vars->commits)
(set-current-commit! commit)
(fold
(lambda (var vars->commits)
(assoc-set! vars->commits var
(cons commit
(or (assoc-ref vars->commits var) '()))))
vars->commits
(current-commit-defined-vars-of-interest)))
'()
commits))
(define (order-in-topology commit)
(hash-ref (topology-vector) commit))
(define (order-in-log commit)
(hash-ref (commit->log-index) commit))
(define (depends? commit dependency)
"Does COMMIT depend on DEPENDENCY?"
(sorted? (map order-in-topology (list commit dependency)) <))
(define (predates? a b)
"Does commit A come before commit B in the original history?"
(sorted? (map order-in-log (list a b)) <))
(define (commits-ordered? a b)
"Commit A should come before B iff B has a direct dependency on A or if it
comes before B in the git history, in that order of precedence."
(or (depends? a b)
(predates? a b)))
(define (list->index-lookup-hash-table lst)
(define mapping (make-hash-table))
(fold (lambda (x i)
(hash-set! mapping x i)
(+ 1 i))
0 lst)
mapping)
(define (hash->alist hsh)
(hash-fold acons '() hsh))
(set-current-commit! from-commit)
;; edges go from commits to variables
(define commits (commits-since to-commit))
(commit->log-index (list->index-lookup-hash-table commits))
(define commits->missing-definitions (commits+missing-definitions commits))
(variables-of-interest
(deduplicate
(apply append (map cdr commits->missing-definitions))))
(define var->comm
(compute-variable->commit-mapping! commits))
(variable->commit-mapping (alist->hash-table var->comm))
(define graph-n (length commits))
(define graph (make-bitvector (expt graph-n 2)))
(define (coord->offset row col)
(+ col (* graph-n row)))
(define (connected? a b)
(bitvector-bit-set? graph (coord->offset a b)))
(define (connect! a b)
(bitvector-set-bit! graph (coord->offset a b)))
(let ((variable->commit-mapping (variable->commit-mapping)))
(for-each
(match-lambda
((commit . vars)
(let ((commit-log-id (order-in-log commit)))
(for-each
(lambda (var)
(let* ((dependencies (hash-ref variable->commit-mapping var)))
(for-each
(lambda (dependency)
(connect! commit-log-id (order-in-log dependency))))))
vars))))
commits->missing-definitions))
prev parent reply other threads:[~2022-11-02 9:22 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-01 1:42 committer.scm jgart
2022-11-01 6:57 ` committer.scm Julien Lepiller
2022-11-01 22:19 ` committer.scm jgart
2022-11-02 9:19 ` Csepp [this message]
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=874jvhiudt.fsf@riseup.net \
--to=raingloom@riseup.net \
--cc=help-guix@gnu.org \
--cc=jgart@dismail.de \
--cc=julien@lepiller.eu \
/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.