PsCraft.psm1
using namespace System using namespace System.IO using namespace System.Management.Automation using module Private/PsCraft.CodeSigner using module Private/PsCraft.ModuleManager # .SYNOPSIS # PsCraft: the giga-chad module builder and manager. # .EXAMPLE # [PsModule]$module = New-PsModule "MyModule" # Creates a new module named "MyModule" in $pwd # $builder = [PsCraft]::new($module.Path) class PsCraft : ModuleManager { static [PsObject] $LocalizedData = (Read-ModuleData) static [IO.FileInfo] InstallPsGalleryModule([string]$moduleName) { return [PsCraft]::InstallPsGalleryModule($moduleName, 'latest', $false) } static [IO.FileInfo] InstallPsGalleryModule([string]$moduleName, [string]$Version, [bool]$UpdateOnly) { # .SYNOPSIS # This method is like install-Module but it installs a PowerShell module no matter what. # .DESCRIPTION # Even on systems that seem to not have a broken PowerShellGet. $Module_Path = ''; $IsValidversion = ($Version -as 'version') -is [version] -or $Version -eq 'latest' if (!$IsValidversion) { throw [System.ArgumentException]::New('Please Provide a valid version string') } $IsValidName = $moduleName -match '^[a-zA-Z0-9_.-]+$' if (!$IsValidName) { throw [System.ArgumentException]::New('Please Provide a valid module name') } # Try Using normal Installation try { if ($UpdateOnly) { [void][PsCraft]::UpdateModule($moduleName, $Version) } else { [void][PsCraft]::InstallModule($moduleName, $Version) } $Module_Path = ([PsCraft]::FindLocalPsModule($moduleName)).Psd1 | Split-Path -ErrorAction Stop } catch { $Module_Path = [PsCraft]::ManuallyInstallModule($moduleName, $Version) } return $Module_Path } static [LocalPsModule[]] Search([string]$Name) { [ValidateNotNullOrWhiteSpace()][string]$Name = $Name $res = @(); $AvailModls = Get-Module -ListAvailable -Name $Name -Verbose:$false -ErrorAction Ignore if ($null -ne $AvailModls) { foreach ($m in ($AvailModls.ModuleBase -as [string[]])) { if ($null -eq $m) { $res += [PsCraft]::FindLocalPsModule($Name, 'LocalMachine', $null); continue } if ([IO.Directory]::Exists($m)) { $res += [PsCraft]::FindLocalPsModule($Name, [IO.DirectoryInfo]::New($m)) } } } return $res } } # Types that will be available to users when they import the module. $typestoExport = @( [moduleManager], [LocalPsModule], [PsModule], [PsCraft] ) $TypeAcceleratorsClass = [PsObject].Assembly.GetType('System.Management.Automation.TypeAccelerators') foreach ($Type in $typestoExport) { if ($Type.FullName -in $TypeAcceleratorsClass::Get.Keys) { $Message = @( "Unable to register type accelerator '$($Type.FullName)'" 'Accelerator already exists.' ) -join ' - ' [System.Management.Automation.ErrorRecord]::new( [System.InvalidOperationException]::new($Message), 'TypeAcceleratorAlreadyExists', [System.Management.Automation.ErrorCategory]::InvalidOperation, $Type.FullName ) | Write-Warning } } # Add type accelerators for every exportable type. foreach ($Type in $typestoExport) { $TypeAcceleratorsClass::Add($Type.FullName, $Type) } # Remove type accelerators when the module is removed. $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { foreach ($Type in $typestoExport) { $TypeAcceleratorsClass::Remove($Type.FullName) } }.GetNewClosure(); $scripts = @(); $Public = Get-ChildItem "$PSScriptRoot/Public" -Filter "*.ps1" -Recurse -ErrorAction SilentlyContinue $scripts += Get-ChildItem "$PSScriptRoot/Private" -Filter "*.ps1" -Recurse -ErrorAction SilentlyContinue $scripts += $Public foreach ($file in $scripts) { Try { if ([string]::IsNullOrWhiteSpace($file.fullname)) { continue } . "$($file.fullname)" } Catch { Write-Warning "Failed to import function $($file.BaseName): $_" $host.UI.WriteErrorLine($_) } } $Param = @{ Function = $Public.BaseName Cmdlet = '*' Alias = '*' } Export-ModuleMember @Param |