Skip to content

Commit a466a52

Browse files
committed
Version 1.0.1.0
1 parent ce3891b commit a466a52

File tree

66 files changed

+774
-86
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+774
-86
lines changed

Docs/PowerCommandDesignAttribute.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# PowerCommandsDesign Attribute
22
## Always describe your Commands
3-
Be kind to your consumer as it often turn out to be you that are the consumer, fill in a shourt description of what the PowerCommand is doing and how to use it.
3+
Be kind to your consumer as it often turn out to be you that are the consumer, fill in a short description of what the PowerCommand is doing and how to use it.
44
This is easy with the usage of the PowerCommandsAttribute, just apply them on the top of your class definition.
55

66
Now lets take a practical example...
@@ -11,7 +11,7 @@ This is how the PowerCommandAttribute look like, to help the user consume this c
1111

1212
![Alt text](images/power_command_attribute.png?raw=true "Attribute")
1313

14-
When the user running this applikcation and wants to now more about the Convert command, he or she just types either:
14+
When the user running this application and wants to now more about the Convert command, he or she just types either:
1515

1616
```describe convert```
1717

@@ -22,18 +22,18 @@ And this help will be displayed:
2222

2323
![Alt text](images/help_convert_command.png?raw=true "Describe convert command")
2424

25-
### A clooser look on the syntax
25+
### A closer look on the syntax
2626
```
2727
[PowerCommandDesign( description: "Converting yaml format to json or xml format",
2828
options: "!path|format",
2929
example: "//Convert to json format|convert --path \"c:\\temp\\test.yaml\" --format json|//Convert to xml format|convert --path \"c:\\temp\\test.yaml\" --format xml")]
3030
```
31-
The user can use this command like this (note that argument and quotes are not described in the attribute beacause this command do not use them):
31+
The user can use this command like this (note that argument and quotes are not described in the attribute because this command do not use them):
3232

3333
![Alt text](images/Command_line_input_described.png?raw=true "Describe convert command")
3434

3535
## Mark argument, quote, option or secret as required with **!** character
36-
If you look close at the example above you see two **options** are declared like this **!path** and **format** the **!** character before the option name tells the Core Runtime that this option requires a value and it will be validated before the command Run methods executes, if he user ommits the **path** option value this will occur:
36+
If you look close at the example above you see two **options** are declared like this **!path** and **format** the **!** character before the option name tells the Core Runtime that this option requires a value and it will be validated before the command Run methods executes, if he user omits the **path** option value this will occur:
3737

3838
![Alt text](images/convert_validation_error.png?raw=true "Describe convert command")
3939

@@ -43,9 +43,9 @@ Describe your arguments, separate them with | use // to display a commented line
4343
### quotes
4444
Describe your quotes, separate them with | use // to display a commented line over the actual quote.
4545
### suggestion
46-
Suggestion will be added to the autocomplete functionallity so the user could use tab to cycle trough the commands and commands with a suggested argument.
46+
Suggestion will be added to the autocomplete functionality so the user could use tab to cycle trough the commands and commands with a suggested argument.
4747
### Options
48-
Describe your options, separate them with | use // to display a commented line over the actual option, all options that are described will also be used by the autocomplete functionallity to help the user find the right option.
48+
Describe your options, separate them with | use // to display a commented line over the actual option, all options that are described will also be used by the autocomplete functionality to help the user find the right option.
4949
Read more about [options](Options.md).
5050
### secrets
5151
Describe your secrets that the commands needs, you probably want to declare a secret as required with **!** character, in the sample above secret **cnDatabase** is marked as required.
@@ -59,7 +59,7 @@ Read more about how to manage [Secrets](Secrets.md).
5959
Describe examples on how to use the command, separate them with | use // to display a commented line over the actual example.
6060

6161
### Separator and comments
62-
options, quotes, arguments and example all have a property on the PowerCommandAttribute, each item are separeted with | and if you want to put a comment row before your item add this with the prefix //, if you look at the example it is used to describe two examples of usage.
62+
options, quotes, arguments and example all have a property on the PowerCommandAttribute, each item are separated with | and if you want to put a comment row before your item add this with the prefix //, if you look at the example it is used to describe two examples of usage.
6363

