I was able to write a short manifest that avoided the overwriting of the original "foobarpy" package in my case, and instead cleanly replace it with a newer version specified using "with-source".
By setting, for example, GUIX_FOOBAR_VERSION=1.23 and GUIX_TEST_PACKAGE=my-package - I can now create an environment which builds the version of foobarpy I want from an https link generated from GUIX_FOOBAR_VERSION, and then create a modified version of "my-package" with foobarpy replaced, rather than overwritten.
This is much better than my original hack, but it's still not recursive so whilst it does rebuild my-package with the new version of foobarpy as a propagated input, it isn't rebuilding the whole dependency tree - other inputs to my-package could also depend on foobarpy, and should be rebuilt too - so what I've done is more of a graft, buthappens to be good enough for my specific use case (the foobarpy is not used anywhere else in my case).
Anyway thought I'd share this here as a template for simple non-recursive cases. I suspect it's not a massive effort to make it recursive, when I have a moment I'll have a think about that too. Any thoughts on how to improve are welcome!
(use-modules (guix transformations) ;; options->transformation
(guix packages) ;; package/inherit
(srfi srfi-1) ;; fold
(srfi srfi-98)) ;; get-environment-variable
(define (generate-foobar-link version)
(string-append "
https://packages.foobar.com/"
(substring version 0 3) "/foobar"
version "_linux64.tar.gz"))
(define transform
;; The package transformation procedure.
(let* ((foobar-version (get-environment-variable "GUIX_FOOBAR_VERSION"))
(foobar-link (string-append
"foobarpy@" foobar-version
"=" (generate-foobar-link foobar-version))))
(format #t "~%Setting Foobar Version: ~a~%" foobar-version)
(options->transformation
`((with-source . ,foobar-link)))))
(define my-foobar-package (transform (specification->package "foobarpy")))
(define-public my-package-with-my-foobar
(let* ((test-package-string (get-environment-variable "GUIX_TEST_PACKAGE"))
(test-package (specification->package test-package-string)))
(package/inherit test-package
(propagated-inputs
`(("foobarpy" ,my-foobar-package)
,@(fold alist-delete (package-propagated-inputs test-package) '("foobarpy")))))))
(packages->manifest (list my-package-with-my-foobar))