From 8b32e01b44a404381e7cf43765636f9c0f44ab51 Mon Sep 17 00:00:00 2001 From: Dominique Louis Date: Mon, 17 Jun 2024 13:08:12 +0100 Subject: [PATCH] Add ability to Deploy app after flashing has finished. --- .../Current/Firmware/FirmwareUpdater.cs | 6 +- .../Current/Provision/ProvisionCommand.cs | 82 ++++++++++++++++--- Source/v2/Meadow.Cli/Strings.cs | 5 ++ 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Source/v2/Meadow.CLI/Commands/Current/Firmware/FirmwareUpdater.cs b/Source/v2/Meadow.CLI/Commands/Current/Firmware/FirmwareUpdater.cs index ef3bb308..ef1d4171 100644 --- a/Source/v2/Meadow.CLI/Commands/Current/Firmware/FirmwareUpdater.cs +++ b/Source/v2/Meadow.CLI/Commands/Current/Firmware/FirmwareUpdater.cs @@ -1,13 +1,9 @@ -using System; -using System.Runtime.InteropServices; -using CliFx; -using DfuSharp; +using System.Runtime.InteropServices; using Meadow.CLI.Core.Internals.Dfu; using Meadow.Hcom; using Meadow.LibUsb; using Meadow.Software; using Microsoft.Extensions.Logging; -using YamlDotNet.Serialization; namespace Meadow.CLI.Commands.DeviceManagement; diff --git a/Source/v2/Meadow.CLI/Commands/Current/Provision/ProvisionCommand.cs b/Source/v2/Meadow.CLI/Commands/Current/Provision/ProvisionCommand.cs index 5d556f80..41d9332c 100644 --- a/Source/v2/Meadow.CLI/Commands/Current/Provision/ProvisionCommand.cs +++ b/Source/v2/Meadow.CLI/Commands/Current/Provision/ProvisionCommand.cs @@ -1,16 +1,13 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Management; -using System.Runtime.InteropServices; +using System.Collections.Concurrent; using CliFx.Attributes; using Meadow.CLI.Commands.DeviceManagement; using Meadow.Cloud.Client; using Meadow.LibUsb; +using Meadow.Package; using Meadow.Software; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using Spectre.Console; -using YamlDotNet.Serialization; namespace Meadow.CLI.Commands.Provision; @@ -18,9 +15,15 @@ namespace Meadow.CLI.Commands.Provision; public class ProvisionCommand : BaseDeviceCommand { public const string DefaultOSVersion = "1.12.0.0"; + private string? appPath; + private string? configuration; + [CommandOption("version", 'v', Description = Strings.Provision.CommandOptionVersion, IsRequired = false)] public string? OsVersion { get; set; } = DefaultOSVersion; + [CommandOption("path", 'p', Description = Strings.Provision.CommandOptionPath, IsRequired = false)] + public string? Path { get; set; } + private ConcurrentQueue bootloaderDeviceQueue = new ConcurrentQueue(); private List selectedDeviceList = default!; @@ -28,21 +31,60 @@ public class ProvisionCommand : BaseDeviceCommand private FileManager fileManager; private IMeadowCloudClient meadowCloudClient; private MeadowConnectionManager connectionManager; + private IPackageManager packageManager; + private bool deployApp = true; public ProvisionCommand(ISettingsManager settingsManager, FileManager fileManager, - IMeadowCloudClient meadowCloudClient, MeadowConnectionManager connectionManager, ILoggerFactory loggerFactory) + IMeadowCloudClient meadowCloudClient, IPackageManager packageManager, MeadowConnectionManager connectionManager, ILoggerFactory loggerFactory) : base(connectionManager, loggerFactory) { this.settingsManager = settingsManager; this.fileManager = fileManager; this.meadowCloudClient = meadowCloudClient; this.connectionManager = connectionManager; + this.packageManager = packageManager; } protected override async ValueTask ExecuteCommand() { AnsiConsole.MarkupLine(Strings.Provision.RunningTitle); + string path = AppTools.ValidateAndSanitizeAppPath(Path); + + if (!string.IsNullOrWhiteSpace(path) + && !File.Exists(path)) + { + deployApp = false; + AnsiConsole.MarkupLine($"[red]{Strings.Provision.FileNotFound}[/]", $"[yellow]{path}[/]"); + AnsiConsole.MarkupLine(Strings.Provision.NoAppDeployment, $"[yellow]{OsVersion}[/]"); + } + else + { + Path = path; + } + + if (deployApp) + { + var provisionSettings = JsonConvert.DeserializeObject(File.ReadAllText(Path!)); + if (provisionSettings == null) + { + throw new Exception("Failed to read provision.json file."); + } + + // Use the settings from provisionSettings as needed + appPath = AppTools.ValidateAndSanitizeAppPath(provisionSettings.AppPath); + configuration = provisionSettings.Configuration; + OsVersion = provisionSettings.OsVersion; + + if (!File.Exists(appPath)) + { + throw new FileNotFoundException($"No App found at location:{appPath}"); + } + + AnsiConsole.MarkupLine(Strings.Provision.TrimmingApp); + await AppTools.TrimApplication(appPath!, packageManager, OsVersion!, configuration, null, null, Console, CancellationToken); + } + bool refreshDeviceList = false; do { @@ -171,16 +213,29 @@ await AnsiConsole.Progress() firmareUpdater.UpdateProgress += (o, e) => { task.Increment(20.00); - task.Description = string.Format($"{formatedDevice}: {e}"); + task.Description = $"{formatedDevice}: {e}"; }; - task.Increment(20.00); if (!await firmareUpdater.UpdateFirmware()) { - task.Description = string.Format($"{formatedDevice}: [red]{Strings.Provision.UpdateFailed}[/]"); + task.Description = $"{formatedDevice}: [red]{Strings.Provision.UpdateFailed}[/]"; task.StopTask(); } + if (deployApp) + { + task.Increment(20.00); + task.Description = $"{Strings.Provision.DeployingApp}"; + + var route = await MeadowConnectionManager.GetRouteFromSerialNumber(deviceSerialNumber!); + if (!string.IsNullOrWhiteSpace(route)) + { + var connection = await GetConnectionForRoute(route, true); + var appDir = System.IO.Path.GetDirectoryName(appPath); + await AppManager.DeployApplication(packageManager, connection, OsVersion!, appDir!, true, false, null, CancellationToken); + } + } + task.Value = 100.00; task.Description = string.Format($"{formatedDevice}: [green]{Strings.Provision.UpdateComplete}[/]"); @@ -192,4 +247,11 @@ await AnsiConsole.Progress() AnsiConsole.MarkupLine($"[green]{Strings.Provision.AllDevicesFlashed}[/]"); } +} + +public class ProvisionSettings +{ + public string? AppPath { get; set; } + public string? Configuration { get; set; } + public string? OsVersion { get; set; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Strings.cs b/Source/v2/Meadow.Cli/Strings.cs index ae51fb09..a2daea1d 100644 --- a/Source/v2/Meadow.Cli/Strings.cs +++ b/Source/v2/Meadow.Cli/Strings.cs @@ -93,6 +93,7 @@ public static class Provision { public const string CommandDescription = "Provision 1 or more devices that are in DFU mode."; public const string CommandOptionVersion = "Target OS version for devices to be provisioned with"; + public const string CommandOptionPath = "Path to the provision.json file"; public const string RefreshDeviceList = "Flash devices (y=Flash selected devices, n=Refresh List)?"; public const string MoreChoicesInstructions = "(Move up and down to reveal more devices)"; public const string Instructions = "Press {0} to toggle a device, {1} to accept and flash the selected device"; @@ -104,5 +105,9 @@ public static class Provision public const string UpdateFailed = "Update failed"; public const string UpdateComplete = "Update completed"; public const string AllDevicesFlashed = "All devices updated!"; + public const string FileNotFound = "Provision Settings file (provision.json), not found at location: {0}."; + public const string NoAppDeployment = "Skipping App Deployment and using default version: {0}"; + public const string DeployingApp = "Deploying App"; + public const string TrimmingApp = "Trimming App, before we get started"; } } \ No newline at end of file