chef-workstation icon indicating copy to clipboard operation
chef-workstation copied to clipboard

Simplify and Improve Shell Init

Open tas50 opened this issue 3 years ago • 4 comments

Currently, we use the 'chef shell-init SHELL_NAME' command to generate shell-specific chef setup commands. This generation is performed once by the user and they add the output to their shell RC init script. There's a few problems with the current approach:

  • Since the 'chef shell-init' command is written in ruby it's very slow and we can't have users include it directly in their shell rc scripts. Instead we have to instruct the user to add the output to their RC script, which adds more complexity
  • Since the process of adding the content to the rc script is a one-time process we can't update the content (including auto-completes) later. When we change chef CLI commands the auto completes will be wrong
  • The shell init command requires the user to know their shell (bash vs. zsh vs. fish), which many users don't know

Proposed solution

Include a new shell init shell script at /opt/chef-workstation/bin/chef-shell-init and symlink it to the appropriate dirs to match our other commands. This will be a shell script instead of a Ruby command and will run on bash, zsh, and fish shells. It will autodetect the currently running shell and output the correct shell init commands. The commands will match the current output of the 'chef shell-init' command for each shell.

tas50 avatar Apr 04 '21 21:04 tas50

The usage on the command line to modify the env vars of the current shell should be:

shell% . chef-shell-init

There should probably be a flag to make it permanent that just appends that command to the right rc file based on the users shell:

shell% . chef-shell-init --permanent

The script should probably live in both /opt/chef-workstation/bin and /opt/chef-workstation/embedded/bin along with a symlink into /usr/bin (or /usr/local/bin for mac or whatever, whatever we do on the given platform)

This ensures that the script is always going to be in the users PATH.

Requirements driving this design:

  • The dot is necessary in order to modify the currently running subshell, and this keeps it easy for users to opt-in only for a subshell
  • The user knowing their shell or knowing where their rc files are is not required (this generally takes a PhD)
  • Not using ruby
  • Short commands that are easy to document and/or memorize

lamont-granquist avatar Apr 04 '21 22:04 lamont-granquist

I updated the description to reference the bin dir and the symlinks. I'm not sure if this is something we'd expect most users to run directly although they totally could. I kind of want to avoid yet another totally different command that folks need to know since that's been a pretty common complaint with customers. We can make the existing chef shell-init sub command execute the chef-shell-init shell script if no args were passed and if --permanent was passed it would handle shoving the chef-shell-init into the appropriate rc file. That way the shell script can remain 100% focused on the env var and autocomplete setup and fun things like parsing existing rc scripts can be done in a nice language.

tas50 avatar Apr 05 '21 00:04 tas50

There maybe a couple more I haven't found yet, but see also:

https://github.com/chef/chef-workstation/issues/1505 https://github.com/chef/chef-workstation/issues/1698

Best if we could get this script generated in an automated way based on current CLI state. It would go well with work in flight to convert the tooling to use cobra for CLI help and info, because that framework can generate shell completion scripts for all platforms (including windows). Some work to be done to see if it can do it all ahead of time, as it seems mostly intended to be interactive.

If we can't auto-generate, we'll need to make sure updating it doesn't fall through the cracks as the shape of the CLI evolves

marcparadise avatar Apr 05 '21 15:04 marcparadise

Phase 1 of this work:

Create a new omnibus software definition that creates a chef-shell-autocompletions script. This script will include just the autocompletion logic for sh, bash, fish, and zsh with appropriate shell logic to add the right autocomplete based on shell. The existing chef shell-init command will then get updated to reference this new script instead of spitting out all the autocompletions via ruby.

tas50 avatar May 19 '21 15:05 tas50