// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using System; using System.Linq; using System.Text; using System.Threading.Tasks; using AWS.Deploy.Common; using AWS.Deploy.Common.IO; using AWS.Deploy.Orchestration.Utilities; namespace AWS.Deploy.Orchestration.CDK { /// /// Abstracts low level node package manager commands to list and install CDK CLI /// in high level APIs. /// public interface ICDKInstaller { /// /// Gets CDK CLI version installed using npx command. /// It checks for local as well as global version /// /// Directory for local node app. /// object wrapped in Task> GetVersion(string workingDirectory); /// /// Installs local version of the AWS SDK CLI in the given working directory /// /// Directory for local node app. /// CDK CLI version to update Task Install(string workingDirectory, Version version); } public class CDKInstaller : ICDKInstaller { private readonly ICommandLineWrapper _commandLineWrapper; private readonly IDirectoryManager _directoryManager; public CDKInstaller(ICommandLineWrapper commandLineWrapper, IDirectoryManager directoryManager) { _commandLineWrapper = commandLineWrapper; _directoryManager = directoryManager; } public async Task> GetVersion(string workingDirectory) { const string command = "npx --no-install cdk --version"; if (!_directoryManager.Exists(workingDirectory)) _directoryManager.CreateDirectory(workingDirectory); TryRunResult result; try { result = await _commandLineWrapper.TryRunWithResult(command, workingDirectory, false); } catch (Exception exception) { throw new NPMCommandFailedException(DeployToolErrorCode.FailedToGetCDKVersion, $"Failed to execute {command}", exception); } var standardOut = result.StandardOut ?? ""; var lines = standardOut.Split(Environment.NewLine).Where(line => !string.IsNullOrWhiteSpace(line)).ToArray(); if (lines.Length < 1) { return TryGetResult.Failure(); } var versionLine = lines.Last(); /* * Split the last line which has the version * typical version line: 1.127.0 (build 0ea309a) * * part 0: 1.127.0 * part 1: build * part 2: 0ea309a * * It could be possible we have more than 3 parts with more information but they can be ignored. */ var parts = versionLine.Split(' ', '(', ')').Where(part => !string.IsNullOrWhiteSpace(part)).ToArray(); if (parts.Length < 3) { return TryGetResult.Failure(); } if (Version.TryParse(parts[0], out var version)) { return TryGetResult.FromResult(version); } return TryGetResult.Failure(); } public async Task Install(string workingDirectory, Version version) { await _commandLineWrapper.Run($"npm install aws-cdk@{version}", workingDirectory, false); } } }