diff --git a/Makefile b/Makefile index a9640bcd4..7b52493de 100644 --- a/Makefile +++ b/Makefile @@ -36,14 +36,14 @@ bootstrap: tools/nuget.exe # run targets -export POWERSHELL=env LD_LIBRARY_PATH=$(MONAD)/lib:$(PSLIB) PSMODULEPATH=$(PSLIB)/Modules $(MONAD)/bin/powershell -export POWERSHELL_SIMPLE=$(POWERSHELL) $(PSLIB)/powershell-simple.exe +export POWERSHELL_HOST=env TEMP=/tmp LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(MONAD)/lib:$(PSLIB) PSMODULEPATH=$(PSLIB)/Modules $(MONAD)/bin/powershell +export POWERSHELL=$(POWERSHELL_HOST) $(PSLIB)/powershell.exe demo: - $(POWERSHELL_SIMPLE) '"a","b","c","a","a" | Select-Object -Unique' + $(POWERSHELL) '"a","b","c","a","a" | Select-Object -Unique' shell: - TEMP=/tmp $(POWERSHELL) $(PSLIB)/powershell-run.exe + $(POWERSHELL) # tests @@ -59,12 +59,12 @@ test-hashbang: ## - we cd because some tests rely on the current working directory PESTER=$(MONAD)/src/pester-tests test-pester: - $(POWERSHELL_SIMPLE) '$$env:TEMP="/tmp"; invoke-pester $(PESTER) -OutputFile $(MONAD)/pester-tests.xml -OutputFormat NUnitXml' + $(POWERSHELL) 'invoke-pester $(PESTER) -OutputFile $(MONAD)/pester-tests.xml -OutputFormat NUnitXml' ## Pester self-tests ## - results in pester-self-tests.xml test-pester-self: - $(POWERSHELL_SIMPLE) 'cd $(PSLIB)/Modules/Pester/Functions; $$env:TEMP="/tmp"; invoke-pester -OutputFile $(MONAD)/pester-self-tests.xml -OutputFormat NUnitXml' + $(POWERSHELL) 'cd $(PSLIB)/Modules/Pester/Functions; $$env:TEMP="/tmp"; invoke-pester -OutputFile $(MONAD)/pester-self-tests.xml -OutputFormat NUnitXml' ## tracing ## - use PAL_DBG_CHANNELS="+LOADER.TRACE" to enable CoreCLR tracing diff --git a/monad-docker.sh b/monad-docker.sh index 676093260..2fbd25391 100644 --- a/monad-docker.sh +++ b/monad-docker.sh @@ -1,15 +1,20 @@ -# docker run magrathea without tty +# docker run magrathea with a non-interactive tty monad-run() { - monad-docker-run "--attach STDOUT --attach STDERR" $* + monad-docker-run "--tty" $* } # docker run magrathea with interactive tty -monad-tty() +monad-it() { monad-docker-run "--interactive --tty" $* } +monad-attach() +{ + monad-docker-run "--attach STDOUT --attach STDERR" $* +} + # runs ephemeral andschwa/magrathea docker container with local # directory mounted and workdir set to /opt monad-docker-run() diff --git a/src/assembly-info/System.Management.Automation.assembly-info.cs b/src/assembly-info/System.Management.Automation.assembly-info.cs index 130586248..a9730c2dd 100644 --- a/src/assembly-info/System.Management.Automation.assembly-info.cs +++ b/src/assembly-info/System.Management.Automation.assembly-info.cs @@ -7,6 +7,7 @@ using System.Reflection; [assembly:InternalsVisibleTo("Microsoft.PowerShell.Security")] [assembly:InternalsVisibleTo("Microsoft.PowerShell.CoreCLR.AssemblyLoadContext")] [assembly:InternalsVisibleTo("PowerShell.Linux.Test")] +[assembly:InternalsVisibleTo("powershell")] [assembly:AssemblyFileVersionAttribute("1.0.0.0")] [assembly:AssemblyVersion("1.0.0.0")] diff --git a/src/host/PSL_profile.ps1 b/src/host/PSL_profile.ps1 new file mode 100644 index 000000000..3bb4ea9a6 --- /dev/null +++ b/src/host/PSL_profile.ps1 @@ -0,0 +1,15 @@ +(get-psprovider 'FileSystem').Home = $env:HOME + +function prompt +{ + "PSL " + $(get-location) + "> " +} + +& { + for ($i = 0; $i -lt 26; $i++) + { + $funcname = ([System.Char]($i+65)) + ':' + $str = "function global:$funcname { set-location $funcname } " + invoke-expression $str + } +} diff --git a/src/powershell-run/host.cs b/src/host/host.cs similarity index 100% rename from src/powershell-run/host.cs rename to src/host/host.cs diff --git a/src/host/host.mk b/src/host/host.mk new file mode 100644 index 000000000..bdaed507f --- /dev/null +++ b/src/host/host.mk @@ -0,0 +1,17 @@ +# This is the makefile for all kinds of powershell hosts +# +# Currently there is powershell-run.exe, which is a very generic interactive and +# non-interactive host + +POWERSHELL_RUN_FOLDER=$(MONAD)/src/host +POWERSHELL_RUN_SRCS=$(addprefix $(POWERSHELL_RUN_FOLDER)/, main.cs host.cs ui.cs rawui.cs readline.cs powershell.assembly-info.cs) + +# direct dependencies to be linked in +POWERSHELL_RUN_DEPS=$(addprefix $(PSLIB)/, System.Management.Automation.dll Microsoft.PowerShell.Commands.Management.dll $(ASSEMBLY_LOAD_CONTEXT_TARGET)) +POWERSHELL_RUN_REFS=$(addprefix -r:, $(POWERSHELL_RUN_DEPS)) + +$(PSLIB)/PSL_profile.ps1: + cp -f $(POWERSHELL_RUN_FOLDER)/$(notdir $@) $@ + +$(PSLIB)/powershell.exe: $(POWERSHELL_RUN_SRCS) $(POWERSHELL_RUN_DEPS) $(PSLIB)/PSL_profile.ps1 + $(CSC) -out:$@ -noconfig -nostdlib -target:exe $(POWERSHELL_RUN_REFS) $(COREREF) $(POWERSHELL_RUN_SRCS) diff --git a/src/powershell-run/main.cs b/src/host/main.cs similarity index 88% rename from src/powershell-run/main.cs rename to src/host/main.cs index 949f9f451..23ec9cd3c 100644 --- a/src/powershell-run/main.cs +++ b/src/host/main.cs @@ -74,55 +74,38 @@ namespace Microsoft.Samples.PowerShell.Host set { this.exitCode = value; } } - // this is the unmanaged main entry point used by the CoreCLR host - public static int UnmanagedMain(int argc, [MarshalAs(UnmanagedType.LPArray,ArraySubType=UnmanagedType.LPStr,SizeParamIndex=0)] String[] argv) - { - List allArgs = new List(); - - for (int i = 0; i < argc; ++i) - { - allArgs.Add(argv[i]); - } - - ManagedMain(allArgs.ToArray()); - - return 0; - } - /// /// Creates and initiates the listener instance. /// /// This parameter is not used. private static void Main(string[] args) { - ManagedMain(args); - } - - private static void ManagedMain(string[] args) - { - - String initialScript = null; + // Custom argument parsing + string initialScript = null; if (args.Length > 0) { for (int i = 0; i < args.Length; ++i) { string arg = args[i]; - bool hasNext = (i+1) 0 ) + if (string.IsNullOrEmpty(initialScript)) { initialScript = string.Join(" ", args); } @@ -158,12 +141,44 @@ namespace Microsoft.Samples.PowerShell.Host // only the default snap-ins will be available. this.myHost = new MyHost(this); InitialSessionState iss = InitialSessionState.CreateDefault2(); - this.myRunSpace = RunspaceFactory.CreateRunspace(this.myHost,iss); + this.myRunSpace = RunspaceFactory.CreateRunspace(this.myHost, iss); this.myRunSpace.Open(); + // Create a PowerShell object to run the commands used to create + // $profile and load the profiles. + lock (this.instanceLock) + { + this.currentPowerShell = PowerShell.Create(); + } + + try + { + this.currentPowerShell.Runspace = this.myRunSpace; + + PSCommand[] profileCommands = HostUtilities.GetProfileCommands("PSL"); + foreach (PSCommand command in profileCommands) + { + this.currentPowerShell.Commands = command; + this.currentPowerShell.Invoke(); + } + } + finally + { + // Dispose the PowerShell object and set currentPowerShell + // to null. It is locked because currentPowerShell may be + // accessed by the ctrl-C handler. + lock (this.instanceLock) + { + this.currentPowerShell.Dispose(); + this.currentPowerShell = null; + } + } + // run the initial script if (initialScript != null) - executeHelper(initialScript,null); + { + executeHelper(initialScript, null); + } } /// Sets the prompt equal to the output of the prompt function @@ -203,7 +218,7 @@ namespace Microsoft.Samples.PowerShell.Host private void executeHelper(string cmd, object input) { // Ignore empty command lines. - if (String.IsNullOrEmpty(cmd)) + if (string.IsNullOrEmpty(cmd)) { return; } @@ -223,8 +238,6 @@ namespace Microsoft.Samples.PowerShell.Host { this.currentPowerShell.Runspace = this.myRunSpace; - // TODO: Find out where this is set in the Monad host code and set all defaults that way - this.currentPowerShell.AddScript(string.Format("(Get-PSProvider 'FileSystem').Home = '{0}'",Environment.GetEnvironmentVariable("HOME"))); this.currentPowerShell.AddScript(cmd); // Add the default outputter to the end of the pipe and then call the @@ -387,12 +400,10 @@ namespace Microsoft.Samples.PowerShell.Host // the user calling "exit". while (!this.ShouldExit) { - string prompt; - prompt = Prompt(this.myHost.Runspace); + string prompt = Prompt(this.myHost.Runspace); this.myHost.UI.Write(ConsoleColor.White, ConsoleColor.Black, prompt); -// string cmd = this.consoleReadLine.Read(); - string cmd = Console.ReadLine(); + string cmd = this.myHost.UI.ReadLine(); this.Execute(cmd); } diff --git a/src/powershell-run/powershell-run.assembly-info.cs b/src/host/powershell.assembly-info.cs similarity index 100% rename from src/powershell-run/powershell-run.assembly-info.cs rename to src/host/powershell.assembly-info.cs diff --git a/src/powershell-run/rawui.cs b/src/host/rawui.cs similarity index 88% rename from src/powershell-run/rawui.cs rename to src/host/rawui.cs index 9349be913..c1871cf94 100644 --- a/src/powershell-run/rawui.cs +++ b/src/host/rawui.cs @@ -14,13 +14,14 @@ namespace Microsoft.Samples.PowerShell.Host { // this is all from https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx - internal class MyRawUserInterface : PSHostRawUserInterface + internal class MyRawUserInterface : PSHostRawUserInterface { // this class provides features otherwise not available through .net internal class Native { [DllImport("libpsnative")] internal static extern int GetTerminalWidth(); + [DllImport("libpsnative")] internal static extern int GetTerminalHeight(); } @@ -55,9 +56,9 @@ namespace Microsoft.Samples.PowerShell.Host public override Coordinates CursorPosition { get { throw new NotImplementedException( - "The method or operation is not implemented."); } + "The method or operation is not implemented."); } set { throw new NotImplementedException( - "The method or operation is not implemented."); } + "The method or operation is not implemented."); } } /// @@ -89,8 +90,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override bool KeyAvailable { - get { return false; } - // get { return Console.KeyAvailable; } + get { return false; } + // get { return Console.KeyAvailable; } } /// @@ -102,8 +103,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override Size MaxPhysicalWindowSize { - // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } - get { return new Size(1024,768); } + // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } + get { return new Size(1024,768); } } /// @@ -114,8 +115,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override Size MaxWindowSize { - // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } - get { return new Size(1024,768); } + // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } + get { return new Size(1024,768); } } /// @@ -125,8 +126,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override Coordinates WindowPosition { - // get { return new Coordinates(Console.WindowLeft, Console.WindowTop); } - // set { Console.SetWindowPosition(value.X, value.Y); } + // get { return new Coordinates(Console.WindowLeft, Console.WindowTop); } + // set { Console.SetWindowPosition(value.X, value.Y); } get { return new Coordinates(0,0); } set { } } @@ -138,8 +139,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override Size WindowSize { - // get { return new Size(Console.WindowWidth, Console.WindowHeight); } - // set { Console.SetWindowSize(value.Width, value.Height); } + // get { return new Size(Console.WindowWidth, Console.WindowHeight); } + // set { Console.SetWindowSize(value.Width, value.Height); } get { return new Size(1024,768); } set { } } @@ -150,8 +151,8 @@ namespace Microsoft.Samples.PowerShell.Host /// public override string WindowTitle { - // get { return Console.Title; } - // set { Console.Title = value; } + // get { return Console.Title; } + // set { Console.Title = value; } get { return "window title"; } set { } } @@ -174,7 +175,7 @@ namespace Microsoft.Samples.PowerShell.Host public override BufferCell[,] GetBufferContents(Rectangle rectangle) { throw new NotImplementedException( - "The method or operation is not implemented."); + "The method or operation is not implemented."); } /// @@ -190,7 +191,7 @@ namespace Microsoft.Samples.PowerShell.Host public override KeyInfo ReadKey(ReadKeyOptions options) { throw new NotImplementedException( - "The method or operation is not implemented."); + "The method or operation is not implemented."); } /// @@ -206,7 +207,7 @@ namespace Microsoft.Samples.PowerShell.Host public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill) { throw new NotImplementedException( - "The method or operation is not implemented."); + "The method or operation is not implemented."); } /// @@ -220,7 +221,7 @@ namespace Microsoft.Samples.PowerShell.Host BufferCell[,] contents) { throw new NotImplementedException( - "The method or operation is not implemented."); + "The method or operation is not implemented."); } /// @@ -233,9 +234,7 @@ namespace Microsoft.Samples.PowerShell.Host public override void SetBufferContents(Rectangle rectangle, BufferCell fill) { throw new NotImplementedException( - "The method or operation is not implemented."); + "The method or operation is not implemented."); } } - } - diff --git a/src/powershell-run/readline.cs b/src/host/readline.cs similarity index 96% rename from src/powershell-run/readline.cs rename to src/host/readline.cs index b1893029e..324638d6d 100644 --- a/src/powershell-run/readline.cs +++ b/src/host/readline.cs @@ -49,28 +49,28 @@ namespace Microsoft.Samples.PowerShell.Host public ConsoleReadLine() { this.tokenColors = new ConsoleColor[] - { - this.defaultColor, // Unknown + { + this.defaultColor, // Unknown ConsoleColor.Yellow, // Command ConsoleColor.Green, // CommandParameter ConsoleColor.Cyan, // CommandArgument ConsoleColor.Cyan, // Number ConsoleColor.Cyan, // String ConsoleColor.Green, // Variable - this.defaultColor, // Member - this.defaultColor, // LoopLabel + this.defaultColor, // Member + this.defaultColor, // LoopLabel ConsoleColor.DarkYellow, // Attribute ConsoleColor.DarkYellow, // Type ConsoleColor.DarkCyan, // Operator - this.defaultColor, // GroupStart - this.defaultColor, // GroupEnd + this.defaultColor, // GroupStart + this.defaultColor, // GroupEnd ConsoleColor.Magenta, // Keyword ConsoleColor.Red, // Comment ConsoleColor.DarkCyan, // StatementSeparator - this.defaultColor, // NewLine - this.defaultColor, // LineContinuation - this.defaultColor, // Position - }; + this.defaultColor, // NewLine + this.defaultColor, // LineContinuation + this.defaultColor, // Position + }; } /// diff --git a/src/powershell-run/ui.cs b/src/host/ui.cs similarity index 100% rename from src/powershell-run/ui.cs rename to src/host/ui.cs diff --git a/src/monad b/src/monad index f6bd69cc0..82cc60caa 160000 --- a/src/monad +++ b/src/monad @@ -1 +1 @@ -Subproject commit f6bd69cc07c0d564379c684654a3c37b0fbfdaad +Subproject commit 82cc60caa6bb6fd5ece013763669d8e1c91809f6 diff --git a/src/monad-build b/src/monad-build index 2b2ea2820..80e99a447 160000 --- a/src/monad-build +++ b/src/monad-build @@ -1 +1 @@ -Subproject commit 2b2ea2820b2dfce1742e4e81023dde9c324f9fa9 +Subproject commit 80e99a447f433f2e8f91a567d8171d5207a88dc3 diff --git a/src/monad-native b/src/monad-native index 102f6163a..99485dea3 160000 --- a/src/monad-native +++ b/src/monad-native @@ -1 +1 @@ -Subproject commit 102f6163a17afec6e27107ec0fdfec5fd458c706 +Subproject commit 99485dea3ecedcaed32a4e31e55cdc2073504511 diff --git a/src/pester-tests/Format-List.Tests.ps1 b/src/pester-tests/Format-List.Tests.ps1 index ac8945f00..e1f807c76 100644 --- a/src/pester-tests/Format-List.Tests.ps1 +++ b/src/pester-tests/Format-List.Tests.ps1 @@ -1,34 +1,34 @@ Describe "Format-List" { BeforeEach { - $input = New-Object PSObject - Add-Member -InputObject $input -MemberType NoteProperty -Name testName -Value testValue + $in = New-Object PSObject + Add-Member -InputObject $in -MemberType NoteProperty -Name testName -Value testValue } It "Should call format list without error" { - { $input | Format-List } | Should Not Throw - { $input | Format-List } | Should Not BeNullOrEmpty + { $in | Format-List } | Should Not Throw + { $in | Format-List } | Should Not BeNullOrEmpty } It "Should be able to call the alias" { - { $input | fl } | Should Not Throw - { $input | fl } | Should Not BeNullOrEmpty + { $in | fl } | Should Not Throw + { $in | fl } | Should Not BeNullOrEmpty } It "Should have the same output whether choosing alias or not" { - $expected = $input | Format-List | Out-String - $actual = $input | fl | Out-String + $expected = $in | Format-List | Out-String + $actual = $in | fl | Out-String $actual | Should Be $expected } It "Should produce the expected output" { $expected = "`n`ntestName : testValue`n`n`n`n" - $input = New-Object PSObject - Add-Member -InputObject $input -MemberType NoteProperty -Name testName -Value testValue + $in = New-Object PSObject + Add-Member -InputObject $in -MemberType NoteProperty -Name testName -Value testValue - $input | Format-List | Should Not BeNullOrEmpty - $input | Format-List | Out-String | Should Not BeNullOrEmpty - $input | Format-List | Out-String | Should Be $expected + $in | Format-List | Should Not BeNullOrEmpty + $in | Format-List | Out-String | Should Not BeNullOrEmpty + $in | Format-List | Out-String | Should Be $expected } It "Should be able to call a property of the piped input" { @@ -64,7 +64,7 @@ Describe "Format-List" { } It "Should be able to take input without piping objects to it" { - $output = { Format-List -InputObject $input } + $output = { Format-List -InputObject $in } $output | Should Not Throw $output | Should Not BeNullOrEmpty diff --git a/src/pester-tests/New-Variable.Tests.ps1 b/src/pester-tests/New-Variable.Tests.ps1 index b45520d7c..32980f0ab 100644 --- a/src/pester-tests/New-Variable.Tests.ps1 +++ b/src/pester-tests/New-Variable.Tests.ps1 @@ -49,18 +49,18 @@ } It "Should be able to set the value of a variable by piped input" { - $input = "value" + $in = "value" - $input | New-Variable -Name var1 + $in | New-Variable -Name var1 - $var1 | Should Be $input + $var1 | Should Be $in } It "Should be able to pipe object properties to output using the PassThru switch" { - $input = Set-Variable -Name testVar -Value "test" -Description "test description" -PassThru + $in = Set-Variable -Name testVar -Value "test" -Description "test description" -PassThru - $output = $input | Format-List -Property Description | Out-String + $output = $in | Format-List -Property Description | Out-String $output | Should Be "`n`nDescription : test description`n`n`n`n" } diff --git a/src/pester-tests/Out-File.Tests.ps1 b/src/pester-tests/Out-File.Tests.ps1 index c7c9a921a..64f106352 100644 --- a/src/pester-tests/Out-File.Tests.ps1 +++ b/src/pester-tests/Out-File.Tests.ps1 @@ -1,6 +1,6 @@ Describe "Out-File" { $expectedContent = "some test text" - $inputObject = New-Object psobject -Property @{text=$expectedContent} + $inObject = New-Object psobject -Property @{text=$expectedContent} $testfile = "/tmp/outfileTest.txt" AfterEach { @@ -28,17 +28,17 @@ } It "Should be able to accept object input" { - { $inputObject | Out-File -FilePath $testfile } | Should Not Throw + { $inObject | Out-File -FilePath $testfile } | Should Not Throw - { Out-File -FilePath $testfile -InputObject $inputObject } | Should Not Throw + { Out-File -FilePath $testfile -InputObject $inObject } | Should Not Throw } It "Should not overwrite when the noclobber switch is used" { - Out-File -FilePath $testfile -InputObject $inputObject + Out-File -FilePath $testfile -InputObject $inObject - { Out-File -FilePath $testfile -InputObject $inputObject -NoClobber -ErrorAction SilentlyContinue } | Should Throw "already exists." - { Out-File -FilePath $testfile -InputObject $inputObject -NoOverWrite -ErrorAction SilentlyContinue } | Should Throw "already exists." + { Out-File -FilePath $testfile -InputObject $inObject -NoClobber -ErrorAction SilentlyContinue } | Should Throw "already exists." + { Out-File -FilePath $testfile -InputObject $inObject -NoOverWrite -ErrorAction SilentlyContinue } | Should Throw "already exists." $actual = Get-Content $testfile @@ -49,8 +49,8 @@ } It "Should Append a new line when the append switch is used" { - { Out-File -FilePath $testfile -InputObject $inputObject } | Should Not Throw - { Out-File -FilePath $testfile -InputObject $inputObject -Append } | Should Not Throw + { Out-File -FilePath $testfile -InputObject $inObject } | Should Not Throw + { Out-File -FilePath $testfile -InputObject $inObject -Append } | Should Not Throw $actual = Get-Content $testfile @@ -71,7 +71,7 @@ It "Should limit each line to the specified number of characters when the width switch is used on objects" { - Out-File -FilePath $testfile -Width 10 -InputObject $inputObject + Out-File -FilePath $testfile -Width 10 -InputObject $inObject $actual = Get-Content $testfile @@ -84,11 +84,11 @@ It "Should allow the cmdlet to overwrite an existing read-only file" { # create a read-only text file - { Out-File -FilePath $testfile -InputObject $inputObject } | Should Not Throw + { Out-File -FilePath $testfile -InputObject $inObject } | Should Not Throw Set-ItemProperty -Path $testfile -Name IsReadOnly -Value $true # write information to the RO file - { Out-File -FilePath $testfile -InputObject $inputObject -Append -Force } | Should Not Throw + { Out-File -FilePath $testfile -InputObject $inObject -Append -Force } | Should Not Throw $actual = Get-Content $testfile diff --git a/src/pester-tests/Set-Variable.Tests.ps1 b/src/pester-tests/Set-Variable.Tests.ps1 index 0b43552cb..46f87e496 100644 --- a/src/pester-tests/Set-Variable.Tests.ps1 +++ b/src/pester-tests/Set-Variable.Tests.ps1 @@ -48,9 +48,9 @@ } It "Should be able to pipe object properties to output using the PassThru switch" { - $input = Set-Variable -Name testVar -Value "test" -Description "test description" -PassThru + $in = Set-Variable -Name testVar -Value "test" -Description "test description" -PassThru - $output = $input | Format-List -Property Description | Out-String + $output = $in | Format-List -Property Description | Out-String # This will cause errors running these tests in windows $output | Should Be "`n`nDescription : test description`n`n`n`n" diff --git a/src/powershell-run/powershell-simple.assembly-info.cs b/src/powershell-run/powershell-simple.assembly-info.cs deleted file mode 100644 index 523523c72..000000000 --- a/src/powershell-run/powershell-simple.assembly-info.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Reflection; -[assembly:AssemblyFileVersionAttribute("1.0.0.0")] -[assembly:AssemblyVersion("1.0.0.0")] diff --git a/src/powershell-run/powershell-simple.cs b/src/powershell-run/powershell-simple.cs deleted file mode 100644 index 5217440df..000000000 --- a/src/powershell-run/powershell-simple.cs +++ /dev/null @@ -1,497 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Management.Automation.Host; -using System.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; -using System.IO; - -namespace ps_hello_world -{ - // this is all from https://msdn.microsoft.com/en-us/library/ee706570%28v=vs.85%29.aspx - - internal class MyRawUserInterface : PSHostRawUserInterface - { - /// - /// Gets or sets the background color of the displayed text. - /// This maps to the corresponding Console.Background property. - /// - public override ConsoleColor BackgroundColor - { - get { return Console.BackgroundColor; } - set { Console.BackgroundColor = value; } - } - - /// - /// Gets or sets the size of the host buffer. In this example the - /// buffer size is adapted from the Console buffer size members. - /// - public override Size BufferSize - { - get { return new Size(200,500); } - set { } - //get { return new Size(Console.BufferWidth, Console.BufferHeight); } - //set { Console.SetBufferSize(value.Width, value.Height); } - } - - /// - /// Gets or sets the cursor position. In this example this - /// functionality is not needed so the property throws a - /// NotImplementException exception. - /// - public override Coordinates CursorPosition - { - get { throw new NotImplementedException( - "The method or operation is not implemented."); } - set { throw new NotImplementedException( - "The method or operation is not implemented."); } - } - - /// - /// Gets or sets the size of the displayed cursor. In this example - /// the cursor size is taken directly from the Console.CursorSize - /// property. - /// - public override int CursorSize - { - get { return 12; } - set { } - //get { return Console.CursorSize; } - //set { Console.CursorSize = value; } - } - - /// - /// Gets or sets the foreground color of the displayed text. - /// This maps to the corresponding Console.ForgroundColor property. - /// - public override ConsoleColor ForegroundColor - { - get { return Console.ForegroundColor; } - set { Console.ForegroundColor = value; } - } - - /// - /// Gets a value indicating whether the user has pressed a key. This maps - /// to the corresponding Console.KeyAvailable property. - /// - public override bool KeyAvailable - { - get { return false; } - // get { return Console.KeyAvailable; } - } - - /// - /// Gets the dimensions of the largest window that could be - /// rendered in the current display, if the buffer was at the least - /// that large. This example uses the Console.LargestWindowWidth and - /// Console.LargestWindowHeight properties to determine the returned - /// value of this property. - /// - public override Size MaxPhysicalWindowSize - { - // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } - get { return new Size(1024,768); } - } - - /// - /// Gets the dimentions of the largest window size that can be - /// displayed. This example uses the Console.LargestWindowWidth and - /// console.LargestWindowHeight properties to determine the returned - /// value of this property. - /// - public override Size MaxWindowSize - { - // get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } - get { return new Size(1024,768); } - } - - /// - /// Gets or sets the position of the displayed window. This example - /// uses the Console window position APIs to determine the returned - /// value of this property. - /// - public override Coordinates WindowPosition - { - // get { return new Coordinates(Console.WindowLeft, Console.WindowTop); } - // set { Console.SetWindowPosition(value.X, value.Y); } - get { return new Coordinates(0,0); } - set { } - } - - /// - /// Gets or sets the size of the displayed window. This example - /// uses the corresponding Console window size APIs to determine the - /// returned value of this property. - /// - public override Size WindowSize - { - // get { return new Size(Console.WindowWidth, Console.WindowHeight); } - // set { Console.SetWindowSize(value.Width, value.Height); } - get { return new Size(1024,768); } - set { } - } - - /// - /// Gets or sets the title of the displayed window. The example - /// maps the Console.Title property to the value of this property. - /// - public override string WindowTitle - { - // get { return Console.Title; } - // set { Console.Title = value; } - get { return "window title"; } - set { } - } - - /// - /// This API resets the input buffer. In this example this - /// functionality is not needed so the method returns nothing. - /// - public override void FlushInputBuffer() - { - } - - /// - /// This API returns a rectangular region of the screen buffer. In - /// this example this functionality is not needed so the method throws - /// a NotImplementException exception. - /// - /// Defines the size of the rectangle. - /// Throws a NotImplementedException exception. - public override BufferCell[,] GetBufferContents(Rectangle rectangle) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - - /// - /// This API reads a pressed, released, or pressed and released keystroke - /// from the keyboard device, blocking processing until a keystroke is - /// typed that matches the specified keystroke options. In this example - /// this functionality is not needed so the method throws a - /// NotImplementException exception. - /// - /// Options, such as IncludeKeyDown, used when - /// reading the keyboard. - /// Throws a NotImplementedException exception. - public override KeyInfo ReadKey(ReadKeyOptions options) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - - /// - /// This API crops a region of the screen buffer. In this example - /// this functionality is not needed so the method throws a - /// NotImplementException exception. - /// - /// The region of the screen to be scrolled. - /// The region of the screen to receive the - /// source region contents. - /// The region of the screen to include in the operation. - /// The character and attributes to be used to fill all cell. - public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - - /// - /// This method copies an array of buffer cells into the screen buffer - /// at a specified location. In this example this functionality is - /// not needed so the method throws a NotImplementedException exception. - /// - /// The parameter is not used. - /// The parameter is not used. - public override void SetBufferContents(Coordinates origin, - BufferCell[,] contents) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - - /// - /// This method copies a given character, foreground color, and background - /// color to a region of the screen buffer. In this example this - /// functionality is not needed so the method throws a - /// NotImplementException exception./// - /// Defines the area to be filled. - /// Defines the fill character. - public override void SetBufferContents(Rectangle rectangle, BufferCell fill) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - } - - - internal class MyHostUI : PSHostUserInterface - { - private MyRawUserInterface myRawUi = new MyRawUserInterface(); - - public override PSHostRawUserInterface RawUI - { - get { return this.myRawUi; } - } - - public override Dictionary Prompt( - string caption, - string message, - System.Collections.ObjectModel.Collection descriptions) - { - throw new NotImplementedException( - "The method or operation is not implemented."); - } - - public override int PromptForChoice(string caption, string message, System.Collections.ObjectModel.Collection choices, int defaultChoice) - { - throw new NotImplementedException("The method or operation is not implemented."); - } - - public override PSCredential PromptForCredential( - string caption, - string message, - string userName, - string targetName) - { - throw new NotImplementedException("The method or operation is not implemented."); - } - - public override PSCredential PromptForCredential( - string caption, - string message, - string userName, - string targetName, - PSCredentialTypes allowedCredentialTypes, - PSCredentialUIOptions options) - { - throw new NotImplementedException("The method or operation is not implemented."); - } - - public override string ReadLine() - { - return Console.ReadLine(); - } - - public override System.Security.SecureString ReadLineAsSecureString() - { - throw new NotImplementedException("The method or operation is not implemented."); - } - - public override void Write(string value) - { - Console.BackgroundColor = ConsoleColor.Black; - Console.Write(value); - Console.ResetColor(); - } - - public override void Write( - ConsoleColor foregroundColor, - ConsoleColor backgroundColor, - string value) - { - // Colors are ignored. - Console.ForegroundColor = foregroundColor; - Console.BackgroundColor = backgroundColor; - Console.Write(value); - Console.ResetColor(); - } - - public override void WriteDebugLine(string message) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write(String.Format( - CultureInfo.CurrentCulture, - "DEBUG: {0}", - message)); - Console.ResetColor(); - Console.WriteLine(); - } - - public override void WriteErrorLine(string value) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.Write(String.Format( - CultureInfo.CurrentCulture, - "ERROR: {0}", - value)); - Console.ResetColor(); - Console.WriteLine(); - } - - public override void WriteLine() - { - System.Console.WriteLine(); - } - - - - public override void WriteLine(string value) - { - Write(value); - Console.WriteLine(); - } - - public override void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value) - { - Write(foregroundColor,backgroundColor,value); - Console.WriteLine(); - } - - public override void WriteProgress(long sourceId, ProgressRecord record) - { - } - - public override void WriteVerboseLine(string message) - { - Console.BackgroundColor = ConsoleColor.Gray; - Console.WriteLine(String.Format(CultureInfo.CurrentCulture, "VERBOSE: {0}", message)); - Console.ResetColor(); - } - - public override void WriteWarningLine(string message) - { - Console.BackgroundColor = ConsoleColor.Yellow; - Console.WriteLine(String.Format(CultureInfo.CurrentCulture, "WARNING: {0}", message)); - Console.ResetColor(); - } - } - - internal class MyHost : PSHost - { - private Program program; - private CultureInfo originalCultureInfo = new CultureInfo("en-US"); - private CultureInfo originalUICultureInfo = new CultureInfo("en-US"); - private Guid myId = Guid.NewGuid(); - - public MyHost(Program program) - { - this.program = program; - } - - private MyHostUI myHostUI = new MyHostUI(); - - public override System.Globalization.CultureInfo CurrentCulture - { - get { return this.originalCultureInfo; } - } - - public override System.Globalization.CultureInfo CurrentUICulture - { - get { return this.originalUICultureInfo; } - } - - public override Guid InstanceId - { - get { return myId; } - } - - public override string Name - { - get { return "MyHost"; } - } - - public override PSHostUserInterface UI - { - get { return myHostUI; } - } - - public override Version Version - { - get { return new Version(0,0,0,0); } - } - - public override void EnterNestedPrompt() - { - throw new NotImplementedException("EnterNestedPrompt not implemented"); - } - - public override void ExitNestedPrompt() - { - throw new NotImplementedException("ExitNestedPrompt not implemented"); - } - - public override void NotifyBeginApplication() - { - Console.WriteLine("MyHost: NotifyBeginApplication"); - return; - } - - public override void NotifyEndApplication() - { - return; - } - - public override void SetShouldExit(int exitCode) - { - Console.WriteLine("SetShouldExit: " + exitCode); - } - } - - class Program - { - - private static void ReportException(Exception e) - { - if (e != null) - { - object error; - IContainsErrorRecord icer = e as IContainsErrorRecord; - if (icer != null) - { - error = icer.ErrorRecord; - } - else - { - error = (object)new ErrorRecord(e, "Host.ReportException", ErrorCategory.NotSpecified, null); - } - - // this should be output through PowerShell, but for simplicity just output it here - Console.WriteLine(error.ToString()); - } - } - - static void test2(string[] args) - { - try - { - MyHost myHost = new MyHost(new Program()); - - InitialSessionState iss = InitialSessionState.CreateDefault2(); - - using (Runspace rs = RunspaceFactory.CreateRunspace(myHost,iss)) - { - rs.Open(); - foreach (var arg in args) - { - using (PowerShell ps = PowerShell.Create()) - { - ps.Runspace = rs; - - Console.WriteLine("script: " + arg); - ps.AddScript(arg); - ps.AddCommand("out-default"); - ps.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error,PipelineResultTypes.Output); - ps.Invoke(); - ps.Dispose(); - } - } - } - } - catch (RuntimeException ex) - { - ReportException(ex); - } - } - - static void Main(string[] args) - { - test2(args); - } - } -} diff --git a/src/ps_test/test_Binders.cs b/src/xunit-tests/test_Binders.cs similarity index 100% rename from src/ps_test/test_Binders.cs rename to src/xunit-tests/test_Binders.cs diff --git a/src/ps_test/test_CorePsExtensions.cs b/src/xunit-tests/test_CorePsExtensions.cs similarity index 100% rename from src/ps_test/test_CorePsExtensions.cs rename to src/xunit-tests/test_CorePsExtensions.cs diff --git a/src/ps_test/test_CorePsPlatform.cs b/src/xunit-tests/test_CorePsPlatform.cs similarity index 100% rename from src/ps_test/test_CorePsPlatform.cs rename to src/xunit-tests/test_CorePsPlatform.cs diff --git a/src/ps_test/test_ExtensionMethods.cs b/src/xunit-tests/test_ExtensionMethods.cs similarity index 100% rename from src/ps_test/test_ExtensionMethods.cs rename to src/xunit-tests/test_ExtensionMethods.cs diff --git a/src/ps_test/test_FileSystemProvider.cs b/src/xunit-tests/test_FileSystemProvider.cs similarity index 100% rename from src/ps_test/test_FileSystemProvider.cs rename to src/xunit-tests/test_FileSystemProvider.cs diff --git a/src/ps_test/test_MshSnapinInfo.cs b/src/xunit-tests/test_MshSnapinInfo.cs similarity index 100% rename from src/ps_test/test_MshSnapinInfo.cs rename to src/xunit-tests/test_MshSnapinInfo.cs diff --git a/src/ps_test/test_PSVersionInfo.cs b/src/xunit-tests/test_PSVersionInfo.cs similarity index 100% rename from src/ps_test/test_PSVersionInfo.cs rename to src/xunit-tests/test_PSVersionInfo.cs diff --git a/src/ps_test/test_Runspace.cs b/src/xunit-tests/test_Runspace.cs similarity index 100% rename from src/ps_test/test_Runspace.cs rename to src/xunit-tests/test_Runspace.cs diff --git a/src/ps_test/test_SecuritySupport.cs b/src/xunit-tests/test_SecuritySupport.cs similarity index 100% rename from src/ps_test/test_SecuritySupport.cs rename to src/xunit-tests/test_SecuritySupport.cs diff --git a/src/ps_test/test_Utils.cs b/src/xunit-tests/test_Utils.cs similarity index 100% rename from src/ps_test/test_Utils.cs rename to src/xunit-tests/test_Utils.cs diff --git a/src/xunit-tests/xunit-tests.mk b/src/xunit-tests/xunit-tests.mk new file mode 100644 index 000000000..73d12d752 --- /dev/null +++ b/src/xunit-tests/xunit-tests.mk @@ -0,0 +1,12 @@ +# xUnit tests for PowerShell +# - results in xunit-tests.xml +# - see https://xunit.github.io/ +TEST_FOLDER=$(MONAD)/src/xunit-tests +TEST_SRCS=$(TEST_FOLDER)/test_*.cs +TEST_TARGETS=$(addprefix $(PSLIB)/, System.Management.Automation.dll Microsoft.PowerShell.Commands.Management.dll) + +$(PSLIB)/PowerShell.Linux.Test.dll: $(TEST_SRCS) $(TEST_TARGETS) + $(CSC) $(CSCOPTS_LIB) -out:$@ $(addprefix -r:$(MONAD_EXT)/xunit/, xunit.core.dll xunit.assert.dll) $(addprefix -r:, $(TEST_TARGETS)) $(COREREF) $(TEST_SRCS) + +test: $(PSLIB)/PowerShell.Linux.Test.dll + $(POWERSHELL_HOST) $(PSLIB)/xunit.console.netcore.exe $< -xml $(MONAD)/xunit-tests.xml