// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using System; using System.IO; using System.Threading.Tasks; using AWS.Deploy.Common; using AWS.Deploy.Common.IO; using AWS.Deploy.Orchestration.Utilities; namespace AWS.Deploy.Orchestration.CDK { /// /// Orchestrates local node app. /// It makes sure that a local node application is initialized in order to be able to /// install CDK CLI in local node_modules. /// /// /// When npm package is initialized, a specified version of CDK CLI is installed along with initialization. /// public interface INPMPackageInitializer { /// /// Checks whether package.json file exists at given working directory or not. /// If there exists a package.json file, it is assumed to have node initialized. /// /// Directory for local node app. /// True, if package.json exists at bool IsInitialized(string workingDirectory); /// /// Initializes npm package at /// /// /// When npm package is initialized, a specified version of CDK CLI is installed along with installation. /// w /// Directory for local node app. /// Version of CDK CLI. /// Thrown when package.json IO fails. /// Thrown when a npm command fails to execute. Task Initialize(string workingDirectory, Version cdkVersion); } public class NPMPackageInitializer : INPMPackageInitializer { private readonly ICommandLineWrapper _commandLineWrapper; private readonly IPackageJsonGenerator _packageJsonGenerator; private readonly IFileManager _fileManager; private readonly IDirectoryManager _directoryManager; private readonly IOrchestratorInteractiveService _interactiveService; private const string _packageJsonFileName = "package.json"; public NPMPackageInitializer(ICommandLineWrapper commandLineWrapper, IPackageJsonGenerator packageJsonGenerator, IFileManager fileManager, IDirectoryManager directoryManager, IOrchestratorInteractiveService interactiveService) { _commandLineWrapper = commandLineWrapper; _packageJsonGenerator = packageJsonGenerator; _fileManager = fileManager; _directoryManager = directoryManager; _interactiveService = interactiveService; } public bool IsInitialized(string workingDirectory) { var packageFilePath = Path.Combine(workingDirectory, _packageJsonFileName); return _fileManager.Exists(packageFilePath); } public async Task Initialize(string workingDirectory, Version cdkVersion) { _interactiveService.LogDebugMessage($"Creating package.json at {workingDirectory}."); var packageJsonFileContent = _packageJsonGenerator.Generate(cdkVersion); var packageJsonFilePath = Path.Combine(workingDirectory, _packageJsonFileName); try { if (!_directoryManager.Exists(workingDirectory)) { _directoryManager.CreateDirectory(workingDirectory); } await _fileManager.WriteAllTextAsync(packageJsonFilePath, packageJsonFileContent); } catch (Exception exception) { throw new PackageJsonFileException(DeployToolErrorCode.FailedToWritePackageJsonFile, $"Failed to write {_packageJsonFileName} at {packageJsonFilePath}", exception); } try { // Install node packages specified in package.json file await _commandLineWrapper.Run("npm install", workingDirectory, false); } catch (Exception exception) { throw new NPMCommandFailedException(DeployToolErrorCode.FailedToInstallNpmPackages, $"Failed to install npm packages at {workingDirectory}", exception); } } } }