Skip to content

Commit f188a01

Browse files
committed
Working on windows.
1 parent 94cbea2 commit f188a01

8 files changed

Lines changed: 180 additions & 29 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
package/dist
33
package/build
44
package/_vendored
5+
package/Output
6+
package/inno_complie_script.iss
57

68
# Byte-compiled / optimized / DLL files
79
__pycache__/

datashuttle/utils/rclone.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,20 @@
1212
from datashuttle.utils.custom_types import TopLevelFolder
1313

1414

15-
def get_rclone_name() -> str:
15+
def get_command(command: str) -> str:
1616
""" """
1717
if getattr(sys, "frozen", False):
1818
# PyInstaller: binary extracted to _MEIPASS
19-
rclone_bin = os.path.join(
20-
sys._MEIPASS,
21-
"rclone.exe" if sys.platform.startswith("win") else "rclone",
22-
)
19+
20+
if sys.platform == "win32":
21+
format_command = f'"{sys._MEIPASS}/rclone.exe" {command}'
22+
else:
23+
format_command = f"{sys._MEIPASS}/rclone {command}"
2324
else:
2425
# Normal Python execution: use PATH or fixed path
25-
rclone_bin = "rclone" # or provide full path if needed
26+
format_command = f"rclone {command}" # or provide full path if needed
2627

27-
return rclone_bin
28+
return format_command
2829

2930

3031
def call_rclone(command: str, pipe_std: bool = False) -> CompletedProcess:
@@ -43,14 +44,17 @@ def call_rclone(command: str, pipe_std: bool = False) -> CompletedProcess:
4344
subprocess.CompletedProcess with `stdout` and `stderr` attributes.
4445
4546
"""
46-
command = f"{get_rclone_name()} {command}"
47+
format_command = get_command(command)
4748

4849
if pipe_std:
4950
output = subprocess.run(
50-
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
51+
format_command,
52+
stdout=subprocess.PIPE,
53+
stderr=subprocess.PIPE,
54+
shell=True,
5155
)
5256
else:
53-
output = subprocess.run(command, shell=True)
57+
output = subprocess.run(format_command, shell=True)
5458

5559
return output
5660

@@ -73,18 +77,18 @@ def call_rclone_through_script(command: str) -> CompletedProcess:
7377
"""
7478
system = platform.system()
7579

76-
command = f"{get_rclone_name()} {command}"
77-
7880
if system == "Windows":
7981
suffix = ".bat"
8082
else:
8183
suffix = ".sh"
8284
command = "#!/bin/bash\n" + command
8385

86+
format_command = get_command(command)
87+
8488
with tempfile.NamedTemporaryFile(
8589
mode="w", suffix=suffix, delete=False
8690
) as tmp_script:
87-
tmp_script.write(command)
91+
tmp_script.write(format_command)
8892
tmp_script_path = tmp_script.name
8993

9094
try:

package/NeuroBlueprint_icon.ico

28.7 KB
Binary file not shown.

package/license.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world

package/package_windows.py

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,86 @@
44

55
import packaging_utils
66

