Fork me on GitHub
#babashka
<
2023-06-09
>
leifericf08:06:17

Is it possible to change the directory in which process/sh runs for one command? I have the following code:

(defn clone-repo
  "Clone a Git repo to a destination path."
  ([repo-url] (clone-repo repo-url "./repos"))
  ([repo-url dest-path] (if-not (file/exists? dest-path) (file/create-dir dest-path) nil)
                        (process/sh "git clone" repo-url dest-path)))

(defn clone-all-repos
  "Clone all Git repos from Azure DevOps."
  [] (let [repo-urls (->> (get-all-repo-data)
                          (tree-seq coll? identity)
                          (keep :sshUrl))]
       (->> repo-urls
            (map clone-repo))))
The problem right now is that all Git repos get cloned into the same directory (`./repos`), but I want each Git repo to be cloned into its own parent directory within ./repos. It doesn't seem like Git offers this as an option to clone, so I'm looking for a way to temporarily change Babashka's working directory (for that one sh command) or something along those lines.

borkdude08:06:55

Yes, (sh {:dir "foo"} ...)

๐Ÿ’ฏ 2
leifericf08:06:45

Aha, thanks! I misunderstood that in the docs. (Noob mistake.)

borkdude08:06:21

If you think the docs can be clearer, suggestions welcome

๐Ÿ‘ 2
leifericf08:06:52

The docs are pretty good! The problem is more that I don't always brain correctly ๐Ÿ˜‚

๐Ÿ˜† 2
๐Ÿง  2
andy14:06:44

> It doesnโ€™t seem like Git offers this as an option to clone Maybe this helps

/tmp/some-dir
$ mkdir repos

/tmp/some-dir
$ git clone  ./repos/process
Cloning into './repos/process'...

/tmp/some-dir
$ git clone  ./repos/process-again
Cloning into './repos/process-again'...

/tmp/some-dir
$ git clone  ./repos/process-3
Cloning into './repos/process-3'...

/tmp/some-dir
$ ls repos/
process/  process-3/  process-again/

๐Ÿ’ก 2
leifericf10:06:27

With Bash, I can do the following to find all directories named .git (find all Git repos on my machine):

find / -name ".git" -type d
Babashka has babashka.fs/glob, which can be used to find files. But can it also find directories? Something akin to -type d. I naively tried this:
(defn find-repos
  "Find all Git repos in a directory."
  [root-path] (babashka.fs/glob root-path "**.git"))

(find-repos "./repos")
But it yields an empty vector. Presumably, because it looks for files, not directories? :thinking_face:

borkdude10:06:01

Good point. I think this is because visit-file is never called on a directory:

(fs/walk-file-tree "."
                   {:pre-visit-dir (fn [dir _]
                                     #_(when (str/includes? (str dir) ".git")
                                       (prn dir)) :continue)
                    :visit-file (fn [path attrs]
                                  (when (and (fs/directory? path)
                                             (str/includes? (str path) ".git"))
                                    (prn path))
                                  :continue)})

borkdude10:06:56

feel free to file a bug report

๐Ÿ‘ 2
leifericf11:06:55

As I'm writing a repro case for the bug report, I discovered something interesting. This:

(babashka.fs/create-dir "./test-dir")
(babashka.fs/glob "." "**test-dir")
Seems to find the directory:
=> [#object[sun.nio.fs.UnixPath 0x35cba6ab "test-dir"]]
But this:
(babashka.fs/create-dir "./.test-dir")
(babashka.fs/glob "." "**.test-dir")
Does not:
=> []
Could it perhaps have something to do with the . in the directory name? :thinking_face:

borkdude11:06:16

I'll get back to you later, busy...

leifericf11:06:33

No rush! Just leaving the info here in case it's useful, and to make a better bug report.

๐Ÿ‘ 2
leifericf11:06:16

FYI, all the info from this thread is gathered https://github.com/babashka/fs/issues/105.

๐Ÿ‘ 2