clj-on-windows

For those interested in making clj on Windows https://dev.clojure.org/jira/browse/TDEPS-67. Also see https://github.com/littleli/scoop-clojure.
seancorfield 2019-07-21T00:20:12.003300Z

Likewise. Windows 10 laptop with Powershell clj installed. If you provide detailed instructions to attempt to repro, I'll try it...

dominicm 2019-07-21T04:57:54.005Z

with a main.clj like:

(ns main)

(defn -main
  [& args]
  (prn args))
running clj -i main.clj -m main -C:dev should output ("-C:dev"), but for windows users I expect it would output ("-C:", "dev"). This isn't quite the same, but I assume it's close enough.

seancorfield 2019-07-21T05:23:35.005900Z

PS C:\Users\seanc\clojure\dom> clj -m example.main -C:dev
(-C: dev)
PS C:\Users\seanc\clojure\dom> clj -m example.main '-C:dev'
(-C:dev) 

seancorfield 2019-07-21T05:25:13.006800Z

I guess I'm not surprised that Windows needs the argument quoted really, given some of the weirdness of invoking PS scripts.

dominicm 2019-07-21T05:26:39.007400Z

I guess the weird thing for me is that clj works properly here? e.g. for clj -C:dev -m example.bar

dominicm 2019-07-21T05:26:53.007700Z

out of curiosity, is this isolated to -C:?

dominicm 2019-07-21T05:27:43.008500Z

