Skip to content

Commit

Permalink
Add meadow update command.
Browse files Browse the repository at this point in the history
  • Loading branch information
CartBlanche committed Jul 2, 2024
1 parent b1f21c6 commit ad9fa9c
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 9 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
run: dotnet build main/MeadowCLI.Classic.sln /p:Configuration=Release

- name: Upload nuget Artifacts for internal testing
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: Meadow.CLI.Classic.nuget.${{ ENV.CLI_RELEASE_VERSION_1 }}
path: 'main\Meadow.CLI.Classic\bin\Release\*.nupkg'
Expand All @@ -100,7 +100,7 @@ jobs:
run: dotnet build main/MeadowCLI.sln /p:Configuration=Release

- name: Upload nuget Artifacts for internal testing
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: Meadow.CLI.nuget.${{ ENV.CLI_RELEASE_VERSION_1 }}
path: 'main\Meadow.CLI\bin\Release\*.nupkg'
Expand All @@ -117,7 +117,7 @@ jobs:
run: dotnet build main/Source/v2/Meadow.CLI.v2.sln /p:Configuration=Release

- name: Upload nuget Artifacts for internal testing
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: Meadow.CLI.nuget.${{ ENV.CLI_RELEASE_VERSION_2 }}
path: 'main\Source\v2\Meadow.CLI\bin\Release\*.nupkg'
Expand Down Expand Up @@ -185,7 +185,7 @@ jobs:
# DevEnvDir: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE'

# - name: Upload VS2019 VSIX Artifacts
# uses: actions/upload-artifact@v2
# uses: actions/upload-artifact@v4
# with:
# name: Meadow.Win.VS2019.vsix.${{ ENV.IDE_TOOLS_RELEASE_VERSION }}
# path: 'vs-win\VS_Meadow_Extension\VS_Meadow_Extension.2019\bin\Release\*.vsix'
Expand Down Expand Up @@ -326,7 +326,7 @@ jobs:
# msbuild vs-mac/VS4Mac_Meadow_Extension.sln /t:Build /p:Configuration=Release /p:CreatePackage=true

