Skip to content

Commit

Permalink
add cake process and filesystem structure
Browse files Browse the repository at this point in the history
remove System.CommandLine
fix cli quotation problems
  • Loading branch information
Blind-Striker committed May 6, 2020
1 parent f6d8e16 commit 1583d66
Show file tree
Hide file tree
Showing 36 changed files with 3,217 additions and 187 deletions.
124 changes: 104 additions & 20 deletions src/LocalStack.AwsLocal/CommandDispatcher.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using LocalStack.AwsLocal.AmbientContexts;
using LocalStack.AwsLocal.Contracts;
using LocalStack.AwsLocal.Extensions;
using LocalStack.AwsLocal.ProcessCore;
using LocalStack.AwsLocal.ProcessCore.IO;
using LocalStack.Client.Contracts;
using LocalStack.Client.Models;

Expand All @@ -14,18 +18,16 @@ public class CommandDispatcher
{
private const string UsageResource = "LocalStack.AwsLocal.Docs.Usage.txt";

private readonly IProcessHelper _processHelper;
private readonly IProcessRunner _processRunner;
private readonly IConfig _config;
private readonly IFileSystem _fileSystem;
private readonly string[] _args;

private CommandDispatcher()
public CommandDispatcher(IProcessRunner processRunner, IConfig config, IFileSystem fileSystem, string[] args)
{
}

public CommandDispatcher(IProcessHelper processHelper, IConfig config, string[] args)
{
_processHelper = processHelper;
_processRunner = processRunner;
_config = config;
_fileSystem = fileSystem;
_args = args;
}

Expand Down Expand Up @@ -57,31 +59,113 @@ public void Run()
return;
}

string cliCommand = _args.GetCliCommand(awsServiceEndpoint.ServiceUrl);
var processSettings = new ProcessSettings
{ NoWorkingDirectory = true, Silent = true, EnvironmentVariables = new Dictionary<string, string>() };
processSettings.EnvironmentVariables.Add("AWS_DEFAULT_REGION", Environment.GetEnvironmentVariable("AWS_DEFAULT_REGION") ?? "us-east-1");
processSettings.EnvironmentVariables.Add("AWS_ACCESS_KEY_ID", Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID") ?? "_not_needed_locally_");
processSettings.EnvironmentVariables.Add("AWS_SECRET_ACCESS_KEY", Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY") ?? "_not_needed_locally_");


var builder = new ProcessArgumentBuilder();
builder.Append(_args[0]);
builder.AppendSwitch("--endpoint-url", "=", awsServiceEndpoint.ServiceUrl);

if (awsServiceEndpoint.ServiceUrl.StartsWith("https"))
{
builder.Append("--no-verify-ssl");
}

var passToNextArgument = false;
for (var i = 0; i < _args.Length; i++)
{
string argument = _args[i];

if (argument == _args[0])
{
continue;
}

if (passToNextArgument)
{
passToNextArgument = false;
continue;
}


if (argument.StartsWith("--") && !argument.Contains("=") && i + 1 < _args.Length) // switch argument
{
string nextArgument = _args[i + 1];
builder.AppendSwitchQuoted(argument, " ", nextArgument);

passToNextArgument = true;
continue;
}

builder.Append(argument);
}


string awsDefaultRegion = Environment.GetEnvironmentVariable("AWS_DEFAULT_REGION") ?? "us-east-1";
string awsAccessKeyId = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID") ?? "_not_needed_locally_";
string awsSecretAccessKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY") ?? "_not_needed_locally_";
processSettings.Arguments = builder;

_processHelper.CmdExecute(cliCommand, null, true, true, new Dictionary<string, string>
string awsExec = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "aws.cmd" : "aws";
FilePath? awsPath = GetAwsPath(awsExec);

if (awsPath == null)
{
{"AWS_DEFAULT_REGION", awsDefaultRegion},
{"AWS_ACCESS_KEY_ID", awsAccessKeyId},
{"AWS_SECRET_ACCESS_KEY", awsSecretAccessKey}
});
ConsoleContext.Current.WriteLine($"ERROR: Unable to find aws cli");
EnvironmentContext.Current.Exit(1);
return;
}

IProcess? process = _processRunner.Start(awsPath, processSettings);

process?.WaitForExit();
}

