/**
 * This file is copied from https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts
 */ import * as fs from "fs" ; import * as path from "path" ; import * as cdk from "aws-cdk-lib" ; import * as lambda from "aws-cdk-lib/aws-lambda" ; /**
 * Dependency files to exclude from the asset hash.
 */ export const DEPENDENCY_EXCLUDES = [ "*.pyc" ] ; /**
 * The location in the image that the bundler image caches dependencies.
 */ export const BUNDLER_DEPENDENCIES_CACHE = "/var/dependencies" ; /**
 * Options for bundling
 */ export interface BundlingOptions { /**
     * Entry path
     */ readonly entry : string ; /**
     * The runtime of the lambda function
     */ readonly runtime : lambda . Runtime ; /**
     * Output path suffix ('python' for a layer, '.' otherwise)
     */ readonly outputPathSuffix : string ; default readonly assetHashType ? : cdk . AssetHashType ; default readonly assetHash ? : string ; readonly installCommands ? : string [ ] ; } /**
 * Produce bundled Lambda asset code
 */ export function bundle ( options ) { const { entry , runtime , outputPathSuffix , installCommands } = options ; const stagedir = cdk . FileSystem . mkdtemp ( "python-bundling-" ) ; const hasDeps = stageDependencies ( entry , stagedir ) ; const hasInstallCommands = stageInstallCommands ( installCommands || [ ] , stagedir ) ; const depsCommand = chain ( [ hasDeps || hasInstallCommands ? `rsync -r ${ BUNDLER_DEPENDENCIES_CACHE }/. ${ cdk . AssetStaging . BUNDLING_OUTPUT_DIR }/${ outputPathSuffix }` : "" , `rsync -r . ${ cdk . AssetStaging . BUNDLING_OUTPUT_DIR }/${ outputPathSuffix }` , ] ) ; const dockerfile = hasInstallCommands ? "Dockerfile.custom" : hasDeps ? "Dockerfile.dependencies" : "Dockerfile" ; fs . copyFileSync ( path . join ( __dirname , "../../../assets/python" , dockerfile ) , path . join ( stagedir , dockerfile ) ) ; const image = cdk . DockerImage . fromBuild ( stagedir , { buildArgs : { IMAGE : runtime . bundlingImage . image , } , file : dockerfile , } ) ; return lambda . Code . fromAsset ( entry , { assetHashType : options . assetHashType , assetHash : options . assetHash , exclude : DEPENDENCY_EXCLUDES , bundling : { image , command : [ "bash" , "-c" , depsCommand ] , } , } ) ; } /**
 * Checks to see if the `entry` directory contains a type of dependency that
 * we know how to install.
 */ export function stageDependencies ( entry , stagedir ) { const prefixes = [ "Pipfile" , "pyproject" , "poetry" , "requirements.txt" ] ; let found = false ; for ( const file of fs . readdirSync ( entry ) ) { for ( const prefix of prefixes ) { if ( file . startsWith ( prefix ) ) { fs . copyFileSync ( path . join ( entry , file ) , path . join ( stagedir , file ) ) ; found = true ; } } } return found ; } function stageInstallCommands ( installCommands , stagedir ) { let found = false ; if ( installCommands . length > 0 ) { const filePath = path . join ( stagedir , "sst-deps-install-command.sh" ) ; fs . writeFileSync ( filePath , installCommands . join ( " && " ) ) ; fs . chmodSync ( filePath , "755" ) ; found = true ; } return found ; } function chain ( commands ) { return commands . filter ( ( c ) => ! ! c ) . join ( " && " ) ; }