Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Creates and activates virtual environment, installs requirements, and
- runs a python script. See "Get-Help path-to-script.ps1 -detailed".
- .DESCRIPTION
- This script will perform the following actions:
- 1. changes the current working directory.
- 2. creates and activates a python virtual environment.
- 3. pip installs requirements file if it exist.
- 4. runs the entrypoint python script with optional arguments.
- 5. reverts to the original working directory when finished.
- The default arguments were set up for a particular use-case: they can be
- easily changed by editing the "[CmdletBinding()]" portion of this script.
- Note: If you're using pyenv make sure a global python is configured, or
- that a valid ".python-version" file is present in the working_directory.
- .PARAMETER working_directory
- -wd <String> (default: "./src/")
- The working directory for the script.
- .PARAMETER virtual_environment
- -venv <String> (default: "../.venv/")
- The path to a virtual environment folder.
- May be absolute or relative to the working_directory argument.
- If the folder or its activate script doesn't exist, it will be created.
- .PARAMETER requirements
- -r <String> (default: "requirements.txt")
- The path to a pip-compatible requirements file.
- May be absolute or relative to the working_directory argument.
- For ease of use, it's not an error if the file doesn't exist.
- .PARAMETER entrypoint
- -py <String>
- Filepath to the python script to be executed.
- May be absolute or relative to the working_directory argument.
- .PARAMETER launch_args
- -args <String[]>
- Arguments that will be forwarded to the executable. (None if empty)
- .PARAMETER dry_run
- -dry
- When this argument is present, the entrypoint will not be launched.
- Instead, only a message will be printed.
- .PARAMETER verbose
- Print verbose logging and debug details (Powershell feature)
- .NOTES
- Author: Alaestor Weissman
- Discord: honshitsu
- Date: 2024-03
- SemVer: 0.1.0
- #>
- [CmdletBinding()]
- Param(
- [ValidateScript({
- if (-Not (Test-Path -LiteralPath $_ ) )
- { throw "Working Directory folder doesn't exist." }
- return $true
- })]
- [String] [Alias("wd")] $working_directory = "./src/",
- [ValidateNotNullorEmpty ()]
- [String] [Alias("venv")] $virtual_environment = "../.venv/",
- [ValidateScript({
- if ([System.IO.Path]::IsPathRooted($_)) {
- $t = $_
- }
- else {
- $t = Join-Path -Path $working_directory -ChildPath $_
- }
- if (-Not (Test-Path -LiteralPath $t ) )
- { throw "Entrypoint doesn't exist." }
- elseif (-Not (Test-Path -LiteralPath $t -PathType Leaf) )
- { throw "Entrypoint is not a file." }
- return $true
- })]
- [ValidateNotNullorEmpty ()]
- [String] [Alias("py")] $entrypoint = "main.py",
- [ValidateNotNullorEmpty ()]
- [String] [Alias("r")] $requirements = "requirements.txt",
- [String[]] [Alias("args")] $launch_args=@(""),
- [Switch] [Alias("dry")] $dry_run
- )
- $original_cwd = (Get-Item .).FullName
- $debug = $DebugPreference -ne "SilentlyContinue"
- function main {
- try
- {
- Write-Verbose ((
- "State",
- "---",
- "OWD: $original_cwd",
- "CWD: $working_directory",
- "DRY: $($dry_run.IsPresent)",
- "ENT: $entrypoint",
- "ARG: $launch_args",
- "REQ: $requirements",
- "DBP: $DebugPreference",
- "---"
- )-join("`n"))
- # Enter the working directory
- Set-Location -LiteralPath $working_directory
- # Create and Activate the virtual environment
- InitializeVirtualEnvironment($virtual_environment)
- # Install requirements if they exist (suppressing boolean output)
- [Void]$(InstallRequirements($requirements))
- # Execute the target python script
- if ($dry_run.IsPresent){
- Write-Host "Execution was prevented (dry_run). Would have run:"
- Write-Host $entrypoint @launch_args
- }
- else {
- python $entrypoint @launch_args
- }
- }
- catch
- {
- $Host.UI.WriteErrorLine((
- "---------------",
- "--- ERROR ---",
- "---------------"
- ) -join "`n"
- )
- if ($debug) {
- $_ | Format-List * -Force
- $_.InvocationInfo | Format-List *
- }
- else {
- $Host.UI.WriteErrorLine(((
- [String]$_.CategoryInfo,
- [String]$_.Exception.ErrorRecord,
- [String]$_.InvocationInfo.PositionMessage
- ) -join "`n"
- ))
- }
- $Host.UI.WriteErrorLine("---------------")
- }
- finally
- {
- # Return to the original working directory
- Set-Location -LiteralPath $original_cwd
- # Exit virtual environment if the command to do so is available
- if ((Get-Command "deactivate" -ErrorAction SilentlyContinue) -ne $null) {
- deactivate
- }
- }
- Exit
- }
- # Creates and activates the virtual environment folder. Throws on error
- function InitializeVirtualEnvironment($folderpath) {
- # Ensure we have python
- if ((Get-Command "python" -ErrorAction SilentlyContinue) -eq $null) {
- throw "Python was not found"
- }
- $activate = Join-Path -Path $folderpath -ChildPath "Scripts\Activate.ps1"
- # Create virtual environment if it doesn't already exist
- if (-not (Test-Path $activate)) {
- python -m venv $folderpath
- if ($LastExitCode -ne 0) {
- throw "Failed to create virtual environment"
- }
- }
- # Ensure virtual environment's activate script exist
- if (-not (Test-Path $activate)) {
- throw "Virtual environment or activate script not found"
- }
- # Activate virtual environment
- & $activate
- # Ensure Python is running in a virtual environment
- python -c 'import sys;sys.exit(0 if sys.prefix != sys.base_prefix else -1)'
- if ($LastExitCode -ne 0) {
- throw "Python appears to not be running in a virtual environment"
- }
- }
- # Returns true if successful, false if file not found. Throws on error
- function InstallRequirements($filepath) {
- if (Test-Path $filepath) {
- pip install -r $filepath --quiet --disable-pip-version-check
- if ($LastExitCode -ne 0) {
- throw "Failed to install the requirements from $filepath"
- }
- return $true
- }
- return $false
- }
- main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement