casey / just

πŸ€– Just a command runner
https://just.systems
Creative Commons Zero v1.0 Universal
18.41k stars 421 forks source link

Problem setting up Nushell on Windows #2137

Open sim4life opened 3 weeks ago

sim4life commented 3 weeks ago

Using the alacritty v0.13.2 terminal, I'm trying to write Nushell v0.93.0 specific commands in my justfile on Windows 11 23H2. My justfile looks like:

for:
  for file in `ls .`; do echo $file; done

for2:
  for direc in `ls -s . | where type == dir | get name`; do \
    echo $direc; \
  done

$ just for

runs fine

$ just for2

/usr/bin/bash: line 1: get: command not found INFO: Could not find "type". INFO: Could not find "==".

It seems that justfile is interpreting ls -s . | where type == dir | get name as a bash command when I want it to be interpreted as Nushell command. If I start my justfile with

set shell := ["nu", "-c"] OR set shell := ["nu", "--env-config", "~\\.config\\nushell\\env.nu", "--config", "~\\.config\\nushell\\config.nu", "-c"] OR I change the recipe to:

for2:
  #!nu
  for dir in `ls -s . | where type == dir | get name`; do \
    echo $dir; \
  done

then it reports the following error:

Error: nu::parser::keyword_missing_arg Γ— Missing argument to in. ╭─[C:\Users\myusername\AppData\Local\Temp\just-UQzDXm\for2:13:13] 12 β”‚ 13 β”‚ for direc in ls -s . | where type == dir | get name; do \ Β· β–² Β· ╰── missing any value that follows in 14 β”‚ echo $direc; \ ╰──── error: Recipe for2 failed with exit code 1

Any suggestions on setting up windows and Nushell cross-platform justfile scripting?

potterxu commented 3 weeks ago

Hi @sim4life ,

Although I am not very familiar with Nushell, I just tried executing the command you provided directly in Nushell

~> for dir in "ls -s . | where type == dir | get name"; do echo $dir; done                      1 06/07/2024 06:00:29 PM
Error: nu::parser::keyword_missing_arg

  Γ— Missing argument to `in`.
   ╭─[entry #21:1:11]
 1 β”‚ for dir in "ls -s . | where type == dir | get name"; do echo $dir; done
   Β·           β–²
   Β·           ╰── missing any value that follows in
   ╰────

I don't think it is a valid nushell script

potterxu commented 3 weeks ago

Check https://www.nushell.sh/book/control_flow.html#for for a valid for loop sytax in nushell

for file in (ls .) {
  print $file
}

for direc in (ls -s . | where type == dir | get name) {
  print $direc
}
starthal commented 3 weeks ago

set shell applies to the shell used for linewise recipes as well as backticks.

So when you set the shell to Nushell, you should write recipe lines in Nushell as well.

If you want to mix Bash and Nushell recipes, set shell to one and use shebang recipes for the other.

If you want to mix Bash and Nushell in the same recipe, you need to call out explicitly from one to the other. You could do this indirectly through just:

set shell := ['nu', '-c'] 

# Nu script
list-dir-names:
    ls -s . | where type == dir | get name

# Bash script
for:
    #!/usr/bin/env bash
    set -euxo pipefail
    for direc in $(just list-dir-names); do echo $direc; done

I don't see a reason to ever do this, but it is possible.

sim4life commented 2 weeks ago

Thanks for the replies: The syntax

for3:
  for direc in (ls -s . | where type == dir | get name) { echo $direc }

was giving me an error:

for3: -c: line 1: syntax error near unexpected token `('

I did NOT intend to mix n match nushell and bash syntax but it seems that the backticks shell command syntax ignores rest of the global shell settings in justfile and chooses bash in Windows. So I ended up completely replacing justfile for-loop syntax with nushell for-loop syntax like:

for2:
  #!nu
  ls -s . | where ($it | $it.type == dir) | get name
casey commented 2 weeks ago

Can you post a complete justfile, along with the error message you're getting? I want to make sure I understand the problem.

starthal commented 2 weeks ago

One clarification to my previous comment: backticks within a recipe line are not preprocessed by just in any way. They are interpreted by the shell normally. So backticks in bash will execute the enclosed command in a subshell, while backticks in Nu just indicate a string.

The only syntax that causes just to change the text of a recipe is {{ }}. After those substitutions are made, the resulting script is interpreted by the shell directly.

potterxu commented 2 weeks ago

@sim4life

Are you referencing the for loop section in the readme and you think you are using a justfile for loop syntax?

for2:
  for direc in `ls -s . | where type == dir | get name`; do \
    echo $direc; \
  done

with your above justfile, you are expecting that

right?

but the for loop section in the readme is actually describing how to write a multi-line constructs in the justfile, and it is taking bash as an example. (which means there is no justfile-syntax for loop, the example is bash for loop)

so, you are trying use so-called "justfile-syntax" for loop and nu command in backticks. However, it is actually mixing a bash for-loop and a nushell command in the backticks.

@casey @starthal Please correct me if I am wrong