Skip to content

Commit ed4654d

Browse files
committed
Version 1.0.4.1
1 parent b4de71e commit ed4654d

File tree

57 files changed

+1188
-765
lines changed

Some content is hidden

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

57 files changed

+1188
-765
lines changed

README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ You could see PowerCommands as your CLI application starter kit. It is a structu
33

44
[Follow progress on twitter](https://twitter.com/PowerCommands) <img src="https://github.com/PowerCommands/PowerCommands2022/blob/main/Docs/images/Twitter.png?raw=true" alt="drawing" width="20"/>
55

6+
## Version 1.0.4.1
7+
**Released 2025-01-21**
8+
- PowerCommandPrivacyAttribute to prevent sensitive data leak out to the logfile.
9+
- Improved dialog and toolbar service.
10+
- New function for deserialization of Yaml.
11+
- Improved ZipService.
12+
- Every PowerCommand implementation now has it´s own working folder.
13+
- Filter on dir command is now not case sensitive.
14+
- Nuget packages has been updated.
615
## Version 1.0.4.0
716
**Released 2024-12-12**
817
- Added a new `FileCommand` command to Read, Copy, Move, Delete files and show file properties.
@@ -13,7 +22,7 @@ You could see PowerCommands as your CLI application starter kit. It is a structu
1322
- Added the feature to `Commands` command to pickup and display diagnostics about the latest RunResult (if any) for a given command (by name).
1423
- Log view is now the default action instead of viewing log files
1524
- Improved `cd` and `dir` command, added som nice new features to them
16-
- All Nuget packages has been updated.
25+
- Nuget packages has been updated.
1726

1827
https://github.com/user-attachments/assets/b718cc18-2cbb-4812-b3a2-0d054e948a00
1928

Templates/PowerCommands.zip

33.2 KB
Binary file not shown.

Templates/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ I recommend you to use the option ```Place solution in the same directory``` som
1818
![Alt text](../Docs/images/VS_solution_option.png?raw=true "Command Base")
1919

2020
# What is new?
21+
## Version 1.0.4.1
22+
**Released 2025-01-21**
23+
- PowerCommandPrivacyAttribute to prevent sensitive data leak out to the logfile.
24+
- Improved dialog and toolbar service.
25+
- New function for deserialization of Yaml.
26+
- Improved ZipService.
27+
- Every PowerCommand implementation now has it´s own working folder.
28+
- Filter on dir command is now not case sensitive.
29+
- Nuget packages has been updated.
2130
## Version 1.0.4.0
2231
**Released 2024-12-12**
2332
- Added a new `FileCommand` command to Read, Copy, Move, Delete files and show file properties.

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

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
public static class ConfigurationGlobals
44
{
5-
public const string Prompt = "pcm>";
5+
public const string ApplicationName = "PC";
66
public const string MainConfigurationFile = "PowerCommandsConfiguration.yaml";
77
public const string SecurityFileName = "security.yaml";
88
public const string WhatsNewFileName = "whats_new.md";
99
public const char ArraySplitter = '|';
1010
public const string SetupConfigurationFile = "setup.yaml";
1111
public const string EncryptionEnvironmentVariableName = "_encryptionManager";
1212

13-
public static readonly string ApplicationDataFolder = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{nameof(PowerCommands)}";
14-
public static readonly string MainConfigurationFileFullPath = Path.Combine(AppContext.BaseDirectory, MainConfigurationFile);
13+
public static readonly string ApplicationDataFolder = Path.Combine($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{nameof(PowerCommands)}", ApplicationName);
14+
public static readonly string EnvironmentVariableName = $"{nameof(PowerCommands)}_{ApplicationName}";
15+
16+
private static string _prompt = "pcm>";
17+
public static string GetPrompt() => _prompt;
18+
public static void SetPrompt(string prompt= "Clairvoyant>") => _prompt = prompt;
1519
}

Templates/src/Core/PainKiller.PowerCommands.Configuration/EXTENSIONS/ConfigurationExtension.cs

+7
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,11 @@ public static string GetPath(this ArtifactPathsConfiguration configuration, stri
2424
.Build();
2525
return serializer.Serialize(configuration);
2626
}
27+
public static T GetObjectFromYaml<T>(this string yaml) where T : new()
28+
{
29+
var serializer = new DeserializerBuilder()
30+
.WithNamingConvention(CamelCaseNamingConvention.Instance)
31+
.Build();
32+
return serializer.Deserialize<T>(yaml);
33+
}
2734
}

Templates/src/Core/PainKiller.PowerCommands.Configuration/PainKiller.PowerCommands.Configuration.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
<LangVersion>12.0</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8-
<Version>1.0.4.0</Version>
8+
<Version>1.0.4.1</Version>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="YamlDotNet" Version="16.2.1" />
12+
<PackageReference Include="YamlDotNet" Version="16.3.0" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

Templates/src/Core/PainKiller.PowerCommands.Core/COMMANDS/CdCommand.cs

+140-138
Large diffs are not rendered by default.

Templates/src/Core/PainKiller.PowerCommands.Core/COMMANDS/DirCommand.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace $safeprojectname$.Commands;
44

55
[PowerCommandDesign(description: "List the content of the working directory or this applications app directory, with the option to open the directory with the File explorer ",
6-
options: "!filter|browse|drive-info",
7-
example: "//List the content and open the current working directory|dir --open|//Open the AppData roaming directory|dir --app --open")]
6+
disableProxyOutput: true,
7+
options: "!filter|browse|drive-info",
8+
example: "//List the content and open the current working directory|dir --open|//Open the AppData roaming directory|dir --app --open")]
89
public class DirCommand(string identifier, CommandsConfiguration configuration) : CdCommand(identifier, configuration)
910
{
1011
public override RunResult Run()

Templates/src/Core/PainKiller.PowerCommands.Core/COMMANDS/FileCommand.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private RunResult ReadFile(string path)
5656
private RunResult WritePreviousCommandResult()
5757
{
5858
var latestCommandResult = IPowerCommandsRuntime.DefaultInstance?.Latest;
59-
if (latestCommandResult == null) return BadParameterError("You must provide a valid file path as the first parameter (must be surrounded with quotation marks if filename contains whitespaces.");
59+
if (latestCommandResult == null) return BadParameterError("Could not fetch the latest command.");
6060
var inputs = latestCommandResult.Input.Raw.Split(' ');
6161
var path = inputs[1].Contains("\"") ? Input.Quotes.First().Replace("\"","") : inputs[1];
6262
if (!string.IsNullOrEmpty(GetOptionValue("target"))) path = GetOptionValue("target"); //If a path is provided with the option flag target, this will be used instead.

Templates/src/Core/PainKiller.PowerCommands.Core/PainKiller.PowerCommands.Core.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<LangVersion>12.0</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8-
<Version>1.0.4.0</Version>
8+
<Version>1.0.4.1</Version>
99
</PropertyGroup>
1010

1111
<ItemGroup>

Templates/src/Core/PainKiller.PowerCommands.Core/PowerCommandsRuntime.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public RunResult ExecuteAsyncCommand(IConsoleCommand command, ICommandLineInput
8787
command.RunAsync().ContinueWith((_) =>
8888
{
8989
command.RunCompleted();
90-
Console.Write(ConfigurationGlobals.Prompt);
90+
Console.Write(ConfigurationGlobals.GetPrompt());
9191
});
9292
Latest = new RunResult(command, input, "Command running async operation", RunResultStatus.Async);
9393
}
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,51 @@
11
using PainKiller.PowerCommands.Security.Services;
22

3-
namespace $safeprojectname$.Services;
4-
public static class DialogService
3+
namespace $safeprojectname$.Services
54
{
6-
public static bool YesNoDialog(string question, string yesValue = "y", string noValue = "n")
5+
public static class DialogService
76
{
8-
WriteHeader($"\n{question}"); ;
9-
Console.WriteLine($"({yesValue}/{noValue}):");
10-
11-
var response = Console.ReadLine();
12-
return $"{response}".Trim().ToLower() == yesValue.ToLower();
13-
}
14-
public static string QuestionAnswerDialog(string question)
15-
{
16-
WriteHeader($"{question}\n");
17-
Console.Write(ConfigurationGlobals.Prompt);
18-
var response = Console.ReadLine();
19-
return $"{response}".Trim();
20-
}
21-
public static string SecretPromptDialog(string question, int maxRetries = 3)
22-
{
23-
var retryCount = 0;
24-
var secret = "";
25-
while (retryCount < maxRetries)
7+
public static bool YesNoDialog(string question, string yesValue = "y", string noValue = "n")
268
{
27-
WriteHeader($"\n{question} ");
28-
secret = PasswordPromptService.Service.ReadPassword();
29-
Console.WriteLine();
30-
Console.Write("Confirm: ".PadLeft(question.Length + 1));
31-
var confirm = PasswordPromptService.Service.ReadPassword();
32-
if (secret != confirm)
9+
WriteHeader($"\n{question}"); ;
10+
Console.WriteLine($"({yesValue}/{noValue}):");
11+
12+
var response = Console.ReadLine();
13+
return $"{response}".Trim().ToLower() == yesValue.ToLower();
14+
}
15+
public static string QuestionAnswerDialog(string question, string prompt = "")
16+
{
17+
WriteHeader($"{question}\n");
18+
Console.Write(string.IsNullOrEmpty(prompt) ? ConfigurationGlobals.GetPrompt() : prompt);
19+
var response = Console.ReadLine();
20+
return $"{response}".Trim();
21+
}
22+
public static string SecretPromptDialog(string question, int maxRetries = 3)
23+
{
24+
var retryCount = 0;
25+
var secret = "";
26+
while (retryCount < maxRetries)
3327
{
34-
ConsoleService.Service.WriteCritical(nameof(DialogService), "\nConfirmation failure, please try again.\n");
35-
retryCount++;
28+
WriteHeader($"\n{question} ");
29+
secret = PasswordPromptService.Service.ReadPassword();
30+
Console.WriteLine();
31+
Console.Write("Confirm: ".PadLeft(question.Length + 1));
32+
var confirm = PasswordPromptService.Service.ReadPassword();
33+
if (secret != confirm)
34+
{
35+
ConsoleService.Service.WriteCritical(nameof(DialogService), "\nConfirmation failure, please try again.\n");
36+
retryCount++;
37+
}
38+
else break;
3639
}
37-
else break;
38-
}
3940

40-
return $"{secret}".Trim();
41-
}
42-
private static void WriteHeader(string text)
43-
{
44-
var originalColor = Console.ForegroundColor;
45-
Console.ForegroundColor = ConsoleColor.Cyan;
46-
Console.Write(text);
47-
Console.ForegroundColor = originalColor;
41+
return $"{secret}".Trim();
42+
}
43+
private static void WriteHeader(string text)
44+
{
45+
var originalColor = Console.ForegroundColor;
46+
Console.ForegroundColor = ConsoleColor.Cyan;
47+
Console.Write(text);
48+
Console.ForegroundColor = originalColor;
49+
}
4850
}
4951
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
1-
namespace $safeprojectname$.Services;
2-
public static class RunCommandService
1+
namespace $safeprojectname$.Services
32
{
4-
public static RunResult Run(string commandName, ICommandLineInput input)
3+
public static class RunCommandService
54
{
6-
var command = GetCommand(commandName, input);
7-
var runResult = command.Run();
8-
return runResult;
9-
}
10-
11-
public static async Task<RunResult> RunAsync(string commandName, ICommandLineInput input)
12-
{
13-
var command = GetCommand(commandName, input);
14-
var runResult = await command.RunAsync();
15-
return runResult;
16-
}
17-
private static IConsoleCommand GetCommand(string commandName, ICommandLineInput input)
18-
{
19-
var command = IPowerCommandServices.DefaultInstance?.Runtime.Commands.FirstOrDefault(c => c.Identifier == commandName);
20-
if (command == null) throw new IndexOutOfRangeException($"{commandName} could not be found, please provide a valid Command name, run commands to see all available commands.");
21-
var pcAttribute = command.GetPowerCommandAttribute();
22-
command.InitializeAndValidateInput(input, pcAttribute);
23-
return command;
5+
public static RunResult Run(string commandName, ICommandLineInput input)
6+
{
7+
var command = GetCommand(commandName, input);
8+
var runResult = command.Run();
9+
return runResult;
10+
}
11+
public static async Task<RunResult> RunAsync(string commandName, ICommandLineInput input)
12+
{
13+
var command = GetCommand(commandName, input);
14+
var runResult = await command.RunAsync();
15+
return runResult;
16+
}
17+
public static IConsoleCommand GetCommand(string commandName)
18+
{
19+
var command = IPowerCommandServices.DefaultInstance?.Runtime.Commands.FirstOrDefault(c => c.Identifier == commandName) ?? IPowerCommandServices.DefaultInstance?.Runtime.Commands.FirstOrDefault(c => c.Identifier == IPowerCommandServices.DefaultInstance?.Configuration.DefaultCommand);
20+
if (command == null) throw new IndexOutOfRangeException($"{commandName} could not be found, please provide a valid Command name, run commands to see all available commands.");
21+
return command;
22+
}
23+
private static IConsoleCommand GetCommand(string commandName, ICommandLineInput input)
24+
{
25+
var command = IPowerCommandServices.DefaultInstance?.Runtime.Commands.FirstOrDefault(c => c.Identifier == commandName);
26+
if (command == null) throw new IndexOutOfRangeException($"{commandName} could not be found, please provide a valid Command name, run commands to see all available commands.");
27+
var pcAttribute = command.GetPowerCommandAttribute();
28+
command.InitializeAndValidateInput(input, pcAttribute);
29+
return command;
30+
}
2431
}
2532
}

0 commit comments

Comments
 (0)