diff --git a/base/Aliases/dcedit.ps1 b/Aliases/dcedit.ps1 similarity index 100% rename from base/Aliases/dcedit.ps1 rename to Aliases/dcedit.ps1 diff --git a/base/Aliases/dco.ps1 b/Aliases/dco.ps1 similarity index 100% rename from base/Aliases/dco.ps1 rename to Aliases/dco.ps1 diff --git a/base/Aliases/dps.ps1 b/Aliases/dps.ps1 similarity index 100% rename from base/Aliases/dps.ps1 rename to Aliases/dps.ps1 diff --git a/base/Aliases/edit b/Aliases/edit similarity index 100% rename from base/Aliases/edit rename to Aliases/edit diff --git a/base/Aliases/l.ps1 b/Aliases/l.ps1 similarity index 100% rename from base/Aliases/l.ps1 rename to Aliases/l.ps1 diff --git a/base/Aliases/ll.ps1 b/Aliases/ll.ps1 similarity index 100% rename from base/Aliases/ll.ps1 rename to Aliases/ll.ps1 diff --git a/base/Aliases/sz-update.ps1 b/Aliases/sz-update.ps1 similarity index 100% rename from base/Aliases/sz-update.ps1 rename to Aliases/sz-update.ps1 diff --git a/base/Aliases/vi b/Aliases/vi similarity index 100% rename from base/Aliases/vi rename to Aliases/vi diff --git a/base/Aliases/vidc.ps1 b/Aliases/vidc.ps1 similarity index 100% rename from base/Aliases/vidc.ps1 rename to Aliases/vidc.ps1 diff --git a/base/Aliases/vim b/Aliases/vim similarity index 100% rename from base/Aliases/vim rename to Aliases/vim diff --git a/base/ConvertFrom-Base64.ps1 b/ConvertFrom-Base64.ps1 similarity index 100% rename from base/ConvertFrom-Base64.ps1 rename to ConvertFrom-Base64.ps1 diff --git a/docker/Edit-DockerCompose.ps1 b/Edit-DockerCompose.ps1 similarity index 50% rename from docker/Edit-DockerCompose.ps1 rename to Edit-DockerCompose.ps1 index cb715a9..9d491f4 100644 --- a/docker/Edit-DockerCompose.ps1 +++ b/Edit-DockerCompose.ps1 @@ -1,18 +1,4 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [ArgumentCompleter({ param ( - $commandName, - $parameterName, - $wordToComplete, - $commandAst, - $fakeBoundParameters - ) - [DockerComposeDirs]::_GetValidValues($wordToComplete,$true) - })] - [string[]]$ProjectPath=@($PWD), - [switch]$Force, - [string[]]$AdditionalFiles - -) +[CmdletBinding(SupportsShouldProcess)]param([string[]]$ProjectPath=@($PWD),[switch]$Force) $local:editCandidates = @('docker-compose.yml','.base.docker-compose.yml') $local:editFiles = @() @@ -23,6 +9,6 @@ foreach( $local:fileName in $EditCandidates ) { } } -Edit-TextFile ($($editFiles | Sort-Object) + $AdditionalFiles) +Edit-TextFile $editFiles $editFiles | Select-Object -First 1 | ForEach-Object { docker-compose --file $(Resolve-Path $_) config -q } diff --git a/base/Edit-MyConfig.ps1 b/Edit-MyConfig.ps1 similarity index 100% rename from base/Edit-MyConfig.ps1 rename to Edit-MyConfig.ps1 diff --git a/base/Edit-MyProfiles.ps1 b/Edit-MyProfiles.ps1 similarity index 100% rename from base/Edit-MyProfiles.ps1 rename to Edit-MyProfiles.ps1 diff --git a/base/Edit-MyScript.ps1 b/Edit-MyScript.ps1 similarity index 73% rename from base/Edit-MyScript.ps1 rename to Edit-MyScript.ps1 index 8095b79..50cf3b0 100644 --- a/base/Edit-MyScript.ps1 +++ b/Edit-MyScript.ps1 @@ -16,13 +16,10 @@ $commandAst, $fakeBoundParameters ) - $local:NotAll = $true - if( $fakeBoundParameters.ContainsKey("All") ) { $NotAll = -not $fakeBoundParameters.All } - [Packagesz]::_GetValidValues($wordToComplete,$NotAll,$true) + [SystemName]::_GetValidValues($wordToComplete,$false,$true) })] - [string]$Package, + [string]$System, [switch]$ForceImport, - [switch]$All, [Parameter(Position = 0, ValueFromRemainingArguments = $true)] [ArgumentCompleter({ param ( $commandName, @@ -31,25 +28,18 @@ $commandAst, $fakeBoundParameters ) - $local:NotAll = $true - $local:Pkg = [string]::Empty - if( $fakeBoundParameters.ContainsKey("All") ) { $NotAll = -not $fakeBoundParameters.All } - if( $fakeBoundParameters.ContainsKey("Package") ) { $Pkg = Join-Path $fakeBoundParameters.Package '' } - $local:possibleValues = [MyScript]::_GetValidValues($wordToComplete,$NotAll,$true) - if( $Pkg ) { - $possibleValues = $possibleValues | - Where-Object { $_ -match "^$Pkg" } | - ForEach-Object { $_.Replace($Pkg,'') } + $local:possibleValues = [MyScript]::_GetValidValues($wordToComplete,$true) + if( $fakeBoundParameters.ContainsKey("System") ) { + $possibleValues = $possibleValues | Where-Object { $_ -match "^sys\.$($fakeBoundParameters.System)" } | ForEach-Object { $_ -replace "^sys\.$($fakeBoundParameters.System).",'' } } - $possibleValues })] [string[]]$ScriptName ) $local:EditRootPath=$MyPSScriptRoot -if( $Package ) { - $EditRootPath = Join-Path $EditRootPath $Package +if( $System ) { + $EditRootPath = Join-Path $EditRootPath "sys.$System" } $local:ScriptPaths = @() foreach( $local:p in $ImportFunction ) { diff --git a/base/Edit-TextFile.ps1 b/Edit-TextFile.ps1 similarity index 100% rename from base/Edit-TextFile.ps1 rename to Edit-TextFile.ps1 diff --git a/docker/Get-DockerProcess.ps1 b/Get-DockerProcess.ps1 similarity index 100% rename from docker/Get-DockerProcess.ps1 rename to Get-DockerProcess.ps1 diff --git a/Get-MyScript.ps1 b/Get-MyScript.ps1 new file mode 100644 index 0000000..f438b76 --- /dev/null +++ b/Get-MyScript.ps1 @@ -0,0 +1,8 @@ +[CmdletBinding()]param( + [string]$Filter, + [switch]$NamesOnly +) +$local:rVal = [MyScript]::_GetValidValues($Filter,$true) +if( $NamesOnly ) { return $rVal } +return $rVal | ForEach-Object { Join-Path $MyPSScriptRoot "$_`.ps1" } + diff --git a/base/Get-Path.ps1 b/Get-Path.ps1 similarity index 100% rename from base/Get-Path.ps1 rename to Get-Path.ps1 diff --git a/base/Get-PossibleArguments.ps1 b/Get-PossibleArguments.ps1 similarity index 100% rename from base/Get-PossibleArguments.ps1 rename to Get-PossibleArguments.ps1 diff --git a/base/Get-Profiles.ps1 b/Get-Profiles.ps1 similarity index 100% rename from base/Get-Profiles.ps1 rename to Get-Profiles.ps1 diff --git a/base/Get-ScopeDepth.ps1 b/Get-ScopeDepth.ps1 similarity index 100% rename from base/Get-ScopeDepth.ps1 rename to Get-ScopeDepth.ps1 diff --git a/base/Invoke-Sudo.ps1 b/Invoke-Sudo.ps1 similarity index 100% rename from base/Invoke-Sudo.ps1 rename to Invoke-Sudo.ps1 diff --git a/README.md b/README.md index d07aac3..47dd6b2 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,14 @@ iwr https://lksz.me/pwsz | iex ``` This sets up the `$PROFILE` file, and initilizes the default dir `$MyPSScriptRoot` with a git clone of this repo. -The `https://lksz.me/pwsz` actually points to the [`Setup-Profile.ps1`](base/Setup-Profile.ps1) script, which means, that after you have the `Scripts` directory setup, you can call `Setup-Profile` to update the `$PROFILE` after the `Setup-Profile.ps1` has been modified (or updated via `git pull`). +The `https://lksz.me/pwsz` actually points to the [`Setup-Profile.ps1`](Setup-Profile.ps1) script, which means, that after you have the `Scripts` directory setup, you can call `Setup-Profile` to update the `$PROFILE` after the `Setup-Profile.ps1` has been modified (or updated via `git pull`). -### The somewhat Short, but with control option +### The Short, but with control option ```PowerShell $sfw=1; iwr https://lksz.me/pwsz | iex; _setup [-sudo] [-Force] [-NoGitClone] [-GitURL ] [-WhatIf] [-Confirm] [] ``` -The key here is `$sfw=1`, which can be substitued with the more verbose `$SetupFromWeb=1`, this let's the [`Setup-Profile`](base/Setup-Profile.ps1) script know to just load it's content, but allow you to manually call it's internal function via `_setup` +The key here is `$sfw=1`, which can be substitued with the more verbose `$SetupFromWeb=1`, this let's the [`Setup-Profile`](Setup-Profile.ps1) script know to just load it's content, but allow you to manually call it's internal function via `_setup` ### The 'I don't trust one liners, what's going on ?!?' option -You can always clone the git repo first, and only then run the [`Setup-Profile.ps1`](base/Setup-Profile.ps1) script. +You can always clone the git repo first, and only then run the [`Setup-Profile.ps1`](Setup-Profile.ps1) script. \ No newline at end of file diff --git a/Reload-MyScripts.ps1 b/Reload-MyScripts.ps1 new file mode 100644 index 0000000..c421da8 --- /dev/null +++ b/Reload-MyScripts.ps1 @@ -0,0 +1,88 @@ +[CmdletBinding(SupportsShouldProcess)]param() + +try { Get-Alias Get-MyAliases -ErrorAction Stop | ForEach-Object { Remove-Item "Alias:$($_.Name)" } } catch {} +function Get-MyAliases { +[CmdletBinding(SupportsShouldProcess)]param([switch]$ScriptsOnly) + + $local:allAliases = @() + + $MyAliasScope = 0 + $local:_scope = 0 + $local:_done = $false + do { + try { + $local:newAliases += Get-Alias -Scope $_scope | + Where-Object { + ($_.Definition -match "^$MyPSScriptRoot") -or (-not $ScriptsOnly -and ($_.Description -match '#MyAlias')) + } + if( $newAliases ) { + $allAliases += $newAliases + $MyAliasScope = $_scope; + Write-Verbose "`$MyAliasScope is now set to $MyAliasScope" + } + } catch { + Write-Verbose "catch: $($_.Exception.Message)" + $_done = $_.Exception.Message -match 'The scope .* exceeds' + } + $_scope += 1 + } until ( $_done ) + + $allAliases +} + +function getScriptName{param([string]$FullPath) + $FullPath -replace '\.ps1$','' -replace "^$([regex]::Escape($MyPSScriptRoot)).",'' +} + +$local:myAliases = [ordered]@{} +if( Test-Path $(Join-Path $MyPSScriptRoot Aliases) ) { + Get-ChildItem $(Join-Path $MyPSScriptRoot Aliases) | ForEach-Object { + $myAliases[$_.BaseName] = Get-Content $_.FullName + } +} + +$local:IsVerbose = [bool]($PSBoundParameters['Verbose']) + +$script:MyAliasScope = 0 + +$local:oldAliases = Get-MyAliases + +$oldAliases = Get-Alias -Scope $MyAliasScope | + Where-Object Name -in $($oldAliases.Name + $myAliases.Keys) + +if( $oldAliases -and $IsVerbose ) { + Write-Verbose "Removing: $($oldAliases.Name -join ', ')" +} +if( Get-Command Remove-Alias -ErrorAction SilentlyContinue ) { + $oldAliases | Remove-Alias -Scope $MyAliasScope +} else { + $oldAliases | ForEach-Object { Remove-Item "Alias:$($_.Name)" } +} + +if( $(. Get-ScopeDepth) -gt 0 ) { Write-Host -ForegroundColor Red "Try sourcing Reload-MyScripts instead of just running it" } +Get-ChildItem $(Join-Path $MyPSScriptRoot profile.d) -Filter '*.ps1' | ForEach-Object { + Write-Verbose "Loading $(getScriptName $_.FullName)..."; + ". '$($_.FullName)';" + } | Invoke-Expression + +$local:CommandsToAlias = ( + @( $MyPSScriptRoot ) + $( + [SystemName]::_GetValidValues("",$true,$true) | ForEach-Object { + Join-Path $MyPSScriptRoot "sys.$_" + } + )) | ForEach-Object { + if( Test-Path $_ ) { + Get-ChildItem (Join-Path $_ '*.ps1') | Where-Object Name -notmatch '\.inc\.ps1$' + } + } + +$CommandsToAlias | ForEach-Object { + Write-Verbose "Creating alias for $(getScriptName $_.FullName) Script..." + Set-Alias $($_.BaseName) $_.FullName -Scope $MyAliasScope + } + +foreach( $local:alias in $myAliases.Keys ) { + Write-Verbose "Adding $($alias) alias..." + Set-Alias -Name $alias -Value $myAliases[$alias] -Description '#MyAlias' -Scope $MyAliasScope +} + diff --git a/base/Setup-Profile.ps1 b/Setup-Profile.ps1 similarity index 95% rename from base/Setup-Profile.ps1 rename to Setup-Profile.ps1 index 8acf000..b4276dc 100644 --- a/base/Setup-Profile.ps1 +++ b/Setup-Profile.ps1 @@ -371,23 +371,9 @@ param( $local:src = "" foreach ( $local:func in $FunctionName ) { - $local:funcDef = $null - foreach( $cmd in (Get-Command -All $func) ) { - if( $cmd.CommandType -in @('Function','Filter') ) { - $funcDef = $cmd.Definition - break - } elseif( -$funcDef -and ($cmd.CommandType -in @('Script','ExternalScript')) ) { - $funcDef = Get-Content $cmd.Definition - } - } - if( -not $funcDef ) { - default { throw "Don't know how to handle $func" } - } - if ( -not $NoHeader ) { $src += "`nfunction $func {" } $src += "`n" - - $src += $funcDef + $src += $((Get-Command -Type Function $func).Definition) if ( -not $NoHeader ) { $src += "`n}" } $src += "`n" } @@ -424,12 +410,11 @@ $local:My_PSScriptRoot = Join-Path (Split-Path -Parent $MyPSModulePath) Scripts Write-Verbose "MyPSScriptRoot = $My_PSScriptRoot" if ( -not (Test-Path $My_PSScriptRoot) ) { New-Item -ItemType Directory -Path $My_PSScriptRoot -Force | Out-Null - New-Item -ItemType Directory -Path $(Join-Path $My_PSScriptRoot base) -Force | Out-Null - New-Item -ItemType Directory -Path $(Join-Path $(Join-Path $My_PSScriptRoot base) profile.d) -Force | Out-Null + New-Item -ItemType Directory -Path $My_PSScriptRoot/profile.d -Force | Out-Null } $global:MyPSScriptRoot = $My_PSScriptRoot -$p = @($p[0], $(Join-Path $My_PSScriptRoot base)) + $($p | Select-Object -Skip 1) +$p = @($p[0], $MyPSScriptRoot) + $($p | Select-Object -Skip 1) $env:PATH = $p -join $PathEnvDelimiter } diff --git a/base/Stop-ProcessTree.ps1 b/Stop-ProcessTree.ps1 similarity index 100% rename from base/Stop-ProcessTree.ps1 rename to Stop-ProcessTree.ps1 diff --git a/base.linux/Set-EnvVariable.ps1 b/base.linux/Set-EnvVariable.ps1 deleted file mode 100644 index a51daa7..0000000 --- a/base.linux/Set-EnvVariable.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -[CmdletBinding()]param( - [string]$Name, - [object]$Value -) - -Set-Item -Path (Join-Path "env:" $Name) -Value $Value diff --git a/base.linux/_.package.json b/base.linux/_.package.json deleted file mode 100644 index 816ed22..0000000 --- a/base.linux/_.package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "package": { - "Condition": [ - { - "custom": null, - "System": [ - "Linux" - ], - "Hostname": null, - "Username": null, - "Logic": 0 - } - ], - "Name": "base.linux" - } -} diff --git a/base.win/Set-EnvVariable.ps1 b/base.win/Set-EnvVariable.ps1 deleted file mode 100644 index 5de891d..0000000 --- a/base.win/Set-EnvVariable.ps1 +++ /dev/null @@ -1,11 +0,0 @@ -[CmdletBinding()]param( - [string]$Name, - [object]$Value, - [ValidateSet('User','Machine')] - [string]$Persist -) - -Set-Item -Path (Join-Path "env:" $Name) -Value $Value -if( $Persist ) { - [environment]::setEnvironmentVariable($Name, $Value, $Persist) -} \ No newline at end of file diff --git a/base.win/_.package.json b/base.win/_.package.json deleted file mode 100644 index 3a5346f..0000000 --- a/base.win/_.package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "package": { - "Name": "base.win", - "Condition": [ - { - "custom": null, - "System": [ - "Windows" - ], - "Hostname": null, - "Username": null, - "Logic": 0 - } - ] - } -} diff --git a/base/Add-PackageCondition.ps1 b/base/Add-PackageCondition.ps1 deleted file mode 100644 index 34a57b0..0000000 --- a/base/Add-PackageCondition.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [Parameter(mandatory=$true, ValueFromPipeline=$true)] - [szPackage]$InputObject, - [szLogic]$logic = "and", - [ScriptBlock]$CustomCondition, - [string[]]$System = $null, - [string[]]$Hostname = $null, - [string[]]$Username = $null -) - -process { - $local:newCond = New-Object -Type 'szCondition' - $newCond.custom = $CustomCondition - $newCond.System = $System - $newCond.Hostname = $Hostname - $newCond.Username = $null - $newCond.Logic = [szLogic]::and - $InputObject.Condition += $newCond - - $InputObject -} diff --git a/base/Get-MyPackages.ps1 b/base/Get-MyPackages.ps1 deleted file mode 100644 index 0f638dc..0000000 --- a/base/Get-MyPackages.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -[CmdletBinding()]param( - [Parameter(ParameterSetName="OptionA")] - [Parameter(ParameterSetName="Path")] - [switch]$Force, - [Parameter(ParameterSetName="Path",Mandatory)] - [switch]$ReturnFullPath, - [Parameter(ParameterSetName="Path")] - [switch]$IncludeRoot -) - -$local:packages = [Packagesz]::_GetValidValues("", -not $Force, $true) | Sort-Object -if( $IncludeRoot -and $ReturnFullPath ) { $MyPSScriptRoot } -foreach ( $local:pkg in $packages ) { - if( $ReturnFullPath ) { - Join-Path $MyPSScriptRoot $pkg - } else { - $pkg - } -} - - diff --git a/base/Get-MyScript.ps1 b/base/Get-MyScript.ps1 deleted file mode 100644 index e780a33..0000000 --- a/base/Get-MyScript.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -[CmdletBinding()]param( - [Parameter(ParameterSetName="Normal")] - [Parameter(ParameterSetName="DropNamespace")] - [string]$Filter, - [Parameter(ParameterSetName="ByPackage",Mandatory)] - [Parameter(ParameterSetName="DropNamespace",Mandatory)] - [ArgumentCompleter({ param ( - $commandName, - $parameterName, - $wordToComplete, - $commandAst, - $fakeBoundParameters - ) - $local:NotAll = $true - if( $fakeBoundParameters.ContainsKey("Force") ) { $NotAll = -not $fakeBoundParameters.Force } - [Packagesz]::_GetValidValues($wordToComplete,$NotAll,$true) - })] - [string]$Package, - [Parameter(ParameterSetName="Normal")] - [Parameter(ParameterSetName="ByPackage")] - [Parameter(ParameterSetName="DropNamespace",Mandatory)] - [switch]$NamesOnly, - [Parameter(ParameterSetName="Normal")] - [Parameter(ParameterSetName="ByPackage")] - [Parameter(ParameterSetName="DropNamespace")] - [switch]$Force, - [Parameter(ParameterSetName="DropNamespace",Mandatory)] - [switch]$DropNamespace -) -$local:rVal = [MyScript]::_GetValidValues($Filter,-not $Force,$true) - -if( $Package ) { - $Package = Join-Path $Package '' - $rVal = $rVal | - Where-Object { $_ -match "^$Package" } - if( $DropNamespace ) { - $rVal = $rVal | - ForEach-Object { $_.Replace($Package,'') } - } -} - -if( $NamesOnly ) { return $rVal } -return $rVal | ForEach-Object { Join-Path $MyPSScriptRoot "$_`.ps1" } - diff --git a/base/New-MyPackage.ps1 b/base/New-MyPackage.ps1 deleted file mode 100644 index f960247..0000000 --- a/base/New-MyPackage.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [string]$Name -) - -[szPackage]::Create($Name) diff --git a/base/Reload-MyScripts.ps1 b/base/Reload-MyScripts.ps1 deleted file mode 100644 index 162cf65..0000000 --- a/base/Reload-MyScripts.ps1 +++ /dev/null @@ -1,111 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param() - -try { Get-Alias Get-MyAliases -ErrorAction Stop | ForEach-Object { Remove-Item "Alias:$($_.Name)" } } catch {} -function Get-MyAliases { -[CmdletBinding(SupportsShouldProcess)]param([switch]$ScriptsOnly) - - $local:allAliases = @() - - $MyAliasScope = 0 - $local:_scope = 0 - $local:_done = $false - do { - try { - $local:newAliases += Get-Alias -Scope $_scope | - Where-Object { - ($_.Definition -match "^$MyPSScriptRoot") -or (-not $ScriptsOnly -and ($_.Description -match '#MyAlias')) - } - if( $newAliases ) { - $allAliases += $newAliases - $MyAliasScope = $_scope; - Write-Verbose "`$MyAliasScope is now set to $MyAliasScope" - } - } catch { - Write-Verbose "catch: $($_.Exception.Message)" - $_done = $_.Exception.Message -match 'The scope .* exceeds' - } - $_scope += 1 - } until ( $_done ) - - $allAliases -} - -function getScriptName{param([string]$FullPath) - $FullPath -replace '\.ps1$','' -replace "^$([regex]::Escape($MyPSScriptRoot)).",'' -} - -$local:IsVerbose = [bool]($PSBoundParameters['Verbose']) - -# Loads mandatory Package code -try { - $null = [Packagesz] -} catch { - $local:PackagePath = $(Join-Path $MyPSScriptRoot 'base') - Join-Path $(Join-Path $PackagePath profile.d) 'classes.ps1' | - Where-Object { Test-Path $_ } | ForEach-Object { . $_ } -} -$local:myPackages = Get-MyPackages -ReturnFullPath -IncludeRoot | Get-Item - -$local:myAliases = [ordered]@{} - -$myPackages | - ForEach-Object { Join-Path $_.FullName Aliases } | - Where-Object { Test-Path $_ } | - Get-ChildItem | ForEach-Object { - $myAliases[$_.BaseName] = Get-Content $_.FullName - } - -$script:MyAliasScope = 0 - -$local:oldAliases = Get-MyAliases - -$oldAliases = Get-Alias -Scope $MyAliasScope | - Where-Object Name -in $($oldAliases.Name + $myAliases.Keys) - -if( $oldAliases -and $IsVerbose ) { - Write-Verbose "Removing: $($oldAliases.Name -join ', ')" -} -if( Get-Command Remove-Alias -ErrorAction SilentlyContinue ) { - $oldAliases | Remove-Alias -Scope $MyAliasScope -} else { - $oldAliases | ForEach-Object { Remove-Item "Alias:$($_.Name)" } -} - -if( $(. Get-ScopeDepth) -gt 0 ) { - Write-Host -ForegroundColor Red "Try sourcing Reload-MyScripts instead of just running it" -} - -foreach( $local:PackagePath in $myPackages ) { - $local:PackageName = $PackagePath.Name - - Join-Path $PackagePath 'profile.d' | Where-Object { Test-Path $_ } | - Get-ChildItem -Filter '*.ps1' | - ForEach-Object { - Write-Verbose "Loading $(getScriptName $_.FullName)..."; - ". '$($_.FullName)';" - } | - Invoke-Expression - - $local:CommandsToAlias = ( - @( $PackagePath ) + $( - [SystemName]::_GetValidValues("",$true,$true) | - ForEach-Object { - Join-Path $PackagePath "sys.$_" - } - )) | - Where-Object { Test-Path $_ } | - ForEach-Object { - Get-ChildItem (Join-Path $_ '*.ps1') | Where-Object Name -notmatch '\.inc\.ps1$' - } - - $CommandsToAlias | ForEach-Object { - Write-Verbose "Creating alias for $(getScriptName $_.FullName) Script..." - Set-Alias $($_.BaseName) $_.FullName -Scope $MyAliasScope - } -} - -foreach( $local:alias in $myAliases.Keys ) { - Write-Verbose "Adding $($alias) alias..." - Set-Alias -Name $alias -Value $myAliases[$alias] -Description '#MyAlias' -Scope $MyAliasScope -} - diff --git a/base/Set-MyPackage.ps1 b/base/Set-MyPackage.ps1 deleted file mode 100644 index 655ae09..0000000 --- a/base/Set-MyPackage.ps1 +++ /dev/null @@ -1,38 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [Parameter(mandatory=$true, ValueFromPipeline=$true)] - [szPackage]$InputObject, - [switch]$Force, - [switch]$PassThru, - [switch]$DryRun -) - -process { - $local:outObj = @{ package = @{ Name = $InputObject.Name; Condition = @() } } - foreach( $local:c in $InputObject.Condition ) { - $local:newC = [ordered]@{} - foreach( $local:p in $c.PSObject.Properties ) { - if( $p.TypeNameOfValue -match 'ScriptBlock' -and $p.Value ) { - $newC[$p.Name] = $p.Value.ToString().Trim() - } else { - $newC[$p.Name] = $p.Value - } - } - $outObj.package.Condition += $newC; - } - $local:jsonOut = $outObj | ConvertTo-Json -Depth 4 - - if( -not $DryRun ) { - $local:jsonPath = Join-Path $MyPSScriptRoot $_.name - if( -not (Test-Path $jsonPath) ) { $null = New-Item -Type Directory $jsonPath -Force:$Force } - $jsonPath = Join-Path $jsonPath '_.package.json' - if( $Force -or -not (Test-Path $jsonPath) ) { - $jsonOut | Out-File $jsonPath -Force:$Force - } elseif ( Test-Path $jsonPath ) { - throw 'Package already exists!' - } - } - - if( $PassThru ) { - $jsonOut - } -} diff --git a/base/_.package.json b/base/_.package.json deleted file mode 100644 index f7b2ff5..0000000 --- a/base/_.package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "package": { - "name": "base" - } -} diff --git a/base/profile.d/Docker.class.ps1 b/base/profile.d/Docker.class.ps1 deleted file mode 100644 index 11d3132..0000000 --- a/base/profile.d/Docker.class.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -class DockerContainer { #: System.Management.Automation.IValidateSetValuesGenerator { - static [string[]] _GetValidValues([string]$wordToComplete,[bool]$Strict) { - $local:possibleValues = $( - docker ps -a --no-trunc --format "{{.Names}}" - ) - return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); - } - - [String[]] GetValidValues() { - return [DockerContainer]::_GetValidValues('',$true) - } -} - -class DockerComposeDirs { #: System.Management.Automation.IValidateSetValuesGenerator { - static [string[]] _GetValidValues([string]$wordToComplete,[bool]$Strict) { - $local:possibleValues = $( - Get-ChildItem -Directory -Depth 3 | - Where-Object { $_ | - Get-ChildItem -Include 'docker-compose.y*l' | - Where-Object Extension -in '.yml','.yaml' - } | ForEach-Object { - $_.FullName.Replace($(Join-Path $PWD ""),'') - } - ) - return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); - } - - [String[]] GetValidValues() { - return [DockerComposeDirs]::_GetValidValues('',$true) - } -} - diff --git a/base/profile.d/MyScript.class.ps1 b/base/profile.d/MyScript.class.ps1 deleted file mode 100644 index ed219be..0000000 --- a/base/profile.d/MyScript.class.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -class MyScript { #: System.Management.Automation.IValidateSetValuesGenerator { - static [string[]] _GetValidValues([string]$wordToComplete,[bool]$CurrentOnly,[bool]$Strict) { - $local:possibleValues = $( - Get-MyPackages -ReturnFullPath -IncludeRoot -Force:$(-not $CurrentOnly) | - Get-ChildItem -Filter '*.ps1' | - Select-Object -ExpandProperty FullName | ForEach-Object { - $_ -replace '\.ps1$','' -replace "$($MyPSScriptRoot -replace '\\',"\\")[/\\]",'' - } - ) - return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); - } - - [String[]] GetValidValues() { - return [MyScript]::_GetValidValues('',$false,$true) - } -} diff --git a/base/profile.d/classes.ps1 b/base/profile.d/classes.ps1 deleted file mode 100644 index 44c05a7..0000000 --- a/base/profile.d/classes.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -. Invoke-Expression ". $(Join-Path $(Join-Path $PackagePath 'src') 'SystemName.class.inc.ps1')" -. Invoke-Expression ". $(Join-Path $(Join-Path $PackagePath 'src') 'Packagesz.class.inc.ps1')" - diff --git a/base/src/Packagesz.class.inc.ps1 b/base/src/Packagesz.class.inc.ps1 deleted file mode 100644 index 047d498..0000000 --- a/base/src/Packagesz.class.inc.ps1 +++ /dev/null @@ -1,97 +0,0 @@ -class Packagesz { #: System.Management.Automation.IValidateSetValuesGenerator { - static [hashtable]GetPackageDictionary() { - $local:packages = @{} - - Get-ChildItem $global:MyPSScriptRoot | - ForEach-Object { Join-Path $_.FullName "_.package.json" } | - Where-Object { Test-Path $_ } | - Get-Item | - ForEach-Object { - $local:testPkg = Get-Content $_ -Raw | - ConvertFrom-Json | - Select-Object -ExpandProperty "package" -ErrorAction SilentlyContinue - if( $testPkg ) { - $local:k = $_.Directory.FullName.Replace($MyPSScriptRoot,'') -replace '^/','' - $packages[$k] = $testPkg - } - } - - return $packages; - } - static [bool] ValidatePackageConditions($Package) { - if( -not $Package.Condition ) { return $true } - $local:valid = $Package.Condition[0].Logic -notin ([szLogic]::or, [szLogic]::ornot) - $local:currentSys = [SystemName]::_GetValidValues('',$true,$true); - $local:hostname = $(hostname) - $local:username = $env:USER ?? $env:USERNAME - foreach( $local:c in $Package.Condition ) { - if( $valid -eq ($c.Logic -in ([szLogic]::or, [szLogic]::ornot )) ) { continue } - - $local:v = $true; - if( $v -and $c.System ) { - $v = $v -and $($c.System | Where-Object { $currentSys -contains $_ }) - } - if( $v -and $c.Hostname ) { - $v = $v -and $($c.Hostname | Where-Object { $hostname -match $_ }) - } - if( $v -and $c.Username ) { - $v = $v -and $($c.Username | Where-Object { $username -match $_ }) - } - if( $v -and $c.custom ) { - $v = $v -and ([bool]$(Invoke-ScriptBlock ([ScriptBlock]::Create($c.custom)))) - } - switch( $c.Logic ) { - [szLogic]::not { $valid = $valid -and -not $v } - [szLogic]::or { $valid = $valid -or $v } - [szLogic]::ornot { $valid = $valid -or -not $v } - default { $valid = $valid -and $v } - } - } - return $valid - } - static [string[]] _GetValidValues([string]$wordToComplete,[bool]$CurrentOnly,[bool]$Strict) { - $local:pkgz = [Packagesz]::GetPackageDictionary() - $local:possibleValues = $pkgz.Keys | - Where-Object { -not $CurrentOnly -or $( - [Packagesz]::ValidatePackageConditions($pkgz[$_]) - ) } - - return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); - } - - [String[]] GetValidValues() { - return [Packagesz]::_GetValidValues('',$false,$true) - } -} - -enum szLogic { - and = 0 - not = 1 # nand - or = 2 - ornot = 3 -} - -class szCondition { - [ScriptBlock]$custom = { $true } - [string[]]$System = $null - [string[]]$Hostname = $null - [string[]]$Username = $null - [szLogic]$Logic = [szLogic]::and - - [string] ToString() { - return "Logic = $($this.Logic); System = $($this.System); Hostname = $($this.Hostname); Username = $($this.Username); Custom = { $($this.Custom.ToString().Trim()) }" - } -} - -class szPackage { - [string]$Name - [szCondition[]]$Condition - - static [szPackage]Create($Name) { - $local:newPkg = New-Object -Type 'szPackage' - $newPkg.Name = $Name - $newPkg.Condition = @() - - return $newPkg - } -} diff --git a/dcc.ps1 b/dcc.ps1 new file mode 100644 index 0000000..6154b3a --- /dev/null +++ b/dcc.ps1 @@ -0,0 +1,3 @@ +[CmdletBinding(SupportsShouldProcess)]param([string[]]$ProjectPath=@($PWD)) + +$ProjectPath | ForEach-Object { docker-compose --file $(Resolve-Path $(Join-Path $_ docker-compose.yml)) config | less } diff --git a/dcdown.ps1 b/dcdown.ps1 new file mode 100644 index 0000000..a7cd9c5 --- /dev/null +++ b/dcdown.ps1 @@ -0,0 +1 @@ +docker-compose down --timeout=3 --volumes --remove-orphans "$args" diff --git a/docker/dcl.ps1 b/dcl.ps1 similarity index 100% rename from docker/dcl.ps1 rename to dcl.ps1 diff --git a/docker/dcll.ps1 b/dcll.ps1 similarity index 100% rename from docker/dcll.ps1 rename to dcll.ps1 diff --git a/docker/dcr.ps1 b/dcr.ps1 similarity index 100% rename from docker/dcr.ps1 rename to dcr.ps1 diff --git a/docker/dcre.ps1 b/dcre.ps1 similarity index 100% rename from docker/dcre.ps1 rename to dcre.ps1 diff --git a/docker/dcreup.ps1 b/dcreup.ps1 similarity index 100% rename from docker/dcreup.ps1 rename to dcreup.ps1 diff --git a/dcup.ps1 b/dcup.ps1 new file mode 100644 index 0000000..5ab64b0 --- /dev/null +++ b/dcup.ps1 @@ -0,0 +1,10 @@ +#[CmdletBinding(SupportsShouldProcess)]param() + +$local:dcParams = [string]::Empty +if( $args ) { + $dcParams = $args | ForEach-Object { + if( $_ -match "(?:^'[^']+'$)|(?:^`"[^`"]+`"$)|(?:^[^\s]+$)" ) { $_ } + else { "'$($_.Replace( "'", "''" ))'" } + } +} +docker-compose up -d --remove-orphans $dcParams && docker-compose logs --follow --tail 10 $dcParams diff --git a/docker/dcx.ps1 b/dcx.ps1 similarity index 100% rename from docker/dcx.ps1 rename to dcx.ps1 diff --git a/docker/di.ps1 b/di.ps1 similarity index 100% rename from docker/di.ps1 rename to di.ps1 diff --git a/docker/dlogs.ps1 b/dl.ps1 similarity index 100% rename from docker/dlogs.ps1 rename to dl.ps1 diff --git a/docker/dll.ps1 b/dll.ps1 similarity index 100% rename from docker/dll.ps1 rename to dll.ps1 diff --git a/docker/_.package.json b/docker/_.package.json deleted file mode 100644 index d790eb8..0000000 --- a/docker/_.package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "package": { - "Condition": [ - { - "custom": "Get-Command docker -Type Application", - "System": null, - "Hostname": null, - "Username": null, - "Logic": 0 - } - ], - "Name": "docker" - } -} diff --git a/docker/dcc.ps1 b/docker/dcc.ps1 deleted file mode 100644 index 9b65de9..0000000 --- a/docker/dcc.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [ArgumentCompleter({ param ( - $commandName, - $parameterName, - $wordToComplete, - $commandAst, - $fakeBoundParameters - ) - [DockerComposeDirs]::_GetValidValues($wordToComplete,$true) - })] - [string[]]$ProjectPath=@($PWD) -) - -$ProjectPath | ForEach-Object { docker-compose --file $(Resolve-Path $(Join-Path $_ docker-compose.yml)) config | less } diff --git a/docker/dcdown.ps1 b/docker/dcdown.ps1 deleted file mode 100644 index 8c83258..0000000 --- a/docker/dcdown.ps1 +++ /dev/null @@ -1,18 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [ArgumentCompleter({ param ( - $commandName, - $parameterName, - $wordToComplete, - $commandAst, - $fakeBoundParameters - ) - [DockerComposeDirs]::_GetValidValues($wordToComplete,$true) - })] - [string[]]$ProjectPath=@($PWD), - [Parameter(Position = 0, ValueFromRemainingArguments = $true)] - [string[]]$CliParams -) - -$ProjectPath | ForEach-Object { - docker-compose --file $(Resolve-Path $(Join-Path $_ docker-compose.yml)) down --timeout=3 --volumes --remove-orphans "$CliParams" -} diff --git a/docker/dcup.ps1 b/docker/dcup.ps1 deleted file mode 100644 index 47cc001..0000000 --- a/docker/dcup.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param( - [ArgumentCompleter({ param ( - $commandName, - $parameterName, - $wordToComplete, - $commandAst, - $fakeBoundParameters - ) - [DockerComposeDirs]::_GetValidValues($wordToComplete,$true) - })] - [string[]]$ProjectPath=@($PWD), - [Parameter(Position = 0, ValueFromRemainingArguments = $true)] - [string[]]$CliParams -) - -$local:dcParams = [string]::Empty -if( $CliParams ) { - $dcParams = $CliParams | ForEach-Object { - if( $_ -match "(?:^'[^']+'$)|(?:^`"[^`"]+`"$)|(?:^[^\s]+$)" ) { $_ } - else { "'$($_.Replace( "'", "''" ))'" } - } -} -$ProjectPath | ForEach-Object { - $local:dcPath = $(Resolve-Path $(Join-Path $_ docker-compose.yml)) - Write-Verbose "docker-compose --file $dcPath up -d --remove-orphans $dcParams && docker-compose --file $dcPath logs --follow --tail 10 $dcParams" - docker-compose --file $dcPath up -d --remove-orphans $dcParams && docker-compose --file $dcPath logs --follow --tail 10 $dcParams -} - diff --git a/docker/dx.ps1 b/dx.ps1 similarity index 100% rename from docker/dx.ps1 rename to dx.ps1 diff --git a/base/profile.d/FromPowerShellCookbook.ps1 b/profile.d/FromPowerShellCookbook.ps1 similarity index 100% rename from base/profile.d/FromPowerShellCookbook.ps1 rename to profile.d/FromPowerShellCookbook.ps1 diff --git a/base/profile.d/FunctionName.class.ps1 b/profile.d/FunctionName.class.ps1 similarity index 100% rename from base/profile.d/FunctionName.class.ps1 rename to profile.d/FunctionName.class.ps1 diff --git a/base/profile.d/MyConfig.class.ps1 b/profile.d/MyConfig.class.ps1 similarity index 85% rename from base/profile.d/MyConfig.class.ps1 rename to profile.d/MyConfig.class.ps1 index 8d2d42b..4e7c457 100644 --- a/base/profile.d/MyConfig.class.ps1 +++ b/profile.d/MyConfig.class.ps1 @@ -1,9 +1,9 @@ class MyConfig { #: System.Management.Automation.IValidateSetValuesGenerator { hidden static [hashtable]$_HardCodedConfigDict = @{ - 'myconfig' = @($(Join-Path $(Join-Path $PackagePath 'src') 'config.files.json'), - $(Join-Path $(Join-Path $PackagePath 'src') 'config.files.local.json')) - 'mymodules' = @($(Join-Path $(Join-Path $PackagePath 'src') 'modules.json'), - $(Join-Path $(Join-Path $PackagePath 'src') 'modules.local.json')) + 'myconfig' = @($(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'config.files.json'), + $(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'config.files.local.json')) + 'mymodules' = @($(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'modules.json'), + $(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'modules.local.json')) } static [hashtable]GetConfigDictionary() { diff --git a/profile.d/MyScript.class.ps1 b/profile.d/MyScript.class.ps1 new file mode 100644 index 0000000..794ee8b --- /dev/null +++ b/profile.d/MyScript.class.ps1 @@ -0,0 +1,15 @@ +class MyScript { #: System.Management.Automation.IValidateSetValuesGenerator { + static [string[]] _GetValidValues([string]$wordToComplete,[bool]$Strict) { + $local:possibleValues = $( + Get-ChildItem $global:MyPSScriptRoot -Filter '*.ps1' -Recurse | + Select-Object -ExpandProperty FullName | ForEach-Object { + $_ -replace '\.ps1$','' -replace "$($MyPSScriptRoot -replace '\\',"\\")[/\\]",'' + } + ) + return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); + } + + [String[]] GetValidValues() { + return [MyScript]::_GetValidValues('',$true) + } +} diff --git a/base/profile.d/Style.ps1 b/profile.d/Style.ps1 similarity index 100% rename from base/profile.d/Style.ps1 rename to profile.d/Style.ps1 diff --git a/base/src/SystemName.class.inc.ps1 b/profile.d/SystemName.class.ps1 similarity index 98% rename from base/src/SystemName.class.inc.ps1 rename to profile.d/SystemName.class.ps1 index 8ce740f..022340f 100644 --- a/base/src/SystemName.class.inc.ps1 +++ b/profile.d/SystemName.class.ps1 @@ -18,7 +18,6 @@ class SystemName { #: System.Management.Automation.IValidateSetValuesGenerator { } $possibleValues.out = $possibleValues.out | Select-Object -Unique | - Where-Object { $_ } | Sort-Object { $local:sortName = "zz_$_"; if( $_ -in $possibleValues.Exist -and $_ -in $possibleValues.Current ) { $sortName[0] = "a" } diff --git a/base/profile.d/Test-MyModules.ps1 b/profile.d/Test-MyModules.ps1 similarity index 100% rename from base/profile.d/Test-MyModules.ps1 rename to profile.d/Test-MyModules.ps1 diff --git a/base/profile.d/UnixCompleters.ps1 b/profile.d/UnixCompleters.ps1 similarity index 100% rename from base/profile.d/UnixCompleters.ps1 rename to profile.d/UnixCompleters.ps1 diff --git a/base/profile.d/env.local.ps1.template b/profile.d/env.local.ps1.template similarity index 100% rename from base/profile.d/env.local.ps1.template rename to profile.d/env.local.ps1.template diff --git a/base/profile.d/env.ps1 b/profile.d/env.ps1 similarity index 100% rename from base/profile.d/env.ps1 rename to profile.d/env.ps1 diff --git a/base/profile.d/load-z.ps1 b/profile.d/load-z.ps1 similarity index 100% rename from base/profile.d/load-z.ps1 rename to profile.d/load-z.ps1 diff --git a/base/src/config.files.json b/src/config.files.json similarity index 79% rename from base/src/config.files.json rename to src/config.files.json index c5bb83b..a11b946 100644 --- a/base/src/config.files.json +++ b/src/config.files.json @@ -37,8 +37,6 @@ "ssh-pub": "~/.ssh/id_*.pub", "ssh-id": ["~/.ssh/id_ed25519","~/.ssh/id_rsa"], "ssh-auth": "~/.ssh/authorized_keys", - "ssh-known": "~/.ssh/known_hosts", - "ssh-conf": "~/.ssh/config", - "sshd-conf": "/etc/ssh/sshd_config", - "ssh" : [ "#ssh-auth", "#ssh-known", "#ssh-conf", "#sshd-conf", "#ssh-pub", "#ssh-id" ] + "ssh-conf": "/etc/ssh/sshd_config", + "ssh" : [ "#ssh-auth", "#ssh-conf", "#ssh-pub", "#ssh-id" ] } diff --git a/base/src/modules.json b/src/modules.json similarity index 100% rename from base/src/modules.json rename to src/modules.json diff --git a/base/src/smartsudo.inc.ps1 b/src/smartsudo.inc.ps1 similarity index 100% rename from base/src/smartsudo.inc.ps1 rename to src/smartsudo.inc.ps1 diff --git a/base.linux/Get-PlexInfo.ps1 b/sys.Linux/Get-PlexInfo.ps1 similarity index 100% rename from base.linux/Get-PlexInfo.ps1 rename to sys.Linux/Get-PlexInfo.ps1 diff --git a/base.linux/Invoke-ViaAnsible.ps1 b/sys.Linux/Invoke-ViaAnsible.ps1 similarity index 100% rename from base.linux/Invoke-ViaAnsible.ps1 rename to sys.Linux/Invoke-ViaAnsible.ps1 diff --git a/base.linux/Pull-ViaAnsible.ps1 b/sys.Linux/Pull-ViaAnsible.ps1 similarity index 100% rename from base.linux/Pull-ViaAnsible.ps1 rename to sys.Linux/Pull-ViaAnsible.ps1 diff --git a/base.linux/Update-ArchOSz.ps1 b/sys.Linux/Update-ArchOSz.ps1 similarity index 100% rename from base.linux/Update-ArchOSz.ps1 rename to sys.Linux/Update-ArchOSz.ps1 diff --git a/base.linux/Update-OSz.ps1 b/sys.Linux/Update-OSz.ps1 similarity index 100% rename from base.linux/Update-OSz.ps1 rename to sys.Linux/Update-OSz.ps1 diff --git a/base.linux/Update-UbuntuOSz.ps1 b/sys.Linux/Update-UbuntuOSz.ps1 similarity index 100% rename from base.linux/Update-UbuntuOSz.ps1 rename to sys.Linux/Update-UbuntuOSz.ps1 diff --git a/base.linux/Update-ViaAnsible.ps1 b/sys.Linux/Update-ViaAnsible.ps1 similarity index 100% rename from base.linux/Update-ViaAnsible.ps1 rename to sys.Linux/Update-ViaAnsible.ps1 diff --git a/base.linux/ls.ps1 b/sys.Linux/ls.ps1 similarity index 100% rename from base.linux/ls.ps1 rename to sys.Linux/ls.ps1 diff --git a/base.linux/sranger.ps1 b/sys.Linux/sranger.ps1 similarity index 100% rename from base.linux/sranger.ps1 rename to sys.Linux/sranger.ps1 diff --git a/base.linux/sz-rsync.ps1 b/sys.Linux/sz-rsync.ps1 similarity index 100% rename from base.linux/sz-rsync.ps1 rename to sys.Linux/sz-rsync.ps1 diff --git a/base.linux/txm.ps1 b/sys.Linux/txm.ps1 similarity index 100% rename from base.linux/txm.ps1 rename to sys.Linux/txm.ps1 diff --git a/base.linux/sz-df.ps1 b/sz-df.ps1 similarity index 100% rename from base.linux/sz-df.ps1 rename to sz-df.ps1 diff --git a/base.linux/sz-du.ps1 b/sz-du.ps1 similarity index 100% rename from base.linux/sz-du.ps1 rename to sz-du.ps1