Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge from rhino-esb/rhino-esb

  • Loading branch information...
commit c82b050b6be92e523a38baa7d96799baa327634e 1 parent 1430fd5
Philip Hoy authored
Showing with 1,540 additions and 388 deletions.
  1. +3 −1 Rhino.ServiceBus.Host/Rhino.ServiceBus.Host.csproj
  2. +98 −0 Rhino.ServiceBus.Tests/CanSendMsgsFromOneWayBusUsingRhinoQueues.cs
  3. +21 −0 Rhino.ServiceBus.Tests/OneWayBusRhinoQueues.config
  4. +9 −7 Rhino.ServiceBus.Tests/Rhino.ServiceBus.Tests.csproj
  5. +4 −4 Rhino.ServiceBus.sln
  6. +2 −0  Rhino.ServiceBus/IOnewayBus.cs
  7. +1 −0  Rhino.ServiceBus/Impl/DefaultServiceBus.cs
  8. +5 −1 Rhino.ServiceBus/Impl/MessageOwnersConfigReader.cs
  9. +48 −14 Rhino.ServiceBus/Impl/OnewayRhinoServiceBusFacility.cs
  10. +6 −7 Rhino.ServiceBus/Rhino.ServiceBus.csproj
  11. +23 −0 Rhino.ServiceBus/RhinoQueues/RhinoQueuesOneWayBus.cs
  12. +3 −0  Rhino.ServiceBus/RhinoQueues/RhinoQueuesTransport.cs
  13. +3 −11 Samples/Starbucks.Tests/Starbucks.Tests.csproj
  14. +3 −11 Samples/Starbucks/Starbucks.csproj
  15. BIN  SharedLibs/Castle.Core.dll
  16. BIN  SharedLibs/Castle.Windsor.dll
  17. BIN  SharedLibs/Esent.Interop.dll
  18. +78 −8 SharedLibs/Esent.Interop.xml
  19. BIN  SharedLibs/Rhino.DistributedHashTable.Client.dll
  20. BIN  SharedLibs/Rhino.DistributedHashTable.dll
  21. BIN  SharedLibs/Rhino.PersistentHashTable.dll
  22. BIN  SharedLibs/Rhino.Queues.dll
  23. +4 −0 Tools/xUnit/xunit.console.exe.config
  24. +3 −0  build_release_4.ps1
  25. +13 −13 default.ps1
  26. +5 −311 psake.ps1
  27. +1,208 −0 psake.psm1
View
4 Rhino.ServiceBus.Host/Rhino.ServiceBus.Host.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,8 @@
<AssemblyName>Rhino.ServiceBus.Host</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\ayende-open-source.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
View
98 Rhino.ServiceBus.Tests/CanSendMsgsFromOneWayBusUsingRhinoQueues.cs
@@ -0,0 +1,98 @@
+using System;
+using System.IO;
+using System.Threading;
+using System.Transactions;
+using Castle.Windsor;
+using Castle.Windsor.Configuration.Interpreters;
+using Rhino.ServiceBus.Impl;
+using Rhino.ServiceBus.Internal;
+using Rhino.ServiceBus.RhinoQueues;
+using Rhino.ServiceBus.Tests.RhinoQueues;
+using Xunit;
+
+namespace Rhino.ServiceBus.Tests
+{
+ public class CanSendMsgsFromOneWayBusUsingRhinoQueues : WithDebugging,IDisposable
+ {
+ private WindsorContainer container;
+
+ public CanSendMsgsFromOneWayBusUsingRhinoQueues()
+ {
+ if (Directory.Exists("one_way.esent"))
+ Directory.Delete("one_way.esent", true);
+ if (Directory.Exists("test_queue.esent"))
+ Directory.Delete("test_queue.esent", true);
+ if (Directory.Exists("test_queue_subscriptions.esent"))
+ Directory.Delete("test_queue_subscriptions.esent", true);
+ container = new WindsorContainer(new XmlInterpreter("OneWayBusRhinoQueues.config"));
+ container.Kernel.AddFacility("rhino.esb", new RhinoServiceBusFacility());
+ container.AddComponent<StringConsumer>();
+ StringConsumer.Value = null;
+ StringConsumer.Event = new ManualResetEvent(false);
+ }
+
+
+
+ [Fact]
+ public void SendMessageToRemoteBus()
+ {
+ using (var bus = container.Resolve<IStartableServiceBus>())
+ {
+ bus.Start();
+ var transport = new RhinoQueuesTransport(new Uri("null://nowhere:24689/middle"),
+ new EndpointRouter(), container.Resolve<IMessageSerializer>(),
+ 1, "one_way.esent", IsolationLevel.ReadCommitted, 5);
+ var oneWay = new RhinoQueuesOneWayBus(new[]
+ {
+ new MessageOwner
+ {
+ Endpoint = bus.Endpoint.Uri,
+ Name = "System",
+ },
+ }, transport);
+
+ oneWay.Send("hello there, one way");
+
+ StringConsumer.Event.WaitOne();
+
+ Assert.Equal("hello there, one way", StringConsumer.Value);
+ }
+ }
+
+ [Fact]
+ public void SendMessageToRemoteBusFromConfigDrivenOneWayBus()
+ {
+ using (var bus = container.Resolve<IStartableServiceBus>())
+ {
+ bus.Start();
+
+ using (var c = new WindsorContainer(new XmlInterpreter("OneWayBusRhinoQueues.config")))
+ {
+ c.Kernel.AddFacility("one.way.rhino.esb", new OnewayRhinoServiceBusFacility());
+ c.Resolve<IOnewayBus>().Send("hello there, one way");
+ StringConsumer.Event.WaitOne();
+ Assert.Equal("hello there, one way", StringConsumer.Value);
+ }
+
+
+ }
+ }
+
+ public class StringConsumer : ConsumerOf<string>
+ {
+ public static ManualResetEvent Event;
+ public static string Value;
+
+ public void Consume(string pong)
+ {
+ Value = pong;
+ Event.Set();
+ }
+ }
+
+ public void Dispose()
+ {
+ container.Dispose();
+ }
+ }
+}
View
21 Rhino.ServiceBus.Tests/OneWayBusRhinoQueues.config
@@ -0,0 +1,21 @@
+<castle>
+ <facilities>
+ <facility id="rhino.esb" >
+ <bus name="test_queue"
+ threadCount="1"
+ numberOfRetries="5"
+ endpoint="rhino.queues://localhost/test_queue"
+ queueIsolationLevel="ReadCommitted" />
+ <messages>
+ <add name="Rhino.ServiceBus.Tests"
+ endpoint="rhino.queues://localhost/test_queue"/>
+ </messages>
+ </facility>
+ <facility id="one.way.rhino.esb" >
+ <messages>
+ <add name="System.String"
+ endpoint="rhino.queues://localhost/test_queue"/>
+ </messages>
+ </facility>
+ </facilities>
+</castle>
View
16 Rhino.ServiceBus.Tests/Rhino.ServiceBus.Tests.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,8 @@
<AssemblyName>Rhino.ServiceBus.Tests</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\ayende-open-source.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -31,15 +33,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\SharedLibs\Castle.Core.dll</HintPath>
</Reference>
- <Reference Include="Castle.MicroKernel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\SharedLibs\Castle.MicroKernel.dll</HintPath>
- </Reference>
- <Reference Include="Castle.Windsor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Windsor, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\SharedLibs\Castle.Windsor.dll</HintPath>
</Reference>
@@ -110,6 +108,7 @@
<Compile Include="BusSubscriptionTests.cs" />
<Compile Include="CanRouteMessageToConsumerThroughContainer.cs" />
<Compile Include="CanSendMsgsFromOneWayBus.cs" />
+ <Compile Include="CanSendMsgsFromOneWayBusUsingRhinoQueues.cs" />
<Compile Include="DelayedMessages.cs" />
<Compile Include="DataStructures\LRUSetTest.cs" />
<Compile Include="DataStructures\HashtableTest.cs" />
@@ -176,6 +175,9 @@
<None Include="BusOnTransactionalQueue.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Include="OneWayBusRhinoQueues.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<None Include="LoadBalancer\BusWithAcceptingWorkLoadBalancer.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
View
8 Rhino.ServiceBus.sln
@@ -1,12 +1,12 @@

