Skip to content

Commit 494db81

Browse files
committed
Fixed installation scripts with correct encoding, added test script running for ps1 files.
1 parent cc06d60 commit 494db81

5 files changed

Lines changed: 61 additions & 7 deletions

File tree

file_utils.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import shutil
3+
import stat
34
from pathlib import Path
45

56
from liquid2 import Environment, FileSystemLoader, StrictUndefined
@@ -97,6 +98,15 @@ def delete_folder(folder_name):
9798
shutil.rmtree(folder_name)
9899

99100

101+
def _make_writable(path: str) -> None:
102+
"""On Windows, clear read-only so deletion can succeed."""
103+
try:
104+
mode = os.stat(path).st_mode
105+
os.chmod(path, mode | stat.S_IWRITE)
106+
except OSError:
107+
pass
108+
109+
100110
def delete_files_and_subfolders(directory):
101111
total_files_deleted = 0
102112
total_folders_deleted = 0
@@ -106,12 +116,14 @@ def delete_files_and_subfolders(directory):
106116
# Delete files
107117
for file in files:
108118
file_path = os.path.join(root, file)
119+
_make_writable(file_path)
109120
os.remove(file_path)
110121
total_files_deleted += 1
111122

112123
# Delete directories
113124
for dir_ in dirs:
114125
dir_path = os.path.join(root, dir_)
126+
_make_writable(dir_path)
115127
os.rmdir(dir_path)
116128
total_folders_deleted += 1
117129

install/powershell/examples.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$ErrorActionPreference = 'Stop'
1+
$ErrorActionPreference = 'Stop'
22

33
# Brand Colors (use exported colors if available, otherwise define them)
44
if (-not $env:YELLOW) { $YELLOW = "$([char]27)[38;2;224;255;110m" } else { $YELLOW = $env:YELLOW }

install/powershell/install.ps1

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,29 @@ if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
6060
Write-Host "${GREEN}${NC} uv detected"
6161
Write-Host ""
6262

63+
try {
64+
$uvOutput = uv tool list 2>$null
65+
} catch {
66+
$uvOutput = @()
67+
}
68+
6369
# Install or upgrade codeplain using uv tool
64-
$codeplainLine = @(uv tool list 2>$null) | Where-Object { $_ -match '^codeplain' } | Select-Object -First 1
70+
$codeplainLine = $uvOutput | Where-Object { $_ -match '^codeplain' } | Select-Object -First 1
6571
if ($codeplainLine) {
6672
$currentVersion = ($codeplainLine -replace 'codeplain v', '').Trim()
6773
Write-Host "${GRAY}codeplain ${currentVersion} is already installed.${NC}"
6874
Write-Host "upgrading to latest version..."
6975
Write-Host ""
70-
uv tool upgrade codeplain 2>&1 | Out-Null
76+
77+
try {
78+
$upgradeOutput = & uv tool upgrade codeplain 2>&1
79+
if ($LASTEXITCODE -ne 0) {
80+
throw "uv exited with code $LASTEXITCODE"
81+
}
82+
} catch {
83+
Write-Host "${RED}Failed to upgrade codeplain.${NC}"
84+
Write-Host $_
85+
}
7186
$newLine = @(uv tool list 2>$null) | Where-Object { $_ -match '^codeplain' } | Select-Object -First 1
7287
$newVersion = ($newLine -replace 'codeplain v', '').Trim()
7388
if ($currentVersion -eq $newVersion) {
@@ -83,6 +98,24 @@ if ($codeplainLine) {
8398
Write-Host "${GREEN}✓ codeplain installed successfully!${NC}"
8499
}
85100

101+
# Ensure uv tool bin directory is on user PATH permanently (so codeplain is available)
102+
$uvBinDir = Join-Path $env:USERPROFILE '.local\bin'
103+
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
104+
if ($userPath) {
105+
$pathEntries = $userPath -split ';' | ForEach-Object { $_.Trim() } | Where-Object { $_ }
106+
if ($uvBinDir -notin $pathEntries) {
107+
$newPath = ($userPath.TrimEnd(';') + ';' + $uvBinDir)
108+
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
109+
$env:Path = $uvBinDir + ';' + $env:Path
110+
Write-Host "${GREEN}${NC} added $uvBinDir to your user PATH"
111+
}
112+
} else {
113+
[Environment]::SetEnvironmentVariable('Path', $uvBinDir, 'User')
114+
$env:Path = $uvBinDir + ';' + $env:Path
115+
Write-Host "${GREEN}${NC} added $uvBinDir to your user PATH"
116+
}
117+
Write-Host ""
118+
86119
# Check if API key already exists
87120
$skipApiKeySetup = $false
88121
if ($env:CODEPLAIN_API_KEY) {

install/powershell/walkthrough.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$ErrorActionPreference = 'Stop'
1+
$ErrorActionPreference = 'Stop'
22

33
# Brand Colors (use exported colors if available, otherwise define them)
44
if (-not $env:YELLOW) { $YELLOW = "$([char]27)[38;2;224;255;110m" } else { $YELLOW = $env:YELLOW }

render_machine/render_utils.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import subprocess
2+
import sys
23
import tempfile
34
import time
45
from typing import Optional
@@ -45,19 +46,27 @@ def execute_script(
4546
script: str, scripts_args: list[str], verbose: bool, script_type: str, frid: Optional[str] = None
4647
) -> tuple[int, str, Optional[str]]:
4748
temp_file_path = None
49+
script_path = file_utils.add_current_path_if_no_path(script)
50+
# On Windows, .ps1 files must be run via PowerShell, not as the executable
51+
if sys.platform == "win32" and script_path.lower().endswith(".ps1"):
52+
cmd = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", script_path] + scripts_args
53+
else:
54+
cmd = [script_path] + scripts_args
4855
try:
4956
start_time = time.time()
5057
result = subprocess.run(
51-
[file_utils.add_current_path_if_no_path(script)] + scripts_args,
58+
cmd,
5259
stdout=subprocess.PIPE,
5360
stderr=subprocess.STDOUT,
5461
text=True,
62+
encoding="utf-8",
63+
errors="replace",
5564
timeout=SCRIPT_EXECUTION_TIMEOUT,
5665
)
5766
elapsed_time = time.time() - start_time
5867
# Log the info about the script execution
5968
if verbose:
60-
with tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".script_output") as temp_file:
69+
with tempfile.NamedTemporaryFile(mode="w+", encoding="utf-8", delete=False, suffix=".script_output") as temp_file:
6170
temp_file.write(f"\n═════════════════════════ {script_type} Script Output ═════════════════════════\n")
6271
temp_file.write(result.stdout)
6372
temp_file.write("\n══════════════════════════════════════════════════════════════════════\n")
@@ -89,7 +98,7 @@ def execute_script(
8998
except subprocess.TimeoutExpired as e:
9099
# Store timeout output in a temporary file
91100
if verbose:
92-
with tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".script_timeout") as temp_file:
101+
with tempfile.NamedTemporaryFile(mode="w+", encoding="utf-8", delete=False, suffix=".script_timeout") as temp_file:
93102
temp_file.write(f"{script_type} script {script} timed out after {SCRIPT_EXECUTION_TIMEOUT} seconds.")
94103
if e.stdout:
95104
decoded_output = e.stdout.decode("utf-8") if isinstance(e.stdout, bytes) else e.stdout

0 commit comments

Comments
 (0)