diff --git a/README.md b/README.md index 2635677aca..c98bd61499 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ - [Package and Deploy to Lambda](#package-and-deploy-to-lambda) - [Getting started](#getting-started) - [Advanced](#advanced) - - [Compiled Languages (Java)](#compiled-languages-java) + - [Compiled Languages](#compiled-languages) + - [Java](#compiled-languages-java) + - [.NET Core](#compiled-languages-dotnetcore) - [IAM Credentials](#iam-credentials) - [Lambda Environment Variables](#lambda-environment-variables) - [Environment Variable file](#environment-variable-file) @@ -323,7 +325,9 @@ $ sam deploy --template-file ./packaged.yaml --stack-name mystack --capabilities ## Advanced -### Compiled Languages (Java) +### Compiled Languages + +#### Java To use SAM Local with compiled languages, such as Java that require a packaged artifact (e.g. a JAR, or ZIP), you can specify the location of the artifact with the `AWS::Serverless::Function` `CodeUri` property in your SAM template. @@ -355,7 +359,30 @@ $ echo '{ "some": "input" }' | sam local invoke $ sam local start-api ``` -You can find a full Java example in the [samples/java](samples/java) folder +You can find a full Java example in the [samples/java](samples/java) folder. + +#### .NET Core + +To use SAM Local with compiled languages, such as .NET Core that require a packaged artifact (e.g. a ZIP), you can specify the location of the artifact with the `AWS::Serverless::Function` `CodeUri` property in your SAM template. + +For example: + +``` +AWSTemplateFormatVersion: 2010-09-09 +Transform: AWS::Serverless-2016-10-31 + +Resources: + ExampleJavaFunction: + Type: AWS::Serverless::Function + Properties: + Handler: HelloWorld::HelloWorld.Function::Handler + CodeUri: ./artifacts/HelloWorld.zip + Runtime: dotnetcore2.0 +``` + +You should then build your ZIP file using your normal build process. + +You can find a .NET Core example in the [samples/hello-world/dotnetcore2.0](samples/hello-world/dotnetcore2.0) folder. ### IAM Credentials diff --git a/samples/README.md b/samples/README.md index 9d8dc48d5d..a89f6b19b8 100644 --- a/samples/README.md +++ b/samples/README.md @@ -10,6 +10,7 @@ To work with the example applications in this repository, first ensure that you' * SAM Local * An Amazon S3 bucket * (Optional) Maven +* (Optional) .NET Core 2.0 To install the AWS CLI, follow the instructions at [Installing the AWS Command Line Interface](http://docs.aws.amazon.com/cli/latest/userguide/installing.html). @@ -19,6 +20,8 @@ To create an Amazon S3 bucket, follow the instructions at [Create a Bucket](http To run the Java examples, you'll need to install Maven. For more information, see [Creating a .jar Deployment Package Using Maven without any IDE (Java) ](http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html). +To run the .NET Core 2.0 examples you'll need to install .NET Core SDK. For more information, see [.NET Downloads](https://www.microsoft.com/net/download/windows). + ## Recommended ## * [Postman](https://www.getpostman.com/) diff --git a/samples/hello-world/dotnetcore2.0/HelloWorld.sln b/samples/hello-world/dotnetcore2.0/HelloWorld.sln new file mode 100644 index 0000000000..df11e0d47c --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/HelloWorld.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{15BADD3C-EB9E-4027-83A8-4164B0FD0B94}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "src\HelloWorld\HelloWorld.csproj", "{1C72B9A4-F5C5-4019-BF0F-CC10BDECF582}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7C692A39-E2E3-4170-AB91-86BD226D61D7}" +ProjectSection(SolutionItems) = preProject + build.cake = build.cake + build.ps1 = build.ps1 + build.sh = build.sh + event.json = event.json + template.yml = template.yml +EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{F090076F-EE78-4CC6-B614-9069D413A885}" +ProjectSection(SolutionItems) = preProject + README.md = README.md +EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1C72B9A4-F5C5-4019-BF0F-CC10BDECF582} = {15BADD3C-EB9E-4027-83A8-4164B0FD0B94} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1C72B9A4-F5C5-4019-BF0F-CC10BDECF582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C72B9A4-F5C5-4019-BF0F-CC10BDECF582}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C72B9A4-F5C5-4019-BF0F-CC10BDECF582}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C72B9A4-F5C5-4019-BF0F-CC10BDECF582}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/samples/hello-world/dotnetcore2.0/README.md b/samples/hello-world/dotnetcore2.0/README.md new file mode 100644 index 0000000000..0c2d8c3f52 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/README.md @@ -0,0 +1,39 @@ +# AWS SAM Hello World Example # + +A simple AWS SAM template that specifies a single Lambda function. + +## Usage ## + +To create and deploy the SAM Hello World example, first ensure that you've met the requirements described in the [root README](../../README.md). Then follow the steps below. + +### Build your package ### + +#### Linux & macOS + + sh build.sh --target=Package + +#### Windows (Powershell) + + build.ps1 --target=Package + +### Test your application locally ### + +Use [SAM Local](https://github.com/awslabs/aws-sam-local) to run your Lambda function locally: + + sam local invoke "HelloWorld" -e event.json + +### Package artifacts ### + +Run the following command, replacing `BUCKET-NAME` with the name of your bucket: + + sam package --template-file template.yaml --s3-bucket BUCKET-NAME --output-template-file packaged-template.yaml + +This creates a new template file, packaged-template.yaml, that you will use to deploy your serverless application. + +### Deploy to AWS CloudFormation ### + +Run the following command, replacing `MY-NEW-STACK` with a name for your CloudFormation stack. + + sam deploy --template-file packaged-template.yaml --stack-name MY-NEW-STACK --capabilities CAPABILITY_IAM + +This uploads your template to an S3 bucket and deploys the specified resources using AWS CloudFormation. \ No newline at end of file diff --git a/samples/hello-world/dotnetcore2.0/build.cake b/samples/hello-world/dotnetcore2.0/build.cake new file mode 100644 index 0000000000..b9e8200823 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/build.cake @@ -0,0 +1,231 @@ +/////////////////////////////////////////////////////////////////////////////// +// ARGUMENTS +/////////////////////////////////////////////////////////////////////////////// + +var target = Argument("target", "Default"); +var configuration = Argument("configuration", "Release"); +var verbosity = Argument("verbosity", "Minimal"); + +/////////////////////////////////////////////////////////////////////////////// +// GLOBAL VARIABLES +/////////////////////////////////////////////////////////////////////////////// + +var sourceDir = Directory("./src"); + +var solutions = GetFiles("./**/*.sln"); +var projects = new [] +{ + sourceDir.Path + "/HelloWorld/HelloWorld.csproj", +}; + +// BUILD OUTPUT DIRECTORIES +var artifactsDir = Directory("./artifacts"); +var publishDir = Directory("./publish/"); + +// VERBOSITY +var dotNetCoreVerbosity = Cake.Common.Tools.DotNetCore.DotNetCoreVerbosity.Normal; +if (!Enum.TryParse(verbosity, true, out dotNetCoreVerbosity)) +{ + dotNetCoreVerbosity = Cake.Common.Tools.DotNetCore.DotNetCoreVerbosity.Normal; + Warning( + "Verbosity could not be parsed into type 'Cake.Common.Tools.DotNetCore.DotNetCoreVerbosity'. Defaulting to {0}", + dotNetCoreVerbosity); +} + +/////////////////////////////////////////////////////////////////////////////// +// COMMON FUNCTION DEFINITIONS +/////////////////////////////////////////////////////////////////////////////// + +string GetProjectName(string project) +{ + return project + .Split(new [] {'/'}, StringSplitOptions.RemoveEmptyEntries) + .Last() + .Replace(".csproj", string.Empty); +} + +/////////////////////////////////////////////////////////////////////////////// +// SETUP / TEARDOWN +/////////////////////////////////////////////////////////////////////////////// + +Setup(ctx => +{ + // Executed BEFORE the first task. + EnsureDirectoryExists(artifactsDir); + EnsureDirectoryExists(publishDir); + Information("Running tasks..."); +}); + +Teardown(ctx => +{ + // Executed AFTER the last task. + Information("Finished running tasks."); +}); + +/////////////////////////////////////////////////////////////////////////////// +// TASK DEFINITIONS +/////////////////////////////////////////////////////////////////////////////// + +Task("Clean") + .Description("Cleans all directories that are used during the build process.") + .Does(() => + { + foreach(var solution in solutions) + { + Information("Cleaning {0}", solution.FullPath); + CleanDirectories(solution.FullPath + "/**/bin/" + configuration); + CleanDirectories(solution.FullPath + "/**/obj/" + configuration); + Information("{0} was clean.", solution.FullPath); + } + + CleanDirectory(artifactsDir); + CleanDirectory(publishDir); + }); + +Task("Restore") + .Description("Restores all the NuGet packages that are used by the specified solution.") + .Does(() => + { + var settings = new DotNetCoreRestoreSettings + { + DisableParallel = false, + NoCache = true, + Verbosity = dotNetCoreVerbosity + }; + + foreach(var solution in solutions) + { + Information("Restoring NuGet packages for '{0}'...", solution); + DotNetCoreRestore(solution.FullPath, settings); + Information("NuGet packages restored for '{0}'.", solution); + } + }); + +Task("Build") + .Description("Builds all the different parts of the project.") + .Does(() => + { + var msBuildSettings = new DotNetCoreMSBuildSettings + { + TreatAllWarningsAs = MSBuildTreatAllWarningsAs.Error, + Verbosity = dotNetCoreVerbosity + }; + + var settings = new DotNetCoreBuildSettings + { + Configuration = configuration, + MSBuildSettings = msBuildSettings, + NoRestore = true + }; + + foreach(var solution in solutions) + { + Information("Building '{0}'...", solution); + DotNetCoreBuild(solution.FullPath, settings); + Information("'{0}' has been built.", solution); + } + }); + +Task("Publish") + .Description("Publish the Lambda Functions.") + .Does(() => + { + foreach(var project in projects) + { + var projectName = project + .Split(new [] {'/'}, StringSplitOptions.RemoveEmptyEntries) + .Last() + .Replace(".csproj", string.Empty); + + var outputDirectory = System.IO.Path.Combine(publishDir, projectName); + + var msBuildSettings = new DotNetCoreMSBuildSettings + { + TreatAllWarningsAs = MSBuildTreatAllWarningsAs.Error, + Verbosity = dotNetCoreVerbosity + }; + + var settings = new DotNetCorePublishSettings + { + Configuration = configuration, + MSBuildSettings = msBuildSettings, + NoRestore = true, + OutputDirectory = outputDirectory, + Verbosity = dotNetCoreVerbosity + }; + + Information("Publishing '{0}'...", projectName); + DotNetCorePublish(project, settings); + Information("'{0}' has been published.", projectName); + } + }); + +Task("Pack") + .Description("Packs all the different parts of the project.") + .Does(() => + { + foreach(var project in projects) + { + var projectName = GetProjectName(project); + + Information("Packing '{0}'...", projectName); + var path = System.IO.Path.Combine(publishDir, projectName); + var files = GetFiles(path + "/*.*"); + Zip( + path, + System.IO.Path.Combine(artifactsDir, $"{projectName}.zip"), + files); + Information("'{0}' has been packed.", projectName); + } + }); + +Task("Run-Local") + .Description("Runs all the acceptance tests locally.") + .Does(() => + { + var settings = new ProcessSettings + { + Arguments = "local invoke \"HelloWorld\" -e event.json", + }; + + Information("Starting the SAM local..."); + using(var process = StartAndReturnProcess("sam", settings)) + { + process.WaitForExit(); + Information("Exit code: {0}", process.GetExitCode()); + } + Information("SAM local has finished."); + }); + +/////////////////////////////////////////////////////////////////////////////// +// TARGETS +/////////////////////////////////////////////////////////////////////////////// + +Task("Package") + .Description("This is the task which will run if target Package is passed in.") + .IsDependentOn("Clean") + .IsDependentOn("Restore") + .IsDependentOn("Build") + .IsDependentOn("Publish") + .IsDependentOn("Pack") + .Does(() => { Information("Package target ran."); }); + +Task("Run") + .Description("This is the task which will run if target Run is passed in.") + .IsDependentOn("Clean") + .IsDependentOn("Restore") + .IsDependentOn("Build") + .IsDependentOn("Publish") + .IsDependentOn("Pack") + .IsDependentOn("Run-Local") + .Does(() => { Information("Run target ran."); }); + +Task("Default") + .Description("This is the default task which will run if no specific target is passed in.") + .IsDependentOn("Run"); + +/////////////////////////////////////////////////////////////////////////////// +// EXECUTION +/////////////////////////////////////////////////////////////////////////////// + +RunTarget(target); diff --git a/samples/hello-world/dotnetcore2.0/build.ps1 b/samples/hello-world/dotnetcore2.0/build.ps1 new file mode 100644 index 0000000000..82529cf602 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/build.ps1 @@ -0,0 +1,235 @@ +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER ShowDescription +Shows description about tasks. +.PARAMETER DryRun +Performs a dry run. +.PARAMETER Experimental +Uses the nightly builds of the Roslyn script engine. +.PARAMETER Mono +Uses the Mono Compiler rather than the Roslyn script engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +https://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "build.cake", + [string]$Target, + [string]$Configuration, + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity, + [switch]$ShowDescription, + [Alias("WhatIf", "Noop")] + [switch]$DryRun, + [switch]$Experimental, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null +function MD5HashFile([string] $filePath) +{ + if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) + { + return $null + } + + [System.IO.Stream] $file = $null; + [System.Security.Cryptography.MD5] $md5 = $null; + try + { + $md5 = [System.Security.Cryptography.MD5]::Create() + $file = [System.IO.File]::OpenRead($filePath) + return [System.BitConverter]::ToString($md5.ComputeHash($file)) + } + finally + { + if ($file -ne $null) + { + $file.Dispose() + } + } +} + +function GetProxyEnabledWebClient +{ + $wc = New-Object System.Net.WebClient + $proxy = [System.Net.WebRequest]::GetSystemWebProxy() + $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials + $wc.Proxy = $proxy + return $wc +} + +Write-Host "Preparing to run build script..." + +if(!$PSScriptRoot){ + $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent +} + +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" +$MODULES_DIR = Join-Path $TOOLS_DIR "Modules" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" +$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" +$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" +$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + + # Check for changes in packages.config and remove installed tools if true. + [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) + if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or + ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { + Write-Verbose -Message "Missing or changed package.config hash..." + Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | + Remove-Item -Recurse + } + + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet tools." + } + else + { + $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" + } + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore addins from NuGet +if (Test-Path $ADDINS_PACKAGES_CONFIG) { + Push-Location + Set-Location $ADDINS_DIR + + Write-Verbose -Message "Restoring addins from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet addins." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore modules from NuGet +if (Test-Path $MODULES_PACKAGES_CONFIG) { + Push-Location + Set-Location $MODULES_DIR + + Write-Verbose -Message "Restoring modules from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet modules." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + + + +# Build Cake arguments +$cakeArguments = @("$Script"); +if ($Target) { $cakeArguments += "-target=$Target" } +if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } +if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } +if ($ShowDescription) { $cakeArguments += "-showdescription" } +if ($DryRun) { $cakeArguments += "-dryrun" } +if ($Experimental) { $cakeArguments += "-experimental" } +if ($Mono) { $cakeArguments += "-mono" } +$cakeArguments += $ScriptArgs + +# Start Cake +Write-Host "Running build script..." +&$CAKE_EXE $cakeArguments +exit $LASTEXITCODE diff --git a/samples/hello-world/dotnetcore2.0/build.sh b/samples/hello-world/dotnetcore2.0/build.sh new file mode 100644 index 0000000000..b9e12527f1 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/build.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +########################################################################## +# This is the Cake bootstrapper script for Linux and OS X. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +# Define directories. +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +TOOLS_DIR=$SCRIPT_DIR/tools +ADDINS_DIR=$TOOLS_DIR/Addins +MODULES_DIR=$TOOLS_DIR/Modules +NUGET_EXE=$TOOLS_DIR/nuget.exe +CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe +PACKAGES_CONFIG=$TOOLS_DIR/packages.config +PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum +ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config +MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config + +# Define md5sum or md5 depending on Linux/OSX +MD5_EXE= +if [[ "$(uname -s)" == "Darwin" ]]; then + MD5_EXE="md5 -r" +else + MD5_EXE="md5sum" +fi + +# Define default arguments. +SCRIPT="build.cake" +CAKE_ARGUMENTS=() + +# Parse arguments. +for i in "$@"; do + case $1 in + -s|--script) SCRIPT="$2"; shift ;; + --) shift; CAKE_ARGUMENTS+=("$@"); break ;; + *) CAKE_ARGUMENTS+=("$1") ;; + esac + shift +done + +# Make sure the tools folder exist. +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" +fi + +# Make sure that packages.config exist. +if [ ! -f "$TOOLS_DIR/packages.config" ]; then + echo "Downloading packages.config..." + curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages + if [ $? -ne 0 ]; then + echo "An error occurred while downloading packages.config." + exit 1 + fi +fi + +# Download NuGet if it does not exist. +if [ ! -f "$NUGET_EXE" ]; then + echo "Downloading NuGet..." + curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + if [ $? -ne 0 ]; then + echo "An error occurred while downloading nuget.exe." + exit 1 + fi +fi + +# Restore tools from NuGet. +pushd "$TOOLS_DIR" >/dev/null +if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then + find . -type d ! -name . ! -name 'Cake.Bakery' | xargs rm -rf +fi + +mono "$NUGET_EXE" install -ExcludeVersion +if [ $? -ne 0 ]; then + echo "Could not restore NuGet tools." + exit 1 +fi + +$MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5" + +popd >/dev/null + +# Restore addins from NuGet. +if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then + pushd "$ADDINS_DIR" >/dev/null + + mono "$NUGET_EXE" install -ExcludeVersion + if [ $? -ne 0 ]; then + echo "Could not restore NuGet addins." + exit 1 + fi + + popd >/dev/null +fi + +# Restore modules from NuGet. +if [ -f "$MODULES_PACKAGES_CONFIG" ]; then + pushd "$MODULES_DIR" >/dev/null + + mono "$NUGET_EXE" install -ExcludeVersion + if [ $? -ne 0 ]; then + echo "Could not restore NuGet modules." + exit 1 + fi + + popd >/dev/null +fi + +# Make sure that Cake has been installed. +if [ ! -f "$CAKE_EXE" ]; then + echo "Could not find Cake.exe at '$CAKE_EXE'." + exit 1 +fi + +# Start Cake +exec mono "$CAKE_EXE" $SCRIPT "${CAKE_ARGUMENTS[@]}" diff --git a/samples/hello-world/dotnetcore2.0/event.json b/samples/hello-world/dotnetcore2.0/event.json new file mode 100644 index 0000000000..eecea441bd --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/event.json @@ -0,0 +1,4 @@ +{ + "name": "John Doe", + "age": 11 +} \ No newline at end of file diff --git a/samples/hello-world/dotnetcore2.0/src/HelloWorld/Event.cs b/samples/hello-world/dotnetcore2.0/src/HelloWorld/Event.cs new file mode 100644 index 0000000000..608835a3e6 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/src/HelloWorld/Event.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace HelloWorld +{ + public class Event + { + [JsonConstructor] + public Event(string name, int age) + { + Name = name; + Age = age; + } + + internal string Name { get; } + internal int Age { get; } + } +} \ No newline at end of file diff --git a/samples/hello-world/dotnetcore2.0/src/HelloWorld/Function.cs b/samples/hello-world/dotnetcore2.0/src/HelloWorld/Function.cs new file mode 100644 index 0000000000..efa7e22275 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/src/HelloWorld/Function.cs @@ -0,0 +1,17 @@ +using Amazon.Lambda.Core; +using Amazon.Lambda.Serialization.Json; + +// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. +[assembly: LambdaSerializer(typeof(JsonSerializer))] + +namespace HelloWorld +{ + public class Function + { + public void Handler(Event @event, ILambdaContext context) + { + context.Logger.Log($"The name is '{@event.Name}'."); + context.Logger.Log($"The age is '{@event.Age}'."); + } + } +} \ No newline at end of file diff --git a/samples/hello-world/dotnetcore2.0/src/HelloWorld/HelloWorld.csproj b/samples/hello-world/dotnetcore2.0/src/HelloWorld/HelloWorld.csproj new file mode 100644 index 0000000000..d3ad1149e5 --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/src/HelloWorld/HelloWorld.csproj @@ -0,0 +1,18 @@ + + + netcoreapp2.0 + + + João Rosa + False + 1.0.0 + 1.0.0 + 1.0.0 + 1.0.0 + Copyright (c) 2018 João Rosa + + + + + + \ No newline at end of file diff --git a/samples/hello-world/dotnetcore2.0/template.yml b/samples/hello-world/dotnetcore2.0/template.yml new file mode 100644 index 0000000000..91effe14bc --- /dev/null +++ b/samples/hello-world/dotnetcore2.0/template.yml @@ -0,0 +1,11 @@ +AWSTemplateFormatVersion: 2010-09-09 +Transform: AWS::Serverless-2016-10-31 +Description: dotnetcore2.0 Hello World + +Resources: + HelloWorld: + Type: AWS::Serverless::Function + Properties: + Handler: HelloWorld::HelloWorld.Function::Handler + CodeUri: ./artifacts/HelloWorld.zip + Runtime: dotnetcore2.0 \ No newline at end of file