# - name: Upload Mac VS2019 mpack Artifacts
# uses: actions/upload-artifact@v2
# uses: actions/upload-artifact@v4
# with:
# name: Meadow.Mac.2019.mpack.${{ ENV.IDE_TOOLS_RELEASE_VERSION }}
# path: 'vs-mac/VS4Mac_Meadow_Extension/bin/Release/net472/*.mpack'
Expand Down Expand Up @@ -435,7 +435,7 @@ jobs:
dotnet msbuild vs-mac/VS4Mac_Meadow_Extension/Meadow.Sdks.IdeExtensions.Vs4Mac.2022.csproj /t:Build /p:Configuration=Release /p:CreatePackage=true
- name: Upload VS2022 mpack Artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: Meadow.Mac.2022.mpack.${{ ENV.IDE_TOOLS_RELEASE_VERSION }}
path: 'vs-mac/VS4Mac_Meadow_Extension/bin/Release/net7.0/*.mpack'
Expand Down Expand Up @@ -584,7 +584,7 @@ jobs:
vsce package
- name: Upload VSIX Artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: Meadow.VSCode.vsix.${{ ENV.IDE_TOOLS_RELEASE_VERSION }}
path: 'vs-code/*.vsix'
Expand Down
8 changes: 7 additions & 1 deletion Source/v2/Meadow.CLI.v2.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Dfu", "Meadow.Dfu\Me
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Firmware", "Meadow.Firmware\Meadow.Firmware.csproj", "{D2274F30-A001-482A-99E3-0AB1970CF695}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meadow.Tooling.Core", "Meadow.Tooling.Core\Meadow.Tooling.Core.csproj", "{A22DBF4A-E472-445E-96C0-930C126039C2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Tooling.Core", "Meadow.Tooling.Core\Meadow.Tooling.Core.csproj", "{A22DBF4A-E472-445E-96C0-930C126039C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Updater", "Meadow.Updater\Meadow.Updater.csproj", "{78D924D6-9D20-46DE-A178-D3AA830B9A55}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -124,6 +126,10 @@ Global
{A22DBF4A-E472-445E-96C0-930C126039C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Release|Any CPU.Build.0 = Release|Any CPU
{78D924D6-9D20-46DE-A178-D3AA830B9A55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78D924D6-9D20-46DE-A178-D3AA830B9A55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78D924D6-9D20-46DE-A178-D3AA830B9A55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78D924D6-9D20-46DE-A178-D3AA830B9A55}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
39 changes: 39 additions & 0 deletions Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Meadow.Hcom;
using Meadow.Package;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

namespace Meadow.CLI.Commands.DeviceManagement;

Expand Down Expand Up @@ -136,4 +137,42 @@ internal static string SanitizeMeadowFilename(string fileName)

return meadowFileName!.Replace(Path.DirectorySeparatorChar, '/');
}

internal static async Task<int> RunProcessCommand(string command, string args, Action<string>? handleOutput = null, Action<string>? handleError = null, CancellationToken cancellationToken = default)
{
var processStartInfo = new ProcessStartInfo
{
FileName = command,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};

using (var process = new Process { StartInfo = processStartInfo })
{
process.Start();

var outputCompletion = ReadLinesAsync(process.StandardOutput, handleOutput, cancellationToken);
var errorCompletion = ReadLinesAsync(process.StandardError, handleError, cancellationToken);

await Task.WhenAll(outputCompletion, errorCompletion, process.WaitForExitAsync());

return process.ExitCode;
}
}

private static async Task ReadLinesAsync(StreamReader reader, Action<string>? handleLine, CancellationToken cancellationToken)
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync(cancellationToken);
if (!string.IsNullOrWhiteSpace(line)
&& handleLine != null)
{
handleLine(line);
}
}
}
}
84 changes: 84 additions & 0 deletions Source/v2/Meadow.CLI/Commands/Current/UpdateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Reflection;
using CliFx.Attributes;
using Microsoft.Extensions.Logging;

namespace Meadow.CLI.Commands.DeviceManagement;

[Command("update", Description = Strings.Update.Description)]
public class UpdateCommand : BaseCommand<UpdateCommand>
{
const string MEADOW_CLI = "WildernessLabs.Meadow.CLI";
const string MEADOW_UPDATER = "Meadow.Updater";
const string CLIFX = "CliFx";

[CommandOption("version", 'v', IsRequired = false)]
public string? Version { get; set; }

public UpdateCommand(ILoggerFactory loggerFactory)
: base(loggerFactory)
{
}

protected override async ValueTask ExecuteCommand()
{
Logger.LogInformation(Strings.Update.Updating, MEADOW_CLI);

string toVersion;
if (!string.IsNullOrWhiteSpace(Version))
{
toVersion = $"v{Version}";
}
else
{
toVersion = "vLatest";
}
;
Logger.LogInformation(Strings.Update.Instruction1, MEADOW_CLI, toVersion);
Logger.LogInformation(Strings.Update.Instruction2);

// Path to the updater executable within the tool's output directory
string meadowUpdaterPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, $"{MEADOW_UPDATER}.dll");

// Ensure the updater executable exists
if (!File.Exists(meadowUpdaterPath))
{
Logger.LogError(Strings.Update.UpdaterNotFound);
return;
}

// Copy all necessary files to a temporary location, so there aren't any access issues
string tempUpdaterDir = Path.Combine(Path.GetTempPath(), MEADOW_UPDATER);
if (!Directory.Exists(tempUpdaterDir))
{
Directory.CreateDirectory(tempUpdaterDir);
}
CopyMeadowUpdaterFiles(Path.GetDirectoryName(meadowUpdaterPath), tempUpdaterDir, MEADOW_UPDATER);

// Supporting files required in the temp directory
CopyMeadowUpdaterFiles(Path.GetDirectoryName(meadowUpdaterPath), tempUpdaterDir, CLIFX);

string commandArguments = $"update -t {MEADOW_CLI}";
if (!string.IsNullOrWhiteSpace(Version))
{
commandArguments += $" -v {Version}";
}

await AppTools.RunProcessCommand("dotnet", $"{Path.Combine(tempUpdaterDir, $"{MEADOW_UPDATER}.dll")} {commandArguments}", cancellationToken: CancellationToken);
}

