Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ Bundle common parameter combinations into named presets so teammates can run fre

`fallbackToDefault` fills in any missing parameters from the automatically generated `<default>` set.

`fallbackToExisting` (optional, works with `fallbackToDefault`) prevents clearing field values when switching to this argument set if the set doesn't define a value for a parameter (or has an empty value). When set to `true`, existing values in the form are preserved instead of being cleared or overwritten with empty defaults. This is useful when you want to change only specific parameters while keeping others unchanged.

## Ready-to-run examples

The repository ships with `examples/ScriptRunnerExamples.json`, a manifest that contains four minimal actions showcasing how to wrap PowerShell, Python, Bash (via WSL), and .NET console apps. Import that file from **Settings ➜ Config sources** and you will get the following definitions (interactive inputs and troubleshooting rules are omitted here for brevity):
Expand Down
4 changes: 4 additions & 0 deletions schema/v1/ScriptRunnerSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@
"type":"boolean",
"description":"When true any missing parameter values inherit from the auto-generated default set."
},
"fallbackToExisting":{
"type":"boolean",
"description":"When true preserves current field values when switching to this set if the set doesn't define a value or has an empty value for a parameter. Works with fallbackToDefault."
},
"arguments":{
"type":"object",
"description":"Map of parameter name to the value that should be pre-filled when this preset is selected.",
Expand Down
15 changes: 12 additions & 3 deletions src/ScriptRunner/ScriptRunner.GUI/Parameters/FileContent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
Expand All @@ -18,7 +18,7 @@ public FileContent(string extension, bool useWslPath)
{
_extension = extension;
_useWslPath = useWslPath;
FileName = Path.GetTempFileName() + "." + extension;
FileName = GetFileContentStoragePath("temp." + extension);
}

public string GetFormattedValue()
Expand All @@ -30,12 +30,21 @@ public string GetFormattedValue()
_ => ((TextBox)Control).Text
};
var hash = string.IsNullOrWhiteSpace(fileContent)? "EMPTY" : ComputeSHA256(fileContent).Substring(0,10);
FileName = Path.Combine(Path.GetTempPath(), hash + "." + _extension);
FileName = GetFileContentStoragePath(hash + "." + _extension);
File.WriteAllText(FileName, fileContent, Encoding.UTF8);
return _useWslPath ? WslPathConverter.ConvertToWslPath(FileName) : FileName;
}


private static string GetFileContentStoragePath(string fileName)
{
var appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ScriptRunner", "FileContentStorage");
if (Directory.Exists(appDataPath) == false)
{
Directory.CreateDirectory(appDataPath);
}
return Path.Combine(appDataPath, fileName);
}

static string ComputeSHA256(string input)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Avalonia.Controls.Documents;
using Avalonia.Controls.Documents;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -53,6 +53,7 @@ public class ArgumentSet
{
public string Description { get; set; }
public bool FallbackToDefault { get; set; }
public bool FallbackToExisting { get; set; }
public Dictionary<string, string> Arguments { get; set; } = new();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -181,6 +181,11 @@ string ResolveAbsolutePath(string path)
{
if (set.Arguments.ContainsKey(key) == false)
{
// If fallbackToExisting is true, only set the value if the default value exists (is not null or empty)
if (set.FallbackToExisting && string.IsNullOrEmpty(val))
{
continue;
}
set.Arguments[key] = val;
}
}
Expand Down Expand Up @@ -348,6 +353,11 @@ string ResolveAbsolutePath(string path)
{
if (set.Arguments.ContainsKey(key) == false)
{
// If fallbackToExisting is true, only set the value if the default value exists (is not null or empty)
if (set.FallbackToExisting && string.IsNullOrEmpty(val))
{
continue;
}
set.Arguments[key] = val;
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/ScriptRunner/ScriptRunner.GUI/Scripts/TextInputScript.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,57 @@
}
]
},
{
"name": "FallbackToExisting Demo",
"description": "Demonstrates the fallbackToExisting feature",
"command": "echo Server: {server}, Port: {port}, Username: {username}",
"params": [
{
"name": "server",
"description": "Server address",
"prompt": "text",
"default": "localhost"
},
{
"name": "port",
"description": "Port number",
"prompt": "text",
"default": ""
},
{
"name": "username",
"description": "Username",
"prompt": "text",
"default": ""
}
],
"predefinedArgumentSets": [
{
"description": "Production Server Only",
"fallbackToDefault": true,
"fallbackToExisting": true,
"arguments": {
"server": "prod.example.com"
}
},
{
"description": "Dev Server (clears other fields)",
"fallbackToDefault": true,
"arguments": {
"server": "dev.example.com"
}
},
{
"description": "Full Production Config",
"fallbackToDefault": true,
"arguments": {
"server": "prod.example.com",
"port": "443",
"username": "admin"
}
}
]
},
{
"name": "AllControlsTest",
"description": "Demo of all available controls",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,34 @@ public ArgumentSet? SelectedArgumentSet
}
}

// Handle fallbackToExisting: preserve current values when new set has empty values
if (_selectedArgumentSet.FallbackToExisting && _controlRecords != null)
{
// Harvest current parameter values from UI controls
var currentValues = new Dictionary<string, string>();
foreach (var controlRecord in _controlRecords)
{
var controlValue = controlRecord.GetFormattedValue()?.Trim();
if (!string.IsNullOrEmpty(controlValue))
{
currentValues[controlRecord.Name] = controlValue;
}
}

// Merge: use new set's values if non-empty, otherwise preserve current values
arguments = new Dictionary<string, string>(arguments);
foreach (var param in selectedAction.Params)
{
// If the new set doesn't have this parameter or has an empty value
if ((!arguments.ContainsKey(param.Name) || string.IsNullOrEmpty(arguments[param.Name]))
&& currentValues.ContainsKey(param.Name))
{
// Preserve the current value
arguments[param.Name] = currentValues[param.Name];
}
}
}

RenderParameterForm(selectedAction, arguments);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private async void ChangeFileClick(object? sender, RoutedEventArgs e)
var sourceWindow = (sender as Control)?.GetVisualRoot() as Window ?? desktop.MainWindow;

var dialog = new OpenFileDialog();
if (string.IsNullOrWhiteSpace(FilePath) == false && Path.GetDirectoryName(FilePath) is { } dir)
if (string.IsNullOrWhiteSpace(FilePath) == false && Path.GetDirectoryName(FilePath) is { } dir && Directory.Exists(dir))
{
dialog.Directory = dir;
dialog.InitialFileName = Path.GetFileName(FilePath);
Expand Down
Loading