Skip to content

Commit

Permalink
Merge pull request #550 from DannyBen/refactor/private-commands
Browse files Browse the repository at this point in the history
Allow ad-hoc revealing of private commands, flags, and environment variables
  • Loading branch information
DannyBen authored Aug 15, 2024
2 parents 1b104a5 + f789858 commit af15e64
Show file tree
Hide file tree
Showing 34 changed files with 571 additions and 40 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.gem
/.yardoc
/coverage
/spec/coverage
/dev
/doc
/Gemfile.lock
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [conflicts](conflicts#readme) - defining mutually exclusive flags
- [needs](needs#readme) - defining flags that need other flags
- [command-private](command-private#readme) - hiding commands from the command list
- [private-reveal](private-reveal#readme) - allowing users to reveal private commands, flags or environment variables
- [stdin](stdin#readme) - reading input from stdin
- [filters](filters#readme) - preventing commands from running unless custom conditions are met
- [commands-expose](commands-expose#readme) - showing sub-commands in the parent's help
Expand Down
1 change: 1 addition & 0 deletions examples/private-reveal/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cli
181 changes: 181 additions & 0 deletions examples/private-reveal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Private Reveal Example

Demonstrates how to allow users to reveal any private commands, flags and
environment variables.

This example was generated with:

```bash
$ bashly init
$ bashly add settings
# ... now edit settings.yml to match the example ...
# ... now edit src/bashly.yml to match the example ...
$ bashly generate
```

<!-- include: settings.yml -->

-----

## `bashly.yml`

````yaml
name: cli
help: Sample application
version: 0.1.0

# All elements with `private: true` in this configuration will be hidden
# unless the environment variable SHOW_PELASE is set (as defined
# in ../settings.yml)

environment_variables:
- name: secret
help: Set secret key
private: true

flags:
- long: --debug
help: Enable debug mode
private: true

commands:
- name: admin
help: Admin operations
expose: true

commands:
- name: list
help: List connected devices
- name: reboot
help: Reboot
private: true
````

## `settings.yml`

````yaml
# When using private commands, flags, or environment variables, you may set
# this option to a name of an environment variable that, if set, will reveal
# all the private elements in the usage texts, as if they were public.
private_reveal_key: SHOW_PLEASE
````


## Output

### `$ ./cli`

````shell
cli - Sample application

Usage:
cli [OPTIONS] COMMAND
cli [COMMAND] --help | -h
cli --version | -v

Commands:
admin Admin operations



````

### `$ ./cli -h`

````shell
cli - Sample application

Usage:
cli [OPTIONS] COMMAND
cli [COMMAND] --help | -h
cli --version | -v

Commands:
admin Admin operations
admin list List connected devices

Global Options:
--help, -h
Show this help

--version, -v
Show version number



````

### `$ ./cli admin -h`

````shell
cli admin - Admin operations

Usage:
cli admin COMMAND
cli admin [COMMAND] --help | -h

Commands:
list List connected devices

Options:
--help, -h
Show this help



````

### `$ export SHOW_PLEASE=1`

````shell


````

### `$ ./cli -h`

````shell
cli - Sample application

Usage:
cli [OPTIONS] COMMAND
cli [COMMAND] --help | -h
cli --version | -v

Commands:
admin Admin operations
admin list List connected devices

Global Options:
--help, -h
Show this help

--version, -v
Show version number



````

### `$ ./cli admin -h`

````shell
cli admin - Admin operations

Usage:
cli admin COMMAND
cli admin [COMMAND] --help | -h

Commands:
list List connected devices

Options:
--help, -h
Show this help



````



4 changes: 4 additions & 0 deletions examples/private-reveal/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# When using private commands, flags, or environment variables, you may set
# this option to a name of an environment variable that, if set, will reveal
# all the private elements in the usage texts, as if they were public.
private_reveal_key: SHOW_PLEASE
4 changes: 4 additions & 0 deletions examples/private-reveal/src/admin_list_command.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
echo "# this file is located in 'src/admin_list_command.sh'"
echo "# code for 'cli admin list' goes here"
echo "# you can edit it freely and regenerate (it will not be overwritten)"
inspect_args
4 changes: 4 additions & 0 deletions examples/private-reveal/src/admin_reboot_command.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
echo "# this file is located in 'src/admin_reboot_command.sh'"
echo "# code for 'cli admin reboot' goes here"
echo "# you can edit it freely and regenerate (it will not be overwritten)"
inspect_args
29 changes: 29 additions & 0 deletions examples/private-reveal/src/bashly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: cli
help: Sample application
version: 0.1.0

# All elements with `private: true` in this configuration will be hidden
# unless the environment variable SHOW_PELASE is set (as defined
# in ../settings.yml)

environment_variables:
- name: secret
help: Set secret key
private: true

flags:
- long: --debug
help: Enable debug mode
private: true

commands:
- name: admin
help: Admin operations
expose: true

commands:
- name: list
help: List connected devices
- name: reboot
help: Reboot
private: true
18 changes: 18 additions & 0 deletions examples/private-reveal/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash

rm -f ./src/*.sh

set -x

bashly generate

### Try Me ###

./cli
./cli -h
./cli admin -h

export SHOW_PLEASE=1

./cli -h
./cli admin -h
1 change: 1 addition & 0 deletions lib/bashly.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module Script
module Introspection
autoloads 'bashly/script/introspection', %i[
Arguments Commands Dependencies EnvironmentVariables Examples Flags
Visibility
]
end
end
Expand Down
5 changes: 5 additions & 0 deletions lib/bashly/libraries/settings/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ partials_extension: sh
# required arguments
show_examples_on_error: false

# When using private commands, flags, or environment variables, you may set
# this option to a name of an environment variable that, if set, will reveal
# all the private elements in the usage texts, as if they were public.
private_reveal_key: ~

# Display various usage elements in color by providing the name of the color
# function. The value for each property is a name of a function that is
# available in your script, for example: `green` or `bold`.
Expand Down
1 change: 1 addition & 0 deletions lib/bashly/script/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Command < Base
include Introspection::EnvironmentVariables
include Introspection::Examples
include Introspection::Flags
include Introspection::Visibility

class << self
def option_keys
Expand Down
2 changes: 2 additions & 0 deletions lib/bashly/script/environment_variable.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Bashly
module Script
class EnvironmentVariable < Base
include Introspection::Visibility

class << self
def option_keys
@option_keys ||= %i[
Expand Down
1 change: 1 addition & 0 deletions lib/bashly/script/flag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Bashly
module Script
class Flag < Base
include Completions::Flag
include Introspection::Visibility

class << self
def option_keys
Expand Down
14 changes: 9 additions & 5 deletions lib/bashly/script/introspection/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ def command_aliases
def command_help_data
result = {}

public_commands.each do |command|
commands.each do |command|
result[command.group_string] ||= {}
result[command.group_string][command.name] = { summary: command.summary_string }
result[command.group_string][command.name] = {
summary: command.summary_string,
visibility: command.visibility,
}
next unless command.expose

command.public_commands.each do |subcommand|
command.commands.each do |subcommand|
result[command.group_string]["#{command.name} #{subcommand.name}"] = {
summary: subcommand.summary_string,
help_only: command.expose != 'always',
summary: subcommand.summary_string,
visibility: subcommand.visibility,
help_only: command.expose != 'always',
}
end
end
Expand Down
19 changes: 19 additions & 0 deletions lib/bashly/script/introspection/visibility.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Bashly
module Script
module Introspection
module Visibility
# Returns :public, :private, or :semi_private based on the `private`
# option of the host, in conjunction with `Settings.private_reveal_key`.
def visibility
if !options['private']
:public
elsif Settings.private_reveal_key
:semi_private
else
:private
end
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/bashly/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class << self
:config_path,
:lib_dir,
:partials_extension,
:private_reveal_key,
:show_examples_on_error,
:source_dir,
:strict,
Expand Down Expand Up @@ -54,6 +55,10 @@ def partials_extension
@partials_extension ||= get :partials_extension
end

def private_reveal_key
@private_reveal_key ||= get :private_reveal_key
end

def production?
env == :production
end
Expand Down
12 changes: 8 additions & 4 deletions lib/bashly/views/command/long_usage.gtx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
= view_marker

> if [[ -n $long_usage ]]; then
options_caption = public_commands.any? && public_flags.any? ? strings[:global_options] : strings[:options]
> if [[ -n "$long_usage" ]]; then
options_caption = strings[:options]
if commands.any? && (public_flags.any? || (flags.any? && Settings.private_reveal_key))
options_caption = strings[:global_options]
end

> printf "%s\n" "{{ options_caption.color(:caption) }}"
>
= render(:usage_flags).indent 2 if public_flags.any?
= render(:usage_flags).indent 2 if flags.any?
= render(:usage_fixed_flags).indent 2
= render(:usage_args).indent 2 if args.any? or catch_all.help
= render(:usage_environment_variables).indent 2 if public_environment_variables.any?
= render(:usage_environment_variables).indent 2 if environment_variables.any?
= render(:usage_examples).indent 2 if examples
= render(:footer).indent 2 if footer
>
Expand Down
Loading

0 comments on commit af15e64

Please sign in to comment.