Repository: metacall/core (language: rust)

Issue:
Remove the patching of Find*.cmake files in Windows CI
## 🚀 Feature

https://github.com/metacall/core/blob/develop/tools/metacall-environment.ps1

This is a requirement we can do in the future, but the idea of this is to avoid overwriting those Find*.cmake files so we can also debug and maintain those CMake files. For example, right now FindNodeJS.cmake has bugs in order to find properly the node libraries once it is built.

Maybe the Python or Ruby patches can be maintained because we do not maintain them.

I am not sure if this should be the best approach but it's an idea that I have had in order to keep debugging the CMake files we maintain in the long term. We can do this at the end (once all languages are supported) because it is just an improvement.

It is also problematic in the sense that those script files have been used for developers to configure or install the project dependencies (in Linux at least for now), and if we do the patching.. we break the repository files itself, and it's a not desired behavior.

Also this approach comes from the distributable, which it makes sense because we are just packaging it and there's no need of maintaining those files, and also they are usually placed on non-standard places (usually in the same folder where everything is built), but this is not the same in the developer environment.


Discussion / hints:
@pkspyder007 what do you think about this?
Honestly I don't like patching these cmake files, it's ok in dist version but while developing if we could just simply set some default nodejs location or install nodejs ourselves in the runtimes dir even if it's present and override the env vars

