Skip to content

Commit

Permalink
Refactor build scripts
Browse files Browse the repository at this point in the history
provide scripts, that simply setup a python env
This env may be used for developers (on windows machines)
Overall flow remains equal, but try to make things a little more
obvious my adding named parameters of scripts.

Signed-off-by: Florian Esser <florian.esser@tngtech.com>
  • Loading branch information
florianesser-tng committed Nov 26, 2024
1 parent 384eb2e commit f9c7cfa
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 342 deletions.
11 changes: 0 additions & 11 deletions WebUI/build/after_build.bat

This file was deleted.

19 changes: 0 additions & 19 deletions WebUI/build/arc_before_build.bat

This file was deleted.

7 changes: 0 additions & 7 deletions WebUI/build/before_build.bat

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
ShowInstDetails show
!macroend
!macro customInstall
IfFileExists "$INSTDIR\resources\env-offline.7z" extracting end
IfFileExists "$INSTDIR\resources\env.7z" extracting end

extracting:
SetDetailsPrint textonly
DetailPrint "Extracting python environment..."
nsExec::ExecToLog '"$INSTDIR\resources\7zr.exe" x "$INSTDIR\resources\env-offline.7z" -o"$INSTDIR\resources"'
Delete "$INSTDIR\resources\env-offline.7z"
nsExec::ExecToLog '"$INSTDIR\resources\7zr.exe" x "$INSTDIR\resources\env.7z" -o"$INSTDIR\resources"'
Delete "$INSTDIR\resources\env.7z"
Delete "$INSTDIR\resources\7zr.exe"

end:
Expand Down
59 changes: 0 additions & 59 deletions WebUI/build/installer.nsh

This file was deleted.

51 changes: 36 additions & 15 deletions WebUI/build/scripts/fetch-python-package-resources.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
// Usage: node fetch-python-package-resources.js <target_dir>
// Usage: node fetch-python-package-resources.js --target-dir=$DIR --conda-env-library-dir=$DIR
const https = require('https');
const fs = require('fs');
const path = require('path');


