Skip to content

Commit

Permalink
Merge pull request #553 from WildernessLabs/dominique-Fix546
Browse files Browse the repository at this point in the history
Add subfolder reading, writing, deleting and deployment
  • Loading branch information
adrianstevens authored Apr 30, 2024
2 parents b05d434 + 974b16c commit f3a2476
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 31 deletions.
30 changes: 30 additions & 0 deletions Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Meadow.CLI.Commands.DeviceManagement;

internal static class AppTools
{
internal const string MeadowRootFolder = "meadow0";

internal static string ValidateAndSanitizeAppPath(string? path)
{
path ??= Directory.GetCurrentDirectory();
Expand Down Expand Up @@ -95,4 +97,32 @@ internal static async Task<bool> TrimApplication(string path,

return true;
}

internal static string SanitiseMeadowFilename(string fileName)
{
var folder = Path.GetDirectoryName(fileName);
if (string.IsNullOrWhiteSpace(folder))
{
folder = MeadowRootFolder;
}
else
{
if (folder.EndsWith('/') == false)
{
folder += "/";
}
if (folder.StartsWith('/') == false)
{
folder = $"/{folder}";
}
if (folder.Contains(MeadowRootFolder) == false)
{
folder = $"/{MeadowRootFolder}{folder}";
}
}

var meadowFileName = Path.Combine(folder, Path.GetFileName(fileName));

return meadowFileName!.Replace(Path.DirectorySeparatorChar, '/');
}
}
25 changes: 13 additions & 12 deletions Source/v2/Meadow.Cli/Commands/Current/File/FileDeleteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public class FileDeleteCommand : BaseDeviceCommand<FileDeleteCommand>
[CommandParameter(0, Name = "MeadowFile", IsRequired = true)]
public string MeadowFile { get; init; } = default!;

private const string MeadowRootFolder = "meadow0";

public FileDeleteCommand(MeadowConnectionManager connectionManager, ILoggerFactory loggerFactory)
: base(connectionManager, loggerFactory)
{ }
Expand All @@ -33,10 +31,10 @@ protected override async ValueTask ExecuteCommand()
var folder = Path.GetDirectoryName(MeadowFile)!.Replace(Path.DirectorySeparatorChar, '/');
if (string.IsNullOrWhiteSpace(folder))
{
folder = MeadowRootFolder;
folder = $"/{AppTools.MeadowRootFolder}/";
}

var fileList = await connection.GetFileList($"/{folder}/", false);
var fileList = await connection.GetFileList($"{folder}", false, CancellationToken);

if (fileList == null || fileList.Length == 0)
{
Expand All @@ -48,7 +46,7 @@ protected override async ValueTask ExecuteCommand()
{
foreach (var file in fileList)
{
await DeleteFileRecursive(device, file, CancellationToken);
await DeleteFileRecursive(device, folder, file, CancellationToken);
}
}
else
Expand All @@ -72,26 +70,29 @@ protected override async ValueTask ExecuteCommand()
}

Logger?.LogInformation($"Deleting file '{MeadowFile}' from device...");
await device.DeleteFile(MeadowFile, CancellationToken);
await device.DeleteFile(AppTools.SanitiseMeadowFilename(MeadowFile), CancellationToken);
}
}
}