7+
# ----------------------------------------------------------------------------------------------------------------------
8+
# Windows - Inno Setup
9+
# ----------------------------------------------------------------------------------------------------------------------
10+
11+
12+
def make_inno_setup_script(version, base_path):
13+
"""{} are required in text so easier to use this method"""
14+
file_body = (
15+
r"""
16+
; Script generated by the Inno Setup Script Wizard.
17+
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
18+
19+
#define MyAppName "Datashuttle"
20+
#define MyAppVersion """
21+
+ '"'
22+
+ version
23+
+ """"
24+
#define MyAppPublisher "Neuroinformatics Unit, Sainsbury Wellcome Centre, London, UK."
25+
#define MyAppURL "www.datashuttle.neuroinformatics.dev"
26+
#define MyAppExeName "terminal_launcher.exe"
27+
28+
[Setup]
29+
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
30+
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
31+
AppId={{D063D197-9D21-426B-BF8C-D5612C74DF15}
32+
AppName={#MyAppName}
33+
AppVersion={#MyAppVersion}
34+
;AppVerName={#MyAppName} {#MyAppVersion}
35+
AppPublisher={#MyAppPublisher}
36+
AppPublisherURL={#MyAppURL}
37+
AppSupportURL={#MyAppURL}
38+
AppUpdatesURL={#MyAppURL}
39+
DefaultDirName={autopf}\DataShuttle
40+
DisableProgramGroupPage=yes
41+
LicenseFile="""
42+
+ base_path
43+
+ """\dist\license.txt
44+
; Uncomment the following line to run in non administrative install mode (install for current user only.)
45+
;PrivilegesRequired=lowest
46+
PrivilegesRequiredOverridesAllowed=dialog
47+
OutputBaseFilename=datashuttle_"""
48+
+ version
49+
+ """
50+
SetupIconFile="""
51+
+ base_path
52+
+ r"""\dist\NeuroBlueprint_icon.ico
53+
UninstallDisplayIcon={app}\NeuroBlueprint_icon.ico
54+
Compression=lzma
55+
SolidCompression=yes
56+
WizardStyle=modern
57+
58+
[Languages]
59+
Name: "english"; MessagesFile: "compiler:Default.isl"
60+
61+
[Tasks]
62+
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
63+
64+
[Files]
65+
Source: """
66+
+ '"'
67+
+ base_path
68+
+ r"""\dist\terminal_launcher.exe"; DestDir: "{app}"; Flags: ignoreversion
69+
Source: """
70+
+ '"'
71+
+ base_path
72+
+ """\dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
73+
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
74+
75+
[Icons]
76+
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
77+
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
78+
79+
[Run]
80+
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
81+
"""
82+
)
83+
84+
return file_body
85+
86+
787
# Constants
888
WEZTERM_VERSION = packaging_utils.get_wezterm_version()
989
WEZTERM_FOLDERNAME = f"WezTerm-windows-{WEZTERM_VERSION}"
@@ -29,11 +109,54 @@
29109
shell=True,
30110
)
31111

32-
# Step 3: Copy WezTerm into dist/_vendored
112+
113+
# Paths
33114
dist_dir = project_root / "dist"
115+
launcher_subdir = dist_dir / "terminal_launcher"
116+
117+
# Copy contents of dist/terminal_launcher/ into dist/
118+
for item in launcher_subdir.iterdir():
119+
dest = dist_dir / item.name
120+
if item.is_dir():
121+
if dest.exists():
122+
shutil.rmtree(dest)
123+
shutil.copytree(item, dest)
124+
else:
125+
shutil.copy2(item, dest)
126+
127+
# Optional: Remove the now-empty terminal_launcher folder
128+
shutil.rmtree(launcher_subdir)
129+
130+
131+
# Step 3: Copy WezTerm into dist/_vendored
34132
terminal_launcher_dist_dir = dist_dir / "terminal_launcher"
35133
vendored_output_path = dist_dir / "_vendored" / WEZTERM_FOLDERNAME
36134

37135
shutil.copytree(
38136
vendored_dir / WEZTERM_FOLDERNAME, vendored_output_path, dirs_exist_ok=True
39137
)
138+
139+
shutil.copy(project_root / "license.txt", dist_dir)
140+
shutil.copy(project_root / "NeuroBlueprint_icon.ico", dist_dir)
141+
142+
shutil.copy(
143+
project_root / "wezterm_config.lua",
144+
project_root / "dist" / "_vendored" / WEZTERM_FOLDERNAME,
145+
)
146+
147+
import os
148+
149+
inno_path = project_root / "inno_complie_script.iss"
150+
151+
if os.path.isfile(inno_path):
152+
os.remove(inno_path)
153+
f = open(inno_path, "a")
154+
155+
text = make_inno_setup_script("0.0.0", str(project_root)) # TODO: version
156+
157+
f.write(text.strip())
158+
f.close()
159+
160+
# TODO: set up downloader
161+
162+
subprocess.call(rf"C:\Program Files (x86)\Inno Setup 6\iscc {inno_path}")