6464
example: "**//Convert to json format**|convert --path \"c:\\temp\\test.yaml\" --format json|**//Convert to xml format**|convert --path \"c:\\temp\\test.yaml\"
6565

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Use Toolbar to guide the user
2+
3+
![Alt text](images/toolbar.png?raw=true "Toolbar")
4+
5+
With the toolbar you have the possibility to design your command with the use of labels in the right down corner.
6+
7+
8+
# Use case 1 - Automatically show the toolbar when the command name is typed by the user
9+
10+
A specific requirement is also that the labels with the values shall have certain colors, not just any default colors. This is how the PowerCommandAttribute look like, to help the user consume this command.
11+
The look is that one showing in the image above with the fruits, notice that the command name is ```toolbar```.
12+
13+
For this case we will use the attribute ```PowerCommandsToolbar``` attribute like this:
14+
15+
![Alt text](images/toolbar_attribute.png?raw=true "Attribute")
16+
17+
You can also see the ```PowerCommandDesign``` attribute, where the suggestions also are added with valid values, if the ```PowerCommandsToolbar``` is omitted the suggestions will be uses as labels instead.
18+
But in this case I want to show the values surrounded by ```[]``` and with a describing label ```[Pick a valid fruit]``` to really guide the user right.
19+
If I had added that as suggestions, the user could not us tab to cycle trough valid values.
20+
21+
## The Command class
22+
For this to work we need to inherit the ```CommandWithToolbarBase``` base class instead of the regular base class ```CommandBase``` class.
23+
But other than that is is just the ```PowerCommandsToolbar``` attribute that you need to add and the rest will just work.
24+
25+
Notice that the Run function starts with calling the base.Run() function, that is to automatically clear the toolbar.
26+
If the user input is wrong the toolbar is programmatically called to show the toolbar again.
27+
```
28+
[PowerCommandsToolbar( labels: "[ Pick a valid fruit ->]|[Apple]|[Orange]|[Banana]",
29+
colors: new [] { ConsoleColor.DarkBlue,ConsoleColor.DarkGreen ,ConsoleColor.Red,ConsoleColor.DarkYellow})]
30+
[PowerCommandDesign( description: "Demonstration of the usage of a command with a toolbar",
31+
suggestions: "Apple|Orange|Banana",
32+
example: "toolbar")]
33+
public class ToolbarCommand : CommandWithToolbarBase<PowerCommandsConfiguration>
34+
{
35+
public ToolbarCommand(string identifier, PowerCommandsConfiguration configuration) : base(identifier, configuration) { }
36+
37+
public override RunResult Run()
38+
{
39+
base.Run();
40+
var fruits = new[] { "Apple", "Orange", "Banana" };
41+
var fruit = Input.SingleArgument;
42+
if(fruits.Any(f => f == fruit))WriteSuccessLine($"You picked {fruit}\nWell done");
43+
else
44+
{
45+
WriteFailureLine($"{fruit} is not a valid fruit!");
46+
DrawToolbar();
47+
}
48+
return Ok();
49+
}
50+
}
51+
```
52+
53+
# Use case 2 - Show toolbar with dynamically content
54+
This use case is a bit more tricky, the command ```openapi``` has this requirements:
55+
- Needs to first set the working directory to a specific folder that contains a couple of *.yaml files.
56+
- If the ```openapi``` is typed a check will performed to see if the current working directory is a valid one.
57+
- if not a label will be displayed to the user with instructions.
58+
- If it is a valid directory a couple of labels will be shown what to do next.
59+
60+
We inherit the same base class ```CommandWithToolbarBase``` base we are also been using functionality from the ```CdCommand``` so that we could use the current WorkingDirectory.
61+
We will not use the ```PowerCommandsToolbar``` attribute because the labels are not static, we will instead listen on the user input from the command line and act on that if the typed in command is ```openapi```.
62+
The base class already listen on this event but we override the behavior and implement a custom one.
63+
64+
Below is the command code, where implementation code skipped, the sample command exist in the source code if you want to use it. It´s actually is implementation code to generate WebApi using OpenAPI specification with their Docker image.
65+
```
66+
[PowerCommandDesign( description: "Generate API with OpenApi Code generator using a docker image, you create two files.\n First one with the API specification, the second one for the config, the filename should contain config so the command knows what is what...\n Navigate to the directory with the files using the cd command.",
67+
example: "openapi --generate")]
68+
public class OpenApiCommand : CommandWithToolbarBase<PowerCommandsConfiguration>
69+
{
70+
public OpenApiCommand(string identifier, PowerCommandsConfiguration configuration) : base(identifier, configuration, autoShowToolbar: false) { }
71+
protected override void ReadLineService_CmdLineTextChanged(object? sender, CmdLineTextChangedArgs e)
72+
{
73+
if (e.CmdText.StartsWith(Identifier))
74+
{
75+
if (e.CmdText == Identifier)
76+
{
77+
Labels.Clear();
78+
if (ValidFilesExists())
79+
{
80+
Labels.Add("Valid files found! ->");
81+
Labels.Add("--generate");
82+
DrawToolbar();
83+
return;
84+
}
85+
Labels.Add("Navigate to a directory with the yaml files, using cd command");
86+
DrawToolbar();
87+
}
88+
}
89+
else
90+
{
91+
ClearToolbar();
92+
Labels.Clear();
93+
}
94+
}
95+
public override RunResult Run()
96+
{
97+
if(HasOption("generate")) GenerateCode();
98+
return Ok();
99+
}
100+
public void GenerateCode()
101+
{
102+
//Implementation code excluded
103+
}
104+
public bool ValidFilesExists()
105+
{
106+
//Implementation code excluded
107+
}
108+
}
109+
```
110+
If the user navigates with ```CdCommand``` to a directory with two *.yaml files this toolbar will be shown.
111+
112+
![Alt text](images/toolbar2.png?raw=true "Toolbar use case 2")
113+
114+
# Use case 3 - Draw toolbar using DialogService
115+
You could also use ```DialogService``` direct in your command without inherit functionality from the ```CommandWithToolbarBase``` base class.
116+
```
117+
DialogService.DrawToolbar(labels, colors)
118+
```
119+
Read more about:
120+
121+
[Design your Command](Design_command.md)
122+
123+
[Input](Input.md)
124+
125+
[options](options.md)
126+
127+
[Back to start](https://github.com/PowerCommands/PowerCommands2022/blob/main/Docs/README.md)

Docs/images/startup.png

-4.01 KB
Loading

Docs/images/toolbar.png

22.3 KB
Loading

Docs/images/toolbar2.png

21.5 KB
Loading

Docs/images/toolbar_attribute.png

58 KB
Loading

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ You could see PowerCommands as your CLI applikation starter kit. It is a structu
1111
- Built in help system with the use of attributes
1212
- Run as job
1313
- Validation rules with attribute
14+
- Toolbar labels to guide the user
1415
- Diagnostic
1516
- Progressbar
1617
- Dialog service (with password prompting)
18+
- Navigation with working directory and familiar cd and dir commands
1719

1820
![Alt text](Docs/images/startup.png?raw=true "Startup")
1921

@@ -27,6 +29,8 @@ You could see PowerCommands as your CLI applikation starter kit. It is a structu
2729

2830
[Power Commands Design attribute](Docs/PowerCommandDesignAttribute.md)
2931

32+
[Patterns to use the Toolbar with dynamic content](Docs/PowerCommandToolbarAttribute.md)
33+
3034
[Command base class](Docs/CommandBase.md)
3135

3236
[Handling the Input](Docs/Input.md)

Templates/PowerCommands.zip

6.02 KB
Binary file not shown.

Templates/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ Open Visual Studio and write Power in the searchbox, you should find the PowerCo
1111

1212
# What is new?
1313

14+
## Version 1.0.1.0
15+
**Released 2023-06-20**
16+
### Toolbar styled Commands
17+
- Added new base command class ```CommandWithToolbarBase``` that opens upp for a new way of designing your commands with a displayed toolbar in the bottom right corner. Can either be display suggestions or be set programmatically listening and reacting on to the cmd line input.
18+
- Added the constant for array splitter to the ```ConfigurationGlobals```, and refactored all code to use it, makes it easier to swap that if necessary.
19+
- Adjusted the run process so that RunCompleted is always triggered, when running async or when a exception is thrown.
1420
## Version 1.0.0.1
1521
**Released 2023-06-12**
1622
### Capability to Run PowerCommand with a service account and using secrets
@@ -20,4 +26,4 @@ If you want to run your PowerCommands application as a Windows scheduled task st
2026
- Copy the environment variable _encryptionManager and create the same as a system environment variable. EncryptionService will look for the system environment variable if the user environment variable is not there.
2127
- For your stored secrets you will need to to do the same thing and change target: User to target: Machine in the **PowerCommandsConfiguration.yaml** file.
2228
### Improved logging
23-
Every log post now includes the current user running the PowerCommand application, the Log commands has been re-designed to use suggestions instead of options where more appropriate.
29+
Every log post now includes the current user running the PowerCommand application, the Log commands has been re-designed to use suggestions instead of options where more appropriate.

Templates/src/Core/PainKiller.PowerCommands.Configuration/DOMAINOBJECTS/ConfigurationGlobals.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public static class ConfigurationGlobals
66
public const string MainConfigurationFile = "PowerCommandsConfiguration.yaml";
77
public const string SecurityFileName = "security.yaml";
88
public const string WhatsNewFileName = "whats_new.md";
9+
public const char ArraySplitter = '|';
910

1011
public static readonly string ApplicationDataFolder = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{nameof(PowerCommands)}";
1112
}

0 commit comments

Comments
 (0)