if (process.argv.length < 3) {
const argv = require('minimist')(process.argv.slice(2));
const targetDirArg = argv.target_dir
const condaEnvLibraryDirArg = argv.conda_env_library_dir

console.error('Usage: fetch-python-package-resources.js <target_dir>');
if (!targetDirArg || !condaEnvLibraryDirArg) {
console.error('Usage: node fetch-python-package-resources.js --target_dir=$DIR --conda_env_library_dir=$DIR\n');
process.exit(1);
}

const targetDir = path.resolve(process.argv[2]);
const targetDir = path.resolve(targetDirArg);
const condaTargetDir = path.join(targetDir, 'conda-env-lib')
const condaEnvLibraryDir = path.resolve(condaEnvLibraryDirArg);

const embeddablePythonUrl = 'https://raw.githubusercontent.com/adang1345/PythonWindows/master/3.11.10/python-3.11.10-embed-amd64.zip';
const getPipScriptUrl = 'https://bootstrap.pypa.io/get-pip.py'
const sevenZrExeUrl = 'https://www.7-zip.org/a/7zr.exe'

function fetchFileIfNotPresent(url, targetDir) {
function fetchFileIfNotPresent(url) {
const expectedFilePath = path.join(targetDir, getBaseFileName(url))
if (fs.existsSync(expectedFilePath)) {
console.log(`omitting fetching of ${url} as ${expectedFilePath} already exists`)
} else {
fetchFile(url, targetDir)
fetchFile(url)
}
}

function fetchFile(url, targetDir) {
function fetchFile(url) {
https.get(url, (response) => {
const filePath = path.join(targetDir, getBaseFileName(url))
const file = fs.createWriteStream(filePath);
Expand All @@ -48,22 +53,38 @@ function getBaseFileName(url) {
}

function prepareTargetPath() {
if (!fs.existsSync(targetDir)) {
if (!fs.existsSync(condaTargetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
}

function provideLibuvDlls() {
console.error("provideLibuvDlls is currently only mocked")
console.error(`please simlink to conda virtual env into ${targetDir} manually`)
function copyLibuvDllsIfNotPresent() {
if (fs.existsSync(path.join(condaTargetDir, 'Library', 'bin', 'uv.dll'))) {
console.log(`omitting fetching copying of libuvDLLs, as they already exist`)
} else {
if (!path.join(condaEnvLibraryDir, 'bin', 'uv.dll')) {
console.log(`provided conda env at ${condaEnvLibraryDir} is missing uv.dll. Aborting`)
process.exit(1);
}
fs.cp(condaEnvLibraryDir, path.join(condaTargetDir, 'Library'), { recursive: true }, (err) => {
if (err) {
console.error(err);
console.log('Failed to copy directory');
process.exit(1)
} else {
console.log('Directory copied successfully');
}
});
}
}


function main() {
prepareTargetPath()
fetchFileIfNotPresent(embeddablePythonUrl, targetDir)
fetchFileIfNotPresent(getPipScriptUrl, targetDir)
fetchFileIfNotPresent(sevenZrExeUrl, targetDir)
provideLibuvDlls()
fetchFileIfNotPresent(embeddablePythonUrl)
fetchFileIfNotPresent(getPipScriptUrl)
fetchFileIfNotPresent(sevenZrExeUrl)
copyLibuvDllsIfNotPresent()
}

main()
73 changes: 73 additions & 0 deletions WebUI/build/scripts/install-full-python-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Usage: node pack-offline.js <npm_package_res_dir> <platform>
//
const fs = require('fs');
const path = require('path');
const AdmZip = require('adm-zip');
const childProcess = require('child_process');

const argv = require('minimist')(process.argv.slice(2));
const envDirArg = argv.env_dir
const platformArg = argv.platform

if (!envDirArg || !platformArg) {
console.error('Usage: node install-full-python-env.js --env_dir=$DIR ---platform=arc|ultra|ultra2\n');
process.exit(1);
}

const envDir = existingFileOrExit(path.resolve(envDirArg));
const platform = platformArg;

function existingFileOrExit(filePath) {
if (!fs.existsSync(filePath)) {
console.error('Resource not found:', filePath);
process.exit(1);
}
return filePath
}


function installPip(pythonExe, getPipFilePath) {
const runGetPip = childProcess.spawnSync(pythonExe, [getPipFilePath]);
console.log(runGetPip.stdout.toString());
//console.error(runGetPip.stderr.toString());
if (runGetPip.status!== 0) {
console.error('Failed to install requirements');
process.exit(1);
}
console.log('Successfully installed pip');
}

function runPipInstall(pythonExe, requirementsFilePath) {
console.log(`installing python dependencies from ${requirementsFilePath}`);
const pipInstall = childProcess.spawnSync(pythonExe, ['-m', 'pip', 'install', '-r', requirementsFilePath]);
console.log(pipInstall.stdout.toString());
console.error(pipInstall.stderr.toString());
if (pipInstall.status!== 0) {
console.error('Failed to install requirements');
process.exit(1);
}
console.log(`Installed dependencies from ${requirementsFilePath} successfully`);
}

function copyToTargetDir(sourceDir, targetDir) {
fs.cpSync(sourceDir, targetDir, { recursive: true });
console.log(`copied resources to ${targetDir}`)
}


function main() {
const targetDir = path.join(envDir, '..', `env-full-${platform}`);
copyToTargetDir(envDir, targetDir)

const pythonExe = existingFileOrExit(path.join(targetDir, 'python.exe'));
const getPipFile = existingFileOrExit(path.join(targetDir, 'get-pip.py'));

const platformSpecificRequirementsTxt = existingFileOrExit(path.join(__dirname, '..', '..','..', 'service', `requirements-${platform}.txt`));
const requirementsTxt = existingFileOrExit(path.join(__dirname, '..', '..', '..', 'service', `requirements.txt`));

installPip(pythonExe, getPipFile)
runPipInstall(pythonExe, platformSpecificRequirementsTxt)
runPipInstall(pythonExe, requirementsTxt)
}

main();
109 changes: 0 additions & 109 deletions WebUI/build/scripts/pack-offline.js
Original file line number Diff line number Diff line change
@@ -1,109 +0,0 @@
// Usage: node pack-offline.js <npm_package_res_dir> <platform>
//
const fs = require('fs');
const path = require('path');
const AdmZip = require('adm-zip');
const childProcess = require('child_process');

if (process.argv.length < 4) {
console.error('Usage: node pack-offline.js <npm_package_res_dir> <platform>');
process.exit(1);
}

const packageResDir = existingFileOrExit(path.resolve(process.argv[2]));
const platform = process.argv[3];

const sevenZipExe = existingFileOrExit(path.join(packageResDir, '7zr.exe'));
const zippedPyenv = existingFileOrExit(path.join(packageResDir, 'env.7z'));

function existingFileOrExit(filePath) {
if (!fs.existsSync(filePath)) {
console.error('Resource not found:', filePath);
process.exit(1);
}
return filePath
}


function unzippedPackagedPyenv(pyenvArchive) {
existingFileOrExit(pyenvArchive)
const pyenvTargetDir = workDir

if (fs.existsSync(pyenvTargetDir)) {
console.warn("Removing existing offline env directory:", pyenvTargetDir);
fs.rmSync(workDir, { recursive: true });
}

const unzip = childProcess.spawnSync(sevenZipExe, ['x', pyenvArchive, `-o${workDir}`]);
console.log(unzip.stdout.toString());
console.error(unzip.stderr.toString());
if (unzip.status !== 0) {
console.error('Failed to extract env.7z');
process.exit(1);
}

const offlineEnvDir = existingFileOrExit(path.join(workDir, 'env'));
return offlineEnvDir
}

function installPip(getPipFilePath, workingDir) {
const runGetPip = spawn(pythonExe, [getPipFilePath], { cwd: workingDir });
runGetPip.stdout.on('data', (data) => {
console.log(data.toString());
});
runGetPip.stderr.on('data', (data) => {
console.error(data.toString());
});
pipInstall.on('close', (code) => {
if (code !== 0) {
console.error('Failed to install pip');
process.exit(1);
}
});
}

function runPipInstall(requirementsFilePath, workingDir) {
const pipInstall = spawn(pythonExe, ['-m', 'pip', 'install', '-r', requirementsFilePath], { cwd: workingDir });
pipInstall.stdout.on('data', (data) => {
console.log(data.toString());
});
pipInstall.stderr.on('data', (data) => {
console.error(data.toString());
});
pipInstall.on('close', (code) => {
if (code !== 0) {
console.error('Failed to install requirements');
process.exit(1);
}
});
}

function zipPyenv(pyEnvDir) {
const offlineEnvArchiveTargetPath = path.join(packageResDir, `env-offline-${platform}.7z`);
const zip = childProcess.spawnSync((sevenZipExe, ['a', offlineEnvArchiveTargetPath, existingFileOrExit(pyEnvDir)]);
console.log(zip.stdout.toString());
console.error(zip.stderr.toString());
if (zip.status !== 0) {
console.error('Failed to compress offline env directory');
process.exit(1);
}

console.log('Offline env has been created successfully:', offlineEnvArchiveTargetPath);
}

function main() {
const workDir = path.join(__dirname, `env-${platform}`);

const offlineEnvDir = unzippedPackagedPyenv(zippedPyenv)
const pythonExe = existingFileOrExit(path.join(offlineEnvDir, 'python.exe'));

const getPipFile = existingFileOrExit(path.join(offlineEnvDir, 'get-pip.py'));
const platformSpecificRequirementsTxt = existingFileOrExit(path.join(__dirname, '..', '..', 'service', `requirements-${platform}.txt`));
const requirementsTxt = existingFileOrExit(path.join(__dirname, '..', '..', 'service', `requirements.txt`));

installPip(getPipFile, offlineEnvDir)
runPipInstall(platformSpecificRequirementsTxt, offlineEnvDir)
runPipInstall(requirementsTxt, offlineEnvDir)

zipPyenv(offlineEnvDir)
}
Loading

0 comments on commit f9c7cfa

Please sign in to comment.