Skip to content

[pull] master from winpython:master #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 19, 2025
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
45 changes: 26 additions & 19 deletions generate_a_winpython_distro.bat
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
rem generate_a_winpython_distro.bat: to be launched from a winpython directory, where 'make.py' is
@echo on

REM === Set default values if not already defined ===
REM === Step 01:Set default values if not already defined ===
if not defined my_release_level set "my_release_level=b1"
if not defined my_create_installer set "my_create_installer=True"
if not defined my_constraints set "my_constraints=C:\WinP\constraints.txt"
Expand All @@ -19,7 +19,7 @@ set "my_time=%my_time: =0%"
REM === Define archive log file path ===
set "my_archive_log=%my_archive_dir%\build_%my_pyver%_%my_release%%my_flavor%_%my_release_level%_of_%date:/=-%at_%my_time%.txt"

REM === Set Python version and release ===
REM === Step 02:Set Python version and release ===
if "%my_python_target%"=="311" (
set "my_python_target_release=3119"
set "my_release=2"
Expand All @@ -34,7 +34,7 @@ if "%my_python_target%"=="311" (
set "my_release=1"
)

REM === Define base build and distribution paths ===
REM === Step 03:Define base build and distribution paths ===
set "my_basedir=%my_root_dir_for_builds%\bd%my_python_target%"
set "my_WINPYDIRBASE=%my_basedir%\bu%my_flavor%\WPy%my_arch%-%my_python_target_release%%my_release%%my_release_level%"

Expand All @@ -44,7 +44,7 @@ set my_buildenv=C:\WinPdev\WPy64-310111

call :log_section preparing winPython for %my_pyver% (%my_python_target%)release %my_release%%my_flavor% (%my_release_level%) *** %my_arch% bit ***

REM === Step: Pre-clear previous build infrastructure ===
REM === Step 04: Pre-clear previous build infrastructure ===
if /i "%my_preclear_build_directory%"=="Yes" (
call :log_section Pre-clear previous build infrastructure

Expand All @@ -63,7 +63,7 @@ if /i "%my_preclear_build_directory%"=="Yes" (
)
)

REM === Step: Create new build ===
REM === Step 05: Create new build ===
call :log_section Create a new build

REM Activate base build environment
Expand Down Expand Up @@ -92,7 +92,7 @@ if not exist "%WINPYDIRBASE%\scripts\env.bat" (
exit /b 1
)

REM === Step: Add pre-requisite packages ===
REM === Step 06: Add pre-requisite packages ===
call :log_section Add pre-requisite packages

set "path=%my_original_path%"
Expand All @@ -110,14 +110,14 @@ if defined my_requirements_pre (
echo No pre-requisite packages specified >>"%my_archive_log%"
)

REM === Step: Install main requirement packages ===
REM === Step 07: Install main requirement packages ===
call :log_section Add main requirement packages
python -m pip install -r "%my_requirements%" -c "%my_constraints%" --pre --no-index --trusted-host=None --find-links="%my_find_links%" >>"%my_archive_log%"

REM Patch installed packages to be portable (WinPython style)
python -c "from wppm import wppm;dist=wppm.Distribution(r'%WINPYDIR%');dist.patch_standard_packages('', to_movable=True)"

REM === Define lockfile paths for included wheels ===
REM === Step 08: Define lockfile paths for included wheels ===
set "WINPYVERLOCK=%WINPYVER2:.=_%"
set "LOCKDIR=%WINPYDIRBASE%\..\"

Expand All @@ -126,7 +126,7 @@ set "pip_lock_includedweb=%LOCKDIR%pylock.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%
set "req_lock_includedlocal=%LOCKDIR%requir.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%my_release_level%_wheelslocal.txt"
set "req_lock_includedweb=%LOCKDIR%requir.%WINPYARCH%-%WINPYVERLOCK%%my_flavor%%my_release_level%_wheels.txt"

REM === Step: Add lockfile wheels for the Wheelhouse (optional) ===
REM === Step 09: Add lockfile wheels for the Wheelhouse (optional) ===
if defined wheelhousereq if exist "%wheelhousereq%" (
call :log_section Add wheels for the Wheelhouse

Expand All @@ -147,7 +147,7 @@ rem set path=%my_original_path%
rem call %my_WINPYDIRBASE%\scripts\env.bat


REM === Freeze environment and generate final lockfiles ===
REM === Step 10: Freeze environment and generate final lockfiles ===
call :log_section Freeze environment and generate lockfiles

set "req=%LOCKDIR%requirement.%my_flavor%-%WINPYARCH%bit-%WINPYVERLOCK%_raw.txt"
Expand Down Expand Up @@ -188,12 +188,7 @@ copy /Y "%req_lock_web%" "%my_changelog_reqfile%"

call :log_section Archive success

rem set path=%my_original_path%
rem call %my_WINPYDIRBASE%\scripts\env.bat

%target_python_exe% -m pip freeze > %my_archive_log%.packages_versions.txt

REM === Step 13: Generate changelog and binaries ===
REM === Step 11: Generate changelog and binaries ===
call :log_section Generate changelog and binaries

REM Define markdown changelog filenames
Expand All @@ -212,12 +207,24 @@ REM === Step 13b: Compress distribution to .7z or installer ===
set "stem=WinPython%my_arch%-%WINPYVER2%%my_flavor%%my_release_level%"
%target_python_exe% -c "from wppm import utils; utils.command_installer_7zip(r'%my_WINPYDIRBASE%', r'%my_WINPYDIRBASE%\..', r'%stem%', r'%my_create_installer%')"

REM === Step 12: Final logs and cleanup ===
call :log_section Final logs and cleanup

REM Restore environment
set "path=%my_original_path%"
call "%my_WINPYDIRBASE%\scripts\env.bat"

REM Freeze final package versions to archive
%target_python_exe% -m pip freeze > "%my_archive_log%.packages_versions.txt"

call :log_section END OF CREATION

start notepad.exe %my_archive_log%
start notepad.exe %my_archive_log%.packages_versions.txt
REM Open log files in Notepad for review
start notepad.exe "%my_archive_log%"
start notepad.exe "%my_archive_log%.packages_versions.txt"

set path=%my_original_path%
REM Restore path again (in case env.bat changed it)
set "path=%my_original_path%"
pause
exit

Expand Down
44 changes: 19 additions & 25 deletions make.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Copyright © 2012 Pierre Raybaut
# Copyright © 2014-2025+ The Winpython development team https://github.com/winpython/
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)
# (see wppm/__init__.py for details)

import os
import re
Expand Down Expand Up @@ -40,27 +40,27 @@ def parse_list_argument(argument_value: str | list[str], separator=" ") -> list[
class WinPythonDistributionBuilder:
"""Builds a WinPython distribution."""

def __init__(self, build_number: int, release_level: str, target_directory: Path, wheels_directory: Path,
tools_directories: list[Path] = None, verbose: bool = False,
flavor: str = ""):
def __init__(self, build_number: int, release_level: str, basedir_wpy: Path,
source_dirs: Path, tools_directories: list[Path] = None,
verbose: bool = False, flavor: str = ""):
"""
Initializes the WinPythonDistributionBuilder.
Args:
build_number: The build number (integer).
release_level: The release level (e.g., "beta", "").
target_directory: The base directory below which WinPython will be created.
wheels_directory: Directory containing wheel files for packages.
basedir_wpy: top directory of the build (c:\...\Wpy...)
source_dirs: Directory containing wheel files for packages.
tools_directories: List of directories containing development tools to include.
verbose: Enable verbose output.
flavor: WinPython flavor (e.g., "Barebone").
"""
self.build_number = build_number
self.release_level = release_level
self.target_directory = Path(target_directory)
self.wheels_directory = Path(wheels_directory)
self.winpython_directory = Path(basedir_wpy)
self.target_directory = self.winpython_directory.parent
self.source_dirs = Path(source_dirs)
self.tools_directories = tools_directories or []
self.verbose = verbose
self.winpython_directory: Path | None = None
self.distribution: wppm.Distribution | None = None
self.flavor = flavor
self.python_zip_file: Path = self._get_python_zip_file()
Expand All @@ -69,10 +69,10 @@ def __init__(self, build_number: int, release_level: str, target_directory: Path

def _get_python_zip_file(self) -> Path:
"""Finds the Python .zip file in the wheels directory."""
for source_item in self.wheels_directory.iterdir():
for source_item in self.source_dirs.iterdir():
if re.match(r"(pypy3|python-).*\.zip", source_item.name):
return source_item
raise RuntimeError(f"Could not find Python zip package in {self.wheels_directory}")
raise RuntimeError(f"Could not find Python zip package in {self.source_dirs}")

@property
def winpython_version_name(self) -> str:
Expand Down Expand Up @@ -108,7 +108,6 @@ def _copy_essential_files(self):

def _create_env_config(self):
"""Creates environment setup"""
self._print_action("Creating env.ini environment setup")
executable_name = self.distribution.short_exe if self.distribution else "python.exe"
config = {
"WINPYthon_exe": executable_name,
Expand All @@ -123,10 +122,9 @@ def _create_env_config(self):
self._print_action(f"Creating env.ini environment {env_path}")
env_path.write_text("\n".join(f"{k}={v}" for k, v in config.items()))

def build(self, winpy_dir: Path = None):
def build(self):
"""Make or finalise WinPython distribution in the target directory"""
print(f"Building WinPython with Python archive: {self.python_zip_file.name}")
self.winpython_directory = Path(winpy_dir)
self._print_action(f"Creating WinPython {self.winpython_directory} base directory")
if self.winpython_directory.is_dir() and len(self.winpython_directory.parts)>=4:
shutil.rmtree(self.winpython_directory)
Expand All @@ -139,10 +137,8 @@ def build(self, winpy_dir: Path = None):
self._create_env_config()

def make_all(build_number: int, release_level: str, basedir_wpy: Path = None,
verbose: bool = False,
flavor: str = "",
source_dirs: Path = None, toolsdirs: str | list[Path] = None,
):
verbose: bool = False, flavor: str = ""):
"""
Make a WinPython distribution for a given set of parameters:
Args:
Expand All @@ -157,16 +153,14 @@ def make_all(build_number: int, release_level: str, basedir_wpy: Path = None,
assert basedir_wpy is not None, "The *winpython_dirname* directory must be specified"

tools_directories = [Path(d) for d in parse_list_argument(toolsdirs, ",")]
winpy_dir = Path(basedir_wpy)
utils.print_box(f"Making WinPython at {winpy_dir}")
os.makedirs(winpy_dir, exist_ok=True)
utils.print_box(f"Making WinPython at {basedir_wpy}")
os.makedirs(basedir_wpy, exist_ok=True)

builder = WinPythonDistributionBuilder(
build_number, release_level, winpy_dir.parent, wheels_directory=source_dirs,
tools_directories=tools_directories,
verbose=verbose, flavor=flavor
)
builder.build(winpy_dir)
build_number, release_level, Path(basedir_wpy),
verbose=verbose, flavor=flavor,
source_dirs=source_dirs, tools_directories=tools_directories)
builder.build()

if __name__ == "__main__":
make_all(
Expand Down