Skip to content

Commit 5864952

Browse files
Embedded Scripts in binary
scripts need to be changed or common script needs to be compiled so the reference to common script or its functions are baked in.
1 parent 292ad16 commit 5864952

3 files changed

Lines changed: 104 additions & 122 deletions

File tree

MacUtilGUI/MacUtilGUI.fsproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@
5252
<AvaloniaResource Include="Assets\**" />
5353
</ItemGroup>
5454

55+
<!-- Include scripts as embedded resources -->
56+
<ItemGroup>
57+
<EmbeddedResource Include="../scripts/**/*.sh" />
58+
<EmbeddedResource Include="../scripts/**/*.toml" />
59+
</ItemGroup>
60+
5561
</Project>

MacUtilGUI/Services/ScriptService.fs

Lines changed: 98 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,46 @@ namespace MacUtilGUI.Services
33
open System
44
open System.IO
55
open System.Diagnostics
6+
open System.Reflection
67
open Tomlyn
78
open MacUtilGUI.Models
89

910
module ScriptService =
1011

11-
let scriptsBasePath =
12-
let currentDir = Directory.GetCurrentDirectory()
13-
let scriptPath = Path.Combine(currentDir, "..", "scripts")
14-
let resolvedPath = Path.GetFullPath(scriptPath)
15-
printfn "Current directory: %s" currentDir
16-
printfn "Scripts path: %s" resolvedPath
17-
printfn "Scripts directory exists: %b" (Directory.Exists(resolvedPath))
18-
resolvedPath
12+
let assembly = Assembly.GetExecutingAssembly()
13+
14+
let getEmbeddedResource (resourcePath: string) : string option =
15+
try
16+
let resourceName = sprintf "MacUtilGUI.%s" (resourcePath.Replace("/", ".").Replace("\\", ".").Replace("-", "_"))
17+
use stream = assembly.GetManifestResourceStream(resourceName)
18+
if stream <> null then
19+
use reader = new StreamReader(stream)
20+
Some(reader.ReadToEnd())
21+
else
22+
printfn "Resource not found: %s" resourceName
23+
None
24+
with
25+
| ex ->
26+
printfn "Error reading embedded resource %s: %s" resourcePath ex.Message
27+
None
28+
29+
let listEmbeddedResources () =
30+
let resourceNames = assembly.GetManifestResourceNames()
31+
printfn "Available embedded resources:"
32+
for name in resourceNames do
33+
printfn " %s" name
34+
35+
let scriptsBasePath = ""
1936

2037
let loadScriptsFromDirectory (directoryPath: string) : ScriptCategory list =
2138
let mutable categories = []
2239

2340
try
24-
let tabDataPath = Path.Combine(scriptsBasePath, directoryPath, "tab_data.toml")
41+
let tabDataPath = sprintf "%s/tab_data.toml" directoryPath
2542

26-
if File.Exists(tabDataPath) then
43+
match getEmbeddedResource tabDataPath with
44+
| Some content ->
2745
try
28-
let content = File.ReadAllText(tabDataPath)
2946
let tomlDoc = Toml.Parse(content)
3047

3148
// Parse the TOML as a dynamic table
@@ -53,7 +70,7 @@ module ScriptService =
5370
let name = entry.["name"].ToString()
5471
let description = entry.["description"].ToString()
5572
let script = entry.["script"].ToString()
56-
let fullPath = Path.Combine(scriptsBasePath, directoryPath, script)
73+
let fullPath = sprintf "%s/%s" directoryPath script
5774

