├── lib
├── Cake.Core.dll
├── Cake.Common.dll
├── Cake.NuGet.dll
├── Nuget.Core.dll
└── Cake.Testing.dll
├── src
├── CakeBoss.Agent
│ ├── Icon.ico
│ ├── Interfaces
│ │ ├── ITerminationService.cs
│ │ └── IAgentService.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Registry
│ │ └── AgentRoot.cs
│ ├── Utils
│ │ └── UptimeUtils.cs
│ ├── Aliases
│ │ ├── AgentSettings.cs
│ │ ├── TerminationAliases.cs
│ │ ├── ApiAliases.cs
│ │ └── AgentAliases.cs
│ ├── Nancy
│ │ ├── ServiceModule.cs
│ │ ├── ServiceStartup.cs
│ │ └── ServiceBootstrapper.cs
│ ├── App.config
│ ├── packages.config
│ ├── Service
│ │ ├── TerminationService.cs
│ │ └── AgentService.cs
│ └── Program.cs
├── Cake.Host
│ ├── Diagnostics
│ │ ├── Formatting
│ │ │ ├── FormatToken.cs
│ │ │ ├── LiteralToken.cs
│ │ │ ├── PropertyToken.cs
│ │ │ └── FormatParser.cs
│ │ ├── IVerbosityAware.cs
│ │ ├── ConsolePalette.cs
│ │ └── CakeBuildLog.cs
│ ├── Scripting
│ │ ├── Mono
│ │ │ ├── MonoScriptHostProxy.cs
│ │ │ ├── CodeGen
│ │ │ │ ├── Parsing
│ │ │ │ │ ├── ScriptTokenType.cs
│ │ │ │ │ ├── ScriptBlock.cs
│ │ │ │ │ ├── ScriptToken.cs
│ │ │ │ │ ├── ScriptBuffer.cs
│ │ │ │ │ └── ScriptTokenizer.cs
│ │ │ │ ├── MonoScriptProcessor.cs
│ │ │ │ └── MonoCodeGenerator.cs
│ │ │ ├── MonoScriptEngine.cs
│ │ │ ├── MonoConsoleReportPrinter.cs
│ │ │ └── MonoScriptSession.cs
│ │ ├── Roslyn
│ │ │ ├── RoslynCodeGenerator.cs
│ │ │ ├── RoslynScriptEngine.cs
│ │ │ ├── Stable
│ │ │ │ ├── RoslynScriptSession.cs
│ │ │ │ └── RoslynScriptSessionFactory.cs
│ │ │ └── Nightly
│ │ │ │ ├── RoslynNightlyScriptSession.cs
│ │ │ │ └── RoslynNightlyScriptSessionFactory.cs
│ │ ├── BuildScriptHost.cs
│ │ ├── DryRunExecutionStrategy.cs
│ │ ├── DryRunScriptHost.cs
│ │ └── DescriptionScriptHost.cs
│ ├── Commands
│ │ ├── ICommand.cs
│ │ ├── ErrorCommandDecorator.cs
│ │ ├── DryRunCommand.cs
│ │ ├── BuildCommand.cs
│ │ ├── DescriptionCommand.cs
│ │ ├── ICommandFactory.cs
│ │ ├── CommandFactory.cs
│ │ ├── HelpCommand.cs
│ │ └── VersionCommand.cs
│ ├── Arguments
│ │ ├── IArgumentParser.cs
│ │ ├── VerbosityParser.cs
│ │ └── ArgumentTokenizer.cs
│ ├── app.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── packages.config
│ ├── CakeConsole.cs
│ ├── CakeArguments.cs
│ ├── CakeReportPrinter.cs
│ ├── CakeOptions.cs
│ ├── NuGet
│ │ └── NuGetVersionUtilityAdapter.cs
│ └── CakeApplication.cs
├── Cake.CakeBoss
│ ├── packages.config
│ ├── Properties
│ │ ├── Namespaces.cs
│ │ └── AssemblyInfo.cs
│ ├── Settings
│ │ └── RemoteSettings.cs
│ ├── Cake.CakeBoss.csproj
│ └── Aliases
│ │ └── AgentAliases.cs
├── CakeBoss.Host
│ ├── Interfaces
│ │ └── IAuthenticationService.cs
│ ├── Commands
│ │ ├── LogCommand.cs
│ │ ├── UpdateCommand.cs
│ │ └── RunCommand.cs
│ ├── Extensions
│ │ ├── HashSetExtensions.cs
│ │ ├── CakeContextExtensions.cs
│ │ └── HostSettingsExtensions.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Auth
│ │ ├── User.cs
│ │ ├── AuthenticationService.cs
│ │ └── HostSettings.cs
│ ├── Nancy
│ │ ├── UserIdentity.cs
│ │ └── UserValidator.cs
│ ├── app.config
│ ├── Tasks
│ │ └── TaskRegistry.cs
│ ├── Console
│ │ ├── ConsoleOutput.cs
│ │ ├── HostLog.cs
│ │ └── HostConsole.cs
│ ├── Aliases
│ │ ├── HostAliases.cs
│ │ └── ScheduleAliases.cs
│ ├── packages.config
│ ├── Host
│ │ ├── ScriptConventions.cs
│ │ └── HostApplication.cs
│ └── Registry
│ │ └── HostRoot.cs
├── SolutionInfo.cs
├── CakeBoss.Agent.Tests
│ ├── Tests
│ │ └── AgentTests.cs
│ ├── app.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Config
│ │ ├── Startup.cs
│ │ └── UnitTestBootstrapper.cs
│ └── packages.config
└── CakeBoss.sln
├── script
├── Install.bat
├── Deploy.bat
├── Uninstall.bat
├── Release.cake
└── Test.cake
├── appveyor.yml
├── .gitattributes
├── .gitignore
├── LICENSE
├── nuspec
└── Cake.CakeBoss.nuspec
└── ReleaseNotes.md
/lib/Cake.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/lib/Cake.Core.dll
--------------------------------------------------------------------------------
/lib/Cake.Common.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/lib/Cake.Common.dll
--------------------------------------------------------------------------------
/lib/Cake.NuGet.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/lib/Cake.NuGet.dll
--------------------------------------------------------------------------------
/lib/Nuget.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/lib/Nuget.Core.dll
--------------------------------------------------------------------------------
/lib/Cake.Testing.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/lib/Cake.Testing.dll
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SharpeRAD/CakeBoss/HEAD/src/CakeBoss.Agent/Icon.ico
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/Formatting/FormatToken.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Diagnostics.Formatting
2 | {
3 | public abstract class FormatToken
4 | {
5 | public abstract string Render(object[] args);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/script/Install.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | @setlocal enableextensions
4 | @cd /d "%~dp0"
5 |
6 | if exist "%cd%\CakeBoss.Agent.exe" (
7 | SET file=%cd%\CakeBoss.Agent.exe
8 | ) else (
9 | SET file=%cd%\CakeBoss.Server.exe
10 | )
11 | ECHO %file%
12 |
13 | CALL "%file%" install
14 | PAUSE
--------------------------------------------------------------------------------
/script/Deploy.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | @setlocal enableextensions
4 | @cd /d "%~dp0"
5 |
6 | if exist "%cd%\CakeBoss.Agent.exe" (
7 | SET file=%cd%\CakeBoss.Agent.exe
8 | ) else (
9 | SET file=%cd%\CakeBoss.Server.exe
10 | )
11 | ECHO %file%
12 |
13 | CALL "%file%" -target=Deploy
14 | PAUSE
--------------------------------------------------------------------------------
/script/Uninstall.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | @setlocal enableextensions
4 | @cd /d "%~dp0"
5 |
6 | if exist "%cd%\CakeBoss.Agent.exe" (
7 | SET file=%cd%\CakeBoss.Agent.exe
8 | ) else (
9 | SET file=%cd%\CakeBoss.Server.exe
10 | )
11 | ECHO %file%
12 |
13 | CALL "%file%" uninstall
14 | PAUSE
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Interfaces/IAuthenticationService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Host
8 | {
9 | public interface IAuthenticationService
10 | {
11 | bool ValidUser(string username, string password);
12 |
13 | bool ValidApiKey(string apiKey);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/Properties/Namespaces.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 | // ReSharper disable CheckNamespace
3 |
4 |
5 | namespace Cake.CakeBoss
6 | {
7 | ///
8 | /// This namespace contains CakeBoss aliases and related members.
9 | ///
10 | [CompilerGenerated]
11 | internal class NamespaceDoc
12 | {
13 | }
14 | }
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # Build script
2 | init:
3 | - git config --global core.autocrlf true
4 |
5 | # Build script
6 | build_script:
7 | - cmd: powershell -NoProfile -ExecutionPolicy unrestricted -Command .\build.ps1 -Target "AppVeyor"
8 |
9 | # Tests
10 | test: off
11 |
12 | # Branches to build
13 | branches:
14 | # Whitelist
15 | only:
16 | - develop
17 | - main
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/MonoScriptHostProxy.cs:
--------------------------------------------------------------------------------
1 | using Cake.Core.Scripting;
2 |
3 | namespace Cake.Host.Scripting.Mono
4 | {
5 | ///
6 | /// Mono script host proxy.
7 | ///
8 | public class MonoScriptHostProxy
9 | {
10 | ///
11 | /// Gets or sets the script host.
12 | ///
13 | /// The script host.
14 | public static IScriptHost ScriptHost { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/Parsing/ScriptTokenType.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Scripting.Mono.CodeGen.Parsing
2 | {
3 | public enum ScriptTokenType
4 | {
5 | Word = 0,
6 | If = 1,
7 | Else = 2,
8 | While = 3,
9 | Switch = 4,
10 | String = 5,
11 | Semicolon = 6,
12 | LeftBrace = 7,
13 | RightBrace = 8,
14 | LeftParenthesis = 9,
15 | RightParenthesis = 10,
16 | Character = 11
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/IVerbosityAware.cs:
--------------------------------------------------------------------------------
1 | using Cake.Core.Diagnostics;
2 |
3 | namespace Cake.Host.Diagnostics
4 | {
5 | ///
6 | /// Represents a verbosity aware log.
7 | ///
8 | public interface IVerbosityAwareLog : ICakeLog
9 | {
10 | ///
11 | /// Sets the verbosity.
12 | ///
13 | /// The desired verbosity.
14 | void SetVerbosity(Verbosity verbosity);
15 | }
16 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Interfaces/ITerminationService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Agent
8 | {
9 | public interface ITerminationService
10 | {
11 | #region Properties (2)
12 | bool Enabled { get; set; }
13 |
14 | int Interval { get; set; }
15 | #endregion
16 |
17 |
18 |
19 |
20 |
21 | #region Functions (1)
22 | bool Termination();
23 | #endregion
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/ICommand.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Commands
2 | {
3 | ///
4 | /// Represents an executable command.
5 | ///
6 | public interface ICommand
7 | {
8 | ///
9 | /// Executes the command with the specified options.
10 | ///
11 | /// The options.
12 | /// true if the command exited successfully; otherwise, false.
13 | bool Execute(CakeOptions options);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Commands/LogCommand.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Host
8 | {
9 | public class LogCommand
10 | {
11 | #region Constructor (1)
12 | public LogCommand()
13 | {
14 |
15 | }
16 | #endregion
17 |
18 |
19 |
20 |
21 |
22 | #region Properties (2)
23 | public string Client { get; set; }
24 |
25 | public ConsoleOutput Output { get; set; }
26 | #endregion
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/Formatting/LiteralToken.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Diagnostics.Formatting
2 | {
3 | public sealed class LiteralToken : FormatToken
4 | {
5 | private readonly string _text;
6 |
7 | public string Text
8 | {
9 | get { return _text; }
10 | }
11 |
12 | public LiteralToken(string text)
13 | {
14 | _text = text;
15 | }
16 |
17 | public override string Render(object[] args)
18 | {
19 | return _text;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/SolutionInfo.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by Cake.
4 | //
5 | //------------------------------------------------------------------------------
6 | using System.Reflection;
7 |
8 | [assembly: AssemblyProduct("CakeBoss")]
9 | [assembly: AssemblyVersion("0.1.5")]
10 | [assembly: AssemblyFileVersion("0.1.5")]
11 | [assembly: AssemblyInformationalVersion("0.1.5")]
12 | [assembly: AssemblyCopyright("Copyright (c) 2015 - 2016 Phillip Sharpe")]
13 |
14 |
--------------------------------------------------------------------------------
/src/Cake.Host/Arguments/IArgumentParser.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Cake.Host.Arguments
4 | {
5 | ///
6 | /// Represents an argument parser.
7 | ///
8 | public interface IArgumentParser
9 | {
10 | ///
11 | /// Parses the specified arguments.
12 | ///
13 | /// The arguments to parse.
14 | /// A instance representing the arguments.
15 | CakeOptions Parse(IEnumerable args);
16 | }
17 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Extensions/HashSetExtensions.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Host
9 | {
10 | public static class HashSetExtensions
11 | {
12 | public static void AddRange(this HashSet set, IEnumerable items)
13 | {
14 | if (items != null)
15 | {
16 | foreach (var item in items)
17 | {
18 | set.Add(item);
19 | }
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Commands/UpdateCommand.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Host
8 | {
9 | public class UpdateCommand
10 | {
11 | #region Constructor (1)
12 | public UpdateCommand()
13 | {
14 |
15 | }
16 | #endregion
17 |
18 |
19 |
20 |
21 |
22 | #region Properties (3)
23 | public string Group { get; set; }
24 |
25 |
26 |
27 | public string Name { get; set; }
28 |
29 | public string Contents { get; set; }
30 | #endregion
31 | }
32 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CakeBoss.Agent")]
9 | [assembly: AssemblyDescription("A host for the Cake-Build")]
10 |
11 | // The following GUID is for the ID of the typelib if this project is exposed to COM
12 | [assembly: Guid("206f12ed-5ffa-4333-a5a9-31c142648ac1")]
13 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/ErrorCommandDecorator.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Commands
2 | {
3 | ///
4 | /// A command that decorates another command but always return failure.
5 | ///
6 | public sealed class ErrorCommandDecorator : ICommand
7 | {
8 | private readonly ICommand _command;
9 |
10 | public ErrorCommandDecorator(ICommand command)
11 | {
12 | _command = command;
13 | }
14 |
15 | public bool Execute(CakeOptions options)
16 | {
17 | _command.Execute(options);
18 | return false;
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CakeBoss.Agent")]
9 | [assembly: AssemblyDescription("A windows service to run Cake-Build scripts")]
10 |
11 | // The following GUID is for the ID of the typelib if this project is exposed to COM
12 | [assembly: Guid("14449d2a-6115-476b-8f8a-78a1bf726299")]
13 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Auth/User.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Host
8 | {
9 | public class User
10 | {
11 | #region Constructor (1)
12 | public User(string username, string password)
13 | {
14 | this.Username = username;
15 | this.Password = password;
16 | }
17 | #endregion
18 |
19 |
20 |
21 |
22 |
23 | #region Properties (2)
24 | public string Username { get; set; }
25 |
26 | public string Password { get; set; }
27 | #endregion
28 | }
29 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Commands/RunCommand.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Host
9 | {
10 | public class RunCommand
11 | {
12 | #region Constructor (1)
13 | public RunCommand()
14 | {
15 |
16 | }
17 | #endregion
18 |
19 |
20 |
21 |
22 |
23 | #region Properties (3)
24 | public string Group { get; set; }
25 |
26 |
27 |
28 | public string Name { get; set; }
29 |
30 | public IDictionary Arguments { get; set; }
31 | #endregion
32 | }
33 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Registry/AgentRoot.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using LightInject;
3 | using Nancy;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Agent
9 | {
10 | public class AgentRoot : ICompositionRoot
11 | {
12 | public void Compose(IServiceRegistry container)
13 | {
14 | //Register Agent
15 | container.Register(new PerContainerLifetime());
16 | container.Register(new PerContainerLifetime());
17 |
18 |
19 |
20 | //Register Nancy
21 | container.Register("Agent");
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/Tests/AgentTests.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using CakeBoss.Agent;
3 |
4 | using Xunit;
5 | #endregion
6 |
7 |
8 |
9 | namespace CakeBoss.Agent.Tests
10 | {
11 | public class ServiceTests
12 | {
13 | public static IAgentService _Service = null;
14 |
15 |
16 |
17 | public ServiceTests()
18 | {
19 | Startup.CreateContainer();
20 |
21 | _Service = Startup.Container.GetInstance();
22 | }
23 |
24 |
25 |
26 | /*
27 | [Fact]
28 | public void Service_Start()
29 | {
30 | Assert.True(_Service.RunTarget("Start", true));
31 | }
32 | */
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Interfaces/IAgentService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Agent
9 | {
10 | public interface IAgentService
11 | {
12 | #region Properties (1)
13 | string CurrentTask { get; set; }
14 | #endregion
15 |
16 |
17 |
18 |
19 |
20 | #region Functions (5)
21 | //Events
22 | void Start(IDictionary arguments);
23 |
24 | void Stop();
25 |
26 | void Shutdown();
27 |
28 | void Terminate();
29 |
30 |
31 |
32 | //Run
33 | bool RunTarget(string target, bool load);
34 | #endregion
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Cake.CakeBoss")]
9 | [assembly: AssemblyDescription("Cake-Build addin that extends allows you to control remote CakeBoss agents")]
10 |
11 | // Setting ComVisible to false makes the types in this assembly not visible
12 | // to COM components. If you need to access a type in this assembly from
13 | // COM, set the ComVisible attribute to true on that type.
14 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/src/Cake.Host/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Nancy/UserIdentity.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Nancy.Security;
6 | #endregion
7 |
8 |
9 |
10 | namespace CakeBoss.Host
11 | {
12 | public class UserIdentity : IUserIdentity
13 | {
14 | #region Constructor (2)
15 | public UserIdentity()
16 | {
17 |
18 | }
19 |
20 | public UserIdentity(string username)
21 | {
22 | this.UserName = username;
23 | }
24 | #endregion
25 |
26 |
27 |
28 |
29 |
30 | #region Properties (2)
31 | public string UserName { get; set; }
32 |
33 | public IEnumerable Claims { get; set; }
34 | #endregion
35 | }
36 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Utils/UptimeUtils.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Diagnostics;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Agent
9 | {
10 | public static class UptimeUtils
11 | {
12 | #region Functions (2)
13 | public static TimeSpan GetUptime()
14 | {
15 | using (var uptime = new PerformanceCounter("System", "System Up Time"))
16 | {
17 | uptime.NextValue();
18 |
19 | return TimeSpan.FromSeconds(uptime.NextValue());
20 | }
21 | }
22 |
23 | public static bool IsStartup()
24 | {
25 | return GetUptime() < new TimeSpan(0, 5, 0);
26 | }
27 | #endregion
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/ConsolePalette.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Cake.Host.Diagnostics
4 | {
5 | public sealed class ConsolePalette
6 | {
7 | public ConsoleColor Background { get; set; }
8 |
9 | public ConsoleColor Foreground { get; set; }
10 |
11 | public ConsoleColor ArgumentBackground { get; set; }
12 |
13 | public ConsoleColor ArgumentForeground { get; set; }
14 |
15 | public ConsolePalette(ConsoleColor background, ConsoleColor foreground,
16 | ConsoleColor argumentBackground, ConsoleColor argumentForeground)
17 | {
18 | Background = background;
19 | Foreground = foreground;
20 | ArgumentBackground = argumentBackground;
21 | ArgumentForeground = argumentForeground;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/Parsing/ScriptBlock.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Scripting.Mono.CodeGen.Parsing
2 | {
3 | public sealed class ScriptBlock
4 | {
5 | private readonly int _index;
6 | private readonly string _content;
7 | private readonly bool _hasScope;
8 |
9 | public int Index
10 | {
11 | get { return _index; }
12 | }
13 |
14 | public string Content
15 | {
16 | get { return _content; }
17 | }
18 |
19 | public bool HasScope
20 | {
21 | get { return _hasScope; }
22 | }
23 |
24 | public ScriptBlock(int index, string content, bool hasScope)
25 | {
26 | _index = index;
27 | _content = content;
28 | _hasScope = hasScope;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Aliases/AgentSettings.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using CakeBoss.Host;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Agent
8 | {
9 | ///
10 | /// Settings used to configure the agent
11 | ///
12 | public class AgentSettings : HostSettings
13 | {
14 | #region Properties (3)
15 | ///
16 | /// Gets or sets if AWS termination time should be polled
17 | ///
18 | public bool EnableTerminationCheck { get; set; }
19 |
20 | ///
21 | /// Gets or sets if the nancy agent service should be enabled
22 | ///
23 | public bool EnableAPI { get; set; }
24 |
25 | ///
26 | /// Gets or sets if the scheduled tasks should be enabled
27 | ///
28 | public bool EnableScheduledTasks { get; set; }
29 | #endregion
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/MonoScriptEngine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core.Diagnostics;
4 | using Cake.Core.Scripting;
5 |
6 | namespace Cake.Host.Scripting.Mono
7 | {
8 | public sealed class MonoScriptEngine : IScriptEngine
9 | {
10 | private readonly ICakeLog _log;
11 |
12 | public MonoScriptEngine(ICakeLog log)
13 | {
14 | _log = log;
15 | }
16 |
17 | public IScriptSession CreateSession(IScriptHost host, IDictionary arguments)
18 | {
19 | if (host == null)
20 | {
21 | throw new ArgumentNullException("host");
22 | }
23 | if (arguments == null)
24 | {
25 | throw new ArgumentNullException("arguments");
26 | }
27 |
28 | // Create the script session.
29 | _log.Debug("Creating script session...");
30 | return new MonoScriptSession(host, _log);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Tasks/TaskRegistry.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Cake.Host.Scripting;
5 |
6 | using FluentScheduler;
7 | using FluentScheduler.Model;
8 | #endregion
9 |
10 |
11 |
12 | namespace CakeBoss.Host
13 | {
14 | public class TaskRegistry : Registry
15 | {
16 | #region Fields (1)
17 | private BuildScriptHost _Host;
18 | #endregion
19 |
20 |
21 |
22 |
23 |
24 | #region Constructor (1)
25 | public TaskRegistry(BuildScriptHost host)
26 | {
27 | if (host == null)
28 | {
29 | throw new ArgumentNullException("host");
30 | }
31 |
32 | _Host = host;
33 | }
34 | #endregion
35 |
36 |
37 |
38 |
39 |
40 | #region Functions (1)
41 | public Schedule Schedule(string target)
42 | {
43 | return this.Schedule(() => _Host.RunTarget(target));
44 | }
45 | #endregion
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/DryRunCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core.Scripting;
3 | using Cake.Host.Scripting;
4 |
5 | namespace Cake.Host.Commands
6 | {
7 | ///
8 | /// A command that dry runs a build script.
9 | ///
10 | public sealed class DryRunCommand : ICommand
11 | {
12 | private readonly IScriptRunner _scriptRunner;
13 | private readonly DryRunScriptHost _host;
14 |
15 | // Delegate factory used by Autofac.
16 | public delegate DryRunCommand Factory();
17 |
18 | public DryRunCommand(IScriptRunner scriptRunner, DryRunScriptHost host)
19 | {
20 | _scriptRunner = scriptRunner;
21 | _host = host;
22 | }
23 |
24 | public bool Execute(CakeOptions options)
25 | {
26 | if (options == null)
27 | {
28 | throw new ArgumentNullException("options");
29 | }
30 | _scriptRunner.Run(_host, options.Script, options.Arguments);
31 | return true;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/BuildCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core.Scripting;
3 | using Cake.Host.Scripting;
4 |
5 | namespace Cake.Host.Commands
6 | {
7 | ///
8 | /// A command that builds and runs a build script.
9 | ///
10 | public sealed class BuildCommand : ICommand
11 | {
12 | private readonly IScriptRunner _scriptRunner;
13 | private readonly BuildScriptHost _host;
14 |
15 | // Delegate factory used by Autofac.
16 | public delegate BuildCommand Factory();
17 |
18 | public BuildCommand(IScriptRunner scriptRunner, BuildScriptHost host)
19 | {
20 | _scriptRunner = scriptRunner;
21 | _host = host;
22 | }
23 |
24 | public bool Execute(CakeOptions options)
25 | {
26 | if (options == null)
27 | {
28 | throw new ArgumentNullException("options");
29 | }
30 | _scriptRunner.Run(_host, options.Script, options.Arguments);
31 | return true;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/DescriptionCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core.Scripting;
3 | using Cake.Host.Scripting;
4 |
5 | namespace Cake.Host.Commands
6 | {
7 | ///
8 | /// A command that displays information about script tasks.
9 | ///
10 | public sealed class DescriptionCommand : ICommand
11 | {
12 | private readonly IScriptRunner _scriptRunner;
13 | private readonly DescriptionScriptHost _host;
14 |
15 | // Delegate factory used by Autofac.
16 | public delegate DescriptionCommand Factory();
17 |
18 | public DescriptionCommand(IScriptRunner scriptRunner, DescriptionScriptHost host)
19 | {
20 | _scriptRunner = scriptRunner;
21 | _host = host;
22 | }
23 |
24 | public bool Execute(CakeOptions options)
25 | {
26 | if (options == null)
27 | {
28 | throw new ArgumentNullException("options");
29 | }
30 | _scriptRunner.Run(_host, options.Script, options.Arguments);
31 | return true;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/Parsing/ScriptToken.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace Cake.Host.Scripting.Mono.CodeGen.Parsing
4 | {
5 | [DebuggerDisplay("{Value,nq} ({Type})")]
6 | public sealed class ScriptToken
7 | {
8 | private readonly ScriptTokenType _type;
9 | private readonly string _value;
10 | private readonly int _index;
11 | private readonly int _length;
12 |
13 | public ScriptTokenType Type
14 | {
15 | get { return _type; }
16 | }
17 |
18 | public string Value
19 | {
20 | get { return _value; }
21 | }
22 |
23 | public int Index
24 | {
25 | get { return _index; }
26 | }
27 |
28 | public int Length
29 | {
30 | get { return _length; }
31 | }
32 |
33 | public ScriptToken(ScriptTokenType type, string value, int index, int length)
34 | {
35 | _type = type;
36 | _value = value;
37 | _index = index;
38 | _length = length;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/RoslynCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Cake.Core.Scripting;
3 | using Cake.Core.Scripting.CodeGen;
4 |
5 | namespace Cake.Host.Scripting.Roslyn
6 | {
7 | public sealed class RoslynCodeGenerator
8 | {
9 | public string Generate(Script script)
10 | {
11 | var usingDirectives = string.Join("\r\n", script.UsingAliasDirectives);
12 | var aliases = GetAliasCode(script);
13 | var code = string.Join("\r\n", script.Lines);
14 | return string.Join("\r\n", usingDirectives, aliases, code);
15 | }
16 |
17 | private static string GetAliasCode(Script context)
18 | {
19 | var result = new List();
20 | foreach (var alias in context.Aliases)
21 | {
22 | result.Add(alias.Type == ScriptAliasType.Method
23 | ? MethodAliasGenerator.Generate(alias.Method)
24 | : PropertyAliasGenerator.Generate(alias.Method));
25 | }
26 | return string.Join("\r\n", result);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Extensions/CakeContextExtensions.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using LightInject;
6 | using Cake.Core;
7 | #endregion
8 |
9 |
10 |
11 | namespace CakeBoss.Host
12 | {
13 | public static class CakeContextExtensions
14 | {
15 | #region Functions (1)
16 | public static IServiceContainer Container;
17 | #endregion
18 |
19 |
20 |
21 |
22 |
23 | #region Functions (3)
24 | public static IServiceContainer GetContainer(this ICakeContext context)
25 | {
26 | return Container;
27 | }
28 |
29 | public static TService GetInstance(this ICakeContext context)
30 | {
31 | return context.GetContainer().GetInstance();
32 | }
33 |
34 | public static TService GetInstance(this ICakeContext context, string serviceName)
35 | {
36 | return context.GetContainer().GetInstance(serviceName);
37 | }
38 | #endregion
39 | }
40 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Misc folders
2 | [Bb]in/
3 | [Oo]bj/
4 | [Tt]emp/
5 | [Pp]ackages/
6 | /[Bb]uild/
7 | *.sln.ide/
8 |
9 | # Build related
10 | build/
11 | tools/
12 | test/tools/
13 |
14 |
15 |
16 | ## Ignore Visual Studio temporary files, build results, and
17 | ## files generated by popular Visual Studio add-ons.
18 |
19 | # User-specific files
20 | *.suo
21 | *.user
22 | *.sln.docstates
23 | *.userprefs
24 | *.GhostDoc.xml
25 | *StyleCop.Cache
26 |
27 | # Build results
28 | [Dd]ebug/
29 | [Rr]elease/
30 | x64/
31 | *_i.c
32 | *_p.c
33 | *.ilk
34 | *.meta
35 | *.obj
36 | *.pch
37 | *.pdb
38 | *.pgc
39 | *.pgd
40 | *.rsp
41 | *.sbr
42 | *.tlb
43 | *.tli
44 | *.tlh
45 | *.tmp
46 | *.log
47 | *.vspscc
48 | *.vssscc
49 | .builds
50 |
51 | # Visual Studio profiler
52 | *.psess
53 | *.vsp
54 | *.vspx
55 |
56 | # ReSharper is a .NET coding add-in
57 | _ReSharper*
58 |
59 | # NCrunch
60 | *.ncrunch*
61 | .*crunch*.local.xml
62 | _NCrunch_*
63 |
64 |
65 |
66 | # Visual Studio Directory
67 | src/.vs/
68 |
69 | # NuGet Packages Directory
70 | src/packages/
71 |
72 | # mstest test results
73 | src/TestResults/
74 |
75 |
76 |
77 | # Windows
78 | Thumbs.db
79 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 - 2016 Phillip Sharpe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Auth/AuthenticationService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | #endregion
4 |
5 |
6 |
7 | namespace CakeBoss.Host
8 | {
9 | public class AuthenticationService : IAuthenticationService
10 | {
11 | #region Fields (1)
12 | private HostSettings _Settings;
13 | #endregion
14 |
15 |
16 |
17 |
18 |
19 | #region Constructor (1)
20 | public AuthenticationService(HostSettings settings)
21 | {
22 | if (settings == null)
23 | {
24 | throw new ArgumentNullException("settings");
25 | }
26 |
27 | _Settings = settings;
28 | }
29 | #endregion
30 |
31 |
32 |
33 |
34 |
35 | #region Functions (2)
36 | public bool ValidUser(string username, string password)
37 | {
38 | return _Settings.ContainsUser(username, password);
39 | }
40 |
41 | public bool ValidApiKey(string apiKey)
42 | {
43 | return _Settings.ContainsApiKey(apiKey);
44 | }
45 | #endregion
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Nancy/ServiceModule.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Nancy;
5 | using Nancy.Security;
6 | #endregion
7 |
8 |
9 |
10 | namespace CakeBoss.Agent
11 | {
12 | public class ServiceModule : NancyModule
13 | {
14 | #region Fields (1)
15 | private IAgentService _Service;
16 | #endregion
17 |
18 |
19 |
20 |
21 |
22 | #region Constructors (1)
23 | public ServiceModule(IAgentService service)
24 | : base("/agent")
25 | {
26 | if (service == null)
27 | {
28 | throw new ArgumentNullException("service");
29 | }
30 |
31 | _Service = service;
32 |
33 | this.RequiresAuthentication();
34 |
35 |
36 |
37 | Get["/current"] = x =>
38 | {
39 | return _Service.CurrentTask;
40 | };
41 |
42 | Post["/run/{target}"] = x =>
43 | {
44 | return _Service.RunTarget(x.target, false);
45 | };
46 | }
47 | #endregion
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Console/ConsoleOutput.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Cake.Core.Diagnostics;
6 | using Cake.Core.IO;
7 | #endregion
8 |
9 |
10 |
11 | namespace CakeBoss.Host
12 | {
13 | ///
14 | /// Output from the cake console
15 | ///
16 | public sealed class ConsoleOutput
17 | {
18 | #region Constructor (1)
19 | public ConsoleOutput(string text, ConsoleColor color)
20 | {
21 | this.Text = text;
22 | this.ForegroundColor = color;
23 | }
24 | #endregion
25 |
26 |
27 |
28 |
29 |
30 | #region Properties (2)
31 | ///
32 | /// Gets or sets the text
33 | ///
34 | /// The text.
35 | public string Text { get; set; }
36 |
37 | ///
38 | /// Gets or sets the foreground color.
39 | ///
40 | /// The foreground color.
41 | public ConsoleColor ForegroundColor { get; set; }
42 | #endregion
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/ICommandFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Cake.Host.Commands
2 | {
3 | ///
4 | /// Represents a command factory.
5 | ///
6 | public interface ICommandFactory
7 | {
8 | ///
9 | /// Creates the build command.
10 | ///
11 | /// The build command.
12 | ICommand CreateBuildCommand();
13 |
14 | ///
15 | /// Creates the description command.
16 | ///
17 | /// The description command.
18 | ICommand CreateDescriptionCommand();
19 |
20 | ///
21 | /// Creates the dry run command.
22 | ///
23 | /// The dry run command.
24 | ICommand CreateDryRunCommand();
25 |
26 | ///
27 | /// Creates the help command.
28 | ///
29 | /// The help command.
30 | ICommand CreateHelpCommand();
31 |
32 | ///
33 | /// Creates the version command.
34 | ///
35 | /// The version command.
36 | ICommand CreateVersionCommand();
37 | }
38 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/Formatting/PropertyToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace Cake.Host.Diagnostics.Formatting
5 | {
6 | public sealed class PropertyToken : FormatToken
7 | {
8 | private readonly int _position;
9 | private readonly string _format;
10 |
11 | public string Format
12 | {
13 | get { return _format; }
14 | }
15 |
16 | public int Position
17 | {
18 | get { return _position; }
19 | }
20 |
21 | public PropertyToken(int position, string format)
22 | {
23 | _position = position;
24 | _format = format;
25 | }
26 |
27 | public override string Render(object[] args)
28 | {
29 | var value = args[_position];
30 | if (!string.IsNullOrWhiteSpace(_format))
31 | {
32 | var formattable = value as IFormattable;
33 | if (formattable != null)
34 | {
35 | return formattable.ToString(_format, CultureInfo.InvariantCulture);
36 | }
37 | }
38 | return (value == null)
39 | ? "[NULL]"
40 | : value.ToString();
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/nuspec/Cake.CakeBoss.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cake.CakeBoss
5 | 0.0.0
6 | Phillip Sharpe
7 | Phillip Sharpe
8 | Cake.CakeBoss
9 | Cake Build addon for calling CakeBoss agents.
10 | CakeBoss addon for cake build.
11 | https://github.com/SharpeRAD/CakeBoss/LICENSE
12 | https://github.com/SharpeRAD/CakeBoss
13 | https://cdn.jsdelivr.net/gh/cake-contrib/graphics/png/cake-contrib-medium.png
14 | false
15 | Copyright (c) Phillip Sharpe 2015
16 | Initial Release
17 | Cake Script Build DevOpps
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Nancy/ServiceStartup.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using Nancy;
3 | using Nancy.Responses;
4 | using Nancy.Bootstrapper;
5 | using Nancy.Authentication.Basic;
6 |
7 | using Cake.Core;
8 | using Cake.Core.Diagnostics;
9 | #endregion
10 |
11 |
12 |
13 | namespace CakeBoss.Agent
14 | {
15 | public class ServiceStaartup : IApplicationStartup
16 | {
17 | #region Functions (3)
18 | public void Initialize(IPipelines pipelines)
19 | {
20 | pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(Program.Container.GetInstance(), "CakeBoss", UserPromptBehaviour.NonAjax));
21 |
22 | pipelines.OnError.AddItemToEndOfPipeline((context, exception) =>
23 | {
24 | //Log Error
25 | ICakeLog log = Program.Container.GetInstance();
26 |
27 | log.Error(exception.Message);
28 |
29 |
30 |
31 | //Return Response
32 | Response response = new JsonResponse(exception.Message, Program.Container.GetInstance());
33 |
34 | response.StatusCode = HttpStatusCode.InternalServerError;
35 |
36 | return response;
37 | });
38 | }
39 | #endregion
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Nancy/UserValidator.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Nancy;
5 | using Nancy.Security;
6 | using Nancy.Authentication.Basic;
7 | #endregion
8 |
9 |
10 |
11 | namespace CakeBoss.Host
12 | {
13 | public class UserValidator : IUserValidator
14 | {
15 | #region Fields (1)
16 | private IAuthenticationService _AuthenticationService;
17 | #endregion
18 |
19 |
20 |
21 |
22 |
23 | #region Constructor (1)
24 | public UserValidator(IAuthenticationService authenticationService)
25 | {
26 | if (authenticationService == null)
27 | {
28 | throw new ArgumentNullException("authenticationService");
29 | }
30 |
31 | _AuthenticationService = authenticationService;
32 | }
33 | #endregion
34 |
35 |
36 |
37 |
38 |
39 | #region Functions (1)
40 | public IUserIdentity Validate(string username, string password)
41 | {
42 | if (_AuthenticationService.ValidUser(username, password))
43 | {
44 | return new UserIdentity(username);
45 | }
46 | else
47 | {
48 | return null;
49 | }
50 | }
51 | #endregion
52 | }
53 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Aliases/TerminationAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using Cake.Core;
3 | using Cake.Core.Annotations;
4 | using Cake.Core.Diagnostics;
5 |
6 | using CakeBoss.Host;
7 | #endregion
8 |
9 |
10 |
11 | namespace CakeBoss.Agent
12 | {
13 | [CakeAliasCategory("CakeBoss")]
14 | public static class TerminationAliases
15 | {
16 | ///
17 | /// Starts the termination service
18 | ///
19 | /// The context.
20 | [CakeMethodAlias]
21 | [CakeAliasCategory("Termination")]
22 | public static void StartTerminationCheck(this ICakeContext context)
23 | {
24 | context.GetContainer().GetInstance().Enabled = true;
25 |
26 | context.Log.Information("Termination service started.");
27 | }
28 |
29 | ///
30 | /// Stops the termination service
31 | ///
32 | /// The context.
33 | [CakeMethodAlias]
34 | [CakeAliasCategory("Termination")]
35 | public static void StopTerminationCheck(this ICakeContext context)
36 | {
37 | context.GetContainer().GetInstance().Enabled = false;
38 |
39 | context.Log.Information("Termination service stopped.");
40 | }
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Aliases/HostAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.ObjectModel;
4 |
5 | using Cake.Core;
6 | using Cake.Core.IO;
7 | using Cake.Core.Annotations;
8 | using Cake.Core.Diagnostics;
9 |
10 | using LightInject;
11 | #endregion
12 |
13 |
14 |
15 | namespace CakeBoss.Host
16 | {
17 | [CakeAliasCategory("CakeBoss")]
18 | public static class HostAliases
19 | {
20 | ///
21 | /// Starts a Nuget server using the specified information.
22 | ///
23 | /// The context.
24 | /// The Nuget server settings.
25 | [CakeMethodAlias]
26 | [CakeAliasCategory("Host")]
27 | public static void ConfigureHost(this ICakeContext context, HostSettings settings)
28 | {
29 | HostSettings instance = context.GetContainer().GetInstance();
30 |
31 | foreach (User user in settings.Users)
32 | {
33 | instance.AddUser(user.Username, user.Password);
34 | }
35 |
36 | foreach (string key in settings.ApiKeys)
37 | {
38 | instance.AddApiKey(key);
39 | }
40 |
41 | instance.Host = settings.Host;
42 | instance.Port = settings.Port;
43 | instance.Url = settings.Url;
44 |
45 | context.Log.Information("Host configured.");
46 | }
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/src/Cake.Host/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Host")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Host")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("206f12ed-5ffa-4333-a5a9-31c142648ac1")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("86e04045-fe0d-4eb4-85c1-8b7792b4c4e3")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Auth/HostSettings.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Cake.Core.IO;
6 | #endregion
7 |
8 |
9 |
10 | namespace CakeBoss.Host
11 | {
12 | public class HostSettings
13 | {
14 | #region Fields (1)
15 | private string _Url;
16 | #endregion
17 |
18 |
19 |
20 |
21 |
22 | #region Constructor (1)
23 | public HostSettings()
24 | {
25 | this.Users = new List();
26 | this.ApiKeys = new List();
27 |
28 | this.Host = "localhost";
29 | this.Port = 8080;
30 |
31 | _Url = "";
32 | }
33 | #endregion
34 |
35 |
36 |
37 |
38 |
39 | #region Properties (4)
40 | public IList Users { get; set; }
41 |
42 | public IList ApiKeys { get; set; }
43 |
44 |
45 |
46 | public string Host { get; set; }
47 |
48 | public int Port { get; set; }
49 |
50 |
51 |
52 | public string Url
53 | {
54 | set
55 | {
56 | _Url = value;
57 | }
58 | get
59 | {
60 | if (!String.IsNullOrEmpty(_Url))
61 | {
62 | return _Url;
63 | }
64 | else
65 | {
66 | return "http://" + this.Host + ":" + this.Port.ToString();
67 | }
68 | }
69 | }
70 | #endregion
71 | }
72 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/Config/Startup.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using LightInject;
5 | using Nancy.Hosting.Self;
6 |
7 | using CakeBoss.Agent;
8 | using CakeBoss.Host;
9 | #endregion
10 |
11 |
12 |
13 | namespace CakeBoss.Agent.Tests
14 | {
15 | public static class Startup
16 | {
17 | #region Fields (2)
18 | public static IServiceContainer Container = null;
19 | public static NancyHost Host = null;
20 | #endregion
21 |
22 |
23 |
24 |
25 |
26 | #region Functions (2)
27 | public static void CreateContainer()
28 | {
29 | if (Container == null)
30 | {
31 | var container = new ServiceContainer();
32 |
33 | container.EnableAnnotatedPropertyInjection();
34 |
35 | container.RegisterFrom();
36 | container.RegisterFrom();
37 |
38 | Container = container;
39 | }
40 | }
41 |
42 | public static void ConfigureHost()
43 | {
44 | if (Host == null)
45 | {
46 | Host = new NancyHost(new Uri("http://localhost:2001"), new UnitTestBootstrapper(), new HostConfiguration()
47 | {
48 | UrlReservations = new UrlReservations()
49 | {
50 | CreateAutomatically = true
51 | }
52 | });
53 |
54 | Host.Start();
55 | }
56 | }
57 | #endregion
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Nancy/ServiceBootstrapper.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using LightInject;
3 | using LightInject.Nancy;
4 |
5 | using Nancy;
6 | using Nancy.Responses;
7 | using Nancy.Bootstrapper;
8 | using Nancy.Authentication.Basic;
9 |
10 | using Cake.Core;
11 | using Cake.Core.Diagnostics;
12 | #endregion
13 |
14 |
15 |
16 | namespace CakeBoss.Agent
17 | {
18 | public class ServiceBootstrapper : LightInjectNancyBootstrapper
19 | {
20 | #region Functions (3)
21 | protected override IServiceContainer GetServiceContainer()
22 | {
23 | return Program.Container;
24 | }
25 |
26 |
27 |
28 | /*
29 | protected override void ApplicationStartup(IServiceContainer container, IPipelines pipelines)
30 | {
31 | base.ApplicationStartup(container, pipelines);
32 |
33 | pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(container.GetInstance(), "CakeBoss", UserPromptBehaviour.NonAjax));
34 |
35 | pipelines.OnError.AddItemToEndOfPipeline((context, exception) =>
36 | {
37 | //Log Error
38 | ICakeLog log = container.GetInstance();
39 |
40 | log.Error(exception.Message);
41 |
42 |
43 |
44 | //Return Response
45 | Response response = new JsonResponse(exception.Message, container.GetInstance());
46 |
47 | response.StatusCode = HttpStatusCode.InternalServerError;
48 |
49 | return response;
50 | });
51 | }*/
52 | #endregion
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/RoslynScriptEngine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core.Diagnostics;
4 | using Cake.Core.Scripting;
5 | using Cake.Host.Scripting.Roslyn.Nightly;
6 | using Cake.Host.Scripting.Roslyn.Stable;
7 |
8 | namespace Cake.Host.Scripting.Roslyn
9 | {
10 | public sealed class RoslynScriptEngine : IScriptEngine
11 | {
12 | private readonly RoslynScriptSessionFactory _stableFactory;
13 | private readonly RoslynNightlyScriptSessionFactory _nightlyFactory;
14 | private readonly ICakeLog _log;
15 |
16 | public RoslynScriptEngine(
17 | RoslynScriptSessionFactory stableFactory,
18 | RoslynNightlyScriptSessionFactory nightlyFactory,
19 | ICakeLog log)
20 | {
21 | _nightlyFactory = nightlyFactory;
22 | _stableFactory = stableFactory;
23 | _log = log;
24 | }
25 |
26 | public IScriptSession CreateSession(IScriptHost host, IDictionary arguments)
27 | {
28 | if (arguments == null)
29 | {
30 | throw new ArgumentNullException("arguments");
31 | }
32 |
33 | // Create the script session.
34 | _log.Debug("Creating script session...");
35 |
36 | // Are we using the experimental bits?
37 | if (arguments.ContainsKey("experimental"))
38 | {
39 | // Use the nightly build.
40 | _log.Debug("Using prerelease build of Roslyn.");
41 | return _nightlyFactory.CreateSession(host);
42 | }
43 |
44 | // Use the stable build.
45 | return _stableFactory.CreateSession(host);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/BuildScriptHost.cs:
--------------------------------------------------------------------------------
1 | using Cake.Core;
2 | using Cake.Core.Diagnostics;
3 | using Cake.Core.Scripting;
4 |
5 | namespace Cake.Host.Scripting
6 | {
7 | ///
8 | /// The script host used to execute Cake.Host scripts.
9 | ///
10 | public sealed class BuildScriptHost : ScriptHost
11 | {
12 | private readonly ICakeReportPrinter _reportPrinter;
13 | private readonly ICakeLog _log;
14 |
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The engine.
19 | /// The context.
20 | /// The report printer.
21 | /// The log.
22 | public BuildScriptHost(
23 | ICakeEngine engine,
24 | ICakeContext context,
25 | ICakeReportPrinter reportPrinter,
26 | ICakeLog log) : base(engine, context)
27 | {
28 | _reportPrinter = reportPrinter;
29 | _log = log;
30 | }
31 |
32 | ///
33 | /// Runs the specified target.
34 | ///
35 | /// The target to run.
36 | /// The resulting report.
37 | public override CakeReport RunTarget(string target)
38 | {
39 | var strategy = new DefaultExecutionStrategy(_log);
40 | var report = Engine.RunTarget(Context, strategy, target);
41 | if (report != null && !report.IsEmpty)
42 | {
43 | _reportPrinter.Write(report);
44 | }
45 | return report;
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Extensions/HostSettingsExtensions.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Linq;
4 | #endregion
5 |
6 |
7 |
8 | namespace CakeBoss.Host
9 | {
10 | public static class HostSettingsExtensions
11 | {
12 | #region Functions (6)
13 | public static T AddUser(this T settings, string username, string password) where T : HostSettings
14 | {
15 | settings.Users.Add(new User(username, password));
16 |
17 | return settings;
18 | }
19 |
20 | public static HostSettings AddApiKey(this T settings, string key) where T : HostSettings
21 | {
22 | settings.ApiKeys.Add(key);
23 |
24 | return settings;
25 | }
26 |
27 |
28 |
29 | public static bool ContainsUser(this T settings, string username, string password) where T : HostSettings
30 | {
31 | return (settings.Users.FirstOrDefault(u => u.Username == username && u.Password == password) != null);
32 | }
33 |
34 | public static bool ContainsApiKey(this T settings, string apiKey) where T : HostSettings
35 | {
36 | return settings.ApiKeys.Contains(apiKey);
37 | }
38 |
39 |
40 |
41 | public static T SetUrl(this T settings, string url) where T : HostSettings
42 | {
43 | settings.Url = url;
44 |
45 | return settings;
46 | }
47 |
48 | public static T SetPort(this T settings, int port) where T : HostSettings
49 | {
50 | settings.Port = port;
51 |
52 | return settings;
53 | }
54 | #endregion
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/MonoScriptProcessor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core;
4 | using Cake.Core.Scripting;
5 | using Cake.Host.Scripting.Mono.CodeGen.Parsing;
6 |
7 | namespace Cake.Host.Scripting.Mono.CodeGen
8 | {
9 | public static class MonoScriptProcessor
10 | {
11 | public static Script Process(Script script, out IReadOnlyList blocks)
12 | {
13 | var lines = new List();
14 | var result = new List();
15 | foreach (var codeBlock in ParseBlocks(script))
16 | {
17 | if (codeBlock.HasScope)
18 | {
19 | result.Add(codeBlock);
20 | }
21 | else
22 | {
23 | lines.AddRange(codeBlock.Content.SplitLines());
24 | }
25 | }
26 | blocks = result; // Assign the parsed blocks.
27 | return new Script(script.Namespaces, lines, script.Aliases, script.UsingAliasDirectives);
28 | }
29 |
30 | private static IEnumerable ParseBlocks(Script script)
31 | {
32 | var code = string.Join(Environment.NewLine, script.Lines);
33 | using (var parser = new ScriptParser(code))
34 | {
35 | var result = new List();
36 | while (true)
37 | {
38 | var block = parser.ParseNext();
39 | if (block == null)
40 | {
41 | break;
42 | }
43 | result.Add(block);
44 | }
45 | return result;
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/DryRunExecutionStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core;
3 | using Cake.Core.Diagnostics;
4 |
5 | namespace Cake.Host.Scripting
6 | {
7 | public sealed class DryRunExecutionStrategy : IExecutionStrategy
8 | {
9 | private readonly ICakeLog _log;
10 | private int _counter;
11 |
12 | public DryRunExecutionStrategy(ICakeLog log)
13 | {
14 | if (log == null)
15 | {
16 | throw new ArgumentNullException("log");
17 | }
18 | _log = log;
19 | _counter = 1;
20 | }
21 |
22 | public void PerformSetup(Action action)
23 | {
24 | }
25 |
26 | public void PerformTeardown(Action action)
27 | {
28 | }
29 |
30 | public void Execute(CakeTask task, ICakeContext context)
31 | {
32 | if (task != null)
33 | {
34 | _log.Information("{0}. {1}", _counter, task.Name);
35 | _counter++;
36 | }
37 | }
38 |
39 | public void Skip(CakeTask task)
40 | {
41 | }
42 |
43 | public void ReportErrors(Action action, Exception exception)
44 | {
45 | }
46 |
47 | public void HandleErrors(Action action, Exception exception)
48 | {
49 | }
50 |
51 | public void InvokeFinally(Action action)
52 | {
53 | }
54 |
55 | public void PerformTaskSetup(Action action, ICakeContext context, ITaskSetupContext setupContext)
56 | {
57 | }
58 |
59 | public void PerformTaskTeardown(Action action, ICakeContext context, ITaskTeardownContext teardownContext)
60 | {
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Cake.Host/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/CommandFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core.Scripting;
3 | using Cake.Host.Scripting;
4 |
5 | namespace Cake.Host.Commands
6 | {
7 | public class CommandFactory : ICommandFactory
8 | {
9 | private readonly BuildCommand _buildCommandFactory;
10 | private readonly DescriptionCommand _descriptionCommandFactory;
11 | private readonly DryRunCommand _dryRunCommandFactory;
12 | private readonly HelpCommand _helpCommandFactory;
13 | private readonly VersionCommand _versionCommandFactory;
14 |
15 | public CommandFactory(
16 | BuildCommand buildCommandFactory,
17 | DescriptionCommand descriptionCommandFactory,
18 | DryRunCommand dryRunCommandFactory,
19 | HelpCommand helpCommandFactory,
20 | VersionCommand versionCommandFactory)
21 | {
22 | _buildCommandFactory = buildCommandFactory;
23 | _descriptionCommandFactory = descriptionCommandFactory;
24 | _dryRunCommandFactory = dryRunCommandFactory;
25 | _helpCommandFactory = helpCommandFactory;
26 | _versionCommandFactory = versionCommandFactory;
27 | }
28 |
29 | public ICommand CreateBuildCommand()
30 | {
31 | return _buildCommandFactory;
32 | }
33 |
34 | public ICommand CreateDescriptionCommand()
35 | {
36 | return _descriptionCommandFactory;
37 | }
38 |
39 | public ICommand CreateDryRunCommand()
40 | {
41 | return _dryRunCommandFactory;
42 | }
43 |
44 | public ICommand CreateHelpCommand()
45 | {
46 | return _helpCommandFactory;
47 | }
48 |
49 | public ICommand CreateVersionCommand()
50 | {
51 | return _versionCommandFactory;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/DryRunScriptHost.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core;
3 | using Cake.Core.Diagnostics;
4 | using Cake.Core.Scripting;
5 |
6 | namespace Cake.Host.Scripting
7 | {
8 | ///
9 | /// The script host used to dry run Cake.Host scripts.
10 | ///
11 | public sealed class DryRunScriptHost : ScriptHost
12 | {
13 | private readonly ICakeLog _log;
14 |
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The engine.
19 | /// The context.
20 | /// The log.
21 | public DryRunScriptHost(ICakeEngine engine, ICakeContext context, ICakeLog log)
22 | : base(engine, context)
23 | {
24 | if (log == null)
25 | {
26 | throw new ArgumentNullException("log");
27 | }
28 | _log = log;
29 | }
30 |
31 | ///
32 | /// Runs the specified target.
33 | ///
34 | /// The target to run.
35 | /// The resulting report.
36 | public override CakeReport RunTarget(string target)
37 | {
38 | _log.Information("Performing dry run...");
39 | _log.Information("Target is: {0}", target);
40 | _log.Information(string.Empty);
41 |
42 | var strategy = new DryRunExecutionStrategy(_log);
43 | var result = Engine.RunTarget(Context, strategy, target);
44 |
45 | _log.Information(string.Empty);
46 | _log.Information("This was a dry run.");
47 | _log.Information("No tasks were actually executed.");
48 |
49 | return result;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/Config/UnitTestBootstrapper.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using LightInject;
3 | using LightInject.Nancy;
4 |
5 | using Nancy;
6 | using Nancy.Responses;
7 | using Nancy.Bootstrapper;
8 | using Nancy.Authentication.Basic;
9 |
10 | using Cake.Core;
11 | using Cake.Core.Diagnostics;
12 | #endregion
13 |
14 |
15 |
16 | namespace CakeBoss.Agent.Tests
17 | {
18 | public class UnitTestBootstrapper : LightInjectNancyBootstrapper
19 | {
20 | #region Functions (3)
21 | protected override IServiceContainer GetServiceContainer()
22 | {
23 | return Startup.Container;
24 | }
25 |
26 | protected override void ConfigureApplicationContainer(IServiceContainer container)
27 | {
28 | base.ConfigureApplicationContainer(container);
29 | }
30 |
31 |
32 |
33 | protected override void ApplicationStartup(IServiceContainer container, IPipelines pipelines)
34 | {
35 | base.ApplicationStartup(container, pipelines);
36 |
37 | pipelines.EnableBasicAuthentication(new BasicAuthenticationConfiguration(container.GetInstance(), "CakeBoss", UserPromptBehaviour.NonAjax));
38 |
39 | pipelines.OnError.AddItemToEndOfPipeline((context, exception) =>
40 | {
41 | //Log Error
42 | ICakeLog log = container.GetInstance();
43 |
44 | log.Error(exception.Message);
45 |
46 |
47 |
48 | //Return Response
49 | Response response = new JsonResponse(exception.Message, container.GetInstance());
50 |
51 | response.StatusCode = HttpStatusCode.InternalServerError;
52 |
53 | return response;
54 | });
55 | }
56 | #endregion
57 | }
58 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Arguments/VerbosityParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core.Diagnostics;
4 |
5 | namespace Cake.Host.Arguments
6 | {
7 | ///
8 | /// Responsible for parsing .
9 | ///
10 | public sealed class VerbosityParser
11 | {
12 | private readonly Dictionary _lookup;
13 |
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public VerbosityParser()
18 | {
19 | _lookup = new Dictionary(StringComparer.OrdinalIgnoreCase)
20 | {
21 | { "q", Verbosity.Quiet },
22 | { "quiet", Verbosity.Quiet },
23 | { "m", Verbosity.Minimal },
24 | { "minimal", Verbosity.Minimal },
25 | { "n", Verbosity.Normal },
26 | { "normal", Verbosity.Normal },
27 | { "v", Verbosity.Verbose },
28 | { "verbose", Verbosity.Verbose },
29 | { "d", Verbosity.Diagnostic },
30 | { "diagnostic", Verbosity.Diagnostic }
31 | };
32 | }
33 |
34 | ///
35 | /// Parses the provided string to a .
36 | ///
37 | /// The string to parse.
38 | /// The verbosity.
39 | public Verbosity Parse(string value)
40 | {
41 | Verbosity verbosity;
42 | if (_lookup.TryGetValue(value, out verbosity))
43 | {
44 | return verbosity;
45 | }
46 | const string format = "The value '{0}' is not a valid verbosity.";
47 | var message = string.Format(format, value ?? string.Empty);
48 | throw new InvalidOperationException(message);
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/ReleaseNotes.md:
--------------------------------------------------------------------------------
1 | ### New in 0.1.5 (Released 2016/01/29)
2 | * Update cake references
3 | * Seperate Termination and Api aliases from main config alias
4 | * Add "StopSchedules" alias
5 | * Add "RestartAgent" and "ReconfigureAgent" aliases
6 | * Check for blank command line target argument
7 |
8 | ### New in 0.1.4 (Released 2016/01/21)
9 | * Simplify build script file copying
10 | * Add extra checks for nuget.exe
11 | * Fix bug in target commaned line
12 | * Add deploy.bat as an example use of target
13 |
14 | ### New in 0.1.3 (Released 2016/01/20)
15 | * Add Linux support
16 | * Select target from command line argument
17 | * Verbose Serilogs
18 |
19 | ### New in 0.1.2 (Released 2016/01/16)
20 | * Fixed SolutionInfo link
21 | * Changed Cake.CakeBoss alias to pass the target in as its own parameter
22 |
23 | ### New in 0.1.1 (Released 2016/01/07)
24 | * Add GitHub releases to build
25 | * Separate Test / Release cake scripts
26 | * Fix log formatting / default locations
27 | * Exclude TopShelf configuration result from logs
28 | * Add icon to agent
29 |
30 | ### New in 0.1.0 (Released 2016/01/05)
31 | * Scheduled Tasks
32 |
33 | ### New in 0.0.9 (Released 2015/12/30)
34 | * Working AppVeyor & visual studio debugging build process
35 |
36 | ### New in 0.0.8 (Released 2015/12/30)
37 | * Override ScriptRunner to alter the location of the addin directory
38 |
39 | ### New in 0.0.7 (Released 2015/12/24)
40 | * Improved host webservice
41 |
42 | ### New in 0.0.6 (Released 2015/12/10)
43 | * Update Cake references
44 |
45 | ### New in 0.0.5 (Released 2015/11/08)
46 | * Cake Addin for calling agent
47 | * Bootstrap using CompositeRoots for improved separation
48 |
49 | ### New in 0.0.4 (Released 2015/11/06)
50 | * Added Nancy webservice
51 |
52 | ### New in 0.0.3 (Released 2015/11/03)
53 | * Added Termination detection
54 | * Added Uptime check to detect StartUp
55 |
56 | ### New in 0.0.2 (Released 2015/10/12)
57 | * Fixed Rosyln experimental references
58 |
59 | ### New in 0.0.1 (Released 2015/10/10)
60 | * First release.
--------------------------------------------------------------------------------
/src/CakeBoss.Host/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/HelpCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core;
3 | using Cake.Core.Diagnostics;
4 |
5 | namespace Cake.Host.Commands
6 | {
7 | ///
8 | /// A command that displays help information.
9 | ///
10 | public sealed class HelpCommand : ICommand
11 | {
12 | private readonly IConsole _console;
13 |
14 | // Delegate factory used by Autofac.
15 | public delegate HelpCommand Factory();
16 |
17 | public HelpCommand(IConsole console)
18 | {
19 | _console = console;
20 | }
21 |
22 | public bool Execute(CakeOptions options)
23 | {
24 | _console.WriteLine();
25 | _console.WriteLine("Usage: Cake.Host.exe [build-script] [-verbosity=value]");
26 | _console.WriteLine(" [-showdescription] [-dryrun] [..]");
27 | _console.WriteLine();
28 | _console.WriteLine("Example: Cake.Host.exe");
29 | _console.WriteLine("Example: Cake.Host.exe build.Cake.Host -verbosity=quiet");
30 | _console.WriteLine("Example: Cake.Host.exe build.Cake.Host -showdescription");
31 | _console.WriteLine();
32 | _console.WriteLine("Options:");
33 | _console.WriteLine(" -verbosity=value Specifies the amount of information to be displayed.");
34 | _console.WriteLine(" ({0})",
35 | string.Join(", ", Enum.GetNames(typeof(Verbosity))));
36 | _console.WriteLine(" -showdescription Shows description about tasks.");
37 | _console.WriteLine(" -dryrun Performs a dry run.");
38 | _console.WriteLine(" -version Displays version information.");
39 | _console.WriteLine(" -help Displays usage information.");
40 | _console.WriteLine(" -experimental Uses the nightly builds of Roslyn script engine.");
41 | _console.WriteLine();
42 |
43 | return true;
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/Parsing/ScriptBuffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace Cake.Host.Scripting.Mono.CodeGen.Parsing
5 | {
6 | public sealed class ScriptBuffer : IDisposable
7 | {
8 | private readonly StringReader _reader;
9 |
10 | public int Position
11 | {
12 | get; private set;
13 | }
14 |
15 | public int PreviousToken
16 | {
17 | get; private set;
18 | }
19 |
20 | public int CurrentToken
21 | {
22 | get; private set;
23 | }
24 |
25 | public int NextToken
26 | {
27 | get; private set;
28 | }
29 |
30 | public bool ReachedEnd
31 | {
32 | get; private set;
33 | }
34 |
35 | public ScriptBuffer(string content)
36 | {
37 | _reader = new StringReader(content);
38 |
39 | // Set initial values.
40 | CurrentToken = ' ';
41 | Position = -1;
42 | }
43 |
44 | public void Dispose()
45 | {
46 | _reader.Dispose();
47 | }
48 |
49 | public bool Read()
50 | {
51 | if (_reader.Peek() == -1)
52 | {
53 | ReachedEnd = true;
54 | return false;
55 | }
56 |
57 | PreviousToken = CurrentToken;
58 | CurrentToken = _reader.Read();
59 | NextToken = _reader.Peek();
60 | Position++;
61 |
62 | return true;
63 | }
64 |
65 | public int Peek()
66 | {
67 | return _reader.Peek();
68 | }
69 |
70 | public void EatWhiteSpace()
71 | {
72 | while (true)
73 | {
74 | if (!Read())
75 | {
76 | break;
77 | }
78 | var current = (char)CurrentToken;
79 | if (!char.IsWhiteSpace(current))
80 | {
81 | break;
82 | }
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/DescriptionScriptHost.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Cake.Core;
5 | using Cake.Core.Scripting;
6 |
7 | namespace Cake.Host.Scripting
8 | {
9 | ///
10 | /// The script host used for showing task descriptions.
11 | ///
12 | public sealed class DescriptionScriptHost : ScriptHost
13 | {
14 | private readonly IConsole _console;
15 | private readonly Dictionary _descriptions;
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// The engine.
21 | /// The context.
22 | /// The console.
23 | public DescriptionScriptHost(ICakeEngine engine, ICakeContext context, IConsole console)
24 | : base(engine, context)
25 | {
26 | if (console == null)
27 | {
28 | throw new ArgumentNullException("console");
29 | }
30 | _console = console;
31 | _descriptions = new Dictionary(StringComparer.OrdinalIgnoreCase);
32 | }
33 |
34 | ///
35 | /// Runs the specified target.
36 | ///
37 | /// The target to run.
38 | /// The resulting report.
39 | public override CakeReport RunTarget(string target)
40 | {
41 | foreach (var task in Tasks)
42 | {
43 | _descriptions.Add(task.Name, task.Description);
44 | }
45 |
46 | _console.WriteLine();
47 | _console.WriteLine("{0,-30}{1}", "Task", "Description");
48 | _console.WriteLine(string.Concat(Enumerable.Range(0, 79).Select(s => "=")));
49 | foreach (var key in _descriptions.Keys)
50 | {
51 | _console.WriteLine("{0,-30}{1}", key, _descriptions[key]);
52 | }
53 |
54 | return null;
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/Cake.Host/CakeConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cake.Core;
3 |
4 | namespace Cake.Host
5 | {
6 | public sealed class CakeConsole : IConsole
7 | {
8 | ///
9 | /// Gets or sets the foreground color.
10 | ///
11 | /// The foreground color.
12 | public ConsoleColor ForegroundColor
13 | {
14 | get { return Console.ForegroundColor; }
15 | set { Console.ForegroundColor = value; }
16 | }
17 |
18 | ///
19 | /// Gets or sets the background color.
20 | ///
21 | /// The background color.
22 | public ConsoleColor BackgroundColor
23 | {
24 | get { return Console.BackgroundColor; }
25 | set { Console.BackgroundColor = value; }
26 | }
27 |
28 | ///
29 | /// Writes the text representation of the specified array of objects to the
30 | /// console output using the specified format information.
31 | ///
32 | /// A composite format string
33 | /// An array of objects to write using format.
34 | public void Write(string format, params object[] arg)
35 | {
36 | Console.Write(format, arg);
37 | }
38 |
39 | ///
40 | /// Writes the text representation of the specified array of objects, followed
41 | /// by the current line terminator, to the console output using the specified
42 | /// format information.
43 | ///
44 | /// A composite format string
45 | /// An array of objects to write using format.
46 | public void WriteLine(string format, params object[] arg)
47 | {
48 | Console.WriteLine(format, arg);
49 | }
50 |
51 | ///
52 | /// Sets the foreground and background console colors to their defaults.
53 | ///
54 | public void ResetColor()
55 | {
56 | Console.ResetColor();
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Aliases/ScheduleAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using Cake.Core;
3 | using Cake.Core.Annotations;
4 | using Cake.Core.Diagnostics;
5 |
6 | using FluentScheduler;
7 | using FluentScheduler.Model;
8 | #endregion
9 |
10 |
11 |
12 | namespace CakeBoss.Host
13 | {
14 | [CakeAliasCategory("CakeBoss")]
15 | [CakeNamespaceImport("FluentScheduler")]
16 | [CakeNamespaceImport("FluentScheduler.Model")]
17 | public static class ScheduleAliases
18 | {
19 | ///
20 | /// Starts the scheduled task manager
21 | ///
22 | /// The context.
23 | [CakeMethodAlias]
24 | [CakeAliasCategory("Schedule")]
25 | public static void StartSchedules(this ICakeContext context)
26 | {
27 | TaskRegistry instance = context.GetContainer().GetInstance();
28 | TaskManager.Initialize(instance);
29 |
30 | context.Log.Information("Scheduled tasks started.");
31 | }
32 |
33 | ///
34 | /// Stops the scheduled task manager
35 | ///
36 | /// The context.
37 | [CakeMethodAlias]
38 | [CakeAliasCategory("Schedule")]
39 | public static void StopSchedules(this ICakeContext context)
40 | {
41 | TaskManager.Stop();
42 |
43 | context.Log.Information("Scheduled tasks stopped.");
44 | }
45 |
46 |
47 |
48 | ///
49 | /// Adds a scheduled task to the task manager
50 | ///
51 | /// The context.
52 | /// The task you want to schedule.
53 | [CakeMethodAlias]
54 | [CakeAliasCategory("Schedule")]
55 | public static Schedule ScheduleTask(this ICakeContext context, string target)
56 | {
57 | context.Log.Information("Scheduling task '{0}'.", target);
58 |
59 | TaskRegistry instance = context.GetContainer().GetInstance();
60 | return instance.Schedule(target);
61 | }
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/src/Cake.Host/Arguments/ArgumentTokenizer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using System.Text;
4 |
5 | namespace Cake.Host.Arguments
6 | {
7 | public static class ArgumentTokenizer
8 | {
9 | public static IEnumerable Tokenize(string arguments)
10 | {
11 | return Tokenize(new StringReader(arguments));
12 | }
13 |
14 | private static IEnumerable Tokenize(StringReader reader)
15 | {
16 | while (reader.Peek() != -1)
17 | {
18 | var character = (char)reader.Peek();
19 | switch (character)
20 | {
21 | case '\"':
22 | yield return ReadQuote(reader);
23 | break;
24 | case ' ':
25 | reader.Read();
26 | break;
27 | default:
28 | yield return Read(reader);
29 | break;
30 | }
31 | }
32 | }
33 |
34 | private static string ReadQuote(StringReader reader)
35 | {
36 | var accumulator = new StringBuilder();
37 | accumulator.Append((char)reader.Read());
38 | while (reader.Peek() != -1)
39 | {
40 | var character = (char)reader.Peek();
41 | if (character == '\"')
42 | {
43 | accumulator.Append((char)reader.Read());
44 | break;
45 | }
46 | reader.Read();
47 | accumulator.Append(character);
48 | }
49 | return accumulator.ToString();
50 | }
51 |
52 | private static string Read(StringReader reader)
53 | {
54 | var accumulator = new StringBuilder();
55 | accumulator.Append((char)reader.Read());
56 | while (reader.Peek() != -1)
57 | {
58 | if ((char)reader.Peek() == ' ')
59 | {
60 | break;
61 | }
62 | accumulator.Append((char)reader.Read());
63 | }
64 | return accumulator.ToString();
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/src/Cake.Host/CakeArguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core;
4 |
5 | namespace Cake.Host
6 | {
7 | public sealed class CakeArguments : ICakeArguments
8 | {
9 | private readonly Dictionary _arguments;
10 |
11 | ///
12 | /// Gets the arguments.
13 | ///
14 | /// The arguments.
15 | public IReadOnlyDictionary Arguments
16 | {
17 | get { return _arguments; }
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public CakeArguments()
24 | {
25 | _arguments = new Dictionary(StringComparer.OrdinalIgnoreCase);
26 | }
27 |
28 | ///
29 | /// Initializes the argument list.
30 | ///
31 | /// The arguments.
32 | public void SetArguments(IDictionary arguments)
33 | {
34 | if (arguments == null)
35 | {
36 | throw new ArgumentNullException("arguments");
37 | }
38 | _arguments.Clear();
39 | foreach (var argument in arguments)
40 | {
41 | _arguments.Add(argument.Key, argument.Value);
42 | }
43 | }
44 |
45 | ///
46 | /// Determines whether or not the specified argument exist.
47 | ///
48 | /// The argument name.
49 | ///
50 | /// true if the argument exist; otherwise false.
51 | ///
52 | public bool HasArgument(string name)
53 | {
54 | return _arguments.ContainsKey(name);
55 | }
56 |
57 | ///
58 | /// Gets an argument.
59 | ///
60 | /// The argument name.
61 | /// The argument value.
62 | public string GetArgument(string name)
63 | {
64 | return _arguments.ContainsKey(name)
65 | ? _arguments[name] : null;
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/script/Release.cake:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | // ARGUMENTS
3 | //////////////////////////////////////////////////////////////////////
4 |
5 | var target = Argument("target", "Default");
6 | var server = System.Environment.MachineName.ToLower();
7 |
8 |
9 |
10 |
11 |
12 | //////////////////////////////////////////////////////////////////////
13 | // SERVICE TASKS
14 | //////////////////////////////////////////////////////////////////////
15 |
16 | Task("Start")
17 | .Description("Service Start.")
18 | .Does(() =>
19 | {
20 | Information("---Add Scheduled Tasks---");
21 | ScheduleTask("Deploy")
22 | .ToRunOnceIn(15).Seconds();
23 |
24 |
25 |
26 | Information("---Configure the agent---");
27 | ConfigureAgent(new AgentSettings()
28 | {
29 | Port = 8888,
30 |
31 | EnableTerminationCheck = false,
32 | EnableAPI = false,
33 | EnableScheduledTasks = true
34 | });
35 | });
36 |
37 | Task("Stop")
38 | .Description("Service Stop.")
39 | .Does(() =>
40 | {
41 |
42 | });
43 |
44 | Task("Startup")
45 | .Description("Server Startup.")
46 | .Does(() =>
47 | {
48 |
49 | });
50 |
51 | Task("Shutdown")
52 | .Description("Server Shutdown.")
53 | .Does(() =>
54 | {
55 |
56 | });
57 |
58 | Task("Terminate")
59 | .Description("AWS Instance Termination.")
60 | .Does(() =>
61 | {
62 |
63 | });
64 |
65 |
66 |
67 |
68 |
69 | //////////////////////////////////////////////////////////////////////
70 | // DEPLOY TASKS
71 | //////////////////////////////////////////////////////////////////////
72 |
73 | Task("Deploy")
74 | .Does(() =>
75 | {
76 | Information("---Example Deployment---");
77 | });
78 |
79 | Task("Update")
80 | .Does(() =>
81 | {
82 | Information("---Update Config---");
83 | });
84 |
85 |
86 |
87 |
88 |
89 | //////////////////////////////////////////////////////////////////////
90 | // TASK TARGETS
91 | //////////////////////////////////////////////////////////////////////
92 |
93 | Task("Default")
94 | .IsDependentOn("Start");
95 |
96 |
97 |
98 |
99 |
100 | ///////////////////////////////////////////////////////////////////////////////
101 | // EXECUTION
102 | ///////////////////////////////////////////////////////////////////////////////
103 |
104 | RunTarget(target);
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/Settings/RemoteSettings.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Cake.Core.IO;
6 | #endregion
7 |
8 |
9 |
10 | namespace Cake.CakeBoss
11 | {
12 | ///
13 | /// The settings used when running a remote target
14 | ///
15 | public class RemoteSettings
16 | {
17 | #region Fields (1)
18 | private string _Url;
19 | #endregion
20 |
21 |
22 |
23 |
24 |
25 | #region Constructor (1)
26 | ///
27 | /// Initializes a new instance of the class.
28 | ///
29 | public RemoteSettings()
30 | {
31 | this.Host = "localhost";
32 | this.Port = 8080;
33 |
34 | _Url = "";
35 | }
36 | #endregion
37 |
38 |
39 |
40 |
41 |
42 | #region Properties (5)
43 | ///
44 | /// Gets or sets the credentials to use when connecting
45 | ///
46 | public string Username { get; set; }
47 |
48 | ///
49 | /// Gets or sets the credentials to use when connecting
50 | ///
51 | public string Password { get; set; }
52 |
53 |
54 |
55 | ///
56 | /// Gets or sets the computer to connect to
57 | ///
58 | public string Host { get; set; }
59 |
60 | ///
61 | /// Gets or sets the remote port to connect on
62 | ///
63 | public int Port { get; set; }
64 |
65 | ///
66 | /// Gets or sets the full URI to connect to
67 | ///
68 | public string Url
69 | {
70 | set
71 | {
72 | _Url = value;
73 | }
74 | get
75 | {
76 | if (!String.IsNullOrEmpty(_Url))
77 | {
78 | return _Url;
79 | }
80 | else
81 | {
82 | return "http://" + this.Host + ":" + this.Port.ToString();
83 | }
84 | }
85 | }
86 | #endregion
87 | }
88 | }
--------------------------------------------------------------------------------
/src/Cake.Host/CakeReportPrinter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using Cake.Core;
6 |
7 | namespace Cake.Host
8 | {
9 | public sealed class CakeReportPrinter : ICakeReportPrinter
10 | {
11 | private readonly IConsole _console;
12 |
13 | public CakeReportPrinter(IConsole console)
14 | {
15 | _console = console;
16 | }
17 |
18 | public void Write(CakeReport report)
19 | {
20 | if (report == null)
21 | {
22 | throw new ArgumentNullException("report");
23 | }
24 |
25 | try
26 | {
27 | var maxTaskNameLength = 29;
28 | foreach (var item in report)
29 | {
30 | if (item.TaskName.Length > maxTaskNameLength)
31 | {
32 | maxTaskNameLength = item.TaskName.Length;
33 | }
34 | }
35 |
36 | maxTaskNameLength++;
37 | string lineFormat = "{0,-" + maxTaskNameLength + "}{1,-20}";
38 | _console.ForegroundColor = ConsoleColor.Green;
39 |
40 | // Write header.
41 | _console.WriteLine();
42 | _console.WriteLine(lineFormat, "Task", "Duration");
43 | _console.WriteLine(new string('-', 20 + maxTaskNameLength));
44 |
45 | // Write task status.
46 | foreach (var item in report)
47 | {
48 | _console.WriteLine(lineFormat, item.TaskName, FormatTime(item.Duration));
49 | }
50 |
51 | // Write footer.
52 | _console.WriteLine(new string('-', 20 + maxTaskNameLength));
53 | _console.WriteLine(lineFormat, "Total:", FormatTime(GetTotalTime(report)));
54 | }
55 | finally
56 | {
57 | _console.ResetColor();
58 | }
59 | }
60 |
61 | private static string FormatTime(TimeSpan time)
62 | {
63 | return time.ToString("c", CultureInfo.InvariantCulture);
64 | }
65 |
66 | private static TimeSpan GetTotalTime(IEnumerable entries)
67 | {
68 | return entries.Select(i => i.Duration)
69 | .Aggregate(TimeSpan.Zero, (t1, t2) => t1 + t2);
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Aliases/ApiAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Cake.Core;
5 | using Cake.Core.Annotations;
6 | using Cake.Core.Diagnostics;
7 |
8 | using Nancy.Hosting.Self;
9 |
10 | using CakeBoss.Host;
11 | #endregion
12 |
13 |
14 |
15 | namespace CakeBoss.Agent
16 | {
17 | [CakeAliasCategory("CakeBoss")]
18 | public static class ApiAliases
19 | {
20 | ///
21 | /// Starts the agent api
22 | ///
23 | /// The context.
24 | [CakeMethodAlias]
25 | [CakeAliasCategory("Api")]
26 | public static void StartApi(this ICakeContext context)
27 | {
28 | if (Program.Host == null)
29 | {
30 | HostSettings hostSettings = context.GetContainer().GetInstance();
31 |
32 | if (!String.IsNullOrEmpty(hostSettings.Url))
33 | {
34 | Program.Host = new NancyHost(new Uri(hostSettings.Url), new ServiceBootstrapper(), new HostConfiguration()
35 | {
36 | EnableClientCertificates = true,
37 |
38 | UrlReservations = new UrlReservations()
39 | {
40 | CreateAutomatically = true
41 | }
42 | });
43 |
44 | Program.Host.Start();
45 |
46 | context.Log.Information("Starting agent api on url '{0}'.", hostSettings.Url);
47 | }
48 | else
49 | {
50 | context.Log.Error("Invalid host url.");
51 | }
52 | }
53 | else
54 | {
55 | context.Log.Error("Agent api has already been configured.");
56 | }
57 | }
58 |
59 | ///
60 | /// Stops the agent Api
61 | ///
62 | /// The context.
63 | [CakeMethodAlias]
64 | [CakeAliasCategory("Api")]
65 | public static void StopApi(this ICakeContext context)
66 | {
67 | if (Program.Host != null)
68 | {
69 | Program.Host.Stop();
70 | Program.Host = null;
71 |
72 | context.Log.Information("Agent api stopped.");
73 | }
74 | else
75 | {
76 | context.Log.Error("Agent api is not running.");
77 | }
78 | }
79 | }
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/script/Test.cake:
--------------------------------------------------------------------------------
1 | #addin "Cake.Powershell"
2 |
3 | //////////////////////////////////////////////////////////////////////
4 | // ARGUMENTS
5 | //////////////////////////////////////////////////////////////////////
6 |
7 | var target = Argument("target", "Default");
8 |
9 |
10 |
11 |
12 |
13 | ///////////////////////////////////////////////////////////////////////////////
14 | // SERVICE EVENTS
15 | ///////////////////////////////////////////////////////////////////////////////
16 |
17 | Task("Start")
18 | .Does(() =>
19 | {
20 | Information("---Add Scheduled Tasks---");
21 | ScheduleTask("Timed")
22 | .ToRunOnceIn(15).Seconds();
23 |
24 |
25 |
26 | Information("---Start Agent---");
27 | ConfigureAgent(new AgentSettings()
28 | {
29 | Port = 8888,
30 |
31 | EnableTerminationCheck = true,
32 | EnableAPI = true,
33 | EnableScheduledTasks = true
34 | }.AddUser("Admin", "Password1"));
35 |
36 |
37 |
38 | Information("---Call API---");
39 | RunRemoteTarget("Remote", new RemoteSettings()
40 | {
41 | Username = "Admin",
42 | Password = "Password1",
43 | Port = 8888
44 | });
45 | });
46 |
47 | Task("Stop")
48 | .Does(() =>
49 | {
50 | Information("---Stop---");
51 | });
52 |
53 | Task("Update")
54 | .Does(() =>
55 | {
56 | Information("---Update Config---");
57 | });
58 |
59 |
60 |
61 |
62 |
63 | ///////////////////////////////////////////////////////////////////////////////
64 | // SPECIAL EVENTS
65 | ///////////////////////////////////////////////////////////////////////////////
66 |
67 | Task("Remote")
68 | .Does(() =>
69 | {
70 | Information("---Remote Webservice Call---");
71 | StartPowershellScript("Write-Host", args =>
72 | {
73 | args.AppendQuoted("Triggering remote deployment");
74 | });
75 | });
76 |
77 | Task("Timed")
78 | .Does(() =>
79 | {
80 | Information("---Timed Task Call---");
81 | UpdateConfig("../../../../script/Release.cake");
82 | });
83 |
84 |
85 |
86 |
87 | //////////////////////////////////////////////////////////////////////
88 | // TASK TARGETS
89 | //////////////////////////////////////////////////////////////////////
90 |
91 | Task("Default")
92 | .IsDependentOn("Start");
93 |
94 |
95 |
96 |
97 |
98 | ///////////////////////////////////////////////////////////////////////////////
99 | // EXECUTION
100 | ///////////////////////////////////////////////////////////////////////////////
101 |
102 | RunTarget(target);
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/MonoConsoleReportPrinter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Cake.Core.Diagnostics;
4 | using Cake.Core.IO;
5 | using Mono.CSharp;
6 |
7 | namespace Cake.Host.Scripting.Mono
8 | {
9 | public sealed class MonoConsoleReportPrinter : ReportPrinter
10 | {
11 | private readonly ICakeLog _log;
12 |
13 | public MonoConsoleReportPrinter(ICakeLog log)
14 | {
15 | _log = log;
16 | }
17 |
18 | public override void Print(AbstractMessage msg, bool showFullPath)
19 | {
20 | if (msg == null)
21 | {
22 | return;
23 | }
24 |
25 | var message = GetFormattedLogMessage(msg);
26 |
27 | if (msg.IsWarning)
28 | {
29 | _log.Warning(message);
30 | }
31 | else if (IsError(msg))
32 | {
33 | _log.Error(message);
34 | }
35 | else
36 | {
37 | _log.Verbose(message);
38 | }
39 | }
40 |
41 | private static string GetFormattedLogMessage(AbstractMessage message)
42 | {
43 | var path = GetSourcePath(message);
44 | var row = message.Location.Row;
45 | var column = message.Location.Column;
46 |
47 | return string.Format(
48 | CultureInfo.InvariantCulture,
49 | "{0} ({1},{2}): {3}",
50 | path.FullPath, row, column, message.Text);
51 | }
52 |
53 | private static FilePath GetSourcePath(AbstractMessage message)
54 | {
55 | string filename = null;
56 |
57 | try
58 | {
59 | if (message.Location.SourceFile != null && message.Location.SourceFile.Name != null)
60 | {
61 | filename = message.Location.SourceFile.Name;
62 | }
63 | }
64 | catch
65 | {
66 | // Fix for issue #298 (https://github.com/Cake.Host-build/Cake.Host/issues/298)
67 | // Not pretty but it should take care of the exception being thrown
68 | // in certain situations when accessing the SourceFile property.
69 | }
70 |
71 | return new FilePath(filename ?? "unknown.Cake.Host").GetFilename();
72 | }
73 |
74 | private static bool IsError(AbstractMessage message)
75 | {
76 | return message.MessageType != null &&
77 | message.MessageType.Equals("error", StringComparison.OrdinalIgnoreCase);
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/Stable/RoslynScriptSession.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using Cake.Core.Diagnostics;
5 | using Cake.Core.IO;
6 | using Cake.Core.Scripting;
7 |
8 | namespace Cake.Host.Scripting.Roslyn.Stable
9 | {
10 | public sealed class RoslynScriptSession : IScriptSession
11 | {
12 | private readonly global::Roslyn.Scripting.Session _roslynSession;
13 | private readonly ICakeLog _log;
14 | private readonly HashSet _importedNamespaces;
15 |
16 | public RoslynScriptSession(IScriptHost host, ICakeLog log)
17 | {
18 | if (host == null)
19 | {
20 | throw new ArgumentNullException("host");
21 | }
22 | if (log == null)
23 | {
24 | throw new ArgumentNullException("log");
25 | }
26 |
27 | var roslynScriptEngine = new global::Roslyn.Scripting.CSharp.ScriptEngine();
28 | _roslynSession = roslynScriptEngine.CreateSession(host, typeof(IScriptHost));
29 |
30 | _log = log;
31 | _importedNamespaces = new HashSet();
32 | }
33 |
34 | public void AddReference(FilePath path)
35 | {
36 | if (path == null)
37 | {
38 | throw new ArgumentNullException("path");
39 | }
40 | _log.Debug("Adding reference to {0}...", path.GetFilename().FullPath);
41 | _roslynSession.AddReference(path.FullPath);
42 | }
43 |
44 | public void AddReference(Assembly assembly)
45 | {
46 | if (assembly == null)
47 | {
48 | throw new ArgumentNullException("assembly");
49 | }
50 | _log.Debug("Adding reference to {0}...", new FilePath(assembly.Location).GetFilename().FullPath);
51 | _roslynSession.AddReference(assembly);
52 | }
53 |
54 | public void ImportNamespace(string @namespace)
55 | {
56 | if (!_importedNamespaces.Contains(@namespace))
57 | {
58 | _log.Debug("Importing namespace {0}...", @namespace);
59 | _roslynSession.ImportNamespace(@namespace);
60 | _importedNamespaces.Add(@namespace);
61 | }
62 | }
63 |
64 | public void Execute(Script script)
65 | {
66 | // Generate the script code.
67 | var generator = new RoslynCodeGenerator();
68 | var code = generator.Generate(script);
69 |
70 | _log.Verbose("Compiling build script...");
71 | _roslynSession.Execute(code);
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/src/Cake.Host/CakeOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core.Diagnostics;
4 | using Cake.Core.IO;
5 |
6 | namespace Cake.Host
7 | {
8 | ///
9 | /// The options that determines how the application should behave.
10 | ///
11 | public sealed class CakeOptions
12 | {
13 | private readonly Dictionary _arguments;
14 |
15 | ///
16 | /// Gets or sets the output verbosity.
17 | ///
18 | /// The output verbosity.
19 | public Verbosity Verbosity { get; set; }
20 |
21 | ///
22 | /// Gets or sets the build script.
23 | ///
24 | /// The build script.
25 | public FilePath Script { get; set; }
26 |
27 | ///
28 | /// Gets the script arguments.
29 | ///
30 | /// The script arguments.
31 | public IDictionary Arguments
32 | {
33 | get { return _arguments; }
34 | }
35 |
36 | ///
37 | /// Gets or sets a value indicating whether to show task descriptions.
38 | ///
39 | ///
40 | /// true to show task description; otherwise, false.
41 | ///
42 | public bool ShowDescription { get; set; }
43 |
44 | ///
45 | /// Gets or sets a value indicating whether to perform a dry run.
46 | ///
47 | ///
48 | /// true if a dry run should be performed; otherwise, false.
49 | ///
50 | public bool PerformDryRun { get; set; }
51 |
52 | ///
53 | /// Gets or sets a value indicating whether to show help.
54 | ///
55 | ///
56 | /// true to show help; otherwise, false.
57 | ///
58 | public bool ShowHelp { get; set; }
59 |
60 | ///
61 | /// Gets or sets a value indicating whether to show version information.
62 | ///
63 | ///
64 | /// true to show version information; otherwise, false.
65 | ///
66 | public bool ShowVersion { get; set; }
67 |
68 | ///
69 | /// Initializes a new instance of the class.
70 | ///
71 | public CakeOptions()
72 | {
73 | _arguments = new Dictionary(StringComparer.OrdinalIgnoreCase);
74 |
75 | Verbosity = Verbosity.Normal;
76 | ShowDescription = false;
77 | ShowHelp = false;
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/Nightly/RoslynNightlyScriptSession.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Cake.Core.Diagnostics;
6 | using Cake.Core.IO;
7 | using Cake.Core.Scripting;
8 |
9 | namespace Cake.Host.Scripting.Roslyn.Nightly
10 | {
11 | public sealed class RoslynNightlyScriptSession : IScriptSession
12 | {
13 | private readonly IScriptHost _host;
14 | private readonly ICakeLog _log;
15 | private readonly HashSet _referencePaths;
16 | private readonly HashSet _references;
17 | private readonly HashSet _namespaces;
18 |
19 | public RoslynNightlyScriptSession(IScriptHost host, ICakeLog log)
20 | {
21 | _host = host;
22 | _log = log;
23 |
24 | _referencePaths = new HashSet(PathComparer.Default);
25 | _references = new HashSet();
26 | _namespaces = new HashSet(StringComparer.Ordinal);
27 | }
28 |
29 | public void AddReference(FilePath path)
30 | {
31 | if (path == null)
32 | {
33 | throw new ArgumentNullException("path");
34 | }
35 | _log.Debug("Adding reference to {0}...", path.GetFilename().FullPath);
36 | _referencePaths.Add(path);
37 | }
38 |
39 | public void AddReference(Assembly assembly)
40 | {
41 | if (assembly == null)
42 | {
43 | throw new ArgumentNullException("assembly");
44 | }
45 | _log.Debug("Adding reference to {0}...", new FilePath(assembly.Location).GetFilename().FullPath);
46 | _references.Add(assembly);
47 | }
48 |
49 | public void ImportNamespace(string @namespace)
50 | {
51 | if (!_namespaces.Contains(@namespace))
52 | {
53 | _log.Debug("Importing namespace {0}...", @namespace);
54 | _namespaces.Add(@namespace);
55 | }
56 | }
57 |
58 | public void Execute(Script script)
59 | {
60 | // Generate the script code.
61 | var generator = new RoslynCodeGenerator();
62 | var code = generator.Generate(script);
63 |
64 | // Create the script options dynamically.
65 | var options = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default
66 | .AddNamespaces(_namespaces)
67 | .AddReferences(_references)
68 | .AddReferences(_referencePaths.Select(r => r.FullPath));
69 |
70 | _log.Verbose("Compiling build script...");
71 | Microsoft.CodeAnalysis.Scripting.CSharp.CSharpScript.Eval(code, options, _host);
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Service/TerminationService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Timers;
4 | using System.Net;
5 | #endregion
6 |
7 |
8 |
9 | namespace CakeBoss.Agent
10 | {
11 | public class TerminationService : ITerminationService
12 | {
13 | #region Fields (3)
14 | private IAgentService _Agent;
15 |
16 | private Timer _Timer;
17 | private object _Lock;
18 | #endregion
19 |
20 |
21 |
22 |
23 |
24 | #region Constructor (1)
25 | public TerminationService(IAgentService agent)
26 | {
27 | if (agent == null)
28 | {
29 | throw new ArgumentNullException("agent");
30 | }
31 |
32 | _Agent = agent;
33 |
34 | _Timer = new Timer(5000);
35 | _Timer.Elapsed += this.Tick;
36 |
37 | _Lock = new Object();
38 | }
39 | #endregion
40 |
41 |
42 |
43 |
44 |
45 | #region Properties (2)
46 | public bool Enabled
47 | {
48 | get
49 | {
50 | return _Timer.Enabled;
51 | }
52 | set
53 | {
54 | _Timer.Enabled = value;
55 | }
56 | }
57 |
58 | public int Interval
59 | {
60 | get
61 | {
62 | return Convert.ToInt32(_Timer.Interval);
63 | }
64 | set
65 | {
66 | _Timer.Interval = value;
67 | }
68 | }
69 | #endregion
70 |
71 |
72 |
73 |
74 |
75 | #region Functions (2)
76 | public void Tick(object sender, EventArgs args)
77 | {
78 | lock (_Lock)
79 | {
80 | if (!_Timer.Enabled)
81 | {
82 | return;
83 | }
84 |
85 | if (this.Termination())
86 | {
87 | _Timer.Stop();
88 | _Agent.Terminate();
89 | }
90 | }
91 | }
92 |
93 | public bool Termination()
94 | {
95 | try
96 | {
97 | string value = new WebClient().DownloadString(new Uri("http://169.254.169.254/latest/meta-data/spot/termination-time"));
98 | return !String.IsNullOrEmpty(value);
99 | }
100 | catch
101 | {
102 | return false;
103 | }
104 | }
105 | #endregion
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/Cake.Host/Commands/VersionCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using Cake.Core;
3 |
4 | namespace Cake.Host.Commands
5 | {
6 | ///
7 | /// A command that shows version information.
8 | ///
9 | public sealed class VersionCommand : ICommand
10 | {
11 | private readonly IConsole _console;
12 |
13 | // Delegate factory used by Autofac.
14 | public delegate VersionCommand Factory();
15 |
16 | public VersionCommand(IConsole console)
17 | {
18 | _console = console;
19 | }
20 |
21 | public bool Execute(CakeOptions options)
22 | {
23 | _console.WriteLine();
24 | _console.WriteLine(@" +## #;;'");
25 | _console.WriteLine(@" #;;# .+;;;;+,");
26 | _console.WriteLine(@" '+;;#;,+';;;;;'#.");
27 | _console.WriteLine(@" ++'''';;;;;;;;;;# ;#;");
28 | _console.WriteLine(@" ##';;;;++'+#;;;;;'. `#:");
29 | _console.WriteLine(@" ;# '+'';;;;;;;;;'#` #.");
30 | _console.WriteLine(@" `#, .'++;;;;;':..........#");
31 | _console.WriteLine(@" '+ `.........';;;;':.........#");
32 | _console.WriteLine(@" #..................+;;;;;':........#");
33 | _console.WriteLine(@" #..................#';;;;;'+''''''.#");
34 | _console.WriteLine(@" #.......,:;''''''''##';;;;;'+'''''#,");
35 | _console.WriteLine(@" #''''''''''''''''''###';;;;;;+''''#");
36 | _console.WriteLine(@" #''''''''''''''''''####';;;;;;#'''#");
37 | _console.WriteLine(@" #''''''''''''''''''#####';;;;;;#''#");
38 | _console.WriteLine(@" #''''''''''''''''''######';;;;;;#'#");
39 | _console.WriteLine(@" #''''''''''''''''''#######';;;;;;##");
40 | _console.WriteLine(@" #''''''''''''''''''########';;;;;;#");
41 | _console.WriteLine(@" #''''''''''''++####+;#######';;;;;;#");
42 | _console.WriteLine(@" #+####':,` ,#####';;;;;;'");
43 | _console.WriteLine(@" +##'''''+.");
44 | _console.WriteLine(@" ___ _ ___ _ _ _ ");
45 | _console.WriteLine(@" / __\__ _| | _____ / __\_ _(_) | __| |");
46 | _console.WriteLine(@" / / / _` | |/ / _ \/__\// | | | | |/ _` |");
47 | _console.WriteLine(@"/ /___ (_| | < __/ \/ \ |_| | | | (_| |");
48 | _console.WriteLine(@"\____/\__,_|_|\_\___\_____/\__,_|_|_|\__,_|");
49 | _console.WriteLine();
50 | _console.WriteLine(@" Version {0}", GetVersion());
51 | _console.WriteLine();
52 |
53 | return true;
54 | }
55 |
56 | private static string GetVersion()
57 | {
58 | var assembly = typeof(CakeApplication).Assembly;
59 | return FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion;
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Host/ScriptConventions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Cake.Core.IO;
6 | using Cake.Core.Scripting;
7 |
8 | namespace CakeBoss.Host
9 | {
10 | ///
11 | /// The script conventions used by Cake.
12 | ///
13 | public sealed class ScriptConventions : IScriptConventions
14 | {
15 | private readonly IFileSystem _fileSystem;
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// The file system.
21 | public ScriptConventions(IFileSystem fileSystem)
22 | {
23 | _fileSystem = fileSystem;
24 | }
25 |
26 | ///
27 | /// Gets the default namespaces.
28 | ///
29 | /// A list containing all default namespaces.
30 | public IReadOnlyList GetDefaultNamespaces()
31 | {
32 | return new List
33 | {
34 | "System", "System.Collections.Generic", "System.Linq",
35 | "System.Text", "System.Threading.Tasks", "System.IO",
36 | "Cake.Core", "Cake.Core.IO", "Cake.Core.Scripting", "Cake.Core.Diagnostics",
37 | "CakeBoss.Host", "CakeBoss.Agent", "Cake.CakeBoss",
38 | "FluentScheduler.Model"
39 | };
40 | }
41 |
42 | ///
43 | /// Gets the default assemblies.
44 | ///
45 | /// The root to where to find Cake related assemblies.
46 | /// A list containing all default assemblies.
47 | public IReadOnlyList GetDefaultAssemblies(DirectoryPath root)
48 | {
49 | // Prepare the default assemblies.
50 | var defaultAssemblies = new List
51 | {
52 | typeof(Action).Assembly, // mscorlib
53 | typeof(Uri).Assembly, // System
54 | typeof(IQueryable).Assembly, // System.Core
55 | typeof(System.Data.DataTable).Assembly, // System.Data
56 | typeof(System.Xml.XmlReader).Assembly, // System.Xml
57 | typeof(System.Xml.Linq.XDocument).Assembly, // System.Xml.Linq
58 | };
59 |
60 | // Load other Cake-related assemblies that we need.
61 | var assemblyDirectory = _fileSystem.GetDirectory(root);
62 | var patterns = new[] { "Cake.Core.dll", "Cake.Common.dll", "CakeBoss.Host.dll", "CakeBoss.Agent.exe", "Cake.CakeBoss.dll", "FluentScheduler.dll" };
63 | foreach (var pattern in patterns)
64 | {
65 | var cakeAssemblies = assemblyDirectory.GetFiles(pattern, SearchScope.Current);
66 | foreach (var cakeAssembly in cakeAssemblies)
67 | {
68 | var assembly = Assembly.LoadFrom(cakeAssembly.Path.FullPath);
69 | defaultAssemblies.Add(assembly);
70 | }
71 | }
72 |
73 | // Return the assemblies.
74 | return defaultAssemblies;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Aliases/AgentAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Cake.Core;
5 | using Cake.Core.IO;
6 | using Cake.Core.Annotations;
7 | using Cake.Core.Diagnostics;
8 | using Cake.Common.IO;
9 |
10 | using LightInject;
11 | using Nancy.Hosting.Self;
12 |
13 | using CakeBoss.Host;
14 | #endregion
15 |
16 |
17 |
18 | namespace CakeBoss.Agent
19 | {
20 | [CakeAliasCategory("CakeBoss")]
21 | public static class AgentAliases
22 | {
23 | ///
24 | /// Configures the agent using the specified information.
25 | ///
26 | /// The context.
27 | /// The agent settings.
28 | [CakeMethodAlias]
29 | [CakeAliasCategory("Agent")]
30 | public static void ConfigureAgent(this ICakeContext context, AgentSettings settings)
31 | {
32 | if (settings == null)
33 | {
34 | throw new ArgumentNullException("settings");
35 | }
36 |
37 |
38 |
39 | //Configure
40 | context.ConfigureHost(settings);
41 |
42 |
43 |
44 | //Start
45 | if (settings.EnableTerminationCheck)
46 | {
47 | context.StartTerminationCheck();
48 | }
49 |
50 | if (settings.EnableAPI)
51 | {
52 | context.StartApi();
53 | }
54 |
55 | if (settings.EnableScheduledTasks)
56 | {
57 | context.StartSchedules();
58 | }
59 | }
60 |
61 |
62 |
63 | ///
64 | /// reloads the agent from the existing config file
65 | ///
66 | /// The context.
67 | /// The path to the new config file.
68 | [CakeMethodAlias]
69 | [CakeAliasCategory("Agent")]
70 | public static void ReconfigureAgent(this ICakeContext context, FilePath path)
71 | {
72 | // Update config file
73 | context.CopyFile(path, FilePath.FromString("./CakeBoss.Agent.cake"));
74 | context.Log.Information("Config file updated.");
75 |
76 | context.RestartAgent();
77 | }
78 |
79 | /// r
80 | /// Reloads the agent from the existing config file
81 | ///
82 | /// The context.
83 | [CakeMethodAlias]
84 | [CakeAliasCategory("Agent")]
85 | public static void RestartAgent(this ICakeContext context)
86 | {
87 | // Stop services
88 | context.StartTerminationCheck();
89 | context.StopSchedules();
90 | context.StopApi();
91 |
92 | // Clear all register references
93 | Program.Container = Program.CreateContainer();
94 |
95 | // Restart the agent
96 | IAgentService service = context.GetContainer().GetInstance();
97 | service.RunTarget("Start", true);
98 | context.Log.Information("Cake engine reloaded.");
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/CakeBuildLog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Core;
4 | using Cake.Core.Diagnostics;
5 | using Cake.Host.Diagnostics.Formatting;
6 |
7 | namespace Cake.Host.Diagnostics
8 | {
9 | public sealed class CakeBuildLog : IVerbosityAwareLog
10 | {
11 | private readonly IConsole _console;
12 | private readonly object _lock;
13 | private readonly IDictionary _palettes;
14 |
15 | public Verbosity Verbosity { get; private set; }
16 |
17 | public CakeBuildLog(IConsole console, Verbosity verbosity = Verbosity.Normal)
18 | {
19 | _console = console;
20 | _lock = new object();
21 | _palettes = CreatePalette();
22 | Verbosity = verbosity;
23 | }
24 |
25 | public void Write(Verbosity verbosity, LogLevel level, string format, params object[] args)
26 | {
27 | if (verbosity > Verbosity)
28 | {
29 | return;
30 | }
31 | lock (_lock)
32 | {
33 | try
34 | {
35 | var palette = _palettes[level];
36 | var tokens = FormatParser.Parse(format);
37 | foreach (var token in tokens)
38 | {
39 | SetPalette(token, palette);
40 | _console.Write("{0}", token.Render(args));
41 | }
42 | }
43 | finally
44 | {
45 | _console.ResetColor();
46 | _console.WriteLine();
47 | }
48 | }
49 | }
50 |
51 | public void SetVerbosity(Verbosity verbosity)
52 | {
53 | Verbosity = verbosity;
54 | }
55 |
56 | private void SetPalette(FormatToken token, ConsolePalette palette)
57 | {
58 | var property = token as PropertyToken;
59 | if (property != null)
60 | {
61 | _console.BackgroundColor = palette.ArgumentBackground;
62 | _console.ForegroundColor = palette.ArgumentForeground;
63 | }
64 | else
65 | {
66 | _console.BackgroundColor = palette.Background;
67 | _console.ForegroundColor = palette.Foreground;
68 | }
69 | }
70 |
71 | private IDictionary CreatePalette()
72 | {
73 | var background = _console.BackgroundColor;
74 | var palette = new Dictionary
75 | {
76 | { LogLevel.Error, new ConsolePalette(ConsoleColor.DarkRed, ConsoleColor.White, ConsoleColor.Red, ConsoleColor.White) },
77 | { LogLevel.Warning, new ConsolePalette(background, ConsoleColor.Yellow, background, ConsoleColor.Yellow) },
78 | { LogLevel.Information, new ConsolePalette(background, ConsoleColor.White, ConsoleColor.DarkBlue, ConsoleColor.White) },
79 | { LogLevel.Verbose, new ConsolePalette(background, ConsoleColor.Gray, background, ConsoleColor.White) },
80 | { LogLevel.Debug, new ConsolePalette(background, ConsoleColor.DarkGray, background, ConsoleColor.Gray) }
81 | };
82 | return palette;
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/Cake.CakeBoss.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2}
8 | Library
9 | Properties
10 | Cake.CakeBoss
11 | Cake.CakeBoss
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | bin\Debug\Cake.CakeBoss.xml
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | bin\Release\Cake.CakeBoss.xml
34 |
35 |
36 |
37 | ..\packages\Cake.Core.0.6.4\lib\net45\Cake.Core.dll
38 | True
39 |
40 |
41 | ..\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll
42 | True
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Properties\SolutionInfo.cs
57 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/MonoCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text;
3 | using Cake.Core.Scripting;
4 | using Cake.Core.Scripting.CodeGen;
5 | using Cake.Host.Scripting.Mono.CodeGen.Parsing;
6 |
7 | namespace Cake.Host.Scripting.Mono.CodeGen
8 | {
9 | public sealed class MonoCodeGenerator
10 | {
11 | public static string Generate(Script script)
12 | {
13 | // Process the script.
14 | IReadOnlyList blocks;
15 | script = MonoScriptProcessor.Process(script, out blocks);
16 |
17 | var code = new StringBuilder();
18 |
19 | if (script.UsingAliasDirectives.Count > 0)
20 | {
21 | foreach (var usingAliasDirective in script.UsingAliasDirectives)
22 | {
23 | code.AppendLine(usingAliasDirective);
24 | }
25 | code.AppendLine();
26 | }
27 |
28 | code.AppendLine("public class CakeBuildScriptImpl");
29 | code.AppendLine("{");
30 | code.AppendLine(" public CakeBuildScriptImpl (IScriptHost scriptHost)");
31 | code.AppendLine(" {");
32 | code.AppendLine(" ScriptHost = scriptHost;");
33 | code.AppendLine(" }");
34 | code.AppendLine();
35 | code.AppendLine(GetAliasCode(script));
36 | code.AppendLine();
37 | code.AppendLine(GetScriptHostProxy());
38 | code.AppendLine();
39 |
40 | foreach (var block in blocks)
41 | {
42 | code.AppendLine(block.Content);
43 | code.AppendLine();
44 | }
45 |
46 | code.AppendLine(" public void Execute ()");
47 | code.AppendLine(" {");
48 |
49 | code.AppendLine(string.Join("\n", script.Lines));
50 | code.AppendLine();
51 | code.AppendLine(" }");
52 | code.AppendLine("}");
53 |
54 | return code.ToString();
55 | }
56 |
57 | private static string GetAliasCode(Script context)
58 | {
59 | var result = new List();
60 | foreach (var alias in context.Aliases)
61 | {
62 | result.Add(alias.Type == ScriptAliasType.Method
63 | ? MethodAliasGenerator.Generate(alias.Method)
64 | : PropertyAliasGenerator.Generate(alias.Method));
65 | }
66 | return string.Join("\r\n", result);
67 | }
68 |
69 | private static string GetScriptHostProxy()
70 | {
71 | // TODO: Generate this from interface.
72 | var rules = new[]
73 | {
74 | "IScriptHost ScriptHost { get; set; }",
75 | "ICakeContext Context { get { return ScriptHost.Context; } }",
76 | "IReadOnlyList Tasks { get { return ScriptHost.Tasks; } }",
77 | "CakeTaskBuilder Task(string name) { return ScriptHost.Task (name); }",
78 | "void Setup (Action action) { ScriptHost.Setup (action); }",
79 | "void Teardown(Action action) { ScriptHost.Teardown (action); }",
80 | "CakeReport RunTarget(string target) { return ScriptHost.RunTarget (target); }"
81 | };
82 |
83 | return " " + string.Join("\r\n ", rules);
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/src/Cake.CakeBoss/Aliases/AgentAliases.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Net;
4 |
5 | using Cake.Core;
6 | using Cake.Core.Annotations;
7 | using Cake.Core.Diagnostics;
8 |
9 | using RestSharp;
10 | using RestSharp.Authenticators;
11 | #endregion
12 |
13 |
14 |
15 | namespace Cake.CakeBoss
16 | {
17 | ///
18 | /// Contains Cake aliases for calling CakeBoss agents
19 | ///
20 | [CakeAliasCategory("CakeBoss")]
21 | public static class AgentAliases
22 | {
23 | ///
24 | /// Run a target on a remote CakeBoss agent
25 | ///
26 | /// The cake context.
27 | /// The script target to run.
28 | /// The information about the remote target to run.
29 | /// If the target ran successfully
30 | [CakeMethodAlias]
31 | public static bool RunRemoteTarget(this ICakeContext context, string target, RemoteSettings settings)
32 | {
33 | if (String.IsNullOrEmpty(target))
34 | {
35 | throw new ArgumentNullException("target");
36 | }
37 |
38 | if (settings == null)
39 | {
40 | throw new ArgumentNullException("settings");
41 | }
42 |
43 | if (String.IsNullOrEmpty(settings.Username))
44 | {
45 | throw new ArgumentNullException("settings.Username");
46 | }
47 | if (String.IsNullOrEmpty(settings.Password))
48 | {
49 | throw new ArgumentNullException("settings.Password");
50 | }
51 |
52 | if (String.IsNullOrEmpty(settings.Url))
53 | {
54 | throw new ArgumentNullException("settings.Url");
55 | }
56 |
57 |
58 |
59 | //Client
60 | string url = settings.Url;
61 |
62 | if (!url.EndsWith("/agent"))
63 | {
64 | if (!url.EndsWith("/"))
65 | {
66 | url += "/";
67 | }
68 |
69 | url += "agent";
70 | }
71 |
72 | RestClient client = new RestClient(url);
73 | client.Authenticator = new HttpBasicAuthenticator(settings.Username, settings.Password);
74 |
75 |
76 |
77 | //Request
78 | RestRequest request = new RestRequest("/run/" + target, Method.POST);
79 | IRestResponse response = client.Execute(request);
80 |
81 | if (response.StatusCode == HttpStatusCode.OK)
82 | {
83 | context.Log.Information("Target {0} ran on agent {1}.", target, url);
84 | return true;
85 | }
86 | else if (response.StatusCode == HttpStatusCode.Unauthorized)
87 | {
88 | context.Log.Error("Unable to authorise. Check the username / password.");
89 | }
90 | else if (response.ErrorMessage == "Unable to connect to the remote server")
91 | {
92 | context.Log.Error("Unable to connect. Check the url for the remote host {1}.", target, url);
93 | }
94 | else
95 | {
96 | context.Log.Error(response.ErrorMessage);
97 | }
98 |
99 | return false;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Service/AgentService.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Cake.Core;
6 | using Cake.Host.Scripting;
7 |
8 | using CakeBoss.Host;
9 | #endregion
10 |
11 |
12 |
13 | namespace CakeBoss.Agent
14 | {
15 | public class AgentService : IAgentService
16 | {
17 | #region Fields (2)
18 | private HostApplication _Application;
19 | private BuildScriptHost _Host;
20 | #endregion
21 |
22 |
23 |
24 |
25 |
26 | #region Constructor (1)
27 | public AgentService(HostApplication application, BuildScriptHost host)
28 | {
29 | if (application == null)
30 | {
31 | throw new ArgumentNullException("application");
32 | }
33 | if (host == null)
34 | {
35 | throw new ArgumentNullException("host");
36 | }
37 |
38 | _Application = application;
39 | _Host = host;
40 | }
41 | #endregion
42 |
43 |
44 |
45 |
46 |
47 | #region Properties (1)
48 | public string CurrentTask { get; set; }
49 | #endregion
50 |
51 |
52 |
53 |
54 |
55 | #region Functions (7)
56 | //Events
57 | public void Start(IDictionary arguments)
58 | {
59 | string target = UptimeUtils.IsStartup() ? "Startup" : "Start";
60 |
61 | if ((arguments != null) && arguments.ContainsKey("target") && !String.IsNullOrWhiteSpace(arguments["target"].ToString()))
62 | {
63 | target = arguments["target"].ToString();
64 | }
65 |
66 | this.RunTarget(target, true);
67 | }
68 |
69 | public void Stop()
70 | {
71 | this.RunTarget("Stop", false);
72 | }
73 |
74 | public void Shutdown()
75 | {
76 | this.RunTarget("Shutdown", false);
77 | }
78 |
79 | public void Terminate()
80 | {
81 | this.RunTarget("Terminate", false);
82 | }
83 |
84 |
85 |
86 | //Run
87 | private IList GetArgs(string target)
88 | {
89 | var args = new List();
90 |
91 | args.Add(@"./CakeBoss.Agent.cake");
92 |
93 | if (!String.IsNullOrEmpty(target))
94 | {
95 | args.Add("-target=" + target);
96 | }
97 |
98 | if (Type.GetType("Mono.Runtime") != null)
99 | {
100 | args.Add("-mono");
101 | }
102 |
103 | args.Add("-experimental=true");
104 | args.Add("-verbosity=verbose");
105 |
106 | return args;
107 | }
108 |
109 | public bool RunTarget(string target, bool load)
110 | {
111 | this.CurrentTask = target;
112 | bool result;
113 |
114 | if (load)
115 | {
116 | IList args = this.GetArgs(target);
117 |
118 | result = _Application.Run(args);
119 | }
120 | else
121 | {
122 | CakeReport report = _Host.RunTarget(target);
123 |
124 | result = (report != null && !report.IsEmpty);
125 | }
126 |
127 | this.CurrentTask = "";
128 | return result;
129 | }
130 | #endregion
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/Cake.Host/NuGet/NuGetVersionUtilityAdapter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.Versioning;
5 | using Cake.Core.IO.NuGet;
6 | using Cake.Core.IO.NuGet.Parsing;
7 | using NuGet;
8 | using IFrameworkTargetable = Cake.Core.IO.NuGet.IFrameworkTargetable;
9 |
10 | namespace Cake.Host.NuGet
11 | {
12 | ///
13 | /// Adapts NuGet's to ,
14 | /// .
15 | ///
16 | public sealed class NuGetVersionUtilityAdapter : INuGetFrameworkCompatibilityFilter, IFrameworkNameParser
17 | {
18 | ///
19 | /// This function tries to normalize a string that represents framework version names
20 | /// (the name of a framework version-specific folder in a nuget package, i.e., "net451" or "net35") into
21 | /// something a framework name that the package manager understands.
22 | ///
23 | /// value to be parsed.
24 | ///
25 | /// A FrameworkName instance corresponding with the provided frameworkName token.
26 | /// When parsing is unsuccessful, returns a FrameworkName with an Identifier property of "Unsupported."
27 | ///
28 | /// when frameworkName is null.
29 | public FrameworkName ParseFrameworkName(string frameworkName)
30 | {
31 | if (frameworkName == null)
32 | {
33 | throw new ArgumentNullException("frameworkName");
34 | }
35 |
36 | return VersionUtility.ParseFrameworkName(frameworkName);
37 | }
38 |
39 | ///
40 | /// Filters the provided list of items, returning only those items compatible with the given project framework.
41 | ///
42 | /// the type of items being filtered
43 | /// The project framework.
44 | /// The items.
45 | /// The compatible items. Empty if try is unsuccessful.
46 | ///
47 | /// projectFramework or items
48 | ///
49 | public IEnumerable GetCompatibleItems(FrameworkName projectFramework, IEnumerable items)
50 | where T : IFrameworkTargetable
51 | {
52 | if (projectFramework == null)
53 | {
54 | throw new ArgumentNullException("projectFramework");
55 | }
56 | if (items == null)
57 | {
58 | throw new ArgumentNullException("items");
59 | }
60 |
61 | var nugetItems = items.Select(item => new FrameworkTargetableWrapper(item)).ToArray();
62 | IEnumerable> compatibleNugetItems;
63 | if (VersionUtility.TryGetCompatibleItems(projectFramework, nugetItems, out compatibleNugetItems))
64 | {
65 | return compatibleNugetItems.Select(item => item.WrappedItem);
66 | }
67 |
68 | return Enumerable.Empty();
69 | }
70 |
71 | private class FrameworkTargetableWrapper : global::NuGet.IFrameworkTargetable
72 | where T : IFrameworkTargetable
73 | {
74 | private readonly T _inner;
75 |
76 | public FrameworkTargetableWrapper(T inner)
77 | {
78 | _inner = inner;
79 | }
80 |
81 | public T WrappedItem
82 | {
83 | get { return _inner; }
84 | }
85 |
86 | public IEnumerable SupportedFrameworks
87 | {
88 | get { return _inner.SupportedFrameworks; }
89 | }
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Agent/Program.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System.IO;
3 | using System.Diagnostics;
4 | using System.Collections.Generic;
5 |
6 | using Topshelf;
7 |
8 | using Serilog;
9 | using Serilog.Events;
10 |
11 | using LightInject;
12 | using Nancy.Hosting.Self;
13 |
14 | using CakeBoss.Host;
15 | #endregion
16 |
17 |
18 |
19 | namespace CakeBoss.Agent
20 | {
21 | class Program
22 | {
23 | #region Fields (2)
24 | public static IServiceContainer Container = null;
25 | public static NancyHost Host = null;
26 | #endregion
27 |
28 |
29 |
30 |
31 | static void Main(string[] args)
32 | {
33 | //Logging
34 | string logFile = @"./Logs/CakeBoss.Agent-{Date}.log";
35 |
36 | if (!Debugger.IsAttached && Directory.Exists("C:/Logs/CakeBoss/"))
37 | {
38 | logFile = @"C:/Logs/CakeBoss/Agent-{Date}.log";
39 | }
40 |
41 | Log.Logger = new LoggerConfiguration()
42 | .WriteTo.RollingFile(logFile)
43 | .WriteTo.ColoredConsole()
44 | .MinimumLevel.Verbose()
45 | .Filter.ByExcluding((LogEvent log) =>
46 | {
47 | return log.MessageTemplate.Text.Contains("Configuration Result:")
48 | && log.Properties.Count > 0
49 | && log.Properties["0"].ToString().Contains("[Success] Name CakeBoss.Agent");
50 | })
51 | .CreateLogger();
52 |
53 |
54 |
55 | //Container
56 | Program.Container = Program.CreateContainer();
57 |
58 |
59 |
60 | //TopShelf
61 | HostFactory.Run(x =>
62 | {
63 | //CommandLine Parameters
64 | IDictionary arguments = x.SelectPlatform(p => p
65 | .AddStringParameter("target"));
66 |
67 |
68 |
69 | //Methods
70 | x.Service(s =>
71 | {
72 | s.ConstructUsing(name => Program.Container.GetInstance());
73 |
74 | s.WhenStarted(ser => ser.Start(arguments));
75 | s.WhenStopped(ser => ser.Stop());
76 | s.WhenShutdown(ser => ser.Shutdown());
77 | });
78 |
79 |
80 |
81 | //Settings
82 | x.StartAutomatically();
83 | x.EnableShutdown();
84 |
85 | x.RunAsNetworkService();
86 |
87 | x.SetDescription("Cake scripting agent for automating deployment tasks");
88 | x.SetDisplayName("CakeBoss - Agent");
89 | x.SetServiceName("CakeBoss.Agent");
90 |
91 | x.UseSerilog(Log.Logger);
92 |
93 |
94 |
95 | //Recovery
96 | x.EnableServiceRecovery(r =>
97 | {
98 | //Actions
99 | r.RestartService(0);
100 | r.RestartService(1);
101 | r.RestartService(2);
102 |
103 | //Settings
104 | r.OnCrashOnly();
105 | r.SetResetPeriod(1);
106 | });
107 | });
108 | }
109 |
110 |
111 |
112 | public static IServiceContainer CreateContainer()
113 | {
114 | var container = new ServiceContainer();
115 |
116 | container.EnableAnnotatedPropertyInjection();
117 |
118 | container.RegisterFrom();
119 | container.RegisterFrom();
120 |
121 | CakeContextExtensions.Container = container;
122 |
123 | return container;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/Stable/RoslynScriptSessionFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using Cake.Core;
4 | using Cake.Core.Diagnostics;
5 | using Cake.Core.Scripting;
6 | using NuGet;
7 |
8 | namespace Cake.Host.Scripting.Roslyn.Stable
9 | {
10 | using Cake.Core.IO;
11 |
12 | public sealed class RoslynScriptSessionFactory
13 | {
14 | private readonly IFileSystem _fileSystem;
15 | private readonly ICakeEnvironment _environment;
16 | private readonly ICakeLog _log;
17 | private readonly FilePath[] _paths;
18 |
19 | public RoslynScriptSessionFactory(
20 | IFileSystem fileSystem,
21 | ICakeEnvironment environment,
22 | ICakeLog log)
23 | {
24 | _fileSystem = fileSystem;
25 | _environment = environment;
26 | _log = log;
27 |
28 | _paths = new FilePath[]
29 | {
30 | @"Roslyn.Compilers.CSharp.1.2.20906.2\lib\net45\Roslyn.Compilers.CSharp.dll",
31 | @"Roslyn.Compilers.Common.1.2.20906.2\lib\net45\Roslyn.Compilers.dll"
32 | };
33 | }
34 |
35 | public IScriptSession CreateSession(IScriptHost host)
36 | {
37 | var root = _environment.GetApplicationRoot();
38 |
39 | // Is Roslyn installed?
40 | if (!IsInstalled(root))
41 | {
42 | _log.Information("Downloading and installing Roslyn...");
43 | Install(root);
44 | }
45 |
46 | // Load Roslyn assemblies dynamically.
47 | foreach (var filePath in _paths)
48 | {
49 | Assembly.LoadFrom(_environment
50 | .GetApplicationRoot()
51 | .CombineWithFilePath(filePath.GetFilename())
52 | .FullPath);
53 | }
54 |
55 | // Create a new session.
56 | return new RoslynScriptSession(host, _log);
57 | }
58 |
59 | private bool IsInstalled(DirectoryPath root)
60 | {
61 | if (root == null)
62 | {
63 | throw new ArgumentNullException("root");
64 | }
65 | foreach (var path in _paths)
66 | {
67 | var filename = path.GetFilename();
68 | var file = _fileSystem.GetFile(root.CombineWithFilePath(filename));
69 | if (!file.Exists)
70 | {
71 | return false;
72 | }
73 | }
74 | return true;
75 | }
76 |
77 | private void Install(DirectoryPath root)
78 | {
79 | if (root == null)
80 | {
81 | throw new ArgumentNullException("root");
82 | }
83 |
84 | var installRoot = root.Combine(Guid.NewGuid().ToString().Replace("-", string.Empty));
85 |
86 | // Install package.
87 | _log.Verbose("Installing package...");
88 | var repository = PackageRepositoryFactory.Default.CreateRepository("https://packages.nuget.org/api/v2");
89 | var packageManager = new PackageManager(repository, installRoot.FullPath);
90 | packageManager.InstallPackage("Roslyn.Compilers.CSharp", new SemanticVersion(new Version(1, 2, 20906, 2)), false, true);
91 |
92 | // Copy files
93 | _log.Verbose("Copying files...");
94 | foreach (var path in _paths)
95 | {
96 | var source = _fileSystem.GetFile(installRoot.CombineWithFilePath(path));
97 | var destination = _fileSystem.GetFile(root.CombineWithFilePath(path.GetFilename()));
98 |
99 | _log.Information("Copying {0}...", source.Path.GetFilename());
100 |
101 | if (!destination.Exists)
102 | {
103 | source.Copy(destination.Path, true);
104 | }
105 | }
106 |
107 | // Delete the install directory.
108 | _log.Verbose("Deleting installation directory...");
109 | _fileSystem.GetDirectory(installRoot).Delete(true);
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/MonoScriptSession.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 | using Cake.Core;
5 | using Cake.Core.Diagnostics;
6 | using Cake.Core.IO;
7 | using Cake.Core.Scripting;
8 | using Cake.Host.Scripting.Mono.CodeGen;
9 | using Mono.CSharp;
10 |
11 | namespace Cake.Host.Scripting.Mono
12 | {
13 | public sealed class MonoScriptSession : IScriptSession
14 | {
15 | private readonly Evaluator _evaluator;
16 | private readonly ICakeLog _log;
17 |
18 | private readonly string[] _skipAssemblies =
19 | {
20 | "mscorlib",
21 | "System",
22 | "System.Core"
23 | };
24 |
25 | public MonoScriptSession(IScriptHost host, ICakeLog log)
26 | {
27 | if (host == null)
28 | {
29 | throw new ArgumentNullException("host");
30 | }
31 | if (log == null)
32 | {
33 | throw new ArgumentNullException("log");
34 | }
35 |
36 | _log = log;
37 |
38 | // Create the evaluator.
39 | var compilerSettings = new CompilerSettings();
40 | var reportPrinter = new MonoConsoleReportPrinter(_log);
41 | var compilerContext = new CompilerContext(compilerSettings, reportPrinter);
42 | _evaluator = new Evaluator(compilerContext);
43 |
44 | // Set our instance of the script host to this static member
45 | MonoScriptHostProxy.ScriptHost = host;
46 |
47 | // This will be our 'base' type from which the evaluator grants access
48 | // to static members to the script being run
49 | _evaluator.InteractiveBaseClass = typeof(MonoScriptHostProxy);
50 | }
51 |
52 | public void AddReference(FilePath path)
53 | {
54 | if (path == null)
55 | {
56 | throw new ArgumentNullException("path");
57 | }
58 | _log.Debug("Adding reference to {0}...", path.FullPath);
59 | _evaluator.ReferenceAssembly(Assembly.LoadFrom(path.FullPath));
60 | }
61 |
62 | public void AddReference(Assembly assembly)
63 | {
64 | if (assembly == null)
65 | {
66 | throw new ArgumentNullException("assembly");
67 | }
68 |
69 | var name = assembly.GetName().Name;
70 |
71 | // We don't need to load these ones as they will already get loaded by Mono.CSharp
72 | if (_skipAssemblies.Contains(name))
73 | {
74 | return;
75 | }
76 |
77 | _log.Debug("Adding reference to {0}...", new FilePath(assembly.Location).GetFilename().FullPath);
78 | _evaluator.ReferenceAssembly(assembly);
79 | }
80 |
81 | public void ImportNamespace(string @namespace)
82 | {
83 | _log.Debug("Importing namespace {0}...", @namespace);
84 | _evaluator.Run("using " + @namespace + ";");
85 | }
86 |
87 | public void Execute(Script script)
88 | {
89 | if (script == null)
90 | {
91 | throw new ArgumentNullException("script");
92 | }
93 |
94 | if (script.UsingAliasDirectives.Count > 0)
95 | {
96 | throw new CakeException("The Mono scripting engine do not support using alias directives.");
97 | }
98 |
99 | var code = MonoCodeGenerator.Generate(script);
100 |
101 | try
102 | {
103 | // Build the class we generated.
104 | _log.Verbose("Compiling build script...");
105 | _evaluator.Run(code);
106 |
107 | // Actually execute it.
108 | _evaluator.Run("new CakeBuildScriptImpl (ScriptHost).Execute ();");
109 | }
110 | catch (InternalErrorException)
111 | {
112 | // The error will be logged via the report printer.
113 | throw new CakeException("An error occured while executing build script.");
114 | }
115 | }
116 | }
117 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Diagnostics/Formatting/FormatParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace Cake.Host.Diagnostics.Formatting
9 | {
10 | public static class FormatParser
11 | {
12 | public static IEnumerable Parse(string format)
13 | {
14 | var reader = new StringReader(format);
15 | while (true)
16 | {
17 | var current = reader.Peek();
18 | if (current == -1)
19 | {
20 | break;
21 | }
22 | var character = (char)current;
23 | if (character == '{')
24 | {
25 | yield return ParseProperty(reader);
26 | }
27 | else
28 | {
29 | yield return ParseText(reader);
30 | }
31 | }
32 | }
33 |
34 | private static FormatToken ParseProperty(TextReader reader)
35 | {
36 | reader.Read(); // Consume
37 | if (reader.Peek() == -1)
38 | {
39 | return new LiteralToken("{");
40 | }
41 | if ((char)reader.Peek() == '{')
42 | {
43 | reader.Read();
44 | return new LiteralToken("{{");
45 | }
46 | var builder = new StringBuilder();
47 | while (true)
48 | {
49 | var current = reader.Peek();
50 | if (current == -1)
51 | {
52 | break;
53 | }
54 |
55 | var character = (char)current;
56 | if (character == '}')
57 | {
58 | reader.Read();
59 |
60 | var accumulated = builder.ToString();
61 | var parts = accumulated.Split(new[] { ':' }, StringSplitOptions.None);
62 | if (parts.Length > 1)
63 | {
64 | var name = parts[0];
65 | var format = string.Join(string.Empty, parts.Skip(1));
66 | var positional = IsNumeric(name);
67 | if (!positional)
68 | {
69 | throw new FormatException("Input string was not in a correct format.");
70 | }
71 | var position = int.Parse(name, CultureInfo.InvariantCulture);
72 | return new PropertyToken(position, format);
73 | }
74 | else
75 | {
76 | var positional = IsNumeric(accumulated);
77 | if (!positional)
78 | {
79 | throw new FormatException("Input string was not in a correct format.");
80 | }
81 | var position = int.Parse(accumulated, CultureInfo.InvariantCulture);
82 | return new PropertyToken(position, null);
83 | }
84 | }
85 | builder.Append((char)reader.Read());
86 | }
87 | return new LiteralToken(builder.ToString());
88 | }
89 |
90 | private static FormatToken ParseText(TextReader reader)
91 | {
92 | var builder = new StringBuilder();
93 | while (true)
94 | {
95 | var current = reader.Peek();
96 | if (current == -1)
97 | {
98 | break;
99 | }
100 | var character = (char)current;
101 | if (character == '{')
102 | {
103 | break;
104 | }
105 | builder.Append((char)reader.Read());
106 | }
107 | return new LiteralToken(builder.ToString());
108 | }
109 |
110 | private static bool IsNumeric(string value)
111 | {
112 | if (string.IsNullOrWhiteSpace(value))
113 | {
114 | return false;
115 | }
116 | foreach (var character in value)
117 | {
118 | if (!char.IsDigit(character))
119 | {
120 | return false;
121 | }
122 | }
123 | return true;
124 | }
125 | }
126 | }
--------------------------------------------------------------------------------
/src/Cake.Host/CakeApplication.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cake.Host.Arguments;
4 | using Cake.Host.Commands;
5 | using Cake.Core;
6 | using Cake.Core.Diagnostics;
7 | using Cake.Host.Diagnostics;
8 |
9 | namespace Cake.Host
10 | {
11 | ///
12 | /// The Cake.Host application.
13 | ///
14 | public sealed class CakeApplication
15 | {
16 | private readonly IVerbosityAwareLog _log;
17 | private readonly ICommandFactory _commandFactory;
18 | private readonly IArgumentParser _argumentParser;
19 | private readonly IConsole _console;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// The log.
25 | /// The command factory.
26 | /// The argument parser.
27 | /// The console.
28 | public CakeApplication(
29 | IVerbosityAwareLog log,
30 | ICommandFactory commandFactory,
31 | IArgumentParser argumentParser,
32 | IConsole console)
33 | {
34 | if (log == null)
35 | {
36 | throw new ArgumentNullException("log");
37 | }
38 | if (commandFactory == null)
39 | {
40 | throw new ArgumentNullException("commandFactory");
41 | }
42 | if (argumentParser == null)
43 | {
44 | throw new ArgumentNullException("argumentParser");
45 | }
46 | if (console == null)
47 | {
48 | throw new ArgumentNullException("console");
49 | }
50 |
51 | _log = log;
52 | _commandFactory = commandFactory;
53 | _argumentParser = argumentParser;
54 | _console = console;
55 | }
56 |
57 | ///
58 | /// Runs the application with the specified arguments.
59 | ///
60 | /// The arguments.
61 | /// The application exit code.
62 | public int Run(IEnumerable args)
63 | {
64 | try
65 | {
66 | // Parse options.
67 | var options = _argumentParser.Parse(args);
68 | if (options != null)
69 | {
70 | _log.SetVerbosity(options.Verbosity);
71 | }
72 |
73 | // Create the correct command and execute it.
74 | var command = CreateCommand(options);
75 | var result = command.Execute(options);
76 |
77 | // Return success if the command succeeded.
78 | // If the parsed options are null, or if the command failed, consider it failed.
79 | return options == null || result == false ? 1 : 0;
80 | }
81 | catch (Exception ex)
82 | {
83 | if (_log.Verbosity == Verbosity.Diagnostic)
84 | {
85 | _log.Error("Error: {0}", ex);
86 | }
87 | else
88 | {
89 | _log.Error("Error: {0}", ex.Message);
90 | }
91 | return 1;
92 | }
93 | }
94 |
95 | private ICommand CreateCommand(CakeOptions options)
96 | {
97 | if (options != null)
98 | {
99 | if (options.ShowHelp)
100 | {
101 | return _commandFactory.CreateHelpCommand();
102 | }
103 |
104 | if (options.ShowVersion)
105 | {
106 | return _commandFactory.CreateVersionCommand();
107 | }
108 |
109 | if (options.Script != null)
110 | {
111 | if (options.PerformDryRun)
112 | {
113 | return _commandFactory.CreateDryRunCommand();
114 | }
115 |
116 | if (options.ShowDescription)
117 | {
118 | _log.SetVerbosity(options.Verbosity);
119 | return _commandFactory.CreateDescriptionCommand();
120 | }
121 |
122 | return _commandFactory.CreateBuildCommand();
123 | }
124 | }
125 |
126 | _console.WriteLine();
127 | _log.Error("Could not find a build script to execute.");
128 | _log.Error("Either the first argument must the build script's path,");
129 | _log.Error("or build script should follow default script name conventions.");
130 |
131 | return new ErrorCommandDecorator(_commandFactory.CreateHelpCommand());
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Console/HostLog.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Diagnostics;
4 | using System.Collections.Generic;
5 |
6 | using Cake.Core;
7 | using Cake.Core.Diagnostics;
8 | using Cake.Host.Diagnostics;
9 | using Cake.Host.Diagnostics.Formatting;
10 |
11 | using Serilog;
12 | using Serilog.Events;
13 | #endregion
14 |
15 |
16 |
17 | namespace CakeBoss.Host
18 | {
19 | public sealed class HostLog : IVerbosityAwareLog
20 | {
21 | #region Fields (3)
22 | private readonly IConsole _console;
23 | private readonly object _lock;
24 | private readonly IDictionary _palettes;
25 | #endregion
26 |
27 |
28 |
29 |
30 |
31 | #region Constructor (1)
32 | public HostLog(IConsole console)
33 | {
34 | _console = console;
35 | _lock = new object();
36 | _palettes = CreatePalette();
37 | Verbosity = Debugger.IsAttached ? Verbosity.Diagnostic : Verbosity.Normal;
38 | }
39 | #endregion
40 |
41 |
42 |
43 |
44 |
45 | #region Properties (1)
46 | public Verbosity Verbosity { get; private set; }
47 | #endregion
48 |
49 |
50 |
51 |
52 |
53 | #region Functions (1)
54 | public void Write(Verbosity verbosity, LogLevel level, string format, params object[] args)
55 | {
56 | if (verbosity > Verbosity)
57 | {
58 | return;
59 | }
60 | lock (_lock)
61 | {
62 | try
63 | {
64 | var palette = _palettes[level];
65 | var tokens = FormatParser.Parse(format);
66 | foreach (var token in tokens)
67 | {
68 | SetPalette(token, palette);
69 | _console.Write("{0}", token.Render(args));
70 | }
71 |
72 | Log.Logger.Write(this.GetLogLevel(level), format, args);
73 | }
74 | finally
75 | {
76 | _console.ResetColor();
77 | _console.WriteLine();
78 | }
79 | }
80 | }
81 |
82 | public void SetVerbosity(Verbosity verbosity)
83 | {
84 | Verbosity = verbosity;
85 | }
86 |
87 | private void SetPalette(FormatToken token, ConsolePalette palette)
88 | {
89 | var property = token as PropertyToken;
90 | if (property != null)
91 | {
92 | _console.BackgroundColor = palette.ArgumentBackground;
93 | _console.ForegroundColor = palette.ArgumentForeground;
94 | }
95 | else
96 | {
97 | _console.BackgroundColor = palette.Background;
98 | _console.ForegroundColor = palette.Foreground;
99 | }
100 | }
101 |
102 |
103 |
104 | private IDictionary CreatePalette()
105 | {
106 | var background = _console.BackgroundColor;
107 | var palette = new Dictionary
108 | {
109 | { LogLevel.Error, new ConsolePalette(ConsoleColor.DarkRed, ConsoleColor.White, ConsoleColor.Red, ConsoleColor.White) },
110 | { LogLevel.Warning, new ConsolePalette(background, ConsoleColor.Yellow, background, ConsoleColor.Yellow) },
111 | { LogLevel.Information, new ConsolePalette(background, ConsoleColor.White, ConsoleColor.DarkBlue, ConsoleColor.White) },
112 | { LogLevel.Verbose, new ConsolePalette(background, ConsoleColor.Gray, background, ConsoleColor.White) },
113 | { LogLevel.Debug, new ConsolePalette(background, ConsoleColor.DarkGray, background, ConsoleColor.Gray) }
114 | };
115 | return palette;
116 | }
117 |
118 | private LogEventLevel GetLogLevel(LogLevel level)
119 | {
120 | switch (level)
121 | {
122 | case LogLevel.Fatal:
123 | return LogEventLevel.Fatal;
124 |
125 | case LogLevel.Error:
126 | return LogEventLevel.Error;
127 |
128 | case LogLevel.Warning:
129 | return LogEventLevel.Warning;
130 |
131 | case LogLevel.Information:
132 | return LogEventLevel.Information;
133 |
134 | case LogLevel.Verbose:
135 | return LogEventLevel.Verbose;
136 | }
137 |
138 | return LogEventLevel.Debug;
139 | }
140 | #endregion
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/CakeBoss.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{805059EC-6CC4-418B-B0ED-E40A21145526}"
7 | ProjectSection(SolutionItems) = preProject
8 | ..\.gitignore = ..\.gitignore
9 | ..\appveyor.yml = ..\appveyor.yml
10 | ..\build.cake = ..\build.cake
11 | ..\build.ps1 = ..\build.ps1
12 | EndProjectSection
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{EA42D027-E363-4943-ABED-1F3C37FD6CA5}"
15 | EndProject
16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{23704DC0-E2D6-47C3-9E11-2A1D8E497980}"
17 | ProjectSection(SolutionItems) = preProject
18 | ..\LICENSE = ..\LICENSE
19 | ..\README.md = ..\README.md
20 | ..\ReleaseNotes.md = ..\ReleaseNotes.md
21 | EndProjectSection
22 | EndProject
23 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script", "Script", "{567027D0-0823-4B53-9FD2-E1FB020DAAD9}"
24 | ProjectSection(SolutionItems) = preProject
25 | ..\script\Release.cake = ..\script\Release.cake
26 | ..\script\Test.cake = ..\script\Test.cake
27 | EndProjectSection
28 | EndProject
29 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.CakeBoss", "Cake.CakeBoss\Cake.CakeBoss.csproj", "{8C311438-E0F0-4A47-AC31-DA29BF901FB2}"
30 | EndProject
31 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cake", "Cake", "{4E7C9059-8E12-4AC4-85E4-C6B0F5CDD339}"
32 | EndProject
33 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CakeBoss", "CakeBoss", "{00965049-79EF-4B11-9A6F-7A60A2E96977}"
34 | EndProject
35 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{22F59941-5BFC-46E9-B683-41DFCABC94FE}"
36 | EndProject
37 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CakeBoss.Host", "CakeBoss.Host\CakeBoss.Host.csproj", "{206F12ED-5FFA-4333-A5A9-31C142648AC1}"
38 | EndProject
39 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CakeBoss.Agent", "CakeBoss.Agent\CakeBoss.Agent.csproj", "{14449D2A-6115-476B-8F8A-78A1BF726299}"
40 | EndProject
41 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CakeBoss.Agent.Tests", "CakeBoss.Agent.Tests\CakeBoss.Agent.Tests.csproj", "{86E04045-FE0D-4EB4-85C1-8B7792B4C4E3}"
42 | EndProject
43 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.Host", "Cake.Host\Cake.Host.csproj", "{C29AF03C-36E0-4161-B28F-B114C2555E7B}"
44 | EndProject
45 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nuget", "Nuget", "{EF82BC0D-0B54-4BBC-9D18-92435B03AC50}"
46 | ProjectSection(SolutionItems) = preProject
47 | ..\nuspec\Cake.CakeBoss.nuspec = ..\nuspec\Cake.CakeBoss.nuspec
48 | EndProjectSection
49 | EndProject
50 | Global
51 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
52 | Debug|Any CPU = Debug|Any CPU
53 | Release|Any CPU = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
56 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
58 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
59 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2}.Release|Any CPU.Build.0 = Release|Any CPU
60 | {206F12ED-5FFA-4333-A5A9-31C142648AC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61 | {206F12ED-5FFA-4333-A5A9-31C142648AC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
62 | {206F12ED-5FFA-4333-A5A9-31C142648AC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
63 | {206F12ED-5FFA-4333-A5A9-31C142648AC1}.Release|Any CPU.Build.0 = Release|Any CPU
64 | {14449D2A-6115-476B-8F8A-78A1BF726299}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65 | {14449D2A-6115-476B-8F8A-78A1BF726299}.Debug|Any CPU.Build.0 = Debug|Any CPU
66 | {14449D2A-6115-476B-8F8A-78A1BF726299}.Release|Any CPU.ActiveCfg = Release|Any CPU
67 | {14449D2A-6115-476B-8F8A-78A1BF726299}.Release|Any CPU.Build.0 = Release|Any CPU
68 | {86E04045-FE0D-4EB4-85C1-8B7792B4C4E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69 | {86E04045-FE0D-4EB4-85C1-8B7792B4C4E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
70 | {86E04045-FE0D-4EB4-85C1-8B7792B4C4E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
71 | {86E04045-FE0D-4EB4-85C1-8B7792B4C4E3}.Release|Any CPU.Build.0 = Release|Any CPU
72 | {C29AF03C-36E0-4161-B28F-B114C2555E7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73 | {C29AF03C-36E0-4161-B28F-B114C2555E7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
74 | {C29AF03C-36E0-4161-B28F-B114C2555E7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
75 | {C29AF03C-36E0-4161-B28F-B114C2555E7B}.Release|Any CPU.Build.0 = Release|Any CPU
76 | EndGlobalSection
77 | GlobalSection(SolutionProperties) = preSolution
78 | HideSolutionNode = FALSE
79 | EndGlobalSection
80 | GlobalSection(NestedProjects) = preSolution
81 | {8C311438-E0F0-4A47-AC31-DA29BF901FB2} = {4E7C9059-8E12-4AC4-85E4-C6B0F5CDD339}
82 | {4E7C9059-8E12-4AC4-85E4-C6B0F5CDD339} = {EA42D027-E363-4943-ABED-1F3C37FD6CA5}
83 | {00965049-79EF-4B11-9A6F-7A60A2E96977} = {EA42D027-E363-4943-ABED-1F3C37FD6CA5}
84 | {22F59941-5BFC-46E9-B683-41DFCABC94FE} = {EA42D027-E363-4943-ABED-1F3C37FD6CA5}
85 | {206F12ED-5FFA-4333-A5A9-31C142648AC1} = {00965049-79EF-4B11-9A6F-7A60A2E96977}
86 | {14449D2A-6115-476B-8F8A-78A1BF726299} = {00965049-79EF-4B11-9A6F-7A60A2E96977}
87 | {86E04045-FE0D-4EB4-85C1-8B7792B4C4E3} = {22F59941-5BFC-46E9-B683-41DFCABC94FE}
88 | {C29AF03C-36E0-4161-B28F-B114C2555E7B} = {4E7C9059-8E12-4AC4-85E4-C6B0F5CDD339}
89 | EndGlobalSection
90 | EndGlobal
91 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Host/HostApplication.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Cake.Host;
6 | using Cake.Host.Commands;
7 | using Cake.Core;
8 | using Cake.Host.Arguments;
9 | using Cake.Core.Diagnostics;
10 | using Cake.Host.Diagnostics;
11 | #endregion
12 |
13 |
14 |
15 | namespace CakeBoss.Host
16 | {
17 | ///
18 | /// The Cake application.
19 | ///
20 | public sealed class HostApplication
21 | {
22 | #region Fields (4)
23 | private readonly IVerbosityAwareLog _log;
24 | private readonly ICommandFactory _commandFactory;
25 | private readonly IArgumentParser _argumentParser;
26 | private readonly IConsole _console;
27 | #endregion
28 |
29 |
30 |
31 |
32 |
33 | #region Constructor (1)
34 | ///
35 | /// Initializes a new instance of the class.
36 | ///
37 | /// The log.
38 | /// The command factory.
39 | /// The argument parser.
40 | /// The console.
41 | public HostApplication(
42 | IVerbosityAwareLog log,
43 | ICommandFactory commandFactory,
44 | IArgumentParser argumentParser,
45 | IConsole console)
46 | {
47 | if (log == null)
48 | {
49 | throw new ArgumentNullException("log");
50 | }
51 | if (commandFactory == null)
52 | {
53 | throw new ArgumentNullException("commandFactory");
54 | }
55 | if (argumentParser == null)
56 | {
57 | throw new ArgumentNullException("argumentParser");
58 | }
59 | if (console == null)
60 | {
61 | throw new ArgumentNullException("console");
62 | }
63 |
64 | _log = log;
65 | _commandFactory = commandFactory;
66 | _argumentParser = argumentParser;
67 | _console = console;
68 | }
69 | #endregion
70 |
71 |
72 |
73 |
74 |
75 | #region Functions (2)
76 | ///
77 | /// Runs the application with the specified arguments.
78 | ///
79 | /// The arguments.
80 | /// The application exit code.
81 | public bool Run(IEnumerable args)
82 | {
83 | try
84 | {
85 | // Parse options.
86 | var options = _argumentParser.Parse(args);
87 | if (options != null)
88 | {
89 | _log.SetVerbosity(options.Verbosity);
90 | }
91 |
92 | // Create the correct command and execute it.
93 | var command = this.CreateCommand(options);
94 | return command.Execute(options);
95 | }
96 | catch (Exception ex)
97 | {
98 | if (_log.Verbosity == Verbosity.Diagnostic)
99 | {
100 | _log.Error("Error: {0}", ex);
101 | }
102 | else
103 | {
104 | _log.Error("Error: {0}", ex.Message);
105 | }
106 |
107 | return false;
108 | }
109 | }
110 |
111 | public ICommand CreateCommand(CakeOptions options)
112 | {
113 | if (options != null)
114 | {
115 | if (options.ShowHelp)
116 | {
117 | return _commandFactory.CreateHelpCommand();
118 | }
119 |
120 | if (options.ShowVersion)
121 | {
122 | return _commandFactory.CreateVersionCommand();
123 | }
124 |
125 | if (options.Script != null)
126 | {
127 | if (options.PerformDryRun)
128 | {
129 | return _commandFactory.CreateDryRunCommand();
130 | }
131 |
132 | if (options.ShowDescription)
133 | {
134 | _log.SetVerbosity(options.Verbosity);
135 | return _commandFactory.CreateDescriptionCommand();
136 | }
137 |
138 | return _commandFactory.CreateBuildCommand();
139 | }
140 | }
141 |
142 | _console.WriteLine();
143 | _log.Error("Could not find a build script to execute.");
144 | _log.Error("Either the first argument must the build script's path,");
145 | _log.Error("or build script should follow default script name conventions.");
146 |
147 | return new ErrorCommandDecorator(_commandFactory.CreateHelpCommand());
148 | }
149 | #endregion
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Roslyn/Nightly/RoslynNightlyScriptSessionFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Reflection;
6 | using Cake.Core;
7 | using Cake.Core.Diagnostics;
8 | using Cake.Core.Scripting;
9 | using NuGet;
10 |
11 | namespace Cake.Host.Scripting.Roslyn.Nightly
12 | {
13 | using Cake.Core.IO;
14 |
15 | public sealed class RoslynNightlyScriptSessionFactory
16 | {
17 | private readonly IFileSystem _fileSystem;
18 | private readonly ICakeEnvironment _environment;
19 | private readonly IGlobber _globber;
20 | private readonly ICakeLog _log;
21 | private readonly FilePath[] _paths;
22 |
23 | public RoslynNightlyScriptSessionFactory(
24 | IFileSystem fileSystem,
25 | ICakeEnvironment environment,
26 | IGlobber globber,
27 | ICakeLog log)
28 | {
29 | _fileSystem = fileSystem;
30 | _environment = environment;
31 | _globber = globber;
32 | _log = log;
33 |
34 | _paths = new FilePath[]
35 | {
36 | @"net45/Microsoft.CodeAnalysis.dll",
37 | @"net45/Microsoft.CodeAnalysis.Scripting.CSharp.dll",
38 | @"net45/Microsoft.CodeAnalysis.Scripting.dll",
39 | @"net45/Microsoft.CodeAnalysis.Desktop.dll",
40 | @"net45/Microsoft.CodeAnalysis.CSharp.dll",
41 | @"net45/Microsoft.CodeAnalysis.CSharp.Desktop.dll",
42 | @"portable-net45+win8+wp8+wpa81/System.Collections.Immutable.dll",
43 | @"portable-net45+win8/System.Reflection.Metadata.dll",
44 | };
45 | }
46 |
47 | public IScriptSession CreateSession(IScriptHost host)
48 | {
49 | // Is Roslyn installed?
50 | if (!IsInstalled())
51 | {
52 | _log.Information("Downloading and installing Roslyn (experimental)...");
53 | Install(new SemanticVersion(1, 0, 0, "rc2"));
54 | }
55 |
56 | // Load Roslyn assemblies dynamically.
57 | foreach (var filePath in _paths)
58 | {
59 | Assembly.LoadFrom(_environment
60 | .GetApplicationRoot()
61 | .CombineWithFilePath(filePath.GetFilename())
62 | .FullPath);
63 | }
64 |
65 | // Create the session.
66 | return new RoslynNightlyScriptSession(host, _log);
67 | }
68 |
69 | private bool IsInstalled()
70 | {
71 | var root = _environment.GetApplicationRoot();
72 | foreach (var path in _paths)
73 | {
74 | var filename = path.GetFilename();
75 | var file = _fileSystem.GetFile(root.CombineWithFilePath(filename));
76 | if (!file.Exists)
77 | {
78 | return false;
79 | }
80 | }
81 | return true;
82 | }
83 |
84 | private void Install(SemanticVersion version)
85 | {
86 | var root = _environment.GetApplicationRoot().MakeAbsolute(_environment);
87 | var installRoot = root.MakeAbsolute(_environment).Combine(Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
88 |
89 | var packages = new Dictionary
90 | {
91 | { "Microsoft.CodeAnalysis.Scripting", version },
92 | { "Microsoft.CodeAnalysis.CSharp", version }
93 | };
94 |
95 | // Install package.
96 | _log.Verbose("Installing packages...");
97 | var packageManager = CreatePackageManager(installRoot);
98 | foreach (var package in packages)
99 | {
100 | _log.Information("Downloading package {0} ({1})...", package.Key, package.Value);
101 | packageManager.InstallPackage(package.Key, package.Value, false, true);
102 | }
103 |
104 | // Copy files.
105 | _log.Verbose("Copying files...");
106 | foreach (var path in _paths)
107 | {
108 | // Find the file within the temporary directory.
109 | var exp = string.Concat(installRoot.FullPath, "/**/", path);
110 | var foundFile = _globber.Match(exp).FirstOrDefault();
111 | if (foundFile == null)
112 | {
113 | var format = "Could not find file {0}.";
114 | var message = string.Format(CultureInfo.InvariantCulture, format, path);
115 | throw new CakeException(message);
116 | }
117 |
118 | var source = _fileSystem.GetFile((FilePath)foundFile);
119 | var destination = _fileSystem.GetFile(root.CombineWithFilePath(path.GetFilename()));
120 |
121 | _log.Information("Copying {0}...", source.Path.GetFilename());
122 |
123 | if (!destination.Exists)
124 | {
125 | source.Copy(destination.Path, true);
126 | }
127 | }
128 |
129 | // Delete the install directory.
130 | _log.Verbose("Deleting installation directory...");
131 | _fileSystem.GetDirectory(installRoot).Delete(true);
132 | }
133 |
134 | private static IPackageManager CreatePackageManager(DirectoryPath path)
135 | {
136 | var sources = new[]
137 | {
138 | new PackageSource("https://packages.nuget.org/api/v2"),
139 | };
140 | var repo = AggregateRepository.Create(PackageRepositoryFactory.Default, sources, false);
141 | return new PackageManager(repo, path.FullPath);
142 | }
143 | }
144 | }
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Console/HostConsole.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | using Serilog;
6 | using Cake.Core;
7 | #endregion
8 |
9 |
10 |
11 | namespace CakeBoss.Host
12 | {
13 | public sealed class HostConsole : IConsole
14 | {
15 | #region Fields (3)
16 | private ConsoleColor _ForegroundColor;
17 | private ConsoleColor _BackgroundColor;
18 |
19 | private IList _Output;
20 | #endregion
21 |
22 |
23 |
24 |
25 |
26 | #region Constructor (1)
27 | public HostConsole()
28 | {
29 | _Output = new List();
30 |
31 | this.ResetColor();
32 | }
33 | #endregion
34 |
35 |
36 |
37 |
38 |
39 | #region Properties (2)
40 | ///
41 | /// Gets or sets the foreground color.
42 | ///
43 | /// The foreground color.
44 | public ConsoleColor ForegroundColor
45 | {
46 | get
47 | {
48 | return _ForegroundColor;
49 | }
50 | set
51 | {
52 | _ForegroundColor = value;
53 | }
54 | }
55 |
56 | ///
57 | /// Gets or sets the background color.
58 | ///
59 | /// The background color.
60 | public ConsoleColor BackgroundColor
61 | {
62 | get
63 | {
64 | return _BackgroundColor;
65 | }
66 | set
67 | {
68 | _BackgroundColor = value;
69 | }
70 | }
71 | #endregion
72 |
73 |
74 |
75 |
76 |
77 | #region Functions (4)
78 | ///
79 | /// Writes the text representation of the specified array of objects to the
80 | /// console output using the specified format information.
81 | ///
82 | /// A composite format string
83 | /// An array of objects to write using format.
84 | public void Write(string format, params object[] arg)
85 | {
86 | this.CreateOutput(String.Format(format, arg), this.ForegroundColor);
87 | }
88 |
89 | ///
90 | /// Writes the text representation of the specified array of objects, followed
91 | /// by the current line terminator, to the console output using the specified
92 | /// format information.
93 | ///
94 | /// A composite format string
95 | /// An array of objects to write using format.
96 | public void WriteLine(string format, params object[] arg)
97 | {
98 | this.CreateOutput(String.Format(format, arg) + Environment.NewLine, this.ForegroundColor);
99 | }
100 |
101 |
102 |
103 | ///
104 | /// Writes the text representation of the specified array of objects to the
105 | /// console output using the specified format information.
106 | ///
107 | /// A composite format string
108 | /// An array of objects to write using format.
109 | public void WriteError(string format, params object[] arg)
110 | {
111 | this.CreateOutput(String.Format(format, arg) + Environment.NewLine, ConsoleColor.Red);
112 | }
113 |
114 | ///
115 | /// Writes the text representation of the specified array of objects, followed
116 | /// by the current line terminator, to the console output using the specified
117 | /// format information.
118 | ///
119 | /// A composite format string
120 | /// An array of objects to write using format.
121 | public void WriteErrorLine(string format, params object[] arg)
122 | {
123 | this.CreateOutput(String.Format(format, arg) + Environment.NewLine, this.ForegroundColor);
124 | }
125 |
126 |
127 |
128 | ///
129 | /// Sets the foreground and background console colors to their defaults.
130 | ///
131 | public void ResetColor()
132 | {
133 | _ForegroundColor = ConsoleColor.White;
134 | _BackgroundColor = ConsoleColor.DarkBlue;
135 | }
136 |
137 |
138 |
139 | private void CreateOutput(string text, ConsoleColor color)
140 | {
141 | /*if (!String.IsNullOrEmpty(text))
142 | {
143 | //Format
144 | text = text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
145 |
146 | //Build
147 | ConsoleOutput output = new ConsoleOutput(text, color);
148 | _Output.Add(output);
149 |
150 | //Flush
151 | if (text.Contains(Environment.NewLine))
152 | {
153 | string info = "";
154 |
155 | foreach (ConsoleOutput part in _Output)
156 | {
157 | info += part.Text;
158 | }
159 |
160 | Log.Logger.Information(info);
161 | _Output.Clear();
162 | }
163 | }*/
164 | }
165 | #endregion
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/CakeBoss.Host/Registry/HostRoot.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using System;
3 |
4 | using Cake.Host;
5 | using Cake.Host.Arguments;
6 | using Cake.Host.Commands;
7 | using Cake.Core;
8 | using Cake.Core.Diagnostics;
9 | using Cake.Core.IO;
10 | using Cake.Core.IO.NuGet;
11 | using Cake.Core.Scripting;
12 | using Cake.Core.Scripting.Analysis;
13 | using Cake.Core.Packaging;
14 | using Cake.NuGet;
15 | using Cake.Host.Diagnostics;
16 | using Cake.Host.Scripting;
17 | using Cake.Host.Scripting.Mono;
18 | using Cake.Host.Scripting.Roslyn;
19 | using Cake.Host.Scripting.Roslyn.Nightly;
20 | using Cake.Host.Scripting.Roslyn.Stable;
21 |
22 | using LightInject;
23 |
24 | using Nancy;
25 | using Nancy.Authentication.Basic;
26 | using Nancy.Serialization.JsonNet;
27 | #endregion
28 |
29 |
30 |
31 | namespace CakeBoss.Host
32 | {
33 | public class HostRoot : ICompositionRoot
34 | {
35 | public void Compose(IServiceRegistry container)
36 | {
37 | //Core Services
38 | container.Register(new PerContainerLifetime());
39 | container.Register(new PerContainerLifetime());
40 | container.Register(new PerContainerLifetime());
41 | container.Register(new PerContainerLifetime());
42 | container.Register(new PerContainerLifetime());
43 | container.Register(new PerContainerLifetime());
44 | container.Register(new PerContainerLifetime());
45 | container.Register(new PerContainerLifetime());
46 | container.Register(new PerContainerLifetime());
47 |
48 | container.Register(new PerContainerLifetime());
49 | container.Register(new PerContainerLifetime());
50 | container.Register(new PerContainerLifetime());
51 |
52 | container.Register(new PerContainerLifetime());
53 |
54 | container.Register(new PerContainerLifetime());
55 | container.Register(new PerContainerLifetime());
56 |
57 |
58 |
59 | // NuGet addins support
60 | container.Register(new PerContainerLifetime());
61 | container.Register(new PerContainerLifetime());
62 |
63 | container.Register(new PerContainerLifetime());
64 | container.Register(new PerContainerLifetime());
65 | container.Register(new PerContainerLifetime());
66 | container.Register(new PerContainerLifetime());
67 |
68 | // URI resource support.
69 | container.Register(new PerContainerLifetime());
70 | container.Register(new PerContainerLifetime());
71 |
72 |
73 |
74 | if (Type.GetType("Mono.Runtime") != null)
75 | {
76 | //Mono Scripting
77 | container.Register(new PerContainerLifetime());
78 | }
79 | else
80 | {
81 | //Roslyn
82 | container.Register(new PerContainerLifetime());
83 | container.Register(new PerContainerLifetime());
84 | container.Register(new PerContainerLifetime());
85 | }
86 |
87 |
88 |
89 | //Cake Services
90 | container.Register(new PerContainerLifetime());
91 | container.Register(new PerContainerLifetime());
92 | container.Register(new PerContainerLifetime());
93 | container.Register(new PerContainerLifetime());
94 |
95 | container.Register(new PerContainerLifetime());
96 | container.Register(new PerContainerLifetime());
97 |
98 |
99 |
100 | //Script Hosts
101 | container.Register(new PerContainerLifetime());
102 | container.Register(new PerContainerLifetime());
103 | container.Register(new PerContainerLifetime());
104 |
105 |
106 |
107 | //Script Commands
108 | container.Register(new PerRequestLifeTime());
109 | container.Register(new PerRequestLifeTime());
110 | container.Register(new PerRequestLifeTime());
111 | container.Register(new PerRequestLifeTime());
112 | container.Register(new PerRequestLifeTime());
113 |
114 |
115 |
116 | //CakeBoss Host
117 | container.Register(new PerContainerLifetime());
118 | container.Register(new PerContainerLifetime());
119 |
120 |
121 |
122 | //Nancy
123 | container.Register();
124 | container.Register();
125 |
126 | container.Register(new PerRequestLifeTime());
127 | }
128 | }
129 | }
--------------------------------------------------------------------------------
/src/Cake.Host/Scripting/Mono/CodeGen/Parsing/ScriptTokenizer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace Cake.Host.Scripting.Mono.CodeGen.Parsing
5 | {
6 | public sealed class ScriptTokenizer : IDisposable
7 | {
8 | private readonly ScriptBuffer _buffer;
9 |
10 | public ScriptTokenizer(string content)
11 | {
12 | _buffer = new ScriptBuffer(content);
13 | }
14 |
15 | public void Dispose()
16 | {
17 | _buffer.Dispose();
18 | }
19 |
20 | public ScriptToken GetNextToken()
21 | {
22 | _buffer.EatWhiteSpace();
23 |
24 | // Reached the end?
25 | if (_buffer.ReachedEnd)
26 | {
27 | return null;
28 | }
29 |
30 | // String?
31 | if (_buffer.CurrentToken == '\"')
32 | {
33 | return ParseString();
34 | }
35 |
36 | // Word or Identifier?
37 | if (IsWordCharacter((char)_buffer.CurrentToken))
38 | {
39 | return ParseWord();
40 | }
41 |
42 | // Single line comment?
43 | if (_buffer.CurrentToken == '/' && _buffer.NextToken == '/')
44 | {
45 | return SkipSingleLineComment();
46 | }
47 |
48 | // Multi line comment?
49 | if (_buffer.CurrentToken == '/' && _buffer.NextToken == '*')
50 | {
51 | return SkipMultiLineComment();
52 | }
53 |
54 | // Some character.
55 | var tokenType = GetCharacterTokenType();
56 | return new ScriptToken(
57 | tokenType,
58 | ((char)_buffer.CurrentToken).ToString(),
59 | _buffer.Position, 1);
60 | }
61 |
62 | private ScriptToken ParseString()
63 | {
64 | var start = _buffer.Position;
65 |
66 | var accumulator = new StringBuilder();
67 | accumulator.Append((char)_buffer.CurrentToken);
68 |
69 | while (true)
70 | {
71 | if (!_buffer.Read())
72 | {
73 | throw new InvalidOperationException("Unterminated string literal.");
74 | }
75 |
76 | accumulator.Append((char)_buffer.CurrentToken);
77 |
78 | var current = (char)_buffer.CurrentToken;
79 | if (current == '\"')
80 | {
81 | var last = (char)_buffer.PreviousToken;
82 | if (last != '\\')
83 | {
84 | break;
85 | }
86 | }
87 | }
88 |
89 | return new ScriptToken(
90 | ScriptTokenType.String,
91 | accumulator.ToString(),
92 | start,
93 | accumulator.Length);
94 | }
95 |
96 | private ScriptToken ParseWord()
97 | {
98 | var start = _buffer.Position;
99 |
100 | var accumulator = new StringBuilder();
101 | accumulator.Append((char)_buffer.CurrentToken);
102 |
103 | while (true)
104 | {
105 | var current = _buffer.Peek();
106 | if (current == -1 || !IsWordCharacter((char)current))
107 | {
108 | break;
109 | }
110 | accumulator.Append((char)current);
111 | _buffer.Read(); // Nom nom nom
112 | }
113 |
114 | var type = ScriptTokenType.Word;
115 |
116 | var identity = accumulator.ToString();
117 | if (identity.Equals("if", StringComparison.Ordinal))
118 | {
119 | type = ScriptTokenType.If;
120 | }
121 | if (identity.Equals("else", StringComparison.Ordinal))
122 | {
123 | type = ScriptTokenType.Else;
124 | }
125 | if (identity.Equals("while", StringComparison.Ordinal))
126 | {
127 | type = ScriptTokenType.While;
128 | }
129 | if (identity.Equals("switch", StringComparison.Ordinal))
130 | {
131 | type = ScriptTokenType.Switch;
132 | }
133 |
134 | return new ScriptToken(
135 | type,
136 | accumulator.ToString(),
137 | start,
138 | accumulator.Length);
139 | }
140 |
141 | private ScriptToken SkipSingleLineComment()
142 | {
143 | while (true)
144 | {
145 | if ((_buffer.CurrentToken == '\r' && _buffer.NextToken == '\n') ||
146 | _buffer.CurrentToken == '\n')
147 | {
148 | break;
149 | }
150 | if (!_buffer.Read())
151 | {
152 | break;
153 | }
154 | }
155 | return GetNextToken();
156 | }
157 |
158 | private ScriptToken SkipMultiLineComment()
159 | {
160 | while (true)
161 | {
162 | if (_buffer.CurrentToken == '*' && _buffer.NextToken == '/')
163 | {
164 | _buffer.Read(); // Nom nom nom
165 | break;
166 | }
167 | if (!_buffer.Read())
168 | {
169 | break;
170 | }
171 | }
172 | return GetNextToken();
173 | }
174 |
175 | private ScriptTokenType GetCharacterTokenType()
176 | {
177 | switch (_buffer.CurrentToken)
178 | {
179 | case '{': return ScriptTokenType.LeftBrace;
180 | case '}': return ScriptTokenType.RightBrace;
181 | case '(': return ScriptTokenType.LeftParenthesis;
182 | case ')': return ScriptTokenType.RightParenthesis;
183 | case ';': return ScriptTokenType.Semicolon;
184 | }
185 | return ScriptTokenType.Character;
186 | }
187 |
188 | private static bool IsWordCharacter(char current)
189 | {
190 | return char.IsLetterOrDigit(current) || current == '_';
191 | }
192 | }
193 | }
--------------------------------------------------------------------------------