/// <summary>
 /// Initializes a new instance of the <see cref="PackagerUtils"/> class.
 /// </summary>
 /// <param name="pathResolver">The path resolver.</param>
 /// <param name="logger">Logging interface.</param>
 /// <param name="s3Util">S3 utility to use for pushing packaged objects.</param>
 /// <param name="platform">The operating system platform</param>
 // ReSharper disable once StyleCop.SA1305
 public PackagerUtils(IPathResolver pathResolver, ILogger logger, IPSS3Util s3Util, IOSInfo platform)
 {
     this.platform     = platform;
     this.s3Util       = s3Util;
     this.logger       = logger;
     this.pathResolver = pathResolver;
 }
        /// <summary>
        /// Packages the file.
        /// </summary>
        /// <param name="artifact">Single file artifact.</param>
        /// <param name="workingDirectory">The working directory.</param>
        /// <param name="zip">if set to <c>true</c> [zip].</param>
        /// <param name="s3">Interface to S3</param>
        /// <param name="logger">Interface to logger.</param>
        /// <returns>A <see cref="ResourceUploadSettings"/></returns>
        public static async Task <ResourceUploadSettings> PackageFile(
            FileInfo artifact,
            string workingDirectory,
            bool zip,
            IPSS3Util s3,
            ILogger logger)
        {
            ResourceUploadSettings resourceToUpload;

            if (zip && string.Compare(
                    Path.GetExtension(artifact.Name),
                    ".zip",
                    StringComparison.OrdinalIgnoreCase) != 0)
            {
                // Zip if zipping is required and file is not already zipped
                var fileToUpload = Path.Combine(
                    workingDirectory,
                    $"{Path.GetFileNameWithoutExtension(artifact.Name)}.zip");

                resourceToUpload = new ResourceUploadSettings
                {
                    File      = new FileInfo(fileToUpload),
                    Hash      = artifact.MD5(),
                    HashMatch = true,
                    KeyPrefix = s3.KeyPrefix
                };

                if (await s3.ObjectChangedAsync(resourceToUpload))
                {
                    logger.LogVerbose($"Zipping '{artifact.FullName}' to {Path.GetFileName(fileToUpload)}");

                    // Compute hash before zipping as zip hashes not idempotent due to temporally changing attributes in central directory
                    Zipper.Zip(
                        new CrossPlatformZipSettings
                    {
                        Artifacts        = artifact.FullName,
                        CompressionLevel = 9,
                        LogMessage       = m => logger.LogVerbose(m),
                        LogError         = e => logger.LogError(e),
                        ZipFile          = fileToUpload,
                        TargetPlatform   = ZipPlatform.Unix
                    });

                    resourceToUpload.HashMatch = false;
                }
            }
            else
            {
                resourceToUpload = new ResourceUploadSettings {
                    File = artifact, Hash = artifact.MD5()
                };
                resourceToUpload.HashMatch = !await s3.ObjectChangedAsync(resourceToUpload);
            }

            return(resourceToUpload);
        }
        /// <summary>
        /// Package a directory to a zip.
        /// </summary>
        /// <param name="artifact">Path to artifact directory.</param>
        /// <param name="workingDirectory">The working directory.</param>
        /// <param name="s3">Interface to S3</param>
        /// <param name="logger">Interface to logger.</param>
        /// <returns>A <see cref="ResourceUploadSettings"/></returns>
        public static async Task <ResourceUploadSettings> PackageDirectory(
            DirectoryInfo artifact,
            string workingDirectory,
            IPSS3Util s3,
            ILogger logger)
        {
            // Property value points to a directory, which must always be zipped.
            var fileToUpload = Path.Combine(workingDirectory, $"{artifact.Name}.zip");

            // Compute hash before zipping as zip hashes not idempotent due to temporally changing attributes in central directory
            var resourceToUpload = new ResourceUploadSettings
            {
                File      = new FileInfo(fileToUpload),
                Hash      = artifact.MD5(),
                HashMatch = true,
                KeyPrefix = s3.KeyPrefix
            };

            if (await s3.ObjectChangedAsync(resourceToUpload))
            {
                logger.LogVerbose($"Zipping directory '{artifact.FullName}' to {Path.GetFileName(fileToUpload)}");

                Zipper.Zip(
                    new CrossPlatformZipSettings
                {
                    Artifacts        = artifact.FullName,
                    CompressionLevel = 9,
                    LogMessage       = m => logger.LogVerbose(m),
                    LogError         = e => logger.LogError(e),
                    ZipFile          = fileToUpload,
                    TargetPlatform   = ZipPlatform.Unix
                });

                resourceToUpload.HashMatch = false;
            }

            return(resourceToUpload);
        }
        /// <summary>
        /// Factory method to create a runtime specific lambda packager.
        /// </summary>
        /// <param name="lambdaArtifact">The lambda artifact to package</param>
        /// <param name="s3">Interface to S3</param>
        /// <param name="logger">Interface to logger.</param>
        /// <param name="platform">Operating system platform</param>
        /// <returns>Runtime specific subclass of <see cref="LambdaPackager"/></returns>
        public static LambdaPackager CreatePackager(
            LambdaArtifact lambdaArtifact,
            IPSS3Util s3,
            ILogger logger,
            IOSInfo platform)
        {
            if (lambdaArtifact == null)
            {
                throw new ArgumentNullException(nameof(lambdaArtifact));
            }

            // To package dependencies, the lambda must be of a supported runtime.
            // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault - Intentionally so.
            switch (lambdaArtifact.RuntimeInfo.RuntimeType)
            {
            case LambdaRuntimeType.Node:

                return(new LambdaNodePackager(lambdaArtifact, s3, logger));

            case LambdaRuntimeType.Python:

                // Python treats Linux and OSX the same so if not Windows, then Linux packager
                return(platform.OSPlatform == OSPlatform.Windows
                               ? (LambdaPythonPackager) new LambdaPythonPackagerWindows(lambdaArtifact, s3, logger)
                               : new LambdaPythonPackagerLinux(lambdaArtifact, s3, logger));

            case LambdaRuntimeType.Ruby:

                return(new LambdaRubyPackager(lambdaArtifact, s3, logger));

            default:

                logger.LogWarning(
                    $"Dependency packaging for lambda runtime '{lambdaArtifact.RuntimeInfo.RuntimeType}' is currently not supported.");
                return(new LambdaPlainPackager(lambdaArtifact, s3, logger));
            }
        }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LambdaPythonPackagerWindows"/> class.
 /// </summary>
 /// <param name="lambdaArtifact">The lambda artifact to package</param>
 /// <param name="s3">Interface to S3</param>
 /// <param name="logger">Interface to logger.</param>
 public LambdaPythonPackagerWindows(LambdaArtifact lambdaArtifact, IPSS3Util s3, ILogger logger)
     : base(lambdaArtifact, s3, logger)
 {
 }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LambdaPlainPackager"/> class.
 /// </summary>
 /// <param name="lambdaArtifact">The lambda artifact to package</param>
 /// <param name="s3">Interface to S3</param>
 /// <param name="logger">Interface to logger.</param>
 public LambdaPlainPackager(LambdaArtifact lambdaArtifact, IPSS3Util s3, ILogger logger)
     : base(lambdaArtifact, s3, logger)
 {
 }