Fix patch:
diff --git a/VERSION b/VERSION
index b09a54cb9..b1d7abc0d 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-0.7.3
\ No newline at end of file
+0.6.2
\ No newline at end of file
diff --git a/tools/metacall-build.ps1 b/tools/metacall-build.ps1
index 77a8e817c..fa118ad68 100755
--- a/tools/metacall-build.ps1
+++ b/tools/metacall-build.ps1
@@ -56,7 +56,7 @@ function sub-build {
 
 		# Prerequisites
 		$files = @(
-			".\runtimes\nodejs\lib\libnode.dll",
+			"$env:ProgramFiles\nodejs\lib\libnode.dll",
 			".\runtimes\ruby\bin\x64-vcruntime140-ruby310.dll"
 		)
 
diff --git a/tools/metacall-configure.ps1 b/tools/metacall-configure.ps1
index d2b07f82d..e4fa73ad3 100755
--- a/tools/metacall-configure.ps1
+++ b/tools/metacall-configure.ps1
@@ -378,7 +378,15 @@ function sub-configure {
 
 	# Build type
 	$Global:BUILD_STRING = "$BUILD_STRING -DCMAKE_BUILD_TYPE=$BUILD_TYPE"
-	
+
+	# Other Environment Options
+	$EnvOpts = Get-Content "$ROOT_DIR\env_vars.txt"
+
+
+	foreach ($opt in $EnvOpts.Split([System.Environment]::NewLine)) {
+		$Global:BUILD_STRING = "$BUILD_STRING $opt"
+	}
+
 	# Execute CMake
 	$CustomFlags = '-DOPTION_BUILD_SECURITY=OFF -DOPTION_FORK_SAFE=OFF -DWARNINGS_ENABLED=OFF' # TODO: Enable warnings when all tests pass
 	echo "BUILD COMMAND: cmake $CustomFlags $BUILD_STRING .."
diff --git a/tools/metacall-environment-win.ps1 b/tools/metacall-environment-win.ps1
new file mode 100644
index 000000000..6db896e40
--- /dev/null
+++ b/tools/metacall-environment-win.ps1
@@ -0,0 +1,290 @@
+$PSDefaultParameterValues['*:Encoding'] = 'utf8'
+
+$Global:ROOT_DIR = "$(Get-Location)"
+$Global:SHOW_HELP = 0
+$Global:PROGNAME = $(Get-Item $PSCommandPath).Basename
+$Global:Arguments = $args
+
+function Set-Python {
+    Write-Output "configure python"
+	Set-Location $ROOT_DIR
+
+	$PythonVersion = '3.9.7'
+	$RuntimeDir    = "$env:ProgramFiles\python"
+	$DepsDir       = "$ROOT_DIR\dependencies"
+
+	mkdir -Force $DepsDir
+	mkdir -Force $RuntimeDir
+	Set-Location $DepsDir
+
+    if (!(Test-Path -Path "$DepsDir\python_installer.exe")) {
+		# Download installer
+		Write-Output "Python installer not found downloading now..."
+		(New-Object Net.WebClient).DownloadFile("https://www.python.org/ftp/python/$PythonVersion/python-$PythonVersion-amd64.exe", "$(Get-Location)\python_installer.exe")
+    }
+
+	Write-Output "Installing python $PythonVersion"
+
+	# Install Python
+	./python_installer.exe /quiet "TargetDir=$RuntimeDir" `
+		Include_debug=1 Include_symbols=1 PrependPath=1 CompileAll=1
+
+	# Set environment variables
+	Add-to-Path $RuntimeDir
+	Add-to-Path "$RuntimeDir\Scripts"
+	[Environment]::SetEnvironmentVariable("PIP_TARGET", "$RuntimeDir\Lib")
+
+	# No patch, save vars for later use
+	$Env_Opts = "$ROOT_DIR\build\env_vars.txt"
+	$PythonRuntimeDir = $RuntimeDir.Replace('\', '/')
+
+	Write-Output "-DPython_VERSION=$PythonVersion" >> $Env_Opts
+	Write-Output "-DPython_ROOT_DIR=""$PythonRuntimeDir""" >> $Env_Opts
+	Write-Output "-DPython_EXECUTABLE=""$PythonRuntimeDir/python.exe""" >> $Env_Opts
+	Write-Output "-DPython_INCLUDE_DIRS=""$PythonRuntimeDir/include""" >> $Env_Opts
+	Write-Output "-DPython_LIBRARIES=""$PythonRuntimeDir/libs/python39_d.lib;$PythonRuntimeDir/libs/python39.lib""" >> $Env_Opts
+
+	$FindPython = "$ROOT_DIR\cmake\FindPython.cmake"
+
+	Write-Output "FIND_PACKAGE_HANDLE_STANDARD_ARGS(Python REQUIRED_VARS Python_EXECUTABLE Python_LIBRARIES Python_INCLUDE_DIRS VERSION_VAR Python_VERSION)" >> $FindPython
+	Write-Output "mark_as_advanced(Python_EXECUTABLE Python_LIBRARIES Python_INCLUDE_DIRS)" >> $FindPython
+
+	# Install dependencies for tests
+	pip3 install requests
+	pip3 install setuptools
+	pip3 install wheel
+	pip3 install rsa
+	pip3 install scipy
+	pip3 install numpy
+	pip3 install scikit-learn
+	pip3 install joblib
+}
+
+function Set-Nodejs {
+	Write-Output "Setting up Node.js"
+	Set-Location $ROOT_DIR
+
+	$DepsDir = "$ROOT_DIR\dependencies"
+	$NodeVersion = "14.18.2"
+	$DLLReleaseVer = "v0.0.1"
+	$RuntimeDir    = "$env:ProgramFiles\nodejs"
+
+	Set-Location $DepsDir
+
+	if (!(Test-Path -Path "$DepsDir\node.msi")) {
+		# Download installer
+		Write-Output "Nodejs MSI installer not found downloading now..."
+		(New-Object Net.WebClient).DownloadFile("https://nodejs.org/download/release/v$NodeVersion/node-v$NodeVersion-x64.msi", "$DepsDir\node.msi")
+    }
+
+	if (!(Test-Path -Path "$DepsDir\node_headers.tar.gz")) {
+		# Download installer
+		Write-Output "Nodejs headers installer not found downloading now..."
+		(New-Object Net.WebClient).DownloadFile("https://nodejs.org/download/release/v$NodeVersion/node-v$NodeVersion-headers.tar.gz", "$DepsDir\node_headers.tar.gz")
+    }
+
+	msiexec.exe /quiet /i "$DepsDir\node.msi" 
+
+	Add-to-Path $RuntimeDir
+	Add-to-Path "$RuntimeDir\include"
+
+	cmake -E tar xzf node_headers.tar.gz
+
+	mkdir "$RuntimeDir\include"
+	Robocopy.exe /move /e "$DepsDir\node-v$NodeVersion\include" "$RuntimeDir\include" /NFL /NDL /NJH /NJS /NC /NS /NP
+	Set-Location $DepsDir
+
+	if (!(Test-Path -Path "$DepsDir\node_dll.zip")) {
+		# Download installer
+		Write-Output "Nodejs Custom DLLs not found downloading now..."
+		(New-Object Net.WebClient).DownloadFile("https://github.com/metacall/node.dll/releases/download/$DLLReleaseVer/node-shared-v$NodeVersion-x64.zip", "$DepsDir\node_dll.zip")
+    }
+
+	Expand-Archive -Path "node_dll.zip" -DestinationPath "$RuntimeDir\lib"
+	
+	$NodeDir  = $RuntimeDir.Replace('\', '/')
+
+	$Env_Opts = "$ROOT_DIR\build\env_vars.txt"
+	Write-Output "-DNodeJS_VERSION=""$NodeVersion""" >> $Env_Opts
+	Write-Output "-DNodeJS_INCLUDE_DIRS=""$NodeDir/include/node""" >> $Env_Opts
+	Write-Output "-DNodeJS_LIBRARY=""$NodeDir/lib/libnode.lib""" >> $Env_Opts
+	Write-Output "-DNodeJS_EXECUTABLE=""$NodeDir/node.exe""" >> $Env_Opts
+	Write-Output "-DNodeJS_LIBRARY_NAME=""libnode.dll""" >> $Env_Opts
+}
+
+function Set-Java {
+		Write-Output "Setting up Java..."
+		$JAVA_VERSION = "17.0.5"
+		$RuntimeDir = "$env:ProgramFiles\openjdk"
+		$DepsDir = "$ROOT_DIR\dependencies"
+
+		Set-Location $DepsDir
+
+		if (!(Test-Path -Path "$DepsDir\openjdk.zip")) {
+			# Download installer
+			Write-Output "OpenJDK not found downloading now..."
+			(New-Object Net.WebClient).DownloadFile("https://aka.ms/download-jdk/microsoft-jdk-$JAVA_VERSION-windows-x64.zip", "$DepsDir\openjdk.zip")
+		}
+
+		Expand-Archive -Path "openjdk.zip" -DestinationPath "$RuntimeDir"
+		robocopy /move /e "$RuntimeDir\jdk-$JAVA_VERSION+8" "$RuntimeDir" /NFL /NDL /NJH /NJS /NC /NS /NP
+
+		Add-to-Path "JAVA_HOME=$RuntimeDir"
+		Add-to-Path "$RuntimeDir\bin"
+		Add-to-Path "$RuntimeDir\bin\server"
+}
+
+function Add-to-Path {
+	$GivenPath = $args[0]
+
+	$NewPath = "$GivenPath;$Env:PATH"
+	setx /M PATH $NewPath
+	$Env:PATH = $NewPath
+
+	$GivenPath >> $env:GITHUB_PATH
+
+	if ( $Null -ne $Env:GITHUB_ENV ) {
+		Write-Output "PATH=$Env:PATH" >> $Env:GITHUB_ENV
+		# echo "{$Env:PATH}" >> $Env:GITHUB_PATH # Doesn't work
+	}
+
+	refreshenv
+
+	Write-Output "PATH:: " $Env:PATH
+}
+
+
+#configure
+
+function configure {
+	# Create option variables file 
+	mkdir "$ROOT_DIR\build"
+	New-Item -Path "$ROOT_DIR\build\env_vars.txt"
+	for ($i = 0; $i -lt $Arguments.Length; $i++) {
+		$var = $Arguments[$i]
+		if ( "$var" -eq 'python' ) {
+			Write-Output "python selected"
+			Set-Python
+		}
+		if ( "$var" -eq 'ruby' ) {
+			Write-Output "ruby selected"
+		}
+		if ( "$var" -eq 'rust' ) {
+			Write-Output "rust selected"
+		}
+		if ( "$var" -eq 'netcore' ) {
+			Write-Output "netcore selected"
+		}
+		if ( "$var" -eq 'netcore2' ) {
+			Write-Output "netcore 2 selected"
+		}
+		if ( "$var" -eq 'netcore5' ) {
+			Write-Output "netcore 5 selected"
+		}
+		if ( "$var" -eq 'rapidjson' ) {
+			Write-Output "rapidjson selected"
+		}
+		if ( "$var" -eq 'funchook' ) {
+			Write-Output "funchook selected"
+		}
+		if ( ("$var" -eq 'v8') -or ("$var" -eq 'v8rep54') ) {
+			Write-Output "v8 selected"
+		}
+		if ( "$var" -eq 'v8rep57' ) {
+			Write-Output "v8 selected"
+		}
+		if ( "$var" -eq 'v8rep58' ) {
+			Write-Output "v8 selected"
+		}
+		if ( "$var" -eq 'v8rep52' ) {
+			Write-Output "v8 selected"
+		}
+		if ( "$var" -eq 'v8rep51' ) {
+			Write-Output "v8 selected"
+		}
+		if ( "$var" -eq 'nodejs' ) {
+			Write-Output "nodejs selected"
+			Set-Nodejs
+		}
+		if ( "$var" -eq 'typescript' ) {
+			Write-Output "typescript selected"
+		}
+		if ( "$var" -eq 'file' ) {
+			Write-Output "file selected"
+		}
+		if ( "$var" -eq 'rpc' ) {
+			Write-Output "rpc selected"
+		}
+		if ( "$var" -eq 'wasm' ) {
+			Write-Output "wasm selected"
+		}
+		if ( "$var" -eq 'java' ) {
+			Write-Output "java selected"
+			Set-Java
+		}
+		if ( "$var" -eq 'c' ) {
+			Write-Output "c selected"
+		}
+		if ( "$var" -eq 'cobol' ) {
+			Write-Output "cobol selected"
+		}
+		if ( "$var" -eq 'swig' ) {
+			Write-Output "swig selected"
+		}
+		if ( "$var" -eq 'metacall' ) {
+			Write-Output "metacall selected"
+		}
+		if ( "$var" -eq 'pack' ) {
+			Write-Output "pack selected"
+		}
+		if ( "$var" -eq 'coverage' ) {
+			Write-Output "coverage selected"
+		}
+		if ( "$var" -eq 'clangformat' ) {
+			Write-Output "clangformat selected"
+		}
+	}
+	
+}
+
+# Help
+function help {
+	Write-Output "Usage: $PROGNAME list of component"
+	Write-Output "Components:"
+	Write-Output "	python"
+	Write-Output "	ruby"
+	Write-Output "	netcore"
+	Write-Output "	netcore2"
+	Write-Output "	netcore5"
+	Write-Output "	rapidjson"
+	Write-Output "	funchook"
+	Write-Output "	v8"
+	Write-Output "	v8rep51"
+	Write-Output "	v8rep54"
+	Write-Output "	v8rep57"
+	Write-Output "	v8rep58"
+	Write-Output "	nodejs"
+	Write-Output "	typescript"
+	Write-Output "	file"
+	Write-Output "	rpc"
+	Write-Output "	wasm"
+	Write-Output "	java"
+	Write-Output "	c"
+	Write-Output "	cobol"
+	Write-Output "	swig"
+	Write-Output "	metacall"
+	Write-Output "	pack"
+	Write-Output "	coverage"
+	Write-Output "	clangformat"
+	Write-Output ""
+}
+
+switch($args.length) {
+	0 {
+		help
+		Break
+	}
+	Default {
+		configure
+	}
+}
\ No newline at end of file


Test patch:
diff --git a/.github/workflows/windows-test.yml b/.github/workflows/windows-test.yml
index 0d5103844..f64a0832a 100644
--- a/.github/workflows/windows-test.yml
+++ b/.github/workflows/windows-test.yml
@@ -36,7 +36,7 @@ jobs:
           arch: amd64
 
       - name: Set up the environment
-        run: cmd.exe /c "powershell .\tools\metacall-environment.ps1 $Env:METACALL_INSTALL_OPTIONS"
+        run: cmd.exe /c "powershell .\tools\metacall-environment-win.ps1 $Env:METACALL_INSTALL_OPTIONS"
         env:
           METACALL_INSTALL_OPTIONS: python nodejs java # ruby netcore5 typescript file rpc wasm java c cobol rust rapidjson funchook swig pack # clangformat v8rep51 coverage
 
@@ -47,7 +47,7 @@ jobs:
           cd "$METACALL_PATH\build"
           cmd.exe /c "powershell ..\tools\metacall-configure.ps1 $Env:METACALL_BUILD_OPTIONS"
         env:
-          METACALL_BUILD_OPTIONS: ${{ matrix.buildtype }} scripts ports tests python nodejs java sanitizer # ruby # netcore5 typescript file rpc wasm java c cobol rust examples dynamic install pack benchmarks # v8 coverage
+          METACALL_BUILD_OPTIONS: ${{ matrix.buildtype }} scripts ports tests python nodejs java sanitizer # ruby netcore5 typescript file rpc wasm java c cobol rust examples dynamic install pack benchmarks # v8 coverage
 
       - name: Build
         working-directory: ./build