diff --git a/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs b/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs index 78abd6c0..00635783 100644 --- a/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs +++ b/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs @@ -63,7 +63,10 @@ internal static async Task TrimApplication(string path, if (configuration is not null) { - file = candidates.Where(c => c.DirectoryName.Contains(configuration)).OrderByDescending(c => c.LastWriteTime).First(); + file = candidates + .Where(c => c.DirectoryName.IndexOf(configuration, StringComparison.OrdinalIgnoreCase) >= 0) + .OrderByDescending(c => c.LastWriteTime) + .First(); if (file == null) { diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppDeployCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppDeployCommand.cs index 920992e8..a3b0c621 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppDeployCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppDeployCommand.cs @@ -5,7 +5,7 @@ namespace Meadow.CLI.Commands.DeviceManagement; -[Command("app deploy", Description = "Deploys a previously compiled Meadow application to a target device. Note: This command does not compile the application.")] +[Command("app deploy", Description = "Deploys a previously compiled Meadow application to a target device")] public class AppDeployCommand : BaseDeviceCommand { private readonly IPackageManager _packageManager; diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs index eafefe56..bd511a39 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs @@ -45,11 +45,6 @@ protected override async ValueTask ExecuteCommand() throw new CommandException(Strings.NoFirmwarePackagesFound, CommandExitCode.GeneralError); } - if (collection.DefaultPackage == null) - { - throw new CommandException(Strings.NoDefaultFirmwarePackageSet, CommandExitCode.GeneralError); - } - var path = AppTools.ValidateAndSanitizeAppPath(Path); Configuration ??= "Release"; diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs index e434be4e..4cd2db13 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs @@ -30,8 +30,6 @@ public AppTrimCommand(FileManager fileManager, IPackageManager packageManager, M protected override async ValueTask ExecuteCommand() { - await _fileManager.Refresh(); - // for now we only support F7 // TODO: add switch and support for other platforms var collection = _fileManager.Firmware["Meadow F7"]; @@ -41,10 +39,7 @@ protected override async ValueTask ExecuteCommand() throw new CommandException(Strings.NoFirmwarePackagesFound, CommandExitCode.GeneralError); } - if (collection.DefaultPackage == null) - { - throw new CommandException(Strings.NoDefaultFirmwarePackageSet, CommandExitCode.GeneralError); - } + await _fileManager.Refresh(); var path = AppTools.ValidateAndSanitizeAppPath(Path); @@ -68,7 +63,9 @@ protected override async ValueTask ExecuteCommand() throw new CommandException(Strings.UnableToGetDeviceInfo, CommandExitCode.GeneralError); } - Logger.LogInformation($"Preparing to trim using v{deviceInfo.OsVersion} assemblies..."); + var package = collection.GetClosestLocalPackage(deviceInfo.OsVersion); + + Logger.LogInformation($"Preparing to trim using v{package?.Version ?? " unknown"} assemblies..."); await AppTools.TrimApplication(path, _packageManager, deviceInfo.OsVersion, Configuration, NoLink, Logger, Console, CancellationToken); Logger.LogInformation("Application trimmed successfully"); } diff --git a/Source/v2/Meadow.Cli/Meadow.CLI.csproj b/Source/v2/Meadow.Cli/Meadow.CLI.csproj index 7f9c4f62..3dab4303 100644 --- a/Source/v2/Meadow.Cli/Meadow.CLI.csproj +++ b/Source/v2/Meadow.Cli/Meadow.CLI.csproj @@ -10,7 +10,7 @@ Wilderness Labs, Inc Wilderness Labs, Inc true - 2.0.46.0 + 2.0.45.0 AnyCPU http://developer.wildernesslabs.co/Meadow/Meadow.CLI/ https://github.com/WildernessLabs/Meadow.CLI diff --git a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs index 75a3506c..11ea7e71 100644 --- a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs +++ b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs @@ -6,5 +6,5 @@ namespace Meadow.CLI; public static class Constants { - public const string CLI_VERSION = "2.0.46.0"; + public const string CLI_VERSION = "2.0.45.0"; } \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Properties/launchSettings.json b/Source/v2/Meadow.Cli/Properties/launchSettings.json index e6bb0322..1f867afc 100644 --- a/Source/v2/Meadow.Cli/Properties/launchSettings.json +++ b/Source/v2/Meadow.Cli/Properties/launchSettings.json @@ -3,49 +3,29 @@ "Meadow.CLI": { "commandName": "Project" }, - "Help": { - "commandName": "Project", - "commandLineArgs": "--help" - }, - "Version": { - "commandName": "Project", - "commandLineArgs": "--version" - }, - "Port List": { - "commandName": "Project", - "commandLineArgs": "port list" - }, - "Port Select": { - "commandName": "Project", - "commandLineArgs": "port select" - }, - "Listen": { - "commandName": "Project", - "commandLineArgs": "listen" - }, - "Listen (no prefix)": { + "App Build": { "commandName": "Project", - "commandLineArgs": "listen -n" + "commandLineArgs": "app build H:\\WL\\Blinky\\Blinky\\BlinkyCs" }, - "Device Info": { + "App Build Debug": { "commandName": "Project", - "commandLineArgs": "device info" + "commandLineArgs": "app build H:\\WL\\Blinky\\Blinky\\BlinkyCs -c Debug" }, - "Device Public Key": { + "App Deploy (project folder)": { "commandName": "Project", - "commandLineArgs": "device info -k" + "commandLineArgs": "app deploy H:\\WL\\Blinky\\Blinky\\BlinkyCs" }, - "Device Reset": { + "App Deploy (untrimmed output)": { "commandName": "Project", - "commandLineArgs": "device reset" + "commandLineArgs": "app deploy F:\\temp\\MeadowApplication1\\bin\\Debug\\netstandard2.1" }, - "Device Clock Read": { + "App Run": { "commandName": "Project", - "commandLineArgs": "device clock" + "commandLineArgs": "app run H:\\WL\\Blinky\\Blinky\\BlinkyCs" }, - "Device Clock Set": { + "App Trim": { "commandName": "Project", - "commandLineArgs": "device clock now" + "commandLineArgs": "app trim H:\\WL\\Blinky\\Blinky\\BlinkyCs --nolink BlinkyLib" }, "Config: Set Route local": { "commandName": "Project", @@ -67,17 +47,37 @@ "commandName": "Project", "commandLineArgs": "config --help" }, - "Runtime Enable": { + "Developer": { "commandName": "Project", - "commandLineArgs": "runtime enable" + "commandLineArgs": "developer -p 2 -v 20" }, - "Runtime Disable": { + "Device Info": { "commandName": "Project", - "commandLineArgs": "runtime disable" + "commandLineArgs": "device info" }, - "Runtime State": { + "Device Public Key": { "commandName": "Project", - "commandLineArgs": "runtime state" + "commandLineArgs": "device info -k" + }, + "Device Reset": { + "commandName": "Project", + "commandLineArgs": "device reset" + }, + "Device Clock Read": { + "commandName": "Project", + "commandLineArgs": "device clock" + }, + "Device Clock Set": { + "commandName": "Project", + "commandLineArgs": "device clock now" + }, + "Dfu Install": { + "commandName": "Project", + "commandLineArgs": "dfu install" + }, + "Dfu Install 0.10": { + "commandName": "Project", + "commandLineArgs": "dfu install -v 0.10" }, "File List": { "commandName": "Project", @@ -103,6 +103,10 @@ "commandName": "Project", "commandLineArgs": "file delete all" }, + "File initial": { + "commandName": "Project", + "commandLineArgs": "file initial meadow.log" + }, "File Read Large": { "commandName": "Project", "commandLineArgs": "file read Meadow.F7.dll" @@ -167,69 +171,65 @@ "commandName": "Project", "commandLineArgs": "firmware write os -v 1.2.0.1" }, - "Trace enable": { - "commandName": "Project", - "commandLineArgs": "trace enable" - }, - "Trace disable": { + "Flash erase": { "commandName": "Project", - "commandLineArgs": "trace disable" + "commandLineArgs": "flash erase" }, - "Trace level": { + "Help": { "commandName": "Project", - "commandLineArgs": "trace level 2" + "commandLineArgs": "--help" }, - "Developer": { + "Listen": { "commandName": "Project", - "commandLineArgs": "developer -p 2 -v 20" + "commandLineArgs": "listen" }, - "Uart trace enable": { + "Listen (no prefix)": { "commandName": "Project", - "commandLineArgs": "uart trace enable" + "commandLineArgs": "listen -n" }, - "Uart trace disable": { + "Port List": { "commandName": "Project", - "commandLineArgs": "uart trace disable" + "commandLineArgs": "port list" }, - "App Build": { + "Port Select": { "commandName": "Project", - "commandLineArgs": "app build H:\\WL\\Blinky\\Blinky\\BlinkyCs" + "commandLineArgs": "port select" }, - "App Build Debug": { + "Runtime Enable": { "commandName": "Project", - "commandLineArgs": "app build H:\\WL\\Blinky\\Blinky\\BlinkyCs -c Debug" + "commandLineArgs": "runtime enable" }, - "App Trim": { + "Runtime Disable": { "commandName": "Project", - "commandLineArgs": "app trim H:\\WL\\Blinky\\Blinky\\BlinkyCs --nolink BlinkyLib" + "commandLineArgs": "runtime disable" }, - "Dfu Install": { + "Runtime State": { "commandName": "Project", - "commandLineArgs": "dfu install" + "commandLineArgs": "runtime state" }, - "Dfu Install 0.10": { + "Version": { "commandName": "Project", - "commandLineArgs": "dfu install -v 0.10" + "commandLineArgs": "--version" }, - "App Deploy (project folder)": { + "Trace enable": { "commandName": "Project", - "commandLineArgs": "app deploy H:\\WL\\Blinky\\Blinky\\BlinkyCs" + "commandLineArgs": "trace enable" }, - "App Deploy (untrimmed output)": { + "Trace disable": { "commandName": "Project", - "commandLineArgs": "app deploy F:\\temp\\MeadowApplication1\\bin\\Debug\\netstandard2.1" + "commandLineArgs": "trace disable" }, - "App Run": { + "Trace level": { "commandName": "Project", - "commandLineArgs": "app run H:\\WL\\Blinky\\Blinky\\BlinkyCs" + "commandLineArgs": "trace level 2" }, - "Flash erase": { + "Uart trace enable": { "commandName": "Project", - "commandLineArgs": "flash erase" + "commandLineArgs": "uart trace enable" }, - "File initial": { + "Uart trace disable": { "commandName": "Project", - "commandLineArgs": "file initial meadow.log" + "commandLineArgs": "uart trace disable" }, "Device provision": { "commandName": "Project", @@ -298,6 +298,10 @@ "legacy flash os": { "commandName": "Project", "commandLineArgs": "flash os" + }, + "WSL": { + "commandName": "WSL2", + "distributionName": "" } } } \ No newline at end of file diff --git a/Source/v2/Meadow.SoftwareManager/F7FirmwarePackageCollection.cs b/Source/v2/Meadow.SoftwareManager/F7FirmwarePackageCollection.cs index bbc764ea..f685d3b6 100644 --- a/Source/v2/Meadow.SoftwareManager/F7FirmwarePackageCollection.cs +++ b/Source/v2/Meadow.SoftwareManager/F7FirmwarePackageCollection.cs @@ -6,12 +6,20 @@ namespace Meadow.Software; +/// +/// Represents a collection of firmware packages for the F7 series. +/// public class F7FirmwarePackageCollection : IFirmwarePackageCollection { /// public event EventHandler DownloadProgress = default!; + + /// public event EventHandler DefaultVersionChanged = default!; + /// + /// The default root directory for storing F7 firmware packages. + /// public static string DefaultF7FirmwareStoreRoot = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WildernessLabs", @@ -21,16 +29,39 @@ public class F7FirmwarePackageCollection : IFirmwarePackageCollection private FirmwarePackage? _defaultPackage; private readonly F7FirmwareDownloadManager _downloadManager; + /// + /// Gets the root directory for storing firmware packages. + /// public string PackageFileRoot { get; } + /// + /// Gets the firmware package with the specified version. + /// + /// The version of the firmware package. + /// The firmware package if found; otherwise, null. public FirmwarePackage? this[string version] => _f7Packages.FirstOrDefault(p => p.Version == version); + + /// + /// Gets the firmware package at the specified index. + /// + /// The index of the firmware package. + /// The firmware package at the specified index. public FirmwarePackage this[int index] => _f7Packages[index]; + /// + /// Initializes a new instance of the class. + /// + /// The Meadow cloud client. internal F7FirmwarePackageCollection(IMeadowCloudClient meadowCloudClient) : this(DefaultF7FirmwareStoreRoot, meadowCloudClient) { } + /// + /// Initializes a new instance of the class. + /// + /// The root path for storing firmware packages. + /// The Meadow cloud client. public F7FirmwarePackageCollection(string rootPath, IMeadowCloudClient meadowCloudClient) { _downloadManager = new F7FirmwareDownloadManager(meadowCloudClient); @@ -43,6 +74,9 @@ public F7FirmwarePackageCollection(string rootPath, IMeadowCloudClient meadowClo PackageFileRoot = rootPath; } + /// + /// Gets the default firmware package. + /// public FirmwarePackage? DefaultPackage { get => _defaultPackage; @@ -56,7 +90,7 @@ private set /// /// Checks the remote (i.e. cloud) store to see if a new firmware package is available. /// - /// A version number if an update is available, otherwise null + /// A version number if an update is available, otherwise null. public async Task UpdateAvailable() { var latestVersion = await _downloadManager.GetLatestAvailableVersion(); @@ -71,6 +105,12 @@ private set return null; } + /// + /// Deletes the specified firmware package. + /// + /// The version of the firmware package to delete. + /// A task representing the asynchronous operation. + /// Thrown if the specified version is not found locally. public async Task DeletePackage(string version) { var packageToDelete = _f7Packages.FirstOrDefault(p => p.Version == version); @@ -84,7 +124,7 @@ public async Task DeletePackage(string version) Directory.Delete(Path.Combine(PackageFileRoot, version), true); - //are we deleting the default package + // Check if we are deleting the default package if (DefaultPackage != null && DefaultPackage.Version == version) { FirmwarePackage? newDefault = null; @@ -109,6 +149,12 @@ public async Task DeletePackage(string version) } } + /// + /// Sets the default firmware package to the specified version. + /// + /// The version to set as the default package. + /// A task representing the asynchronous operation. + /// Thrown if the specified version is not found locally. public async Task SetDefaultPackage(string version) { await Refresh(); @@ -125,11 +171,19 @@ public async Task SetDefaultPackage(string version) _downloadManager.SetDefaultVersion(PackageFileRoot, version); } + /// + /// Clears the default firmware package. + /// public void ClearDefaultPackage() { _defaultPackage = null; } + /// + /// Checks if the specified version is available for download. + /// + /// The version to check. + /// A task representing the asynchronous operation, with a result indicating whether the version is available for download. public async Task IsVersionAvailableForDownload(string version) { var meta = await _downloadManager.GetReleaseMetadata(version); @@ -147,6 +201,10 @@ public async Task IsVersionAvailableForDownload(string version) return false; } + /// + /// Gets the latest available version of the firmware package. + /// + /// A task representing the asynchronous operation, with a result of the latest available version if available; otherwise, null. public async Task GetLatestAvailableVersion() { var meta = await _downloadManager.GetReleaseMetadata(); @@ -164,6 +222,12 @@ public async Task IsVersionAvailableForDownload(string version) return meta.Version; } + /// + /// Retrieves the specified firmware package. + /// + /// The version of the firmware package to retrieve. + /// Whether to overwrite the existing package if it already exists. + /// A task representing the asynchronous operation, with a result indicating whether the package was successfully retrieved. public async Task RetrievePackage(string version, bool overwrite = false) { void ProgressHandler(object sender, long e) @@ -188,6 +252,10 @@ void ProgressHandler(object sender, long e) } } + /// + /// Refreshes the collection of local firmware packages. + /// + /// A task representing the asynchronous operation. public Task Refresh() { _f7Packages.Clear(); @@ -262,29 +330,98 @@ public Task Refresh() return Task.CompletedTask; } + /// + /// Gets the local firmware package with the specified version. + /// + /// The version of the firmware package. + /// The local firmware package if found; otherwise, null. public FirmwarePackage? GetLocalPackage(string osVersion) { return _f7Packages.FirstOrDefault(p => p.Version == osVersion); } + /// + /// Gets the closest local firmware package that matches the specified version, + /// with the same major and minor version, and is equal to or lower than the specified version. + /// + /// The version to match. + /// The closest matching local firmware package if found; otherwise, null. + public FirmwarePackage? GetClosestLocalPackage(string osVersion) + { + if (string.IsNullOrEmpty(osVersion)) + { + throw new ArgumentException("Version cannot be null or empty", nameof(osVersion)); + } + + var versionToCompare = new Version(osVersion); + return _f7Packages + .Where(p => + { + var packageVersion = new Version(p.Version); + return packageVersion.Major == versionToCompare.Major && + packageVersion.Minor == versionToCompare.Minor && + packageVersion <= versionToCompare; + }) + .OrderByDescending(p => new Version(p.Version)) + .FirstOrDefault(); + } + + /// + /// Returns an enumerator that iterates through the collection of firmware packages. + /// + /// An enumerator for the collection of firmware packages. public IEnumerator GetEnumerator() { return _f7Packages.GetEnumerator(); } + /// + /// Returns an enumerator that iterates through the collection of firmware packages. + /// + /// An enumerator for the collection of firmware packages. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + /// + /// Contains constants for firmware file names and directories. + /// public static class F7FirmwareFiles { + /// + /// The coprocessor bootloader file name. + /// public const string CoprocBootloaderFile = "bootloader.bin"; + + /// + /// The coprocessor partition table file name. + /// public const string CoprocPartitionTableFile = "partition-table.bin"; + + /// + /// The coprocessor application file name. + /// public const string CoprocApplicationFile = "MeadowComms.bin"; + + /// + /// The OS with bootloader file name. + /// public const string OSWithBootloaderFile = "Meadow.OS.bin"; + + /// + /// The OS without bootloader file name. + /// public const string OsWithoutBootloaderFile = "Meadow.OS.Update.bin"; + + /// + /// The runtime file name. + /// public const string RuntimeFile = "Meadow.OS.Runtime.bin"; + + /// + /// The BCL (Base Class Library) folder name. + /// public const string BclFolder = "meadow_assemblies"; } -} +} \ No newline at end of file diff --git a/Source/v2/Meadow.SoftwareManager/IFirmwarePackageCollection.cs b/Source/v2/Meadow.SoftwareManager/IFirmwarePackageCollection.cs index 625a2b9d..27e5124b 100644 --- a/Source/v2/Meadow.SoftwareManager/IFirmwarePackageCollection.cs +++ b/Source/v2/Meadow.SoftwareManager/IFirmwarePackageCollection.cs @@ -25,6 +25,7 @@ public interface IFirmwarePackageCollection : IEnumerable Task IsVersionAvailableForDownload(string version); Task RetrievePackage(string version, bool overwrite = false); FirmwarePackage? GetLocalPackage(string version); + FirmwarePackage? GetClosestLocalPackage(string version); FirmwarePackage this[int index] { get; } FirmwarePackage? this[string version] { get; } string PackageFileRoot { get; } diff --git a/Source/v2/Meadow.Tooling.Core/Package/PackageManager.AssemblyManager.cs b/Source/v2/Meadow.Tooling.Core/Package/PackageManager.AssemblyManager.cs index a8f2094f..c00b4299 100644 --- a/Source/v2/Meadow.Tooling.Core/Package/PackageManager.AssemblyManager.cs +++ b/Source/v2/Meadow.Tooling.Core/Package/PackageManager.AssemblyManager.cs @@ -28,7 +28,7 @@ private string GetAssemblyPathForOS(string? osVersion) { store.Refresh(); - var package = store.GetLocalPackage(osVersion!); + var package = store.GetClosestLocalPackage(osVersion!); if (package == null) {