Move NSIS patching to rerender and build from locked environment.

This commit is contained in:
Ryan Volz 2023-07-27 18:55:32 -04:00
parent 18d6127d5f
commit 406c969bee
9 changed files with 9283 additions and 97 deletions

View File

@ -53,16 +53,17 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install coreutils for macOS
if: runner.os == 'macOS'
run: brew install coreutils
- name: Install python environment
uses: mamba-org/provision-with-micromamba@main
uses: mamba-org/setup-micromamba@v1
with:
environment-file: buildenv.yaml
environment-file: installer_specs/buildenv.conda-lock.yml
environment-name: buildenv
- name: Build installer
shell: bash -l {0}
@ -183,7 +184,7 @@ jobs:
- name: Upload to Github artifact
if: ${{ (success() || failure()) && !startsWith(github.ref, 'refs/tags/') }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
path: dist/*
name: ${{ matrix.OS_NAME }}-${{ matrix.ARCH }}

View File

@ -110,19 +110,6 @@ if __name__ == "__main__":
platform = spec_dir_extract_platform(args.installer_spec_dir)
if platform.startswith("win"):
# patch constructor's nsis template
import patch_ng
pset = patch_ng.fromfile(
"static/0001-Customize-Windows-NSIS-installer-script.patch"
)
pset.write_hunks(
pathlib.Path(constructor_main.__file__).parent / "nsis" / "main.nsi.tmpl",
args.installer_spec_dir / "main.nsi.tmpl",
pset.items[0].hunks,
)
args.output_dir.mkdir(parents=True, exist_ok=True)
if not platform.startswith("win"):

View File

@ -1,6 +1,10 @@
name: buildenv
channels:
- conda-forge
platforms:
- linux-64
- osx-64
- win-64
dependencies:
- anaconda-client
- conda-build

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,13 @@
#!/usr/bin/env python3
import contextlib
import pathlib
import shutil
from typing import Any, Dict, Optional
import conda_lock
from conda_package_streaming.package_streaming import stream_conda_component
from conda_package_streaming.url import conda_reader_for_url
import diff_match_patch
import yaml
@ -93,10 +97,20 @@ def render_constructors(
company: str,
license_file: pathlib.Path,
output_dir: pathlib.Path,
builder_lockfile_path: pathlib.Path,
) -> None:
lock_content = conda_lock.conda_lock.parse_conda_lock_file(lockfile_path)
lock_work_dir = lockfile_path.parent
builder_lock_content = conda_lock.conda_lock.parse_conda_lock_file(
builder_lockfile_path
)
constructor_lockdeps = [
lockdep
for lockdep in builder_lock_content.package
if lockdep.name == "constructor"
]
# render main + installer env specs into environment file for creating installer
conda_lock.conda_lock.do_render(
lockfile=lock_content,
@ -185,10 +199,65 @@ def render_constructors(
with construct_yaml_path.open("w") as f:
yaml.safe_dump(construct_dict, stream=f)
if platform.startswith("win"):
# patch constructor's nsis template
constructor_platform_lockdeps = [
lockdep
for lockdep in constructor_lockdeps
if lockdep.platform == platform
]
if constructor_platform_lockdeps:
lockdep = constructor_platform_lockdeps[0]
# get the NSIS template that comes with the locked constructor package
constructor_filename, constructor_pkg = conda_reader_for_url(
lockdep.url
)
with contextlib.closing(constructor_pkg):
for tar, member in stream_conda_component(
constructor_filename, constructor_pkg, component="pkg"
):
if (
member.name
== "site-packages/constructor/nsis/main.nsi.tmpl"
):
locked_nsi_tmpl = tar.extractfile(member).read().decode()
break
# read the original and custom NSIS templates
local_constructor_nsis = pathlib.Path("constructor") / "nsis"
with (local_constructor_nsis / "main.nsi.tmpl.orig").open("r") as f:
orig_nsi_tmpl = f.read()
with (local_constructor_nsis / "main.nsi.tmpl").open("r") as f:
custom_nsi_tmpl = f.read()
# get patch from original NSIS template to locked version we will be
# building with and apply it to the custom template
dmp = diff_match_patch.diff_match_patch()
line_orig, line_locked, line_array = dmp.diff_linesToChars(
orig_nsi_tmpl, locked_nsi_tmpl
)
diffs = dmp.diff_main(line_orig, line_locked, checklines=False)
dmp.diff_charsToLines(diffs, line_array)
patches = dmp.patch_make(orig_nsi_tmpl, diffs)
patched_nsi_tmpl, results = dmp.patch_apply(patches, custom_nsi_tmpl)
if not all(results):
raise RuntimeError("Conflicts found when patching NSIS template")
# write patched template to constructor dir
with (constructor_dir / "main.nsi.tmpl").open("w") as f:
f.write(patched_nsi_tmpl)
# update orig and custom with locked and patched
with (local_constructor_nsis / "main.nsi.tmpl.orig").open("w") as f:
f.write(locked_nsi_tmpl)
with (local_constructor_nsis / "main.nsi.tmpl").open("w") as f:
f.write(patched_nsi_tmpl)
def render(
environment_file: pathlib.Path,
installer_environment_file: pathlib.Path,
builder_environment_file: pathlib.Path,
version: str,
company: str,
license_file: pathlib.Path,
@ -219,6 +288,17 @@ def render(
lock_work_dir = output_dir / "lockwork"
lock_work_dir.mkdir(parents=True, exist_ok=True)
# create the locked build environment specification
builder_lockfile_path = output_dir / "buildenv.conda-lock.yml"
conda_lock.conda_lock.run_lock(
environment_files=[builder_environment_file],
conda_exe=conda_exe,
mamba=True,
micromamba=True,
kinds=("lock",),
lockfile_path=builder_lockfile_path,
)
# read environment files and create the lock file
lockfile_path = lock_work_dir / f"{env_name}.conda-lock.yml"
conda_lock.conda_lock.run_lock(
@ -256,6 +336,7 @@ def render(
company=company,
license_file=license_file,
output_dir=output_dir,
builder_lockfile_path=builder_lockfile_path,
)
# clean up conda-lock work dir
@ -309,6 +390,18 @@ if __name__ == "__main__":
" (default: %(default)s)"
),
)
parser.add_argument(
"builder_environment_file",
type=pathlib.Path,
nargs="?",
default=here / "buildenv.yaml",
help=(
"YAML file defining the builder environment for running conda-constructor,"
" with a 'name' string and 'channels', 'platforms', and 'dependencies'"
" lists."
" (default: %(default)s)"
),
)
parser.add_argument(
"-v",
"--version",
@ -378,6 +471,7 @@ if __name__ == "__main__":
render(
environment_file=args.environment_file,
installer_environment_file=args.installer_environment_file,
builder_environment_file=args.builder_environment_file,
version=args.version,
company=args.company,
license_file=args.license_file,

View File

@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ryan Volz <ryan.volz@gmail.com>
Date: Wed, 23 Feb 2022 18:11:22 -0500
Subject: [PATCH] Customize Windows NSIS installer script.
1. Never clear the full pkg dir
2. Delete environment variables set in registry by PothosSDR
3. Do not show "advanced" installation options
---
constructor/nsis/main.nsi.tmpl | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl
index 865ebb3..2e84269 100644
--- a/constructor/nsis/main.nsi.tmpl
+++ b/constructor/nsis/main.nsi.tmpl
@@ -153,7 +153,7 @@ Page Custom InstModePage_Create InstModePage_Leave
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE OnDirectoryLeave
!insertmacro MUI_PAGE_DIRECTORY
# Custom options now differ depending on installation mode.
-Page Custom mui_AnaCustomOptions_Show
+#Page Custom mui_AnaCustomOptions_Show
!insertmacro MUI_PAGE_INSTFILES
#if with_conclusion_text is True
!define MUI_FINISHPAGE_TITLE __CONCLUSION_TITLE__
@@ -1185,7 +1185,7 @@ Section "Install"
${If} $Ana_ClearPkgCache_State = ${BST_CHECKED}
DetailPrint "Clearing package cache..."
- push '"$INSTDIR\_conda.exe" clean --all --force-pkgs-dirs --yes'
+ push '"$INSTDIR\_conda.exe" clean --all --yes'
push 'Failed to clear package cache'
push 'WithLog'
call AbortRetryNSExecWait
@@ -1218,6 +1218,26 @@ Section "Install"
${EndIf}
${If} $ARGV_NoRegistry == "0"
+ # Delete registry entries for environment variables set by PothosSDR
+ # With admin rights, we can delete them
+ ${If} ${UAC_IsAdmin}
+ DetailPrint "Deleting PothosSDR registry environment variables..."
+ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+ DeleteRegValue ${env_hklm} "GR_PREFIX"
+ DeleteRegValue ${env_hklm} "GRC_BLOCKS_PATH"
+ DeleteRegValue ${env_hklm} "UHD_PKG_PATH"
+ DeleteRegValue ${env_hklm} "VOLK_PREFIX"
+ # Without admin rights, we have to shadow them with empty values set for the user
+ ${Else}
+ DetailPrint "Overriding PothosSDR registry environment variables for user..."
+ !define env_hkcu 'HKCU "Environment"'
+ WriteRegExpandStr ${env_hkcu} "GR_PREFIX" ""
+ WriteRegExpandStr ${env_hkcu} "GRC_BLOCKS_PATH" ""
+ WriteRegExpandStr ${env_hkcu} "UHD_PKG_PATH" ""
+ WriteRegExpandStr ${env_hkcu} "VOLK_PREFIX" ""
+ ${EndIf}
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
# Registry uninstall info
WriteRegStr SHCTX "${UNINSTREG}" "DisplayName" "${UNINSTALL_NAME}"
WriteRegStr SHCTX "${UNINSTREG}" "DisplayVersion" "${VERSION}"
@@ -1326,6 +1346,15 @@ Section "Uninstall"
# In case the last command fails, run the slow method to remove leftover
RMDir /r /REBOOTOK "$INSTDIR"
+ # Delete user environment variables that we set during installation
+ ${IfNot} ${UAC_IsAdmin}
+ DeleteRegValue ${env_hkcu} "GR_PREFIX"
+ DeleteRegValue ${env_hkcu} "GRC_BLOCKS_PATH"
+ DeleteRegValue ${env_hkcu} "UHD_PKG_PATH"
+ DeleteRegValue ${env_hkcu} "VOLK_PREFIX"
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${EndIf}
+
${If} $INSTALLER_NAME_FULL != ""
DeleteRegKey SHCTX "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTALLER_NAME_FULL"
${EndIf}
--
2.40.0