private async Task DeleteFileRecursive(IMeadowDevice device, MeadowFileInfo fileInfo, CancellationToken cancellationToken)
private async Task DeleteFileRecursive(IMeadowDevice device, string directoryname, MeadowFileInfo fileInfo, CancellationToken cancellationToken)
{
var meadowFile = AppTools.SanitiseMeadowFilename(Path.Combine(directoryname, fileInfo.Name));
if (fileInfo.IsDirectory)
{
var subfolderFiles = await device.GetFileList(fileInfo.Name, false, cancellationToken);
// Add a backslash as we're a directory and not a file
meadowFile += "/";
var subfolderFiles = await device.GetFileList(meadowFile, false, cancellationToken);

foreach (var subfolderFile in subfolderFiles)
{
await DeleteFileRecursive(device, subfolderFile, cancellationToken);
await DeleteFileRecursive(device, meadowFile, subfolderFile, cancellationToken);
}
return;
}

var fileName = Path.GetFileName(fileInfo.Name);
Logger?.LogInformation($"Deleting file '{fileName}' from device...");
await device.DeleteFile(fileName, cancellationToken);
Logger?.LogInformation($"Deleting file '{meadowFile}' from device...");

await device.DeleteFile(meadowFile, cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected override async ValueTask ExecuteCommand()

Logger?.LogInformation($"Reading file '{MeadowFile}' from device...\n");

var data = await device.ReadFileString(MeadowFile, CancellationToken);
var data = await device.ReadFileString(AppTools.SanitiseMeadowFilename(MeadowFile), CancellationToken);

if (data == null)
{
Expand Down
16 changes: 2 additions & 14 deletions Source/v2/Meadow.Cli/Commands/Current/File/FileListCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public class FileListCommand : BaseDeviceCommand<FileListCommand>
{
public const int FileSystemBlockSize = 4096;

private const string MeadowRootFolder = "meadow0";
private const string FolderLabel = "[folder]";

[CommandOption("verbose", 'v', IsRequired = false)]
Expand All @@ -27,18 +26,7 @@ protected override async ValueTask ExecuteCommand()

if (Folder != null)
{
if (Folder.EndsWith('/') == false)
{
Folder += "/";
}
if (Folder.StartsWith('/') == false)
{
Folder = $"/{Folder}";
}
if (Folder.Contains(MeadowRootFolder) == false)
{
Folder = $"/{MeadowRootFolder}{Folder}";
}
Folder = AppTools.SanitiseMeadowFilename(Folder);

Logger?.LogInformation($"Getting file list from '{Folder}'...");
}
Expand All @@ -47,7 +35,7 @@ protected override async ValueTask ExecuteCommand()
Logger?.LogInformation($"Getting file list...");
}

var files = await device.GetFileList(Folder ?? $"/{MeadowRootFolder}/", Verbose, CancellationToken);
var files = await device.GetFileList(Folder ?? $"/{AppTools.MeadowRootFolder}/", Verbose, CancellationToken);

if (files == null || files.Length == 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected override async ValueTask ExecuteCommand()
await device.RuntimeDisable();
}

var success = await device.ReadFile(MeadowFile, LocalFile, CancellationToken);
var success = await device.ReadFile(AppTools.SanitiseMeadowFilename(MeadowFile), LocalFile, CancellationToken);

if (success)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected override async ValueTask ExecuteCommand()
}
else
{
var targetFileName = GetTargetFileName(i);
var targetFileName = AppTools.SanitiseMeadowFilename(GetTargetFileName(i));

Logger?.LogInformation(
$"Writing '{Files[i]}' as '{targetFileName}' to device");
Expand Down
27 changes: 25 additions & 2 deletions Source/v2/Meadow.Tooling.Core/App/AppManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static async Task DeployApplication(
dependencies.Add(Path.Combine(localBinaryDirectory, "App.pdb"));
}

var binaries = Directory.EnumerateFiles(localBinaryDirectory, "*.*", SearchOption.TopDirectoryOnly)
var binaries = Directory.EnumerateFiles(localBinaryDirectory, "*.*", SearchOption.AllDirectories)
.Where(s => new FileInfo(s).Extension != ".dll")
.Where(s => new FileInfo(s).Extension != ".pdb")
.Where(s => !s.Contains(".DS_Store")).ToList();
Expand Down Expand Up @@ -127,6 +127,20 @@ public static async Task DeployApplication(
// now send all files with differing CRCs
foreach (var localFile in localFiles)
{
string? meadowFilename = string.Empty;
if (!localFile.Key.Contains(MeadowLinker.PreLinkDirectoryName)
&& !localFile.Key.Contains(MeadowLinker.PostLinkDirectoryName))
{
meadowFilename = GetRelativePath(localBinaryDirectory, localFile.Key);
if (!meadowFilename.StartsWith("/meadow0/"))
{
meadowFilename = "/meadow0/" + meadowFilename;
}
}
else
{
meadowFilename = null;
}
var existing = deviceFiles.FirstOrDefault(f => Path.GetFileName(f.Name) == Path.GetFileName(localFile.Key));

if (existing != null && existing.Crc != null)
Expand All @@ -139,9 +153,10 @@ public static async Task DeployApplication(
}
}

logger?.LogInformation($"Sending '{localFile.Key}'");
send_file:

if (!await connection.WriteFile(localFile.Key, null, cancellationToken))
if (!await connection.WriteFile(localFile.Key, meadowFilename, cancellationToken))
{
logger?.LogWarning($"Error sending'{Path.GetFileName(localFile.Key)}' - retrying");
await Task.Delay(100);
Expand All @@ -152,4 +167,12 @@ public static async Task DeployApplication(
//on macOS, if we don't write a blank line we lose the writing notifcation for the last file
logger?.LogInformation(string.Empty);
}

// Path.GetRelativePath is only available in .NET 8 but we also need to support netstandard2.0, hence using this
static string GetRelativePath(string relativeTo, string path)
{
// Determine the difference
var relativePath = path.Substring(relativeTo.Length + 1);
return relativePath;
}
}

0 comments on commit f3a2476

Please sign in to comment.