package/packaging_utils.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import subprocess
2+
import zipfile
3+
from sys import platform
24

35
import requests
46

@@ -25,10 +27,21 @@ def download_wezterm(vendored_dir, wezterm_foldername):
2527
f.write(chunk)
2628

2729
print("📦 Extracting WezTerm with system unzip...")
28-
subprocess.run(
29-
["unzip", "-q", str(wezterm_zip_path), "-d", str(vendored_dir)],
30-
check=True,
31-
)
30+
31+
if platform == "darwin": ## TODO always use same way
32+
subprocess.run(
33+
[
34+
"unzip",
35+
"-q",
36+
str(wezterm_zip_path),
37+
"-d",
38+
str(vendored_dir),
39+
],
40+
check=True,
41+
)
42+
else:
43+
with zipfile.ZipFile(wezterm_zip_path, "r") as zip_ref:
44+
zip_ref.extractall(vendored_dir)
3245

3346
wezterm_zip_path.unlink() # Optional: clean up ZIP
3447
print("✅ WezTerm ready.")

package/terminal_launcher.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,33 @@ def main():
1414

1515
WEZTERM_VERSION = packaging_utils.get_wezterm_version()
1616

17-
if getattr(sys, "frozen", False):
18-
# Running as a bundled executable
19-
base_path = Path(sys.executable).parent.parent
20-
else:
21-
# Running as a script
22-
base_path = Path(__file__).resolve().parent.parent
23-
24-
print("BaSE PATH", base_path)
2517
print("WEZTERM_VERSION", WEZTERM_VERSION)
2618

2719
if platform.system() == "Windows":
20+
if getattr(sys, "frozen", False):
21+
# Running as a bundled executable
22+
base_path = Path(sys.executable).parent
23+
else:
24+
# Running as a script
25+
base_path = Path(__file__).resolve().parent
26+
2827
wezterm_path = (
29-
Path(__file__).parent.parent.parent
28+
Path(__file__).parent.parent
3029
/ f"_vendored\WezTerm-windows-{WEZTERM_VERSION}"
3130
)
3231
wezterm_exe_path = wezterm_path / "wezterm-gui.exe"
3332
wezterm_config_path = wezterm_path / "wezterm_config.lua"
3433
exe = base_path / "datashuttle" / "datashuttle.exe"
3534

3635
elif platform.system() == "Darwin":
36+
# This is a hot mess, almost direct copy from above.
37+
if getattr(sys, "frozen", False):
38+
# Running as a bundled executable
39+
base_path = Path(sys.executable).parent.parent
40+
else:
41+
# Running as a script
42+
base_path = Path(__file__).resolve().parent.parent
43+
3744
wezterm_path = base_path / f"_vendored/WezTerm-macos-{WEZTERM_VERSION}"
3845
wezterm_exe_path = (
3946
wezterm_path / "Wezterm.app/Contents/MacOS/wezterm-gui"
@@ -44,6 +51,7 @@ def main():
4451

4552
# https://github.com/wezterm/wezterm/releases/download/20240203-110809-5046fc22/WezTerm-macos-20240203-110809-5046fc22.zip
4653

54+
print("BaSE PATH", base_path)
4755
print("CWD", os.getcwd())
4856
print("HELLO WORLD")
4957
print("EXE", exe)
@@ -56,7 +64,7 @@ def main():
5664
env["WEZTERM_CONFIG_FILE"] = str(wezterm_config_path.as_posix())
5765

5866
if system == "Windows":
59-
cmd = f'{wezterm_exe_path} start -- cmd /c "echo Starting datashuttle... && {exe}"'
67+
cmd = f'"{wezterm_exe_path}" start -- "{exe}"'
6068

6169
subprocess.Popen(cmd, shell=True, env=env)
6270

package/terminal_launcher_windows.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ exe = EXE(
2424
bootloader_ignore_signals=False,
2525
strip=False,
2626
upx=True,
27-
console=True,
27+
console=False, # Set `True` for debugging
2828
disable_windowed_traceback=False,
2929
argv_emulation=False,
3030
target_arch=None,

0 commit comments

Comments
 (0)