5875
yield {
5976
Name = name
@@ -76,31 +93,9 @@ module ScriptService =
7693
with
7794
| ex ->
7895
printfn "Error parsing TOML file %s: %s" tabDataPath ex.Message
79-
else
80-
// If no tab_data.toml, scan for .sh files directly
81-
let directoryFullPath = Path.Combine(scriptsBasePath, directoryPath)
82-
if Directory.Exists(directoryFullPath) then
83-
let shellFiles = Directory.GetFiles(directoryFullPath, "*.sh")
84-
let scripts =
85-
shellFiles
86-
|> Array.map (fun filePath ->
87-
let fileName = Path.GetFileNameWithoutExtension(filePath)
88-
{
89-
Name = fileName
90-
Description = sprintf "Shell script: %s" fileName
91-
Script = Path.GetFileName(filePath)
92-
TaskList = "I"
93-
Category = directoryPath
94-
FullPath = filePath
95-
})
96-
|> Array.toList
97-
98-
if not scripts.IsEmpty then
99-
let category = {
100-
Name = directoryPath
101-
Scripts = scripts
102-
}
103-
categories <- category :: categories
96+
| None ->
97+
printfn "ERROR: Embedded resource not found: %s" tabDataPath
98+
printfn "This should not happen if resources are properly embedded!"
10499
with
105100
| ex ->
106101
printfn "Error loading scripts from %s: %s" directoryPath ex.Message
@@ -111,9 +106,11 @@ module ScriptService =
111106
let mutable allCategories = []
112107

113108
try
114-
let mainTabsPath = Path.Combine(scriptsBasePath, "tabs.toml")
115-
if File.Exists(mainTabsPath) then
116-
let content = File.ReadAllText(mainTabsPath)
109+
listEmbeddedResources() // Debug: list all available resources
110+
111+
let mainTabsPath = "tabs.toml"
112+
match getEmbeddedResource mainTabsPath with
113+
| Some content ->
117114
let tomlDoc = Toml.Parse(content)
118115
let table = tomlDoc.ToModel()
119116

@@ -125,12 +122,9 @@ module ScriptService =
125122
let categories = loadScriptsFromDirectory directory
126123
allCategories <- allCategories @ categories
127124
| _ -> ()
128-
else
129-
// Fallback: scan known directories
130-
let knownDirectories = ["applications-setup"; "system-setup"]
131-
for directory in knownDirectories do
132-
let categories = loadScriptsFromDirectory directory
133-
allCategories <- allCategories @ categories
125+
| None ->
126+
printfn "ERROR: Main tabs.toml not found in embedded resources!"
127+
printfn "This should not happen if resources are properly embedded!"
134128
with
135129
| ex ->
136130
printfn "Error loading scripts: %s" ex.Message
@@ -139,33 +133,66 @@ module ScriptService =
139133

140134
let runScript (scriptInfo: ScriptInfo) : string =
141135
try
142-
let startInfo = ProcessStartInfo()
143-
startInfo.FileName <- "/bin/bash"
144-
startInfo.Arguments <- sprintf "-c \"cd '%s' && chmod +x '%s' && ./'%s'\""
145-
(Path.GetDirectoryName(scriptInfo.FullPath))
146-
(Path.GetFileName(scriptInfo.FullPath))
147-
(Path.GetFileName(scriptInfo.FullPath))
148-
startInfo.UseShellExecute <- false
149-
startInfo.CreateNoWindow <- true
150-
startInfo.RedirectStandardOutput <- true
151-
startInfo.RedirectStandardError <- true
152-
153-
let proc = Process.Start(startInfo)
154-
if proc <> null then
155-
let output = proc.StandardOutput.ReadToEnd()
156-
let error = proc.StandardError.ReadToEnd()
157-
proc.WaitForExit()
136+
// Get the script content from embedded resources
137+
match getEmbeddedResource scriptInfo.FullPath with
138+
| Some scriptContent ->
139+
// Create a temporary file to execute the script
140+
let tempDir = Path.GetTempPath()
141+
let scriptFileName = Path.GetFileName(scriptInfo.Script) // Get just the filename, not the full path
142+
let tempFileName = sprintf "%s_%s" (Guid.NewGuid().ToString("N").Substring(0, 8)) scriptFileName
143+
let tempFilePath = Path.Combine(tempDir, tempFileName)
158144

159-
let fullOutput =
160-
if String.IsNullOrEmpty(error) then
161-
output
145+
try
146+
// Write script content to temporary file
147+
File.WriteAllText(tempFilePath, scriptContent)
148+
149+
// Make the temporary file executable
150+
let chmodStartInfo = ProcessStartInfo()
151+
chmodStartInfo.FileName <- "/bin/chmod"
152+
chmodStartInfo.Arguments <- sprintf "+x \"%s\"" tempFilePath
153+
chmodStartInfo.UseShellExecute <- false
154+
chmodStartInfo.CreateNoWindow <- true
155+
156+
let chmodProc = Process.Start(chmodStartInfo)
157+
if chmodProc <> null then
158+
chmodProc.WaitForExit()
159+
160+
// Execute the script
161+
let startInfo = ProcessStartInfo()
162+
startInfo.FileName <- "/bin/bash"
163+
startInfo.Arguments <- sprintf "\"%s\"" tempFilePath
164+
startInfo.UseShellExecute <- false
165+
startInfo.CreateNoWindow <- true
166+
startInfo.RedirectStandardOutput <- true
167+
startInfo.RedirectStandardError <- true
168+
169+
let proc = Process.Start(startInfo)
170+
if proc <> null then
171+
let output = proc.StandardOutput.ReadToEnd()
172+
let error = proc.StandardError.ReadToEnd()
173+
proc.WaitForExit()
174+
175+
let fullOutput =
176+
if String.IsNullOrEmpty(error) then
177+
output
178+
else
179+
sprintf "%s\n--- ERRORS ---\n%s" output error
180+
181+
printfn "Executed script: %s (Exit Code: %d)" scriptInfo.Name proc.ExitCode
182+
fullOutput
162183
else
163-
sprintf "%s\n--- ERRORS ---\n%s" output error
164-
165-
printfn "Executed script: %s (Exit Code: %d)" scriptInfo.Name proc.ExitCode
166-
fullOutput
167-
else
168-
let errorMsg = sprintf "Failed to start script: %s" scriptInfo.Name
184+
let errorMsg = sprintf "Failed to start script: %s" scriptInfo.Name
185+
printfn "%s" errorMsg
186+
errorMsg
187+
finally
188+
// Clean up temporary file
189+
if File.Exists(tempFilePath) then
190+
try
191+
File.Delete(tempFilePath)
192+
with
193+
| _ -> () // Ignore cleanup errors
194+
| None ->
195+
let errorMsg = sprintf "Script content not found in embedded resources: %s" scriptInfo.FullPath
169196
printfn "%s" errorMsg
170197
errorMsg
171198
with

MacUtilGUI/Services/TomlParser.fs

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)