Skip to content

help commands lists all custom commands as main... and more! #10707

@UliTroyo

Description

@UliTroyo

Describe the bug

When using help commands to list all available commands, all custom commands exported from a main function inside a module show up as "main", instead of correctly showing the module name as the command's name.

Weirdly, it will still show the command in the correct alphabetical position!

And upon further examination, more funny behavior emerges. I'll demonstrate in the How to reproduce section below.

How to reproduce

  1. Make the following test module as my_command.nu. Note the special usage comment above the exported main function:
# my_command.nu

# 🧩 My special usage comment.
export def main [] {
  print "wow!"
}
  1. Use the module:
use my_command.nu
  1. Check the commands list:
help commands | where usage =~ '🧩 My special usage comment.'
╭───┬──────┬──────────┬──────────────┬──────────────────────────────╮
 # │ name │ category │ command_type │            usage             │
├───┼──────┼──────────┼──────────────┼──────────────────────────────┤
 0  main  default   custom        🧩 My special usage comment. 
╰───┴──────┴──────────┴──────────────┴──────────────────────────────╯
        ^
Shouldn't I be called 'my_command'?
  1. If you check the command's help menu, even though we invoke it with my_command, under Usage the name still shows up as main:
my_command --help
🧩 My special usage comment.

Usage:
  > main

Flags:
  -h, --help - Display the help message for this command

Input/output types:
  ╭───┬───────┬────────╮
   # │ input │ output │
  ├───┼───────┼────────┤
   0  any    any    
  ╰───┴───────┴────────╯
  1. But the strangeness continues! Modify the my_command.nu file so that it now looks like below. Note that we now have three separate exported commands, each with slightly different naming conventions, and all with the same usage comment:
# my_command.nu

# 🧩 My special usage comment.
export def main [] {
  print "wow!"
}

# 🧩 My special usage comment.
export def "main two" [] {
  print "cool!"
}

# 🧩 My special usage comment.
export def "my_command three" [] {
  print "weird!"
}
  1. Let's use it again, this time importing everything:
use my_command.nu *
  1. Let's check the my_command help again. Note that we've gained one subcommand for main two, but not one for my_command three.
my_command --help
🧩 My special usage comment.

Usage:
  > main

Subcommands:
  main two - 🧩 My special usage comment.

Flags:
  -h, --help - Display the help message for this command

Input/output types:
  ╭───┬───────┬────────╮
   # │ input │ output │
  ├───┼───────┼────────┤
   0  any    any    
  ╰───┴───────┴────────╯
  1. We can't invoke main two by calling my_command two though!
my_command two --help
Error: nu::parser::extra_positional

  × Extra positional argument.
   ╭─[entry #18:1:1]
 1  my_command two --help
   ·            ─┬─
   ·             ╰── extra positional argument
   ╰────
  help: Usage: main
  1. We have to use main two instead. Note the command name main two under Usage:
main two --help
🧩 My special usage comment.

Usage:
  > main two

Flags:
  -h, --help - Display the help message for this command

Input/output types:
  ╭───┬───────┬────────╮
   # │ input │ output │
  ├───┼───────┼────────┤
   0  any    any    
  ╰───┴───────┴────────╯
  1. However my_command three works fine. Note the correct command name under Usage:
my_command three --help
🧩 My special usage comment.

Usage:
  > my_command three

Flags:
  -h, --help - Display the help message for this command

Input/output types:
  ╭───┬───────┬────────╮
   # │ input │ output │
  ├───┼───────┼────────┤
   0  any    any    
  ╰───┴───────┴────────╯
  1. And it gets really funky if we search for the commands by their usage comment. Notice that main two shows up before main, even though alphabetically it should be before. The reason is that in this table, all exported main functions show up in their correct alphabetical place. Thus, this output thinks the names are main two, my_command, and my_command three. If you had an exported main function from a module called aardvark.nu, it would probably show up first in the commands list, but with the name main.
help commands | where usage =~ '🧩 My special usage comment.'
╭───┬──────────────────┬──────────┬──────────────┬──────────────────────────────╮
 # │       name       │ category │ command_type │            usage             │
├───┼──────────────────┼──────────┼──────────────┼──────────────────────────────┤
 0  main two          default   custom        🧩 My special usage comment. 
 1  main              default   custom        🧩 My special usage comment. 
 2  my_command three  default   custom        🧩 My special usage comment. 
╰───┴──────────────────┴──────────┴──────────────┴──────────────────────────────╯

Expected behavior

The following behavior would be nice:

  1. Exported main functions in named modules could show the correct command name in the commands list and under the command's --help.
  2. Exported submodules like main two could be invokable under their correct command name as my_command two, and probably should not be invokable as main two. They could also not show up as main two in the commands list or under the command's --help.
  3. Exported submodules like my_command three could show up under the main command's --help under the Submodules heading.

Screenshots

No response

Configuration

key value
version 0.85.0
branch
commit_hash
build_os macos-x86_64
build_target x86_64-apple-darwin
rust_version rustc 1.72.0 (5680fa18f 2023-08-23)
rust_channel stable-x86_64-apple-darwin
cargo_version cargo 1.72.0 (103a7ff2e 2023-08-15)
build_time 2023-09-19 18:31:19 -04:00
build_rust_channel release
allocator mimalloc
features dataframe, default, extra, sqlite, trash, which, zip
installed_plugins dns query, highlight, inc, query, query json, query web, query xml

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A:help-systemRelated to help commands and our documentation system (not docs itself)A:modulesIssues related to functionality of the module system. See also usage:modulesA:scoping/name-resolutionHow Nu finds which variables/functions are in scope and to what they are boundcategory:bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions