A reflection to accompany bb-timemachine. Babashka has put me truly in control of my environment. I now script things consistently rather than "remember shell commands". And it doesn't even cost more time! A REPL with p/shell and fs/[all the nice things] is all I need. And I get real data rather than lines of text. That means I can keep growing the little seeds of shell scripts into useful namespaces if the problem at hand is important.
bb-timemachine grew out of this attitude. Try make our days a little bit nicer. You all might be better served copying what you want from the 50 lines of implementation rather than using the dependency! Dependencies may act as a barrier against learning.
this might be pretty cool to run benchmarks with, and run some comparison against the results (like in golang, you'd use a tool called benchstat). Or, use it to build a pair of binaries for a tool at different hashes and subsequently run them with hyperfine. ✨
I actually think I will use bb-timemachine at some point to clean up my current script! It looks like a nice abstraction 👏
Glad you like it! I stumbled into the API design. First, just take a function and "run it in the past". Then, do the same for arbitrary shell commands. I expected to have to hard-code knowledge of how to run the tests, but then I didn't!
Yeah that's really nice. I think it will not be much work to update my script. It will replace these lines and is probably much faster https://gist.github.com/jeroenvandijk/10aa1a7ef82e15be689f5af34f387079#file-test-clj-L56-L73
It is definitely faster than 6 seconds, at least for our code base at work! I don't personally notice the difference between a local folder with a fresh JVM. One thing to watch out for is you only get tracked files copied over, but that's probably the case for test suites already running on CI.
Yeah i think that's what I would want. I'll let you know how it compares once I get to it
Ok I did a quick test. It is very fast, insignificant overhead. The only thing is that it doesn't take my submodules into account. I will try to find out if there is something that you can do with worktree that supports this
Maybe something like this?
(timemachine/do-at "HEAD"
(fn [dir]
(p/shell {:dir dir} "git submodule update --init --recursive")
(into #{}
(map fs/file-name)
(fs/list-dir dir))))
;; => #{"example"
;; "README.md"
;; "LICENSE"
;; "bb.edn"
;; "src"
;; "tests.edn"
;; ".gitignore"
;; "deps.edn"
;; ".git"
;; "test"}
I haven't tested with real submodules, though, so not sure if it'll actually work.Very elegant! It sort of works except for the cleanup part
16: (defn worktree-remove [dir worktree]
17: (p/shell {:dir dir :out :discard :err :discard}
^--- fatal: working trees containing submodules cannot be moved or removed
18:
But I guess that can be fixed.
Time wise unfortunately it is the same as before so it seems the submodule checkout is the culprit. I can imagine it can be done a bit faster when done locally, but I'll have to do some research for this. Either way the extra time was never a big issue for me. I like your approach so will probably migrate to it when I figure the submodule thing outMaybe it needs a --force https://stackoverflow.com/a/74566600/105406
Right, probably requires a bit more work then. Glad we at least were able to pinpoint the culprit of those 6 seconds!
Last attempt for today!
(defn ^{:indent 1} do-at-auto-submodule
[git-revision handle-fn]
(let [tempdir (fs/create-temp-dir)
repo-dir "."
sha (rev-parse repo-dir git-revision)
worktree-dir (str (fs/file tempdir sha))]
(worktree-add repo-dir worktree-dir sha)
(try
(p/shell {:dir worktree-dir} "git submodule update --init --recursive")
(handle-fn worktree-dir)
(finally
(p/shell {:dir repo-dir :out :discard :err :discard}
"git worktree remove" worktree-dir "--force")))))
(do-at-auto-submodule "HEAD" #(->> % fs/list-dir (map fs/file-name) set))
;; => #{"example"
;; "README.md"
;; "LICENSE"
;; "bb.edn"
;; "src"
;; "tests.edn"
;; ".gitignore"
;; "deps.edn"
;; ".git"
;; "test"}Putting away the computer for now, hope you get the submodules under control!
With --force it doesn't complain anymore. And when i add --no-fetch to the submodule command it is also much faster. 2 seconds now. So that's nice!
git submodule update --init --recursive --jobs 8 --no-fetch