cljr, the command line tool for ClojureCLR, is available for alpha testing.
Instructions for installing the tool and notes on what is implemented, work that remains to be done, etc., are on the README on the repo: https://github.com/clojure/clr.core.cli
If you don't feel like reading, here's the skinny:
(1) Have ClojureCLR installed as a tool.
(2)
dotnet tool install --global Clojure.Cljr --version 0.1.0-alpha1
(3) cd into your ClojureCLR app's root directory and invoke
cljr
from the command line to start a REPL.
If you have some tests to run, a deps.edn file along these lines:
{:paths ["src/main/clojure"]
:deps
{io.github.clojure/clr.data.generators {:git/tag "v1.1.0" :git/sha "d25d292"}}
:aliases
{:test
{:extra-paths ["src/test/clojure"]
:extra-deps {io.github.dmiller/test-runner {:git/tag "v0.5.1clr" :git/sha "814e06f"}}
:exec-fn cognitect.test-runner.api/test
:exec-args {:dirs ["src/test/clojure"]}}}}
will allow you to run tests using
cljr -X:test
It's an alpha release. My recent testing of libraries was all done this way, so at least that much works. Have at it.I hit this error:
(~/clojure)-(!2007)-> cljr
You must install or update .NET to run this application.
App: /home/sean/.dotnet/tools/cljr
Architecture: x64
Framework: '', version '6.0.0' (x64)
.NET location: /usr/share/dotnet
The following frameworks were found:
7.0.19 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Learn about framework resolution:
To install missing framework, download:
This is on Ubuntu and I've just been auto-updating via apt without paying attention to what dotnet stuff it has been updating...
I had .Net 6 and 8 covered. 7.0 hit end of life earlier this month, so I didn't have it in there. I can release another alpha with 7.0 coverage. I can do that now if you want to try it that way before updating.
NP. I installed NET 6.0 and now get this error:
(~/clojure)-(!2011)-> dotnet --list-runtimes
6.0.31 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
7.0.19 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
6.0.31 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
7.0.19 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Thu May 30 14:27:29
(~/clojure)-(!2012)-> dotnet --list-sdks
6.0.423 [/usr/share/dotnet/sdk]
7.0.409 [/usr/share/dotnet/sdk]
Thu May 30 14:27:33
(~/clojure)-(!2013)-> cljr
/home/sean/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha1/clojure.cljr/0.1.0-alpha1/tools/net6.0/any/tools/run-clojure-main.ps1 :
File \\wsl.localhost\Ubuntu-20.04\home\sean\.dotnet\tools\.store\clojure.cljr\0.1.0-alpha1\clojure.cljr\0.1.0-alpha1\tools\net6.0\a
ny\tools\run-clojure-main.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see
about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ /home/sean/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha1/clojure.clj ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess (I installed NET 8.0 as well but, of course, same error -- and I don't know enough about dotnet-on-Linux to know how to solve the above)
Setting ExecutionPolicy to RemoteSigned doesn't appear to be sufficient since run-clojure-main.ps1 is not signed.
(I'm a bit surprised it's trying to run PowerShell stuff at all, given I'm on Ubuntu)
These is a PS shell script to run clojure.main. If this is a problem, I'll have to figure out how to invoked clojure.main installed as a tool on Linux. (Anyone with a clue invited to help out.)
Is cljr a Clojure program?
(`clojure.main` isn't installed for me on Linux so what I typed before wouldn't work)
cljr is a C# program. It does a bunch of CLI arg processing, then starts clojure.main . I remember having difficulty getting the System.Diagnostics.Process to execute clojure.main directly. It seemed to have trouble invoking an installed dotnet tool. So I created the powershell script to do the invocation.
I'm open to suggestions on better ways to approach this.
You will definitely need clojure.main installed.
Ah, ok... So I missed a step somewhere... link to how to get clojure.main installed on Linux?
And you'll need the latest clojure.main -- 1.12.0-alpha9
There are some updates in the 1.12 code that are required to make it all work.
OK... found it...
dotnet tool install --global Clojure.Main --version 1.12.0-alpha9 I have done it and have it installed.
But not sure how to invoke it, which could be a problem.
Ah, on Linux it has to be Clojure.Main, not clojure.main -- it's been a while since I tried this!
So a .sh file for Linux with Clojure.Main $* and the .ps1 for Windows with clojure.main $args yes?
Well, that's really helpful. It says 'clojure.main' on the install.
(~/clojure)-(!2027)-> dotnet tool install --global --version 1.12.0-alpha9 Clojure.Main
Tool 'clojure.main' was successfully updated from version '1.12.0-alpha7' to version '1.12.0-alpha9'.
Thu May 30 17:54:11
(~/clojure)-(!2028)-> clojure.main
clojure.main: command not found
Thu May 30 17:54:14
(~/clojure)-(!2029)-> Clojure.Main
Clojure 1.12.0-alpha9
user=>I think as you say. sh for Linux and .ps1 for WIndows.
I really need to spend more time on WSL2. 😢
I installed it on the Windows side and still have that security error:
PS C:\Users\seanc> cljr
C:\Users\seanc\.dotnet\tools\.store\clojure.cljr\0.1.0-alpha1\clojure.cljr\0.1.0-alpha1\too
ls\net6.0\any\tools\run-clojure-main.ps1 : File C:\Users\seanc\.dotnet\tools\.store\clojure
.cljr\0.1.0-alpha1\clojure.cljr\0.1.0-alpha1\tools\net6.0\any\tools\run-clojure-main.ps1
cannot be loaded because running scripts is disabled on this system. For more information,
see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ C:\Users\seanc\.dotnet\tools\.store\clojure.cljr\0.1.0-alpha1\clojure ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccessIf you are brave enough:
powershell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
That has to be done for each session tho', right?
S C:\Users\dmill> cljr
WARNING: Use of :paths external to the project has been deprecated, please remove: .
Starting main
Clojure 1.12.0-alpha9
user=>
(~/clojure)-(!2031)-> powershell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
Thu May 30 18:04:22
(~/clojure)-(!2032)-> cljr
Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your computer. If
you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning message. Do you want to run
\\wsl.localhost\Ubuntu-20.04\home\sean\.dotnet\tools\.store\clojure.cljr\0.1.0-alpha1\clojure.cljr\0.1.0-alpha1\tools\net6.0\any\to
ols\run-clojure-main.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"): R
Execution error (FileNotFoundException) at System.Diagnostics.StackFrame/ (NO_FILE:0).
Could not locate clojure/tools/deps/script/make_classpath2 with extensions .cljr, .cljc, .clj, .cljr.dll, .cljc.dll, or .clj.dll on load path. Please check that namespaces with dashes use underscores in the Clojure file name.
Full report at:
C:\Users\seanc\AppData\Local\Temp\clojure-8484c54a-697a-4feb-99d7-528ab3302338.edn
Unhandled exception. System.IO.FileNotFoundException: Could not find file '/home/sean/clojure/.cpcache/3912492268DC336644D4DFB6EE915940.cp'.
File name: '/home/sean/clojure/.cpcache/3912492268DC336644D4DFB6EE915940.cp'
at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize)
at System.IO.File.InternalReadAllText(String path, Encoding encoding)
at System.IO.File.ReadAllText(String path)
at Cljr.Program.Main(String[] args) in C:\work\clojure\clr.core.cli\src\dotnet\Cljr\Program.cs:line 380
AbortedI think you can make it sticky.
But the better solution is to differentiate and use .sh vs .ps1 depending on context. I think.
It works on PS now
PS C:\Users\seanc> powershell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
PS C:\Users\seanc> cljr
WARNING: Use of :paths external to the project has been deprecated, please remove: .
Starting main
Clojure 1.12.0-alpha9
user=>
(but not WSL2 per above)> Ooops, the successful execution I showed was from the wrong terminal. Sigh.
I suspect the error on Linux is because of the split-brain filesystem when trying to run PS scripts on Linux -- so I expect it'll be solved by a .sh file.
Or maybe I did have the correct terminal.
The WARNING may be because of no deps.edn file?
Apparently need to run in PS. I get an error about not being able ro find one of the Clojure source files that are needed when I run directly from the WSL bash shell. (or whatever it is)
That could be a problem with the CLOJURE_LOAD_PATH that I set up not being compatible with Ubuntu. Maybe running cljr under Powershell on WSL/Ubuntu is the way to go?
Can I specify a different version of Clojure in deps-cljr.edn? :mvn/version isn't supported, right?
You cannot specify a different version of ClojureCLR. I don't know how to do that. (A brief discussion of the issue at the bottom of the README at clr.core.cli.)
No :mvn/version support. I doubt that I will go toward Maven support. I've not found helpful libraries for that in the .Net world. I'm not up to rolling my own from scratch.
PS Microsoft.PowerShell.Core\FileSystem::\\wsl.localhost\Ubuntu-20.04\home\sean\clojure> cljr -X:test
Starting exec/tool
Running tests in #{"test"}
Testing user
Ran 0 tests containing 0 assertions.
0 failures, 0 errors.
with deps-clr.edn:
{:path ["src"]
:aliases
{:test
{:extra-paths ["test"]
:extra-deps {io.github.dmiller/test-runner {:git/tag "v0.5.1clr" :git/sha "814e06f"}}
:exec-fn cognitect.test-runner.api/test}}}
in a PS window, I cd'd to the mounted Linux folder 🙂Let me summarize where I think we are (before I head off for a meal) re running under Ubuntu (for me, at least, WSL2/Ubuntu).
(1) make sure you have the latest alpha of clojure.main installed
(2) install the cljr tool using the dotnet tool install command.
(3) Running directly from the shell runs into two problems: (a) a permisson problem running the .ps1 script; (b) when you solve that problem (by setting the powershell execution policy) there is still a problem with cljr not being able to find some Clojure source. (Which is there, because next ...)
(4) cljr does seem to run under Powershell on Ubuntu.
Possible solution to the permission problem in item (3): use a .sh script on non-Windows, the .ps1 script on Windows. Remaining to be determined -- does this solve the missing file problem?
Are there tests to be run?
That seems to be correct (and, no, my test folder is empty -- but is required in order to run -X:test)
Ah, so that is good. So, what do think is a good way to proceed? Concede defeat and run under powershell?
If the cljr program can tell whether it is running on Windows or WSL2, it can select the .ps1 or .sh file to run Clojure.Main.
I can have that ready to test sometime tomorrow. (I have to go eat something now.) I already have a test for Windows in the code -- something about how command lines arguments are passed requires special handling -- picked that up from the Clojure(JVM) version of the CLI tool. Thanks for your effort.
Okay. I made the change to run a .sh script when not on Windows. The results are perplexing.
Here is a sequence of things I did, with some commentary.
Get rid of old install of Clojure.Cljr and install the latest version from my local machine:
$ dotnet tool uninstall Clojure.Cljr -g
Tool 'clojure.cljr' (version '0.1.0-alpha2') was successfully uninstalled.
$ dotnet tool install Clojure.Cljr -g --add-source /mnt/c/work/clojure/clr.core.cli/src/dotnet/Cljr/nupkg --version 0.1.0-alpha2
You can invoke the tool using the following command: cljr
Tool 'clojure.cljr' (version '0.1.0-alpha2') was successfully installed.
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$ diff /home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh run-it.sh
1c1
< Clojure.Main $*
---
> Clojure.Main $*
david@DESKTOP-IBDM5GL:~/test-cljr$ sh run-it.sh
Clojure 1.12.0-alpha9
user=>
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$ cat >run-it2.sh
Clojure.Main $*
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$
david@DESKTOP-IBDM5GL:~/test-cljr$ sh run-it2.sh
Clojure 1.12.0-alpha9
user=>
david@DESKTOP-IBDM5GL:~/test-cljr$ sh /home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh
/home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh: 1: Clojure.Main: not found
Make sure I have Clojure.Main installed.
$ Clojure.Main
Clojure 1.12.0-alpha9
user=>
$
Try running cljr:
$ cljr
/home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh: 1: Clojure.Main: not found
run-clojure-main.sh has the file contents you suggested:
$ more /home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh
Clojure.Main $*
If I try to sh it by hand, I get the same error message.
However, if I sh a local copy, it works.
$ diff /home/david/.dotnet/tools/.store/clojure.cljr/0.1.0-alpha2/clojure.cljr/0.1.0-alpha2/tools/net8.0/any/tools/run-clojure-main.sh run-it2.sh
1c1
< Clojure.Main $*
---
> Clojure.Main $*
david@DESKTOP-IBDM5GL:~/test-cljr$ sh run-it2.sh
Clojure 1.12.0-alpha9
user=>
Well, though they look pretty similar, there is a difference. (I made a local copy of run-clojure-main.sh named run-it3.sh:
$ hd run-it2.sh
00000000 20 43 6c 6f 6a 75 72 65 2e 4d 61 69 6e 20 24 2a | Clojure.Main $*|
00000010 0a |.|
00000011
$ hd run-it3.sh
00000000 ef bb bf 43 6c 6f 6a 75 72 65 2e 4d 61 69 6e 20 |...Clojure.Main |
00000010 24 2a 0d 0a |$*..|
An extra space in run-it2.sh -- I was testing to see if the space I thought I had at the beginning was a problem -- but that ef bb bf at the beginning of the script file being delivered with cljr -- Oh, that just hurts.
You do not want to know how much time those invisible bytes cost me.
So, trying again:
$ dotnet tool uninstall Clojure.Cljr -g
Tool 'clojure.cljr' (version '0.1.0-alpha2') was successfully uninstalled.
$ dotnet tool install Clojure.Cljr -g --add-source /mnt/c/work/clojure/clr.core.cli/src/dotnet/Cljr/nupkg --version 0.1.0-alpha2
You can invoke the tool using the following command: cljr
Tool 'clojure.cljr' (version '0.1.0-alpha2') was successfully installed.
$ cljr
Starting main
Clojure 1.12.0-alpha9
user=>
$ cljr -X:test
Starting exec/tool
No function found on command line or in :exec-fn
;; To be expected -- the deps.edn in this directory is minimal, no test alias
I'll get alpha2 released within the hour.So it had a UTF-8 BOM at the beginning. What editor did you create it with?
Visual Studio. I didn't even think about it. I went back out and edited it in Notepad++. Even there, the BOM doesn't appear. There is a command to convert to ASCII that gets rid of the BOM.
Interesting. I use VS Code and I've never seen it add a BOM. Maybe there's a setting to disable that? It'll mess up a lot of tooling that tries to read files.
> open File menu and select "Advanced save options" and there you should select "UTF-8 without signature" (and that also answered your last question 🙂. Yes "UTF-8 without signature" is same as without BOM
That would do it.
And in VS Code, there's also a default encoding setting:
I'll be changing those.