Beispiel #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LambdaPythonPackager"/> class.
 /// </summary>
 /// <param name="lambdaArtifact">The lambda artifact to package</param>
 /// <param name="s3">Interface to S3</param>
 /// <param name="logger">Interface to logger.</param>
 protected LambdaPythonPackager(LambdaArtifact lambdaArtifact, IPSS3Util s3, ILogger logger)
     : base(lambdaArtifact, s3, logger)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="LambdaPackager"/> class.
 /// </summary>
 /// <param name="lambdaArtifact">The lambda artifact to package</param>
 /// <param name="s3">Interface to S3</param>
 /// <param name="logger">Interface to logger.</param>
 protected LambdaPackager(LambdaArtifact lambdaArtifact, IPSS3Util s3, ILogger logger)
 {
     this.LambdaArtifact = lambdaArtifact;
     this.Logger         = logger;
     this.S3             = s3;
 }
Beispiel #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LambdaSiblingModulePackager"/> class.
 /// </summary>
 /// <param name="lambdaArtifact">The lambda artifact to package</param>
 /// <param name="s3">Interface to S3</param>
 /// <param name="logger">Interface to logger.</param>
 protected LambdaSiblingModulePackager(LambdaArtifact lambdaArtifact, IPSS3Util s3, ILogger logger)
     : base(lambdaArtifact, s3, logger)
 {
 }