// 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);
}
}
}