I'm still uncertain whether this is a powershell issue or a clj issue. I'm leaning towards the latter due to the fact that clj -C:dev is parsed correctly (I'm assuming at least!)

seancorfield 2019-07-21T05:29:19.008900Z

It's to do with how main opts are passed through the running program.

seancorfield 2019-07-21T05:30:05.009500Z

PS doesn't know what you're doing so it parses the arguments for you -- the ' around it defeat that.

seancorfield 2019-07-21T05:30:48.010100Z

If you try to specify deps on the cmd line for clj on PS, you need to triple up the double quotes around the version as I recall... it's definitely annoying.

dominicm 2019-07-21T05:32:11.010900Z

Just so I'm certain though, clj -C:dev results in the expected arguments going to the tdeps classpath calculator?

seancorfield 2019-07-21T05:35:49.011900Z

But clj -C :dev is also valid.

dominicm 2019-07-21T05:37:08.012200Z

For sure, but isn't what is written in most documentation.

dominicm 2019-07-21T05:37:40.013Z

I'm still confused as to why PS decides to parse arguments in [main-opt] but not to clj itself.

seancorfield 2019-07-21T05:37:42.013200Z

Right. But that's how it works on windows

seancorfield 2019-07-21T05:37:58.013600Z

It parses them in both cases

seancorfield 2019-07-21T05:38:47.014600Z

clj -C :dev does not work on Mac / Linux but it does work on Windows

seancorfield 2019-07-21T05:40:27.015800Z

If you need -C:dev passed into your code, you need '-C:dev'

dominicm 2019-07-21T05:43:00.016400Z

it does work on mac/linux 🙂

dominicm 2019-07-21T05:43:30.016900Z

are you saying that when using clj on windows, you always put the space between, e.g. clj -C :dev?

seancorfield 2019-07-21T05:44:24.017900Z

When I type clj -C :dev on Linux it doesn't work

seancorfield 2019-07-21T05:45:34.018900Z

I get Missing required argument for "-C ALIASES" on Linux

seancorfield 2019-07-21T05:46:17.019800Z

On windows it behaves exactly like clj -C:dev

seancorfield 2019-07-21T05:48:33.020200Z

Another Windows PS weirdness with quoting

PS C:\Users\seanc\clojure\dom> clj -Sdeps '{:deps {seancorfield/next.jdbc {:mvn/version """1.0.2"""}}}'
Downloading: seancorfield/next.jdbc/1.0.2/next.jdbc-1.0.2.pom from <https://repo.clojars.org/>
Downloading: seancorfield/next.jdbc/1.0.2/next.jdbc-1.0.2.jar from <https://repo.clojars.org/>
Clojure 1.10.1
user=&gt; ^Z
PS C:\Users\seanc\clojure\dom&gt; clj -Sdeps '{:deps {seancorfield/next.jdbc {:mvn/version "1.0.2"}}}'
Error while parsing option "--config-data {:deps {seancorfield/next.jdbc {:mvn/version 1.0.2}}}": java.lang.NumberFormatException: Invalid number: 1.0.2
PS C:\Users\seanc\clojure\dom&gt;

seancorfield 2019-07-21T05:48:41.020400Z

Crazy CR/LF fixed!

dominicm 2019-07-21T05:51:44.021600Z

I think it used to work on Linux. I agree it doesn't now. It's weird because it's just tools.cli in use.

seancorfield 2019-07-21T05:52:20.021900Z

No, not for the shell script itself (`clj`)

dominicm 2019-07-21T05:52:38.022200Z

ah, there's preparsing. I see.

dominicm 2019-07-21T05:54:58.023500Z

Just so I am 100% certain I understand. Is there something in clojure.ps1 that converts -A: foo into -A :foo? Or in windows is it just expected that users will type something different?

seancorfield 2019-07-21T05:58:03.024100Z

I didn't say -A: foo is treated like -A :foo.

seancorfield 2019-07-21T05:59:03.024700Z

I think there are several things at play here. clj allows for the leading : to be omitted on an alias.

seancorfield 2019-07-21T05:59:08.024900Z

(on all platforms)

seancorfield 2019-07-21T05:59:30.025400Z

So clj -Cdev and clj -C:dev are treated the same -- by clj.

seancorfield 2019-07-21T06:00:17.026100Z

Windows PS parses -C:dev as -C: dev and then ignores the the : after -C

seancorfield 2019-07-21T06:00:31.026400Z

so clj sees -C dev

dominicm 2019-07-21T06:11:10.027900Z

Ah!

dominicm 2019-07-21T06:12:25.028600Z

so to match tdeps behavior in pack I need to also ignore the trailing : somehow. :thinking_face:

seancorfield 2019-07-21T06:13:07.029Z

That isn't tdeps behavior, per se.

seancorfield 2019-07-21T06:13:20.029300Z

I suspect that is PS script behavior.

dominicm 2019-07-21T06:14:12.029900Z

if it was general PS script behavior, then it would also happen in the argument passed to pack.

seancorfield 2019-07-21T06:15:13.030600Z

But I thought you said that -C:aot was being passed to pack as -C: aot separately?

seancorfield 2019-07-21T06:15:58.031300Z

And the println example shows that -C:dev is parsed -- by PS -- as -C: dev two separate args

dominicm 2019-07-21T06:17:54.032700Z

It is being passed to pack separately. Did I misunderstand you, I thought you meant that it was general PS script behavior, do you mean that it's clojure ps script behavior?

seancorfield 2019-07-21T06:18:34.033Z

I think it's PS behavior.

dominicm 2019-07-21T06:19:30.034800Z

elseif ($arg.StartsWith('-R')) {
      $aliases, $params = $params
      if ($aliases) {
        $ResolveAliases += ":$aliases"
      }
    }
The use of "StartsWith" makes this interesting 🙂

seancorfield 2019-07-21T06:19:42.035100Z

But it doesn't matter with clj because a) the leading : can be omitted on aliases because that's what clj does on all platforms and b) the trailing : doesn't matter in the PS script for clj.

seancorfield 2019-07-21T06:20:27.035800Z

Right. The clj script only cares about the leading character.

dominicm 2019-07-21T06:20:52.036600Z

I wonder if this works on windows: -Ranything foo

seancorfield 2019-07-21T06:21:13.037100Z

My point is that Windows users of clj need to get used to "weird" quoting and already have to triple-quote versions in -Sdeps for example.

seancorfield 2019-07-21T06:21:49.037600Z

PS C:\Users\seanc\clojure\dom&gt; clj -Cand_anything_you_want dev
Error building classpath. Specified aliases are undeclared: [:dev]
PS C:\Users\seanc\clojure\dom&gt;

