Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure CLI by

This problem arose trying to run a Clojure project on WSL2 from a project originally built on Windoze.

The original :local/root paths started with "C:/..." but on WSL2 (running Ubuntu 22) they need to be converted to "/mnt/c/..." to run.

Manually changing them makes them work, but it's a hassle. Won't even mention source control woes.

Imagining automatic conversion rules feels dreadful, it would be better if we could simply specify OS-specific values. Maybe something like:

{some.ns/some-lib {:local/root 
                    {:local-path/windows "C:/..." 
                     :local-path/linux "/mnt/c/..." 
                     :local-path/macos "/some/other/dev/path"}}}

At runtime, the correct local-path should be selected for the value based on the OS on which the JVM is running.

Surely this can also be a problem on MacOS running Parallels, where file system integration is also tight but the Guest OS can have different values for the same paths on the Host. And knowing what these might be a priori is probably not practical, given the Cambrian explosion of Linux distributions, Windows editions, and MacOS versions. It would be the developer's responsibility to set these values based on a concrete development setup. So, IMHO, it would be enough optionally to offer some ability to provide a map with certain high-level OS options in place of a string.

It also seems obvious to me that these values will always be developer-centric and possibly subject to employer devops policies.

(Yes, this is my implementation bias, but I would gladly support any general way to handle this problem.)

1 Answer

0 votes

FWIW I would recommend just using relative paths for :local/root. Absolute paths are not necessary and just makes things complicated.

In my own setup I have all my projects in ~/code. So ~/code/project and ~/code/some-lib, in deps.edn I just use :local/root "../some-lib" from the project and everything works. Regardless of whether thats executing in WSL/Windows or whatever else.

I also have setups where everything is in the same ~/code/project and ~/code/project/packages/some-lib where I again just use :local/root "packages/some-lib" instead of the absolute path.

(Most of the projects actually still use project.clj, but the same method applies)

If you avoid absolute paths your entire problem goes away. ;)

For local project references this is what I do (everything off the same top-level working dir), of course. But is not always practical when dealing with third party vendor jar files. These can often be buried in long paths based on standard installation defaults, particularly on Windoze.
If they are regular JAR files you could copy them into the project? Like a `vendor` dir? I have done so in the past for things that weren't available via maven.

You could also move things into a host specific alias and have the user activate it accordingly. So just :aliases {:win {:extra-deps ...} :linux {:extra-deps ...}}`.
Most of the time they involve binaries besides the jar file.

However, the last point you made was helpful. Then just run it with the right alias. Is it possible to invoke multiple aliases? I don't think I ever tried. For example I have some JVM settings related to memory in custom aliases when I know I may need to run it with more RAM. In any case, thanks for that suggestion!
Yes, multile aliases are no problem. Just clj -A:foo:bar:etc.