internal static void CopyMeadowUpdaterFiles(string? sourceDirectory, string targetDirectory, string filesToCopy)
{
if (sourceDirectory == null)
{
return;
}

var toolUpdaterFiles = Directory.GetFiles(sourceDirectory, $"{filesToCopy}*");
foreach (var file in toolUpdaterFiles)
{
string fileName = Path.GetFileName(file);
string destFile = Path.Combine(targetDirectory, fileName);
File.Copy(file, destFile, true);
}
}
}
10 changes: 10 additions & 0 deletions Source/v2/Meadow.Cli/Meadow.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<ProjectReference Include="..\Meadow.Dfu\Meadow.Dfu.csproj" />
<ProjectReference Include="..\Meadow.Linker\Meadow.Linker.csproj" />
<ProjectReference Include="..\Meadow.Tooling.Core\Meadow.Tooling.Core.csproj" />
<ProjectReference Include="..\Meadow.Updater\Meadow.Updater.csproj" />
<ProjectReference Include="..\Meadow.UsbLib\Meadow.UsbLib.csproj" />
</ItemGroup>

Expand All @@ -62,4 +63,13 @@
<ItemGroup>
<None Include="..\..\..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<None Update="..\Meadow.Updater\bin\$(Configuration)\net8.0\Meadow.Updater.exe">
<Pack>true</Pack>
<PackagePath>tools\net8.0\any\</PackagePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
12 changes: 11 additions & 1 deletion Source/v2/Meadow.Cli/Strings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Meadow.Telemetry;
using System.Numerics;
using Meadow.Telemetry;

namespace Meadow.CLI;

Expand Down Expand Up @@ -86,4 +87,13 @@ public static class Telemetry

public const string AskToParticipate = "Would you like to participate?";
}

public static class Update
{
public const string Description = "Update WildernessLabs.Meadow.CLI";
public const string Updating = "Updating {0}";
public const string Instruction1 = "This will initially uninstall {0} and will then install version {1}";
public const string Instruction2 = "Please wait about 10s to allow the above steps to complete.";
public const string UpdaterNotFound = "Meadow.Updater not found.";
}
}
20 changes: 20 additions & 0 deletions Source/v2/Meadow.Updater/Meadow.Updater.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>11</LangVersion>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

<PropertyGroup>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\MeadowCLIKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CliFx" Version="*" />
</ItemGroup>
</Project>
35 changes: 35 additions & 0 deletions Source/v2/Meadow.Updater/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using CliFx;
using CliFx.Exceptions;
using System.Diagnostics;

namespace Meadow.Updater;

public class Program
{
public static async Task<int> Main(string[] args)
{
int returnCode;

try
{
returnCode = await new CliApplicationBuilder()
.AddCommandsFromThisAssembly()
//.UseTypeActivator(serviceProvider.GetService!)
.SetExecutableName("Meadow.Updater")
.Build()
.RunAsync();
}
catch (CommandException ce)
{
returnCode = ce.ExitCode;
}
catch (Exception ex)
{
Console.WriteLine($"Operation failed: {ex.Message}");
returnCode = 1;
}

return returnCode;
}
}
11 changes: 11 additions & 0 deletions Source/v2/Meadow.Updater/Strings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
namespace Meadow.Updater;

public static class Strings
{
public static class Update
{
public const string Description = "Update the specified tool";
public const string NoToolSpecified = "No tool specified. Exiting.";
}
}
Loading

0 comments on commit ad9fa9c

Please sign in to comment.