Index: env.scm ================================================================== --- env.scm +++ env.scm @@ -41,38 +41,79 @@ (val (cdr varval))) (if incremental (exec (sql db "DELETE FROM envvars WHERE context=? AND var=?") context var)) (exec (sql db "INSERT INTO envvars (context,var,val) VALUES (?,?,?)") context var val))) (get-environment-variables))))) -;; apply contexts to current environment +;; merge contexts in the order given ;; - each context is applied in the given order ;; - variables in the paths list are split on the separator and the components ;; merged using simple delta addition -;; -(define (env:apply-contexts db basecontext contexts paths outputf formats) - - (for-each - (lambda (context) - (query - (for-each-row - (lambda (row) - (let ((var (car row)) - (vala (cadr row)) - (valb (caddr row))) - ;;(print "var: " var " vala: " vala " valb" valb " paths: " paths) - (if (assoc var paths) ;; this var is a PATH - (let ((current (get-environment-variable var))) ;; use this NOT vala - ;;(pp paths) - ;;(pp var) - (env:process-path-envvar var (cadr (assoc var paths)) current valb)) - (begin - (setenv var valb)))))) - (sql db "SELECT b.var,a.val,b.val FROM envvars AS a JOIN envvars AS b ON a.var=b.var WHERE a.context=? AND b.context=? AND a.val != b.val") - ;;(sql db "SELECT b.var,a.val,b.val FROM envvars AS a JOIN envvars AS b ON a.var=b.var WHERE a.context=? AND b.context=?") - basecontext context)) - contexts)) - +;; returns a hash of the merged vars +;; +(define (env:merge-contexts db basecontext contexts paths) + (let ((result (make-hash-table))) + (for-each + (lambda (context) + (query + (for-each-row + (lambda (row) + (let ((var (car row)) + (val (cadr row))) + (hash-table-set! result var + (if (and (hash-table-ref/default results var #f) + (assoc var paths)) ;; this var is a path and there is a previous path + (let ((sep (cadr (assoc var paths)))) + (env:merge-path-envvar sep (hash-table-ref results var) valb)) + valb))))) + (sql db "SELECT var,val FROM envvars WHERE context=?") + context)) + contexts) + result)) + +;; get list of removed variables between two contexts +;; +(define (env:get-removed db contexta contextb) + (let ((result (make-hash-table))) + (query + (for-each-row + (lambda (row) + (let ((var (car row)) + (val (cadr row))) + (hash-table-set! result var valb)))) + (sql db "SELECT var,val FROM envvars WHERE context=? AND var NOT IN (SELECT var FROM envvars WHERE context=?)") + contexta contextb) + result)) + +;; get list of variables added to contextb from contexta +;; +(define (env:get-added db contexta contextb) + (let ((result (make-hash-table))) + (query + (for-each-row + (lambda (row) + (let ((var (car row)) + (val (cadr row))) + (hash-table-set! result var valb)))) + (sql db "SELECT var,val FROM envvars WHERE context=? AND var NOT IN (SELECT var FROM envvars WHERE context=?)") + contextb contexta) + result)) + +;; get list of variables in both contexta and contexb that have been changed +;; +(define (env:get-changed db contexta contextb) + (let ((result (make-hash-table))) + (query + (for-each-row + (lambda (row) + (let ((var (car row)) + (val (cadr row))) + (hash-table-set! result var val)))) + (sql db "SELECT var,val FROM envvars WHERE context=? AND val != (SELECT val FROM envvars WHERE var=? AND context=?)") + contexta contextb)) + result) + +;; (define (env:blind-merge l1 l2) (if (null? l1) l2 (if (null? l2) l1 (cons (car l1) (cons (car l2) (env:blind-merge (cdr l1) (cdr l2))))))) @@ -88,13 +129,10 @@ ;; (print "AFTER: " (string-intersperse pathb-parts "\n ")) ;; (print "COMMON: " (string-intersperse common-parts "\n ")) (string-intersperse final separator))) (define (env:process-path-envvar varname separator patha pathb) - (begin - (print "Process-path-envvar: " varname) - ) (let ((newpath (env:merge-path-envvar separator patha pathb))) (setenv varname newpath))) (define (env:have-context db context) (> (query fetch-value (sql db "SELECT count(id) FROM envvars WHERE context=?") context) Index: megatest.scm ================================================================== --- megatest.scm +++ megatest.scm @@ -1896,10 +1896,24 @@ (env:close-database db) (set! *didsomething* #t)) (begin (debug:print 0 "ERROR: Parameter to -envcap should be =. E.G. envdat=original, got: " envcap) (set! *didsomething* #t))))) + +;; delta "language" will eventually be res=a+b-c but for now it is just res=a-b +;; +(let ((envdelta (args:get-arg "-envdelta"))) + (if envdelta + (let ((match (string-match "([a-z]+)=([a-z\-,]+)" envdelta))) + (if match + (let* ((resctx (cadr match)) + (equn (caddr match)) + (parts (string-split equn "-")) + (minuend (car parts)) + (subtraend (cadr parts)) + ( + ;;====================================================================== ;; Exit and clean up ;;======================================================================