in src/Amazon.Lambda.Tools/TemplateProcessor/TemplateProcessorManager.cs [140:230]
private async Task<UpdateResourceResults> ProcessUpdatableResourceAsync(string templateDirectory, IUpdateResourceField field, string[] args)
{
UpdateResourceResults results;
var localPath = field.GetLocalPath();
if (!field.IsImagePushed && !Path.IsPathRooted(localPath))
localPath = Path.Combine(templateDirectory, localPath);
bool deleteArchiveAfterUploaded = false;
// If ImageUri needs to be processed.
if (field.IsImagePushed)
{
results = new UpdateResourceResults { ImageUri = localPath };
}
// Uploading a single file as the code for the resource. If the single file is not a zip file then zip the file first.
else if (File.Exists(localPath))
{
if(field.IsCode && !string.Equals(Path.GetExtension(localPath), ".zip", StringComparison.OrdinalIgnoreCase))
{
this.Logger.WriteLine($"Creating zip archive for {localPath} file");
results = new UpdateResourceResults { ZipArchivePath = GenerateOutputZipFilename(field) };
LambdaPackager.BundleFiles(results.ZipArchivePath, Path.GetDirectoryName(localPath), new string[] { localPath }, this.Logger);
}
else
{
results = new UpdateResourceResults { ZipArchivePath = localPath };
}
}
// If IsCode is false then the local path needs to point to a file and not a directory. When IsCode is true
// it can point either to a file or a directory.
else if (!field.IsCode && !File.Exists(localPath))
{
throw new LambdaToolsException($"File that the field {field.Resource.Name}/{field.Name} is pointing to doesn't exist", LambdaToolsException.LambdaErrorCode.ServerlessTemplateMissingLocalPath);
}
else if (!Directory.Exists(localPath))
{
throw new LambdaToolsException($"Directory that the field {field.Resource.Name}/{field.Name} is pointing doesn't exist", LambdaToolsException.LambdaErrorCode.ServerlessTemplateMissingLocalPath);
}
// To maintain compatibility if the field is point to current directory or not set at all but a prepackaged zip archive is given
// then use it as the package source.
else if (IsCurrentDirectory(field.GetLocalPath()) && !string.IsNullOrEmpty(this.DefaultOptions.Package))
{
results = new UpdateResourceResults { ZipArchivePath = this.DefaultOptions.Package };
}
else if(field.IsCode)
{
// If the function is image upload then run the .NET tools to handle running
// docker build even if the current folder is not a .NET project. The .NET
// could be in a sub folder or be a self contained Docker build.
if (IsDotnetProjectDirectory(localPath) || field.Resource.UploadType == CodeUploadType.Image)
{
results = await PackageDotnetProjectAsync(field, localPath, args);
}
else
{
results = new UpdateResourceResults { ZipArchivePath = GenerateOutputZipFilename(field) };
LambdaPackager.BundleDirectory(results.ZipArchivePath, localPath, false, this.Logger);
}
deleteArchiveAfterUploaded = true;
}
else
{
throw new LambdaToolsException($"Unable to determine package action for the field {field.Resource.Name}/{field.Name}", LambdaToolsException.LambdaErrorCode.ServerlessTemplateUnknownActionForLocalPath);
}
if(!string.IsNullOrEmpty(results.ZipArchivePath))
{
string s3Key;
using (var stream = File.OpenRead(results.ZipArchivePath))
{
s3Key = await Utilities.UploadToS3Async(this.Logger, this.S3Client, this.S3Bucket, this.S3Prefix, Path.GetFileName(results.ZipArchivePath), stream);
results.S3Key = s3Key;
}
// Now that the temp zip file is uploaded to S3 clean up by deleting the temp file.
if (deleteArchiveAfterUploaded)
{
try
{
File.Delete(results.ZipArchivePath);
}
catch (Exception e)
{
this.Logger?.WriteLine($"Warning: Unable to delete temporary archive, {results.ZipArchivePath}, after uploading to S3: {e.Message}");
}
}
}
return results;
}