Skip to content

Commit

Permalink
Add ability to Deploy app after flashing has finished.
Browse files Browse the repository at this point in the history
  • Loading branch information
CartBlanche committed Jun 17, 2024
1 parent df8973e commit ed8c4f2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
82 changes: 72 additions & 10 deletions Source/v2/Meadow.CLI/Commands/Current/Provision/ProvisionCommand.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,90 @@
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;

[Command("provision", Description = Strings.Provision.CommandDescription)]
public class ProvisionCommand : BaseDeviceCommand<ProvisionCommand>
{
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<ILibUsbDevice> bootloaderDeviceQueue = new ConcurrentQueue<ILibUsbDevice>();

private List<string> selectedDeviceList = default!;
private ISettingsManager settingsManager;
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<ProvisionSettings>(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
{
Expand Down Expand Up @@ -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}[/]");

Expand All @@ -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; }
}
5 changes: 5 additions & 0 deletions Source/v2/Meadow.Cli/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
}
}

0 comments on commit ed8c4f2

Please sign in to comment.