private static string GetUsageInfo()
{
using (Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream(UsageResource))
using Stream? stream = Assembly.GetCallingAssembly().GetManifestResourceStream(UsageResource);
using var reader = new StreamReader(stream ?? throw new NullReferenceException(nameof(stream)));
string result = reader.ReadToEnd();

return result;
}

private FilePath? GetAwsPath(params string[] awsPaths)
{
string[]? pathDirs = null;

// Look for each possible executable name in various places.
foreach (string toolExeName in awsPaths)
{
using (var reader = new StreamReader(stream))

// Cache the PATH directory list if we didn't already.
if (pathDirs == null)
{
string result = reader.ReadToEnd();
string? pathEnv = Environment.GetEnvironmentVariable("PATH");
if (!string.IsNullOrEmpty(pathEnv))
{
pathDirs = pathEnv.Split(new[] { !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ':' : ';' },
StringSplitOptions.RemoveEmptyEntries);
}
else
{
pathDirs = new string[] { };
}
}

return result;
// Look in every PATH directory for the file.
foreach (var pathDir in pathDirs)
{
FilePath file = new DirectoryPath(pathDir).CombineWithFilePath(toolExeName);
if (_fileSystem.Exist(file))
{
return file.FullPath;
}
}
}

return null;
}
}
}
57 changes: 57 additions & 0 deletions src/LocalStack.AwsLocal/Contracts/IDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/***************************************************************************************
* Title: cake-build/cake
* Author: Mattias Karlsson, Patrik Svensson, Gary Ewan Park, Dave Glick
* Date: 01.05.2020
* Code version: commit: 0c46856abe976f6c122f05a5e82ccb854fd923c1
* Availability: https://github.com/cake-build/cake/blob/develop/src/Cake.Core/IO/IDirectory.cs
*
***************************************************************************************/

using System.Collections.Generic;
using LocalStack.AwsLocal.ProcessCore.IO;

namespace LocalStack.AwsLocal.Contracts
{
/// Represents a directory.
public interface IDirectory : IFileSystemInfo
{
/// <summary>
/// Gets the path to the directory.
/// </summary>
/// <value>The path.</value>
new DirectoryPath? Path { get; }

/// <summary>
/// Creates the directory.
/// </summary>
void Create();

/// <summary>
/// Moves the directory to the specified destination path.
/// </summary>
/// <param name="destination">The destination path.</param>
void Move(DirectoryPath destination);

/// <summary>
/// Deletes the directory.
/// </summary>
/// <param name="recursive">Will perform a recursive delete if set to <c>true</c>.</param>
void Delete(bool recursive);

/// <summary>
/// Gets directories matching the specified filter and scope.
/// </summary>
/// <param name="filter">The filter.</param>
/// <param name="scope">The search scope.</param>
/// <returns>Directories matching the filter and scope.</returns>
IEnumerable<IDirectory> GetDirectories(string filter, SearchScope scope);

/// <summary>
/// Gets files matching the specified filter and scope.
/// </summary>
/// <param name="filter">The filter.</param>
/// <param name="scope">The search scope.</param>
/// <returns>Files matching the specified filter and scope.</returns>
IEnumerable<IFile> GetFiles(string filter, SearchScope scope);
}
}
65 changes: 65 additions & 0 deletions src/LocalStack.AwsLocal/Contracts/IFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/***************************************************************************************
* Title: cake-build/cake
* Author: Mattias Karlsson, Patrik Svensson, Gary Ewan Park, Dmytro Dziuma
* Date: 01.05.2020
* Code version: commit: 0c46856abe976f6c122f05a5e82ccb854fd923c1
* Availability: https://github.com/cake-build/cake/blob/develop/src/Cake.Core/IO/IFile.cs
*
***************************************************************************************/

using System.IO;
using LocalStack.AwsLocal.ProcessCore.IO;