-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Starbucks", "Starbucks", "{64DC50EF-F634-4E75-8375-ACC6D42E2DB4}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rhino.ServiceBus", "Rhino.ServiceBus\Rhino.ServiceBus.csproj", "{1B21C8A5-5E0E-412B-A7F4-9F28B4427F21}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rhino.ServiceBus.Tests", "Rhino.ServiceBus.Tests\Rhino.ServiceBus.Tests.csproj", "{EAC59871-8B6B-4A1B-A2AE-69F7194F047E}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Starbucks", "Starbucks", "{64DC50EF-F634-4E75-8375-ACC6D42E2DB4}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Starbucks", "Samples\Starbucks\Starbucks.csproj", "{0FC43226-8030-46FC-A2AB-D064207FF364}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rhino.ServiceBus.Host", "Rhino.ServiceBus.Host\Rhino.ServiceBus.Host.csproj", "{8FBBDD2A-A832-4827-9325-C670B6DC06FB}"
View
2  Rhino.ServiceBus/IOnewayBus.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Rhino.ServiceBus
{
public interface IOnewayBus
View
1  Rhino.ServiceBus/Impl/DefaultServiceBus.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Linq;
using Castle.MicroKernel;
+using Castle.MicroKernel.Context;
using Castle.MicroKernel.Proxy;
using log4net;
using Rhino.ServiceBus.Exceptions;
View
6 Rhino.ServiceBus/Impl/MessageOwnersConfigReader.cs
@@ -15,7 +15,7 @@ public MessageOwnersConfigReader(IConfiguration configuration, ICollection<Messa
this.configuration = configuration;
this.messageOwners = messageOwners;
}
-
+ public string EndpointScheme { get; private set; }
public void ReadMessageOwners()
{
IConfiguration messageConfig = configuration.Children["messages"];
@@ -36,6 +36,10 @@ public void ReadMessageOwners()
try
{
ownerEndpoint = new Uri(uriString);
+ if(EndpointScheme==null)
+ {
+ EndpointScheme = ownerEndpoint.Scheme;
+ }
}
catch (Exception e)
{
View
62 Rhino.ServiceBus/Impl/OnewayRhinoServiceBusFacility.cs
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Transactions;
using Castle.Core;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.Registration;
using Rhino.ServiceBus.Internal;
using Rhino.ServiceBus.Msmq;
+using Rhino.ServiceBus.RhinoQueues;
using Rhino.ServiceBus.Serializers;
using System.Linq;
@@ -22,27 +25,58 @@ public void UseMessageSerializer<TMessageSerializer>()
protected override void Init()
{
- new MessageOwnersConfigReader(FacilityConfig, messageOwners).ReadMessageOwners();
-
+ var messageOwnersReader = new MessageOwnersConfigReader(FacilityConfig, messageOwners);
+ messageOwnersReader.ReadMessageOwners();
+ if (IsRhinoQueues(messageOwnersReader.EndpointScheme))
+ {
+ var path = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory);
+ Kernel.Register(
+ Component.For<ITransport>()
+ .LifeStyle.Is(LifestyleType.Singleton)
+ .ImplementedBy(typeof (RhinoQueuesTransport))
+ .DependsOn(new
+ {
+ threadCount = 1,
+ endpoint = new Uri("null://nowhere:24689/middle"),
+ queueIsolationLevel = IsolationLevel.ReadCommitted,
+ numberOfRetries = 5,
+ path = Path.Combine(path,"one_way.esent")
+ }),
+ Component.For<IOnewayBus>()
+ .LifeStyle.Is(LifestyleType.Singleton)
+ .ImplementedBy<RhinoQueuesOneWayBus>()
+ .DependsOn(new {messageOwners = messageOwners.ToArray()})
+ );
+ }
+ else
+ {
+ Kernel.Register(
+ Component.For<IMessageBuilder>()
+ .LifeStyle.Is(LifestyleType.Singleton)
+ .ImplementedBy<MessageBuilder>(),
+ Component.For<IOnewayBus>()
+ .LifeStyle.Is(LifestyleType.Singleton)
+ .ImplementedBy<OnewayBus>()
+ .DependsOn(new {messageOwners = messageOwners.ToArray()}));
+
+ }
Kernel.Register(
- Component.For<IMessageBuilder>()
- .LifeStyle.Is(LifestyleType.Singleton)
- .ImplementedBy<MessageBuilder>(),
- Component.For<IOnewayBus>()
- .LifeStyle.Is(LifestyleType.Singleton)
- .ImplementedBy<OnewayBus>()
- .DependsOn(new{messageOwners = messageOwners.ToArray()}),
Component.For<IReflection>()
- .LifeStyle.Is(LifestyleType.Singleton)
- .ImplementedBy<DefaultReflection>(),
-
+ .LifeStyle.Is(LifestyleType.Singleton)
+ .ImplementedBy<DefaultReflection>(),
Component.For<IMessageSerializer>()
.LifeStyle.Is(LifestyleType.Singleton)
.ImplementedBy(serializerImpl),
Component.For<IEndpointRouter>()
- .ImplementedBy<EndpointRouter>()
- );
+ .ImplementedBy<EndpointRouter>()
+ );
+
+ }
+
+ private static bool IsRhinoQueues(string endpointScheme)
+ {
+ return endpointScheme.Equals("rhino.queues", StringComparison.InvariantCultureIgnoreCase);
}
}
}
View
13 Rhino.ServiceBus/Rhino.ServiceBus.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,8 @@
<AssemblyName>Rhino.ServiceBus</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\ayende-open-source.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -33,15 +35,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\SharedLibs\Castle.Core.dll</HintPath>
</Reference>
- <Reference Include="Castle.MicroKernel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\SharedLibs\Castle.MicroKernel.dll</HintPath>
- </Reference>
- <Reference Include="Castle.Windsor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Windsor, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\SharedLibs\Castle.Windsor.dll</HintPath>
</Reference>
@@ -120,6 +118,7 @@
<Compile Include="Messages\ReadyToWork.cs" />
<Compile Include="Msmq\AbstractMsmqListener.cs" />
<Compile Include="Msmq\QueueCreationModule.cs" />
+ <Compile Include="RhinoQueues\RhinoQueuesOneWayBus.cs" />
<Compile Include="Transport\SubQueue.cs" />
<Compile Include="Msmq\TransportActions\ShutDownAction.cs" />
<Compile Include="Msmq\TransportState.cs" />
View
23 Rhino.ServiceBus/RhinoQueues/RhinoQueuesOneWayBus.cs
@@ -0,0 +1,23 @@
+using Rhino.ServiceBus.Impl;
+using Rhino.ServiceBus.Internal;
+
+namespace Rhino.ServiceBus.RhinoQueues
+{
+ public class RhinoQueuesOneWayBus : IOnewayBus
+ {
+ private MessageOwnersSelector messageOwners;
+ private ITransport transport;
+
+ public RhinoQueuesOneWayBus(MessageOwner[] messageOwners, ITransport transport)
+ {
+ this.messageOwners = new MessageOwnersSelector(messageOwners, new EndpointRouter());
+ this.transport = transport;
+ this.transport.Start();
+ }
+
+ public void Send(params object[] msgs)
+ {
+ transport.Send(messageOwners.GetEndpointForMessageBatch(msgs), msgs);
+ }
+ }
+}
View
3  Rhino.ServiceBus/RhinoQueues/RhinoQueuesTransport.cs
@@ -128,6 +128,9 @@ public IQueue Queue
public void Start()
{
+ if (haveStarted)
+ return;
+
shouldContinue = true;
var port = endpoint.Port;
View
14 Samples/Starbucks.Tests/Starbucks.Tests.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -31,19 +31,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\SharedLibs\Castle.Core.dll</HintPath>
</Reference>
- <Reference Include="Castle.DynamicProxy2, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\SharedLibs\Castle.DynamicProxy2.dll</HintPath>
- </Reference>
- <Reference Include="Castle.MicroKernel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\SharedLibs\Castle.MicroKernel.dll</HintPath>
- </Reference>
- <Reference Include="Castle.Windsor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Windsor, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\SharedLibs\Castle.Windsor.dll</HintPath>
</Reference>
View
14 Samples/Starbucks/Starbucks.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -31,19 +31,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\SharedLibs\Castle.Core.dll</HintPath>
</Reference>
- <Reference Include="Castle.DynamicProxy2, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\SharedLibs\Castle.DynamicProxy2.dll</HintPath>
- </Reference>
- <Reference Include="Castle.MicroKernel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\SharedLibs\Castle.MicroKernel.dll</HintPath>
- </Reference>
- <Reference Include="Castle.Windsor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+ <Reference Include="Castle.Windsor, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\SharedLibs\Castle.Windsor.dll</HintPath>
</Reference>
View
BIN  SharedLibs/Castle.Core.dll
Binary file not shown
View
BIN  SharedLibs/Castle.Windsor.dll
Binary file not shown
View
BIN  SharedLibs/Esent.Interop.dll
Binary file not shown
View
86 SharedLibs/Esent.Interop.xml
@@ -2353,6 +2353,25 @@
<param name="grbit">Retrieval options.</param>
<returns>The data retrieved from the column as an UInt64. Null if the column is null.</returns>
</member>
+ <member name="M:Microsoft.Isam.Esent.Interop.Api.DeserializeObjectFromColumn(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,Microsoft.Isam.Esent.Interop.JET_COLUMNID)">
+ <summary>
+ Deserialize an object from a column.
+ </summary>
+ <param name="sesid">The session to use.</param>
+ <param name="tableid">The table to read from.</param>
+ <param name="columnid">The column to read from.</param>
+ <returns>The deserialized object. Null if the column was null.</returns>
+ </member>
+ <member name="M:Microsoft.Isam.Esent.Interop.Api.DeserializeObjectFromColumn(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,Microsoft.Isam.Esent.Interop.JET_COLUMNID,Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit)">
+ <summary>
+ Deserialize an object from a column.
+ </summary>
+ <param name="sesid">The session to use.</param>
+ <param name="tableid">The table to read from.</param>
+ <param name="columnid">The column to read from.</param>
+ <param name="grbit">The retrieval options to use.</param>
+ <returns>The deserialized object. Null if the column was null.</returns>
+ </member>
<member name="M:Microsoft.Isam.Esent.Interop.Api.CreateReturnValue``1(``0,System.Int32,Microsoft.Isam.Esent.Interop.JET_wrn,System.Int32)">
<summary>
Create the nullable return value.
@@ -2380,6 +2399,15 @@
<param name="tableid">The table to retrieve the information for.</param>
<returns>A dictionary mapping column names to column IDs.</returns>
</member>
+ <member name="M:Microsoft.Isam.Esent.Interop.Api.GetTableColumnid(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,System.String)">
+ <summary>
+ Get the columnid of the specified column.
+ </summary>
+ <param name="sesid">The session to use.</param>
+ <param name="tableid">The table containing the column.</param>
+ <param name="columnName">The name of the column.</param>
+ <returns>The id of the column.</returns>
+ </member>
<member name="M:Microsoft.Isam.Esent.Interop.Api.GetTableColumns(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID)">
<summary>
Iterates over all the columns in the table, returning information about each one.
@@ -2484,6 +2512,7 @@
<param name="dataOffset">The offset in the data buffer to set data from.</param>
<param name="grbit">SetColumn options.</param>
<param name="setinfo">Used to specify itag or long-value offset.</param>
+ <returns>A warning value.</returns>
</member>
<member name="M:Microsoft.Isam.Esent.Interop.Api.JetRetrieveColumn(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,Microsoft.Isam.Esent.Interop.JET_COLUMNID,System.Byte[],System.Int32,System.Int32,System.Int32@,Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit,Microsoft.Isam.Esent.Interop.JET_RETINFO)">
<summary>
@@ -2574,6 +2603,7 @@
<param name="dataSize">The size of data to set.</param>
<param name="grbit">SetColumn options.</param>
<param name="setinfo">Used to specify itag or long-value offset.</param>
+ <returns>A warning value.</returns>
</member>
<member name="M:Microsoft.Isam.Esent.Interop.Api.MakeKey(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,System.Byte[],Microsoft.Isam.Esent.Interop.MakeKeyGrbit)">
<summary>
@@ -2884,6 +2914,15 @@
<param name="columnid">The columnid to set.</param>
<param name="data">The data to set.</param>
</member>
+ <member name="M:Microsoft.Isam.Esent.Interop.Api.SerializeObjectToColumn(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,Microsoft.Isam.Esent.Interop.JET_COLUMNID,System.Object)">
+ <summary>
+ Write a serialized form of an object to a column.
+ </summary>
+ <param name="sesid">The session to use.</param>
+ <param name="tableid">The table to write to. An update should be prepared.</param>
+ <param name="columnid">The column to write to.</param>
+ <param name="value">The object to write. The object must be serializable.</param>
+ </member>
<member name="M:Microsoft.Isam.Esent.Interop.Api.SetColumns(Microsoft.Isam.Esent.Interop.JET_SESID,Microsoft.Isam.Esent.Interop.JET_TABLEID,Microsoft.Isam.Esent.Interop.ColumnValue[])">
<summary>
Sets columns.
@@ -7075,6 +7114,21 @@
Gets a text message describing the exception.
</summary>
</member>
+ <member name="T:Microsoft.Isam.Esent.Interop.Server2003.Server2003Param">
+ <summary>
+ System parameters that have been added to the Windows Server 2003 version of ESENT.
+ </summary>
+ </member>
+ <member name="F:Microsoft.Isam.Esent.Interop.Server2003.Server2003Param.AlternateDatabaseRecoveryPath">
+ <summary>
+ The full path to each database is persisted in the transaction logs
+ at run time. Ordinarily, these databases must remain at the original
+ location for transaction replay to function correctly. This
+ parameter can be used to force crash recovery or a restore operation
+ to look for the databases referenced in the transaction log in the
+ specified folder.
+ </summary>
+ </member>
<member name="T:Microsoft.Isam.Esent.Interop.SystemParameters">
<summary>
This class provides static properties to set and get
@@ -7192,10 +7246,6 @@
<summary>
Gets the maximum key size. This depends on the Esent version and database
page size.
- <para>
- Supported on Windows Vista and up. Ignored on Windows XP and
- Windows Server 2003.
- </para>
</summary>
</member>
<member name="P:Microsoft.Isam.Esent.Interop.SystemParameters.ColumnsKeyMost">
@@ -7211,10 +7261,6 @@
<member name="P:Microsoft.Isam.Esent.Interop.SystemParameters.LVChunkSizeMost">
<summary>
Gets the lv chunks size. This depends on the database page size.
- <para>
- Supported on Windows 7 and up. Ignored on Windows XP,
- Windows Server 2003, Windows Vista and Windows Server 2008.
- </para>
</summary>
</member>
<member name="P:Microsoft.Isam.Esent.Interop.SystemParameters.Configuration">
@@ -8475,6 +8521,17 @@
folder that will contain the transaction logs for the instance.
</summary>
</member>
+ <member name="P:Microsoft.Isam.Esent.Interop.InstanceParameters.AlternateDatabaseRecoveryDirectory">
+ <summary>
+ Gets or sets the relative or absolute file system path of the
+ a folder where crash recovery or a restore operation can find
+ the databases referenced in the transaction log in the
+ specified folder.
+ </summary>
+ <remarks>
+ This parameter is ignored on Windows XP.
+ </remarks>
+ </member>
<member name="P:Microsoft.Isam.Esent.Interop.InstanceParameters.BaseName">
<summary>
Gets or sets the three letter prefix used for many of the files used by
@@ -9276,6 +9333,19 @@
Indexes are updated only by Update or and not during JetSetColumn or JetSetColumns
</remarks>
</member>
+ <member name="M:Microsoft.Isam.Esent.Interop.Update.SaveAndGotoBookmark">
+ <summary>
+ Update the tableid and position the tableid on the record that was modified.
+ This can be useful when inserting a record because by default the tableid
+ remains in its old location.
+ </summary>
+ <remarks>
+ Save is the final step in performing an insert or an update. The update is begun by
+ calling creating an Update object and then by calling JetSetColumn or JetSetColumns one or more times
+ to set the record state. Finally, Update is called to complete the update operation.
+ Indexes are updated only by Update or and not during JetSetColumn or JetSetColumns
+ </remarks>
+ </member>
<member name="M:Microsoft.Isam.Esent.Interop.Update.Cancel">
<summary>
Cancel the update.
View
BIN  SharedLibs/Rhino.DistributedHashTable.Client.dll
Binary file not shown
View
BIN  SharedLibs/Rhino.DistributedHashTable.dll
Binary file not shown
View
BIN  SharedLibs/Rhino.PersistentHashTable.dll
Binary file not shown
View
BIN  SharedLibs/Rhino.Queues.dll
Binary file not shown
View
4 Tools/xUnit/xunit.console.exe.config
@@ -18,4 +18,8 @@
</transforms>
</xunit>
+ <startup>
+ <requiredRuntime version="v4.0.30319" safemode="true"/>
+ </startup>
+
</configuration>
View
3  build_release_4.ps1
@@ -0,0 +1,3 @@
+import-module .\psake.psm1
+invoke-psake -framework '4.0' .\default.ps1 -properties @{config='Release';target_framework_version='4.0'}
+remove-module psake
View
26 default.ps1
@@ -7,7 +7,11 @@ properties {
$version = "1.8.0.0"
$tools_dir = "$base_dir\Tools"
$release_dir = "$base_dir\Release"
-}
+ $config = "Debug"
+ $target_framework_version = "3.5"
+}
+
+$framework = '4.0'
include .\psake_ext.ps1
@@ -39,15 +43,6 @@ task Init -depends Clean {
Generate-Assembly-Info `
-file "$base_dir\Rhino.ServiceBus.Host\Properties\AssemblyInfo.cs" `
- -title "Rhino DistributedHashTable $version" `
- -description "Distributed Hash Table for .NET" `
- -company "Hibernating Rhinos" `
- -product "Rhino DHT $version" `
- -version $version `
- -copyright "Hibernating Rhinos & Ayende Rahien 2004 - 2009"
-
- Generate-Assembly-Info `
- -file "$base_dir\Rhino.ServiceBus.DistributedHashTableIntegration\Properties\AssemblyInfo.cs" `
-title "Rhino Service Bus $version" `
-description "Developer friendly service bus for .NET" `
-company "Hibernating Rhinos" `
@@ -59,14 +54,19 @@ task Init -depends Clean {
new-item $buildartifacts_dir -itemType directory
}
-task Compile -depends Init {
- exec msbuild "/p:OutDir=""$buildartifacts_dir "" $sln_file"
+task Compile -depends Init {
+ $build_properties = "OutDir=$buildartifacts_dir;Configuration=$config"
+ if($target_framework_version -eq '4.0')
+ {
+ $build_properties = "$build_properties;TargetFrameworkVersion=$target_framework_version"
+ }
+ msbuild $sln_file /p:$build_properties
}
task Test -depends Compile {
$old = pwd
cd $build_dir
- exec "$tools_dir\xUnit\xunit.console.exe" "$build_dir\Rhino.ServiceBus.Tests.dll"
+ & $tools_dir\xUnit\xunit.console.exe "$build_dir\Rhino.ServiceBus.Tests.dll"
cd $old
}
View
316 psake.ps1
@@ -1,311 +1,5 @@
-# psake v0.22
-# Copyright © 2009 James Kovacs
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-param(
- [string]$buildFile = 'default.ps1',
- [string[]]$taskList = @(),
- [string]$framework = '3.5',
- [switch]$debug = $false,
- [switch]$help = $false,
- [switch]$timing = $false,
- [switch]$docs = $false
-)
-
-if($help) {
-@"
-psake [buildFile] [tasks] [-framework ver] [-debug] [-timing] [-docs]
- where buildFile is the name of the build file, (default: default.ps1)
- tasks is a list of tasks to execute from the build file,
- ver is the .NET Framework version to target - 1.0, 1.1, 2.0, 3.0, or 3.5 (default)
- debug dumps information on the properties, includes, and tasks, as well as more detailed error information.
- timing prints a report showing how long each task took to execute
- docs prints a list of available tasks
-
-psake -help
- Displays this message.
-"@
- return
-}
-
-$global:tasks = @{}
-$global:properties = @()
-$global:includes = New-Object System.Collections.Queue
-$global:psake_version = "0.22"
-$global:psake_buildScript = $buildFile
-$global:psake_frameworkVersion = $framework
-
-$script:executedTasks = New-Object System.Collections.Stack
-$script:callStack = New-Object System.Collections.Stack
-$script:originalEnvPath = $env:path
-$script:originalDirectory = Get-Location
-$originalErrorActionPreference = $Global:ErrorActionPreference
-
-function task([string]$name=$null, [scriptblock]$action = $null, [scriptblock]$precondition = $null, [scriptblock]$postcondition = $null, [switch]$continueOnError = $false, [string[]]$depends = @(), [string]$description = $null) {
- if (($name -eq $null) -or ($name.Trim() -eq "")) {
- throw "Error: Task must have a name"
- }
- if($name.ToLower() -eq 'default' -and $action -ne $null) {
- throw "Error: Default task cannot specify an action"
- }
- $newTask = @{
- Name = $name
- DependsOn = $depends
- Action = $action
- Precondition = $precondition
- Postcondition = $postcondition
- ContinueOnError = $continueOnError
- Description = $description
- }
- if($global:tasks.$name -ne $null) { throw "Error: Task, $name, has already been defined." }
- $global:tasks.$name = $newTask
-}
-
-function properties([scriptblock]$propertyBlock) {
- $global:properties += $propertyBlock
-}
-
-function include([string]$include){
- if (!(test-path $include)) { throw "Error: $include not found."}
- $global:includes.Enqueue((Resolve-Path $include));
-}
-
-function AssertNotCircular([string]$name) {
- if($script:callStack.Contains($name)) {
- throw "Error: Circular reference found for task, $name"
- }
-}
-
-function ExecuteTask([string]$name) {
- if($script:executedTasks.Contains($name)) { return }
- AssertNotCircular $name
- $script:callStack.Push($name)
-
- $task = $global:tasks.$name
- foreach($childTask in $task.DependsOn) {
- ExecuteTask $childTask
- }
- if($name -ne 'default') {
- $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
- $precondition = $true
- if($task.Precondition -ne $null) {
- $precondition = (& $task.Precondition)
- }
- "Executing task, $name..."
- if($task.Action -ne $null) {
- if($precondition) {
- trap {
- if ($task.ContinueOnError) {
- "-"*70
- "Error in Task [$name] $_"
- "-"*70
- continue
- } else {
- throw $_
- }
- }
- & $task.Action
- $postcondition = $true
- if($task.Postcondition -ne $null) {
- $postcondition = (& $task.Postcondition)
- }
- if (!$postcondition) {
- throw "Error: Postcondition failed for $name"
- }
- } else {
- "Precondition was false not executing $name"
- }
- }
- $stopwatch.stop()
- $task.Duration = $stopwatch.Elapsed
- }
-
- $poppedTask = $script:callStack.Pop()
- if($poppedTask -ne $name) {
- throw "Error: CallStack was corrupt. Expected $name, but got $poppedTask."
- }
- $script:executedTasks.Push($name)
-}
-
-function Dump-Tasks {
- 'Dumping tasks:'
- foreach($key in $global:tasks.Keys) {
- $task = $global:tasks.$key;
- $task.Name + " depends on " + $task.DependsOn.Length + " other tasks: " + $task.DependsOn;
- }
- "`n"
-}
-
-function Dump-Properties {
- 'Dumping properties:'
- $global:properties
-}
-
-function Dump-Includes {
- 'Dumping includes:'
- $global:includes
-}
-
-function Configure-BuildEnvironment {
- $version = $null
- switch ($framework) {
- '1.0' { $version = 'v1.0.3705' }
- '1.1' { $version = 'v1.1.4322' }
- '2.0' { $version = 'v2.0.50727' }
- '3.0' { $version = 'v2.0.50727' } # .NET 3.0 uses the .NET 2.0 compilers
- '3.5' { $version = 'v3.5' }
- default { throw "Error: Unknown .NET Framework version, $framework" }
- }
- $frameworkDir = "$env:windir\Microsoft.NET\Framework\$version\"
- if(!(test-path $frameworkDir)) {
- throw "Error: No .NET Framework installation directory found at $frameworkDir"
- }
- $env:path = "$frameworkDir;$env:path"
- $global:ErrorActionPreference = "Stop"
-}
-
-function Cleanup-Environment {
- $env:path = $script:originalEnvPath
- Set-Location $script:originalDirectory
- $global:ErrorActionPreference = $originalErrorActionPreference
- remove-variable tasks -scope "global"
- remove-variable properties -scope "global"
- remove-variable includes -scope "global"
- remove-variable psake_* -scope "global"
-}
-
-#borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
-function Resolve-Error($ErrorRecord=$Error[0]) {
- $ErrorRecord | Format-List * -Force
- $ErrorRecord.InvocationInfo | Format-List *
- $Exception = $ErrorRecord.Exception
- for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) {
- "$i" * 70
- $Exception | Format-List * -Force
- }
-}
-
-function Write-Documentation {
- $list = New-Object System.Collections.ArrayList
- foreach($key in $global:tasks.Keys) {
- if($key -eq "default") {
- continue;
- }
- $task = $global:tasks.$key;
- $content = "" | Select-Object Name, Description
- $content.Name = $task.Name
- $content.Description = $task.Description
- $index = $list.Add($content);
- }
-
- $list | Sort 'Name' | Format-Table -Auto
-}
-
-function exec([string]$command, [string]$parameters) {
- & $command $parameters
- if ($lastExitCode -ne 0) {
- throw "Error: Failed to execute ""$command"" with parameters ""$parameters"""
- }
-}
-
-function Run-Psake {
- trap {
- Cleanup-Environment
- Write-Host -foregroundcolor Red $_
- if($debug) {
- "-" * 80
- "An Error Occurred. See Error Details Below:"
- "-" * 80
- Resolve-Error
- "-" * 80
- }
- exit(1)
- }
-
- $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
-
- # Execute the build file to set up the tasks and defaults
- if(test-path $buildFile) {
- $buildFile = resolve-path $buildFile
- set-location (split-path $buildFile)
- & $buildFile
- } else {
- throw "Error: Could not find the build file, $buildFile."
- }
-
- if($debug) {
- Dump-Includes
- Dump-Properties
- Dump-Tasks
- }
-
- Configure-BuildEnvironment
-
- # N.B. The initial dot (.) indicates that variables initialized/modified
- # in the propertyBlock are available in the parent scope.
- while ($global:includes.Count -gt 0) {
- $includeBlock = $global:includes.Dequeue();
- . $includeBlock;
- }
- foreach($propertyBlock in $global:properties) {
- . $propertyBlock
- }
-
- if($docs) {
- Write-Documentation
- Cleanup-Environment
- exit(0)
- }
-
- # Execute the list of tasks or the default task
- if($taskList.Length -ne 0) {
- foreach($task in $taskList) {
- ExecuteTask $task
- }
- } elseif ($global:tasks.default -ne $null) {
- ExecuteTask default
- } else {
- throw 'Error: default task required'
- }
-
- $stopwatch.Stop()
-
- if ($timing) {
- "-"*70
- "Build Time Report"
- "-"*70
- $list = @()
- while ($script:executedTasks.Count -gt 0) {
- $name = $script:executedTasks.Pop()
- $task = $global:tasks.$name
- if($name -eq "default") {
- continue;
- }
- $list += "" | Select-Object @{Name="Name";Expression={$name}}, @{Name="Duration";Expression={$task.Duration}}
- }
- [Array]::Reverse($list)
- $list += "" | Select-Object @{Name="Name";Expression={"Total:"}}, @{Name="Duration";Expression={$stopwatch.Elapsed}}
- $list | Format-Table -Auto | Out-String -Stream | ? {$_} # using "Out-String -Stream" to filter out the blank line that Format-Table prepends
- }
-
- # Clear out any global variables
- Cleanup-Environment
-}
-
-Run-Psake
+# Helper script for those who want to run
+# psake without importing the module.
+import-module .\psake.psm1
+invoke-psake @args
+remove-module psake
View
1,208 psake.psm1
@@ -0,0 +1,1208 @@
+# psake
+# Copyright (c) 2010 James Kovacs
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+#Requires -Version 2.0
+
+#-- Private Module Variables (Listed here for quick reference)
+[system.collections.stack]$script:context
+
+#-- Public Module Variables -- The psake hashtable variable is initialized in the invoke-psake function
+$script:psake = @{}
+$script:psake.use_exit_on_error = $false # determines if psake uses the "exit()" function when an exception occurs
+$script:psake.log_error = $false # determines if the exception details are written to a file
+$script:psake.build_success = $false # indicates that the current build was successful
+$script:psake.version = "4.00" # contains the current version of psake
+$script:psake.build_script_file = $null # contains a System.IO.FileInfo for the current build file
+$script:psake.framework_version = "" # contains the framework version # for the current build
+$script:psake.default_build_file_name = 'default.ps1'
+
+Export-ModuleMember -Variable "psake"
+
+#-- Private Module Functions
+function ExecuteTask
+{
+ param([string]$taskName)
+
+ Assert (![string]::IsNullOrEmpty($taskName)) "Task name should not be null or empty string"
+
+ $taskKey = $taskName.ToLower()
+
+ Assert ($script:context.Peek().tasks.Contains($taskKey)) "task [$taskName] does not exist"
+
+ if ($script:context.Peek().executedTasks.Contains($taskKey))
+ {
+ return
+ }
+
+ Assert (!$script:context.Peek().callStack.Contains($taskKey)) "Error: Circular reference found for task, $taskName"
+
+ $script:context.Peek().callStack.Push($taskKey)
+
+ $task = $script:context.Peek().tasks.$taskKey
+
+ $taskName = $task.Name
+
+ $precondition_is_valid = if ($task.Precondition -ne $null) {& $task.Precondition} else {$true}
+
+ if (!$precondition_is_valid)
+ {
+ "Precondition was false not executing $name"
+ }
+ else
+ {
+ if ($taskKey -ne 'default')
+ {
+ $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+ if ( ($task.PreAction -ne $null) -or ($task.PostAction -ne $null) )
+ {
+ Assert ($task.Action -ne $null) "Error: Action parameter must be specified when using PreAction or PostAction parameters"
+ }
+
+ if ($task.Action -ne $null)
+ {
+ try
+ {
+ foreach($childTask in $task.DependsOn)
+ {
+ ExecuteTask $childTask
+ }
+
+ $script:context.Peek().currentTaskName = $taskName
+
+ if ($script:context.Peek().taskSetupScriptBlock -ne $null)
+ {
+ & $script:context.Peek().taskSetupScriptBlock
+ }
+
+ if ($task.PreAction -ne $null)
+ {
+ & $task.PreAction
+ }
+
+ $script:context.Peek().formatTaskNameString -f $taskName
+ & $task.Action
+
+ if ($task.PostAction -ne $null)
+ {
+ & $task.PostAction
+ }
+
+ if ($script:context.Peek().taskTearDownScriptBlock -ne $null)
+ {
+ & $script:context.Peek().taskTearDownScriptBlock
+ }
+ }
+ catch
+ {
+ if ($task.ContinueOnError)
+ {
+ "-"*70
+ "Error in Task [$taskName] $_"
+ "-"*70
+ }
+ else
+ {
+ throw $_
+ }
+ }
+ } # if ($task.Action -ne $null)
+ else
+ {
+ #no Action was specified but we still execute all the dependencies
+ foreach($childTask in $task.DependsOn)
+ {
+ ExecuteTask $childTask
+ }
+ }
+ $stopwatch.stop()
+ $task.Duration = $stopwatch.Elapsed
+ } # if ($name.ToLower() -ne 'default')
+ else
+ {
+ foreach($childTask in $task.DependsOn)
+ {
+ ExecuteTask $childTask
+ }
+ }
+
+ if ($task.Postcondition -ne $null)
+ {
+ Assert (& $task.Postcondition) "Error: Postcondition failed for $taskName"
+ }
+ }
+
+ $poppedTaskKey = $script:context.Peek().callStack.Pop()
+
+ Assert ($poppedTaskKey -eq $taskKey) "Error: CallStack was corrupt. Expected $taskKey, but got $poppedTaskKey."
+
+ $script:context.Peek().executedTasks.Push($taskKey)
+}
+
+function Configure-BuildEnvironment
+{
+ if ($framework.Length -ne 3 -and $framework.Length -ne 6) {
+ throw "Error: Invalid .NET Framework version, $framework, specified"
+ }
+ $versionPart = $framework.Substring(0,3)
+ $bitnessPart = $framework.Substring(3)
+ $versions = $null
+ switch ($versionPart)
+ {
+ '1.0' { $versions = @('v1.0.3705') }
+ '1.1' { $versions = @('v1.1.4322') }
+ '2.0' { $versions = @('v2.0.50727') }
+ '3.0' { $versions = @('v2.0.50727') }
+ '3.5' { $versions = @('v3.5','v2.0.50727') }
+ '4.0' { $versions = @('v4.0.30319') }
+ default { throw "Error: Unknown .NET Framework version, $versionPart, specified in $framework" }
+ }
+
+ $bitness = 'Framework'
+ if($versionPart -ne '1.0' -and $versionPart -ne '1.1') {
+ switch ($bitnessPart)
+ {
+ 'x86' { $bitness = 'Framework' }
+ 'x64' { $bitness = 'Framework64' }
+ $null {
+ $ptrSize = [System.IntPtr]::Size
+ switch ($ptrSize)
+ {
+ 4 { $bitness = 'Framework' }
+ 8 { $bitness = 'Framework64' }
+ default { throw "Error: Unknown pointer size ($ptrSize) returned from System.IntPtr." }
+ }
+ }
+ default { throw "Error: Unknown .NET Framework bitness, $bitnessPart, specified in $framework" }
+ }
+ }
+ $frameworkDirs = $versions | foreach { "$env:windir\Microsoft.NET\$bitness\$_\" }
+
+ $frameworkDirs | foreach { Assert (test-path $_) "Error: No .NET Framework installation directory found at $_" }
+
+ $env:path = [string]::Join(';', $frameworkDirs) + ";$env:path"
+ #if any error occurs in a PS function then "stop" processing immediately
+ # this does not effect any external programs that return a non-zero exit code
+ $global:ErrorActionPreference = "Stop"
+}
+
+function Cleanup-Environment
+{
+ $env:path = $script:context.Peek().originalEnvPath
+ Set-Location $script:context.Peek().originalDirectory
+ $global:ErrorActionPreference = $script:context.Peek().originalErrorActionPreference
+}
+
+#borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
+function Resolve-Error($ErrorRecord=$Error[0])
+{
+ "ErrorRecord"
+ $ErrorRecord | Format-List * -Force | Out-String -Stream | ? {$_}
+ ""
+ "ErrorRecord.InvocationInfo"
+ $ErrorRecord.InvocationInfo | Format-List * | Out-String -Stream | ? {$_}
+ ""
+ "Exception"
+ $Exception = $ErrorRecord.Exception
+ for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
+ {
+ "$i" * 70
+ $Exception | Format-List * -Force | Out-String -Stream | ? {$_}
+ ""
+ }
+}
+
+function Write-Documentation
+{
+ $list = New-Object System.Collections.ArrayList
+ foreach($key in $script:context.Peek().tasks.Keys)
+ {
+ if($key -eq "default")
+ {
+ continue
+ }
+ $task = $script:context.Peek().tasks.$key
+ $content = "" | Select-Object Name, Description
+ $content.Name = $task.Name
+ $content.Description = $task.Description
+ $index = $list.Add($content)
+ }
+
+ $list | Sort 'Name' | Format-Table -Auto
+}
+
+function Write-TaskTimeSummary
+{
+ "-"*70
+ "Build Time Report"
+ "-"*70
+ $list = @()
+ while ($script:context.Peek().executedTasks.Count -gt 0)
+ {
+ $taskKey = $script:context.Peek().executedTasks.Pop()
+ $task = $script:context.Peek().tasks.$taskKey
+ if($taskKey -eq "default")
+ {
+ continue
+ }
+ $list += "" | Select-Object @{Name="Name";Expression={$task.Name}}, @{Name="Duration";Expression={$task.Duration}}
+ }
+ [Array]::Reverse($list)
+ $list += "" | Select-Object @{Name="Name";Expression={"Total:"}}, @{Name="Duration";Expression={$stopwatch.Elapsed}}
+ $list | Format-Table -Auto | Out-String -Stream | ? {$_} # using "Out-String -Stream" to filter out the blank line that Format-Table prepends
+}
+
+#-- Public Module Functions
+function Exec
+{
+<#
+.SYNOPSIS
+Helper function for executing command-line programs.
+
+.DESCRIPTION
+This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode to see if an error occcured.
+If an error is detected then an exception is thrown. This function allows you to run command-line programs without
+having to explicitly check fthe $lastexitcode variable.
+
+.PARAMETER cmd
+The scriptblock to execute. This scriptblock will typically contain the command-line invocation.
+Required
+
+.PARAMETER errorMessage
+The error message used for the exception that is thrown.
+Optional
+
+.EXAMPLE
+exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
+
+This example calls the svn command-line client.
+
+.LINK
+Assert
+Invoke-psake
+Task
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+
+ param(
+ [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
+ [Parameter(Position=1,Mandatory=0)][string]$errorMessage = "Error executing command: " + $cmd
+ )
+ & $cmd
+ if ($lastexitcode -ne 0)
+ {
+ throw $errorMessage
+ }
+}
+
+function Assert
+{
+<#
+.SYNOPSIS
+Helper function for "Design by Contract" assertion checking.
+
+.DESCRIPTION
+This is a helper function that makes the code less noisy by eliminating many of the "if" statements
+that are normally required to verify assumptions in the code.
+
+.PARAMETER conditionToCheck
+The boolean condition to evaluate
+Required
+
+.PARAMETER failureMessage
+The error message used for the exception if the conditionToCheck parameter is false
+Required
+
+.EXAMPLE
+Assert $false "This always throws an exception"
+
+This example always throws an exception
+
+.EXAMPLE
+Assert ( ($i % 2) -eq 0 ) "%i is not an even number"
+
+This exmaple may throw an exception if $i is not an even number
+
+.LINK
+Invoke-psake
+Task
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+
+.NOTES
+It might be necessary to wrap the condition with paranthesis to force PS to evaluate the condition
+so that a boolean value is calculated and passed into the 'conditionToCheck' parameter.
+
+Example:
+ Assert 1 -eq 2 "1 doesn't equal 2"
+
+PS will pass 1 into the condtionToCheck variable and PS will look for a parameter called "eq" and
+throw an exception with the following message "A parameter cannot be found that matches parameter name 'eq'"
+
+The solution is to wrap the condition in () so that PS will evaluate it first.
+
+ Assert (1 -eq 2) "1 doesn't equal 2"
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+
+ param(
+ [Parameter(Position=0,Mandatory=1)]$conditionToCheck,
+ [Parameter(Position=1,Mandatory=1)]$failureMessage
+ )
+ if (!$conditionToCheck) { throw $failureMessage }
+}
+
+function Task
+{
+<#
+.SYNOPSIS
+Defines a build task to be executed by psake
+
+.DESCRIPTION
+This function creates a 'task' object that will be used by the psake engine to execute a build task.
+Note: There must be at least one task called 'default' in the build script
+
+.PARAMETER Name
+The name of the task
+Required
+
+.PARAMETER Action
+A scriptblock containing the statements to execute
+Optional
+
+.PARAMETER PreAction
+A scriptblock to be executed before the 'Action' scriptblock.
+Note: This parameter is ignored if the 'Action' scriptblock is not defined.
+Optional
+
+.PARAMETER PostAction
+A scriptblock to be executed after the 'Action' scriptblock.
+Note: This parameter is ignored if the 'Action' scriptblock is not defined.
+Optional
+
+.PARAMETER Precondition
+A scriptblock that is executed to determine if the task is executed or skipped.
+This scriptblock should return $true or $false
+Optional
+
+.PARAMETER Postcondition
+A scriptblock that is executed to determine if the task completed its job correctly.
+An exception is thrown if the scriptblock returns $false.
+Optional
+
+.PARAMETER ContinueOnError
+If this switch parameter is set then the task will not cause the build to fail when an exception is thrown
+
+.PARAMETER Depends
+An array of tasks that this task depends on. They will be executed before the current task is executed.
+
+.PARAMETER Description
+A description of the task.
+
+.EXAMPLE
+A sample build script is shown below:
+
+task default -depends Test
+
+task Test -depends Compile, Clean {
+ "This is a test"
+}
+
+task Compile -depends Clean {
+ "Compile"
+}
+
+task Clean {
+ "Clean"
+}
+
+The 'default' task is required and should not contain an 'Action' parameter.
+It uses the 'depends' parameter to specify that 'Test' is a dependency
+
+The 'Test' task uses the 'depends' parameter to specify that 'Compile' and 'Clean' are dependencies
+The 'Compile' task depends on the 'Clean' task.
+
+Note:
+The 'Action' parameter is defaulted to the script block following the 'Clean' task.
+
+The equivalent 'Test' task is shown below:
+
+task Test -depends Compile, Clean -Action {
+ $testMessage
+}
+
+The output for the above sample build script is shown below:
+Executing task, Clean...
+Clean
+Executing task, Compile...
+Compile
+Executing task, Test...
+This is a test
+
+Build Succeeded!
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name Duration
+---- --------
+Clean 00:00:00.0065614
+Compile 00:00:00.0133268
+Test 00:00:00.0225964
+Total: 00:00:00.0782496
+
+.LINK
+Invoke-psake
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [string]$name = $null,
+ [Parameter(Position=1,Mandatory=0)]
+ [scriptblock]$action = $null,
+ [Parameter(Position=2,Mandatory=0)]
+ [scriptblock]$preaction = $null,
+ [Parameter(Position=3,Mandatory=0)]
+ [scriptblock]$postaction = $null,
+ [Parameter(Position=4,Mandatory=0)]
+ [scriptblock]$precondition = $null,
+ [Parameter(Position=5,Mandatory=0)]
+ [scriptblock]$postcondition = $null,
+ [Parameter(Position=6,Mandatory=0)]
+ [switch]$continueOnError = $false,
+ [Parameter(Position=7,Mandatory=0)]
+ [string[]]$depends = @(),
+ [Parameter(Position=8,Mandatory=0)]
+ [string]$description = $null
+ )
+
+ if ($name.ToLower() -eq 'default')
+ {
+ Assert ($action -eq $null) "Error: 'default' task cannot specify an action"
+ }
+
+ $newTask = @{
+ Name = $name
+ DependsOn = $depends
+ PreAction = $preaction
+ Action = $action
+ PostAction = $postaction
+ Precondition = $precondition
+ Postcondition = $postcondition
+ ContinueOnError = $continueOnError
+ Description = $description
+ Duration = 0
+ }
+
+ $taskKey = $name.ToLower()
+
+ Assert (!$script:context.Peek().tasks.ContainsKey($taskKey)) "Error: Task, $name, has already been defined."
+
+ $script:context.Peek().tasks.$taskKey = $newTask
+}
+
+function Properties
+{
+<#
+.SYNOPSIS
+Define a scriptblock that contains assignments to variables that will be available to all tasks in the build script
+
+.DESCRIPTION
+A build script may declare a "Properies" function which allows you to define
+variables that will be available to all the "Task" functions in the build script.
+
+.PARAMETER properties
+The script block containing all the variable assignment statements
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Properties {
+ $build_dir = "c:\build"
+ $connection_string = "datasource=localhost;initial catalog=northwind;integrated security=sspi"
+}
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+.LINK
+Invoke-psake
+Task
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+
+.NOTES
+You can have more than 1 "Properties" function defined in the script
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [scriptblock]$properties
+ )
+ $script:context.Peek().properties += $properties
+}
+
+function Include
+{
+<#
+.SYNOPSIS
+Include the functions or code of another powershell script file into the current build script's scope
+
+.DESCRIPTION
+A build script may declare an "includes" function which allows you to define
+a file containing powershell code to be included and added to the scope of
+the currently running build script.
+
+.PARAMETER fileNamePathToInclude
+A string containing the path and name of the powershell file to include
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Include ".\build_utils.ps1"
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+
+.LINK
+Invoke-psake
+Task
+Properties
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+
+.NOTES
+You can have more than 1 "Include" function defined in the script
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [string]$fileNamePathToInclude
+ )
+ Assert (test-path $fileNamePathToInclude) "Error: Unable to include $fileNamePathToInclude. File not found."
+ $script:context.Peek().includes.Enqueue((Resolve-Path $fileNamePathToInclude));
+}
+
+function FormatTaskName
+{
+<#
+.SYNOPSIS
+Allows you to define a format mask that will be used when psake displays
+the task name
+
+.DESCRIPTION
+Allows you to define a format mask that will be used when psake displays
+the task name. The default is "Executing task, {0}..."
+
+.PARAMETER format
+A string containing the format mask to use, it should contain a placeholder ({0})
+that will be used to substitute the task name.
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+FormatTaskName "[Task: {0}]"
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+You should get the following output:
+------------------------------------
+
+[Task: Clean]
+[Task: Compile]
+[Task: Test]
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name Duration
+---- --------
+Clean 00:00:00.0043477
+Compile 00:00:00.0102130
+Test 00:00:00.0182858
+Total: 00:00:00.0698071
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [string]$format
+ )
+ $script:context.Peek().formatTaskNameString = $format
+}
+
+function TaskSetup
+{
+<#
+.SYNOPSIS
+Adds a scriptblock that will be executed before each task
+
+.DESCRIPTION
+This function will accept a scriptblock that will be executed before each
+task in the build script.
+
+.PARAMETER include
+A scriptblock to execute
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+TaskSetup {
+ "Running 'TaskSetup' for task $script:context.Peek().currentTaskName"
+}
+
+You should get the following output:
+------------------------------------
+
+Running 'TaskSetup' for task Clean
+Executing task, Clean...
+Running 'TaskSetup' for task Compile
+Executing task, Compile...
+Running 'TaskSetup' for task Test
+Executing task, Test...
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name Duration
+---- --------
+Clean 00:00:00.0054018
+Compile 00:00:00.0123085
+Test 00:00:00.0236915
+Total: 00:00:00.0739437
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+FormatTaskName
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [scriptblock]$setup
+ )
+ $script:context.Peek().taskSetupScriptBlock = $setup
+}
+
+function TaskTearDown
+{
+<#
+.SYNOPSIS
+Adds a scriptblock that will be executed after each task
+
+.DESCRIPTION
+This function will accept a scriptblock that will be executed after each
+task in the build script.
+
+.PARAMETER include
+A scriptblock to execute
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+TaskTearDown {
+ "Running 'TaskTearDown' for task $script:context.Peek().currentTaskName"
+}
+
+You should get the following output:
+------------------------------------
+
+Executing task, Clean...
+Running 'TaskTearDown' for task Clean
+Executing task, Compile...
+Running 'TaskTearDown' for task Compile
+Executing task, Test...
+Running 'TaskTearDown' for task Test
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name Duration
+---- --------
+Clean 00:00:00.0064555
+Compile 00:00:00.0218902
+Test 00:00:00.0309151
+Total: 00:00:00.0858301
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+FormatTaskName
+TaskSetup
+Assert
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+ param(
+ [Parameter(Position=0,Mandatory=1)]
+ [scriptblock]$teardown)
+ $script:context.Peek().taskTearDownScriptBlock = $teardown
+}
+
+function Invoke-psake
+{
+<#
+.SYNOPSIS
+Runs a psake build script.
+
+.DESCRIPTION
+This function runs a psake build script
+
+.PARAMETER BuildFile
+The psake build script to execute (default: default.ps1).
+
+.PARAMETER TaskList
+A comma-separated list of task names to execute
+
+.PARAMETER Framework
+The version of the .NET framework you want to build. You can append x86 or x64 to force a specific framework. If not specified, x86 or x64 will be detected based on the bitness of the PowerShell process.
+Possible values: '1.0', '1.1', '2.0', '2.0x86', '2.0x64', '3.0', '3.0x86', '3.0x64', '3.5', '3.5x86', '3.5x64', '4.0', '4.0x86', '4.0x64'
+Default = '3.5'
+
+.PARAMETER Docs
+Prints a list of tasks and their descriptions
+
+.PARAMETER Parameters
+A hashtable containing parameters to be passed into the current build script. These parameters will be processed before the 'Properties' function of the script is processed. This means you can access parameters from within the 'Properties' function!
+
+.PARAMETER Properties
+A hashtable containing properties to be passed into the current build script. These properties will override matching properties that are found in the 'Properties' function of the script.
+
+.EXAMPLE
+Invoke-psake
+
+Runs the 'default' task in the 'default.ps1' build script in the current directory
+
+.EXAMPLE
+Invoke-psake '.\build.ps1'
+
+Runs the 'default' task in the '.build.ps1' build script
+
+.EXAMPLE
+Invoke-psake '.\build.ps1' Tests,Package
+
+Runs the 'Tests' and 'Package' tasks in the '.build.ps1' build script
+
+.EXAMPLE
+Invoke-psake Tests
+
+If you have your Tasks in the .\default.ps1. This example will run the 'Tests' tasks in the 'default.ps1' build script.
+
+.EXAMPLE
+Invoke-psake 'Tests, Package'
+
+If you have your Tasks in the .\default.ps1. This example will run the 'Tests' and 'Package' tasks in the 'default.ps1' build script.
+NOTE: the quotes around the list of tasks to execute.
+
+.EXAMPLE
+Invoke-psake '.\build.ps1' -docs
+
+Prints a report of all the tasks and their descriptions and exits
+
+.EXAMPLE
+Invoke-psake .\parameters.ps1 -parameters @{"p1"="v1";"p2"="v2"}
+
+Runs the build script called 'parameters.ps1' and passes in parameters 'p1' and 'p2' with values 'v1' and 'v2'
+
+.EXAMPLE
+Invoke-psake .\properties.ps1 -properties @{"x"="1";"y"="2"}
+
+Runs the build script called 'properties.ps1' and passes in parameters 'x' and 'y' with values '1' and '2'
+
+.OUTPUTS
+ If there is an exception and '$psake.use_exit_on_error' -eq $true
+ then runs exit(1) to set the DOS lastexitcode variable
+ otherwise set the '$psake.build_success variable' to $true or $false depending
+ on whether an exception was thrown
+
+.NOTES
+When the psake module is loaded a variabled called $psake is created it is a hashtable
+containing some variables that can be used to configure psake:
+
+$psake.use_exit_on_error = $false # determines if psake uses the "exit()" function when an exception occurs
+$psake.log_error = $false # determines if the exception details are written to a file
+$psake.build_success = $false # indicates that the current build was successful
+$psake.version = "4.00" # contains the current version of psake
+$psake.build_script_file = $null # contains a System.IO.FileInfo for the current build file
+$psake.framework_version = "" # contains the framework version # for the current build
+
+$psake.use_exit_on_error and $psake.log_error are boolean variables that can be set before you call Invoke-Psake.
+
+You should see the following when you display the contents of the $psake variable right after importing psake
+
+PS projects:\psake> Import-Module .\psake.psm1
+PS projects:\psake> $psake
+
+Name Value
+---- -----
+version 4.00
+build_script_file
+use_exit_on_error False
+build_success False
+log_error False
+framework_version
+
+After a build is executed the following $psake values are updated (build_script_file, build_success, and framework_version)
+
+PS projects:\psake> Invoke-psake .\examples\default.ps1
+Executing task: Clean
+Executed Clean!
+Executing task: Compile
+Executed Compile!
+Executing task: Test
+Executed Test!
+
+Build Succeeded!
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name Duration
+---- --------
+Clean 00:00:00.0798486
+Compile 00:00:00.0869948
+Test 00:00:00.0958225
+Total: 00:00:00.2712414
+
+PS projects:\psake> $psake
+
+Name Value
+---- -----
+version 4.00
+build_script_file C:\Users\Jorge\Documents\Projects\psake\examples\default.ps1
+use_exit_on_error False
+build_success True
+log_error False
+framework_version 3.5
+
+.LINK
+Task
+Include
+Properties
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+ SupportsShouldProcess=$False,
+ SupportsTransactions=$False,
+ ConfirmImpact="None",
+ DefaultParameterSetName="")]
+
+ param(
+ [Parameter(Position=0,Mandatory=0)]
+ [string]$buildFile = $script:psake.default_build_file_name,
+ [Parameter(Position=1,Mandatory=0)]
+ [string[]]$taskList = @(),
+ [Parameter(Position=2,Mandatory=0)]
+ [string]$framework = '3.5',
+ [Parameter(Position=3,Mandatory=0)]
+ [switch]$docs = $false,
+ [Parameter(Position=4,Mandatory=0)]
+ [System.Collections.Hashtable]$parameters = @{},
+ [Parameter(Position=5, Mandatory=0)]
+ [System.Collections.Hashtable]$properties = @{}
+ )
+
+ Begin
+ {
+ $script:psake.build_success = $false
+ $script:psake.framework_version = $framework
+
+ if ($script:context -eq $null)
+ {
+ $script:context = New-Object System.Collections.Stack
+ }
+
+ $script:context.push(@{
+ "formatTaskNameString" = "Executing task: {0}";
+ "taskSetupScriptBlock" = $null;
+ "taskTearDownScriptBlock" = $null;
+ "executedTasks" = New-Object System.Collections.Stack;
+ "callStack" = New-Object System.Collections.Stack;
+ "originalEnvPath" = $env:path;
+ "originalDirectory" = Get-Location;
+ "originalErrorActionPreference" = $global:ErrorActionPreference;
+ "tasks" = @{};
+ "properties" = @();
+ "includes" = New-Object System.Collections.Queue;
+ })
+ }
+
+ Process
+ {
+ try
+ {
+ $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+ <#
+ If the default.ps1 file exists and the given "buildfile" isn't found assume that the given
+ $buildFile is actually the target Tasks to execute in the default.ps1 script.
+ #>
+ if((Test-Path $script:psake.default_build_file_name ) -and !(test-path $buildFile)) {
+ $list = New-Object System.Collections.ArrayList
+ foreach($t in $buildFile.Split(',')) {
+ $t1 = $t.Trim()
+ if($t1 -ne $null -or $t1 -ne "") {
+ $list.Add($t1)
+ }
+ }
+ $taskList = $list.ToArray()
+ $buildFile = $script:psake.default_build_file_name
+ }
+
+ # Execute the build file to set up the tasks and defaults
+ Assert (test-path $buildFile) "Error: Could not find the build file, $buildFile."
+
+ $script:psake.build_script_file = dir $buildFile
+ set-location $script:psake.build_script_file.Directory
+ . $script:psake.build_script_file.FullName
+
+ if ($docs)
+ {
+ Write-Documentation
+ Cleanup-Environment
+ return
+ }
+
+ Configure-BuildEnvironment
+
+ # N.B. The initial dot (.) indicates that variables initialized/modified
+ # in the propertyBlock are available in the parent scope.
+ while ($script:context.Peek().includes.Count -gt 0)
+ {
+ $includeBlock = $script:context.Peek().includes.Dequeue()
+ . $includeBlock
+ }
+
+ foreach($key in $parameters.keys)
+ {
+ if (test-path "variable:\$key")
+ {
+ set-item -path "variable:\$key" -value $parameters.$key | out-null
+ }
+ else
+ {
+ new-item -path "variable:\$key" -value $parameters.$key | out-null
+ }
+ }
+
+ foreach($propertyBlock in $script:context.Peek().properties)
+ {
+ . $propertyBlock
+ }
+
+ foreach($key in $properties.keys)
+ {
+ if (test-path "variable:\$key")
+ {
+ set-item -path "variable:\$key" -value $properties.$key | out-null
+ }
+ }
+
+ # Execute the list of tasks or the default task
+ if($taskList.Length -ne 0)
+ {
+ foreach($task in $taskList)
+ {
+ ExecuteTask $task<