dominicm 2019-07-21T06:22:00.037900Z

cool, it works

dominicm 2019-07-21T06:23:12.039400Z

Here's the difference between the -Sdeps case and the -C: case

clj -A:pack -m pack.main -C:foobar
      ^ works on win       ^ does not work on win
The syntax works in one place, and not the other.

2019-07-21T06:23:14.039600Z

fwiw: https://clojure.atlassian.net/browse/TDEPS-133

seancorfield 2019-07-21T06:24:19.040400Z

@dominicm Because that cmd line is actually passed in as

clj -A: pack -m pack.main -C: foobar

seancorfield 2019-07-21T06:24:39.041Z

It's absolutely consistent.

dominicm 2019-07-21T06:25:04.041500Z

@seancorfield I know, but then clojure.ps1 massages it to -A:pack -m pack.main -C: foobar So the massaging happens in one place but not the other. Which makes perfect sense now I've read the source.

seancorfield 2019-07-21T06:25:35.041700Z

No, it doesn't.

seancorfield 2019-07-21T06:26:06.042500Z

The PS script knows that the arguments are parsed and passed in separately.

seancorfield 2019-07-21T06:26:54.043600Z

PS C:\Users\seanc\clojure\dom&gt; clj -Cand_anything_you_want:dev
Error building classpath. Specified aliases are undeclared: [:dev]
PS C:\Users\seanc\clojure\dom&gt;

dominicm 2019-07-21T06:27:15.044200Z

isn't that what this code does?

elseif ($arg.StartsWith('-R')) {
      $aliases, $params = $params
      if ($aliases) {
        $ResolveAliases += ":$aliases"
      }
    }
If $arg (`-R:`) starts with "-R", then get the next param "foobar" and add to the arguments, :foobar

seancorfield 2019-07-21T06:27:26.044400Z

The cmd line is parsed to clj -Cand_anything_you_want: dev by Windows/PS.

👍 1
seancorfield 2019-07-21T06:27:48.045100Z

The clj shell script checks the first two chars (`-C`) and ignores the rest.

seancorfield 2019-07-21T06:28:09.045600Z

The shell script gets the next argument as the params for that.

seancorfield 2019-07-21T06:28:53.046500Z

So the issue is that tools.cli does not accept -A: aot as being the same as -A:aot and so it parses it "incorrectly"...

seancorfield 2019-07-21T06:29:59.047500Z

So... as I said... Windows requires extra quoting to override the PS parsing... so that strings are passed into tools.cli (in pack) as-is.

dominicm 2019-07-21T06:31:10.048900Z

Communicating on the internet is hard 😄 I am confident I understand the behavior now, and I think you do too. I guess my wording isn't communicating what I'm trying to say very well.

seancorfield 2019-07-21T06:31:26.049300Z

(and it's no surprise because you already have to say """1.0.2""" to get "1.0.2" in -Sdeps on Windows)

carkh 2019-07-21T06:31:39.049600Z

on ps

seancorfield 2019-07-21T06:31:56.050300Z

My suggestion: tell Windows users of pack to wrap options in ' quotes '

dominicm 2019-07-21T06:33:06.051700Z

that makes copy/paste harder. I was actually thinking of implementing the ps1 code above at the java-level. By aliasing -R: to -R.

carkh 2019-07-21T06:33:19.052200Z

cmd users do not have this problem, though they have other ones

seancorfield 2019-07-21T06:33:54.053600Z

Any cmd user trying to run clj is going to have even worse problems @carkh

seancorfield 2019-07-21T06:34:17.054500Z

We're not talking about lein/`boot` here. Just clj.

carkh 2019-07-21T06:34:18.054600Z

there is the unofficial command line, works great

dominicm 2019-07-21T06:34:53.055200Z

I guess that's not my full reason. My full reason is that -Sdeps is an escaping issue with the shell, and if pack took a -Sdeps flag, it would work the same as clj's does. In this case, clj is "fixing" the options to make -R:foo behave like it does on Linux, I'd like pack to look & feel like clj does.