namespace LocalStack.AwsLocal.Contracts
{
/// <summary>
/// Represents a file.
/// </summary>
public interface IFile : IFileSystemInfo
{
/// <summary>
/// Gets the path to the file.
/// </summary>
/// <value>The path.</value>
new FilePath? Path { get; }

/// <summary>
/// Gets the length of the file.
/// </summary>
/// <value>The length of the file.</value>
long Length { get; }

/// <summary>
/// Gets or sets the file attributes.
/// </summary>
/// <value>The file attributes.</value>
FileAttributes Attributes { get; set; }

/// <summary>
/// Copies the file to the specified destination path.
/// </summary>
/// <param name="destination">The destination path.</param>
/// <param name="overwrite">Will overwrite existing destination file if set to <c>true</c>.</param>
void Copy(FilePath destination, bool overwrite);

/// <summary>
/// Moves the file to the specified destination path.
/// </summary>
/// <param name="destination">The destination path.</param>
void Move(FilePath destination);

/// <summary>
/// Deletes the file.
/// </summary>
void Delete();

/// <summary>
/// Opens the file using the specified options.
/// </summary>
/// <param name="fileMode">The file mode.</param>
/// <param name="fileAccess">The file access.</param>
/// <param name="fileShare">The file share.</param>
/// <returns>A <see cref="Stream"/> to the file.</returns>
Stream Open(FileMode fileMode, FileAccess fileAccess, FileShare fileShare);
}
}
33 changes: 33 additions & 0 deletions src/LocalStack.AwsLocal/Contracts/IFileSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/***************************************************************************************
* Title: cake-build/cake
* Author: Mattias Karlsson, Patrik Svensson, Gary Ewan Park
* Date: 01.05.2020
* Code version: commit: 0c46856abe976f6c122f05a5e82ccb854fd923c1
* Availability: https://github.com/cake-build/cake/blob/develop/src/Cake.Core/IO/IFileSystem.cs
*
***************************************************************************************/

using LocalStack.AwsLocal.ProcessCore.IO;

namespace LocalStack.AwsLocal.Contracts
{
/// <summary>
/// Represents a file system.
/// </summary>
public interface IFileSystem
{
/// <summary>
/// Gets a <see cref="IFile"/> instance representing the specified path.
/// </summary>
/// <param name="path">The path.</param>
/// <returns>A <see cref="IFile"/> instance representing the specified path.</returns>
IFile GetFile(FilePath path);

/// <summary>
/// Gets a <see cref="IDirectory"/> instance representing the specified path.
/// </summary>
/// <param name="path">The path.</param>
/// <returns>A <see cref="IDirectory"/> instance representing the specified path.</returns>
IDirectory GetDirectory(DirectoryPath path);
}
}
41 changes: 41 additions & 0 deletions src/LocalStack.AwsLocal/Contracts/IFileSystemInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/***************************************************************************************
* Title: cake-build/cake
* Author: Mattias Karlsson, Gary Ewan Park
* Date: 01.05.2020
* Code version: commit: 0c46856abe976f6c122f05a5e82ccb854fd923c1
* Availability: https://github.com/cake-build/cake/blob/develop/src/Cake.Core/IO/IFileSystemInfo.cs
*
***************************************************************************************/

using LocalStack.AwsLocal.ProcessCore.IO;

namespace LocalStack.AwsLocal.Contracts
{
/// <summary>
/// Represents an entry in the file system
/// </summary>
public interface IFileSystemInfo
{
/// <summary>
/// Gets the path to the entry.
/// </summary>
/// <value>The path.</value>
Path? Path { get; }

/// <summary>
/// Gets a value indicating whether this <see cref="IFileSystemInfo"/> exists.
/// </summary>
/// <value>
/// <c>true</c> if the entry exists; otherwise, <c>false</c>.
/// </value>
bool Exists { get; }

/// <summary>
/// Gets a value indicating whether this <see cref="IFileSystemInfo"/> is hidden.
/// </summary>
/// <value>
/// <c>true</c> if the entry is hidden; otherwise, <c>false</c>.
/// </value>
bool Hidden { get; }
}
}
Loading

0 comments on commit 1583d66

Please sign in to comment.