Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] [refactor] Update meadow firmware download command to use Meadow Cloud #447

Merged
merged 17 commits into from
Feb 8, 2024

Conversation

stevenkuhn
Copy link
Contributor

@stevenkuhn stevenkuhn commented Feb 6, 2024

This updates the v2 version of meadow firmware download to retrieve the Meadow firmware from Meadow.Cloud. From the user's perspective the only change is that it will require a user to have a Meadow.Cloud account and for that user to login with meadow cloud login. The only additional command-line option is the --host argument:

USAGE
  meadow firmware download [options]

DESCRIPTION
  Download a firmware package

OPTIONS
  -f|--force        Default: "False".
  -v|--version
  --host            Optionally set a host (default is https://www.meadowcloud.co)
  -h|--help         Shows help text.

Example

An example of this command would be:

C:\>meadow login
Logging into https://www.meadowcloud.co...
Signed in as [email protected]
Done

C:\>meadow firmware download
Retrieving firmware information from Meadow.Cloud...
Latest available version is '1.8.0.0'...
Downloading firmware package '1.8.0.0'...
Firmware package '1.8.0.0' downloaded

An example if the user is not logged in:

C:\>meadow firmware download
Retrieving firmware information from Meadow.Cloud...
You must be signed into Meadow.Cloud to execute this command. Run 'meadow cloud login' to do so.

Meadow.Cloud.Client Refactoring

Details

This introduces a new IMeadowCloudClient interface that provides the starting point when working with operations that involve Meadow.Cloud. The current properties and methods on this interface look like below.

public interface IMeadowCloudClient
{
    IApiTokenClient ApiToken { get; }
    ICollectionClient Collection { get; }
    ICommandClient Command { get; }
    IDeviceClient Device { get; }
    IFirmwareClient Firmware { get; }
    IPackageClient Package { get; }
    IUserClient User { get; }

    Task<bool> Authenticate(string? host = default, CancellationToken cancellationToken = default);
}

Each individual client on IMeadowCloudClient represents a operations that are specific to that client. For this pull request, the only client implemented is IFirmwareClient which is described below:

public interface IFirmwareClient
{
    Task<IEnumerable<GetFirmwareVersionsResponse>> GetVersions(string type, CancellationToken cancellationToken = default);
    Task<GetFirmwareVersionResponse?> GetVersion(string type, string version, CancellationToken cancellationToken = default);
    Task<HttpResponseMessage> GetDownloadResponse(string url, CancellationToken cancellationToken = default);
    Task<HttpResponseMessage> GetDownloadResponse(Uri url, CancellationToken cancellationToken = default);
}

The implementation for these clients abstracts out the specific details of the underlying HttpClient calls providing a cleaner approach for users of IMeadowCloudClient. For example, getting a specific firmware version from Meadow.Cloud in F7FirmwareDownloadManager.GetReleaseMetadata() is now this:

public async Task<F7ReleaseMetadata?> GetReleaseMetadata(string? version = null, CancellationToken cancellationToken = default)
{
    version = !string.IsNullOrWhiteSpace(version) ? version : "latest";
    var response = await _meadowCloudClient.Firmware.GetVersion("Meadow_Beta", version, cancellationToken);

    if (response == null)
    {
        return null;
    }

    return new F7ReleaseMetadata()
    {
        Version = response.Version,
        MinCLIVersion = response.MinCLIVersion,
        DownloadURL = response.DownloadUrl,
        NetworkDownloadURL = response.NetworkDownloadUrl
    };
}

And the usage of the client in FirmwareDownloadCommand is reduced to:

var isAuthenticated = await _meadowCloudClient.Authenticate(Host, CancellationToken);
if (!isAuthenticated)
{
    Logger?.LogError($"You must be signed into Meadow.Cloud to execute this command. Run 'meadow cloud login' to do so.");
    return;
}

Instantiation and Usage

The creation of IMeadowCloudClient in the CLI is done through the DI container. Without a DI container, it would look something like this (not putting in CancellationToken for brevity):

var httpClient = new HttpClient();            // create & manage HttpClient appropriately.
var identityManager = new IdentityManager();
var userAgent = "my.example.useragent";       // MeadowCloudUserAgent.Cli and
                                              // MeadowCloudUserAgent.Workbench
                                              // are also available.
IMeadowCloudClient client = new MeadowCloudClient(httpClient, identityManager, userAgent);

if (!await client.Authenticate())
{
    // TODO: do something if the user is not authenticated. In the CLI, the user
    // is required to do a `meadow cloud login`.
}

var versions = await client.Firmware.GetVersions("Meadow_Beta");

@stevenkuhn stevenkuhn merged commit 234aad3 into develop Feb 8, 2024
1 check passed
@stevenkuhn stevenkuhn deleted the feature/cloud-firmware-api-and-refactor branch February 8, 2024 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants