Skip to content

cark/clojure-windows-cli-issues

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 

Repository files navigation

The issues

A few problems were introduced with the choice of using Poweshell scripts on Windows for the clojure cli.

  • Quote escaping : 3 escaping rules when using from cmd.exe. Escaping different from Posix systems even from Powershell only.
  • Incompatible command line between Powershell and Posix, even worse from cmd.exe
  • Quoting issues cannot be fixed on Powershell
  • Powershell startup time tax
  • Cider cannot “jack-in” a deps.edn project, slowing deps.edn adoption.
  • Shadow-clj doesn’t work on Windows with a deps.edn project, slowing deps.edn adoption. (this was fixed, shadow-cljs now invokes powershell directly)
  • Cannot create a clojure batch file or exe in the path because of Powershell aliases discovery causing infinite recursion on first invocation from Powershell
  • Competing implementation would probably go away if we fix this
  • Need to lower Powershell security by changing global script execution policy
  • Current installation process is clunky, and not “Windows idiomatic”

These are not bugs

Those issues are not bugs.

  • They cannot be fixed as long as we use Powershell
  • Almost every issue goes away with a binary wrapper around the Powershell scripts.
  • Every single one of those issues goes away with a binary rewrite of the Powershell/bash scripts

Works with my workflow

I’m of the opinion that “works with my workflow” isn’t good enough. Workflows differ, issues are real and are quite easily fixable.

Solutions

The goal is to make the dev tools work, that means the command line must work from a regular command shell, and the quoting must ressemble the one on unix. There are several levels of solutions.

  • We can completely rewrite the powershell scripts in some other language.
  • We can keep these around but write a wrapper for their invocation from the regular command line.
rewritewrapper
work is already donebadgood
some problems might persistgoodbad
previous testing is lostbadgood
performance penaltygoodslightly bad depending on language
System complexitygoodbad (more pieces)
Powershell performance taxgoodbad
The low hanging fruitbadgood

Wrapper

The goal would be to create both a clojure and clj commands, and place these in the path.

  • We can invoke directly the powershell command, facing the 3 quote escaping rules
  • Create a temporary ps1 file, having to contend with only 2 escaping rules at a time, but do so twice.
  • Use the -EncodedCommand powershell command line

Light parsing of the command line is required for maximum Posix compatibility

batch/cmd filesCompiled.net CompiledGraalVM exe
can do temp filesbadgoodgoodgood
can deal with escapingbadgoodgoodgood
performance (run time)goodgoodwe’re using .net with poweshell so very slightly less goodgood
ease of usegoodgoodgoodbad (at time of writing)
ease of buildgooddependsbadbad
know-howgooddependsdependsdepends
complexitybaddependsbadbad

I went ahead and made an exploratory wrapper using Nim. Been using -EncodedCommand, thus avoiding the temp file. Works well for me at least !

Rewrite

We can completely sidestep the powershell issues.

batch/cmd filesGit bashcompiled (c, c++, D, rust, nim, pascal!).net compiled (c#, f#, what else is there?)GraalVM exe
self-containedbadbadgoodgood? (dll problems ?)
ease of port/maintenancebadgoodCan do it in a portable waywe have the powershell implementation that’s a thin .net wrapper : goodishcan use clojure so good i guess ?
caching/avoid launching javabadgoodgoodgoodit is java, but should be fast
0 to clojure time (newbies)goodbadgoodgoodi don’t know
professional ease of usegooddependsgoodgooddon’t know
performancegoodgoodgoodbad .net is also slow to startgood
can be done at allbadgoodgoodgoodgood
know-howgooddependsdependsslightly better, c# so easy, good standard libborkdude is our specialist !
available servicesvery badgood enoughdependsvery goodgood
a joy to work withbadnopedependsdependsgood
build processgoodgoodCan do it in a portable waydependsdon’t know
ease of feature paritybadgoodgood i we make it the main implementationbadclojure so good
ease of maintenancebadgoodgood if portablemediumgood
can use it on unix toonoyesyes if portablenot in a self contained mannergood
clojure all the way downnononopossiblyyes

I went ahead and made a portable implementation using Nim. Tested on Windows and Linux.

My opinion

I leaned toward a compiled wrapper, and made one to explore the possibility : exploratory wrapper using Nim. Been using -EncodedCommand, thus avoiding the temp file. It works well enough, but we’re still paying the Powershell performance tax this way, we also still face the Alias discovery Powershell bug.

IMO the perfect solution is the portable compiled rewrite of the shell script. An example of what it could look like is here : portable implementation.

Disclaimer

  • I’m not entirely certain if this fulfills Alex Miller’s requirements.
  • I winged it on many table cells, i expect some help in filling/amending those judgment calls and adding more dimensions.
  • English is not my native language, so yeah approximate spelling !
  • I left out the installation part, I made a tentative native windows installer containing the exploratory wrapper and powershell modules

About

weighting our options

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published