diff --git a/nanoFirmwareFlasher/FirmwarePackage.cs b/nanoFirmwareFlasher/FirmwarePackage.cs
index 79c2500a..aa7185f4 100644
--- a/nanoFirmwareFlasher/FirmwarePackage.cs
+++ b/nanoFirmwareFlasher/FirmwarePackage.cs
@@ -7,8 +7,10 @@
using System;
using System.IO;
using System.IO.Compression;
+using System.Linq;
using System.Net;
using System.Net.Http;
+using System.Text.RegularExpressions;
namespace nanoFramework.Tools.FirmwareFlasher
{
@@ -64,132 +66,243 @@ protected FirmwarePackage(string targetName, string fwVersion, bool stable)
/// a dictionary which keys are the start addresses and the values are the complete filenames (the bin files)
protected async System.Threading.Tasks.Task DownloadAndExtractAsync()
{
+ string fwFileName = null;
+
// reference targets
var repoName = _stable ? _refTargetsStableRepo : _refTargetsDevRepo;
string requestUri = $"{_bintrayApiPackages}/{repoName}/{_targetName}";
- if (Verbosity >= VerbosityLevel.Normal)
+ // flag to signal if the work-flow step was successful
+ bool stepSuccesful = false;
+
+ // flag to skip download if the fw package exists and it's recent
+ bool skipDownload = false;
+
+ // setup download folder
+ // set download path
+ LocationPath = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
+ ".nanoFramework");
+
+ try
{
- Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
+ // create home directory
+ Directory.CreateDirectory(LocationPath);
+
+ // add readme file
+ File.WriteAllText(
+ Path.Combine(
+ LocationPath,
+ "README.txt"),
+ _readmeContent);
+
+ // set location path to target folder
+ LocationPath = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
+ ".nanoFramework",
+ _targetName);
}
+ catch
+ {
+ Console.WriteLine("");
- HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);
+ return ExitCodes.E9006;
+ }
- if (response.StatusCode == HttpStatusCode.NotFound)
+ var fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();
+
+ if (fwFiles.Any())
{
- if (Verbosity >= VerbosityLevel.Normal)
+ // get file creation date (from the 1st one)
+ if ((DateTime.UtcNow - File.GetLastWriteTimeUtc(fwFiles.First())).TotalHours < 4)
{
- Console.WriteLine("");
- Console.Write($"Trying to find {_targetName} in community targets repository...");
+ // fw package has less than 4 hours
+ // skip download
+ skipDownload = true;
}
+ }
+
+ if (!skipDownload)
+ {
+ // try to perform request
+ try
+ {
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.Write($"Trying to find {_targetName} in {(_stable ? "stable" : "developement")} repository...");
+ }
- // try with community targets
- requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
- repoName = _communityTargetsepo;
+ HttpResponseMessage response = await _bintrayClient.GetAsync(requestUri);
- response = await _bintrayClient.GetAsync(requestUri);
+ if (response.StatusCode == HttpStatusCode.NotFound)
+ {
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.WriteLine("");
+ Console.Write($"Trying to find {_targetName} in community targets repository...");
+ }
+
+ // try with community targets
+ requestUri = $"{_bintrayApiPackages}/{_communityTargetsepo}/{_targetName}";
+ repoName = _communityTargetsepo;
+
+ response = await _bintrayClient.GetAsync(requestUri);
+
+ if (response.StatusCode == HttpStatusCode.NotFound)
+ {
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.WriteLine("");
+ }
+
+ // can't find this target
+ return ExitCodes.E9005;
+ }
+ }
- if (response.StatusCode == HttpStatusCode.NotFound)
- {
if (Verbosity >= VerbosityLevel.Normal)
{
- Console.WriteLine("");
+ Console.WriteLine($"OK");
}
- // can't find this target
- return ExitCodes.E9005;
- }
- }
+ // read and parse response
+ string responseBody = await response.Content.ReadAsStringAsync();
+ BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject(responseBody);
- if (Verbosity >= VerbosityLevel.Normal)
- {
- Console.WriteLine($"OK");
+ // if no specific version was requested, use latest available
+ if (string.IsNullOrEmpty(_fwVersion))
+ {
+ _fwVersion = packageInfo.LatestVersion;
+ }
- Console.Write($"Downloading firmware package...");
+ // set exposed property
+ Version = _fwVersion;
+
+ stepSuccesful = true;
+ }
+ catch
+ {
+ // exception with download, assuming it's something with network connection or Bintray API
+ }
}
- // read and parse response
- string responseBody = await response.Content.ReadAsStringAsync();
- BintrayPackageInfo packageInfo = JsonConvert.DeserializeObject(responseBody);
+ // cleanup any fw file in the folder
+ var filesToDelete = Directory.EnumerateFiles(LocationPath, "*.bin").ToList();
+ filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.hex").ToList());
+ filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.s19").ToList());
+ filesToDelete.AddRange(Directory.EnumerateFiles(LocationPath, "*.dfu").ToList());
- // if no specific version was requested, use latest available
- if (string.IsNullOrEmpty(_fwVersion))
+ foreach (var file in filesToDelete)
{
- _fwVersion = packageInfo.LatestVersion;
+ File.Delete(file);
}
- // set exposed property
- Version = _fwVersion;
-
- // setup download folder
- try
+ // check for file existence or download one
+ if (stepSuccesful &&
+ !skipDownload)
{
- // set download path
- LocationPath = Path.Combine(
- Path.GetTempPath(),
- Guid.NewGuid().ToString());
+ // reset flag
+ stepSuccesful = false;
- // create directory
- Directory.CreateDirectory(LocationPath);
+ fwFileName = $"{_targetName}-{_fwVersion}.zip";
- if (Verbosity >= VerbosityLevel.Normal)
+ // check if we already have the file
+ if (!File.Exists(
+ Path.Combine(
+ LocationPath,
+ fwFileName)))
{
- Console.WriteLine("OK");
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.Write($"Downloading firmware package...");
+ }
+
+ try
+ {
+ // setup and perform download request
+ requestUri = $"https://dl.bintray.com/nfbot/{repoName}/{fwFileName}";
+
+ using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
+ {
+ if (fwFileResponse.IsSuccessStatusCode)
+ {
+ using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
+ {
+ using (var fileStream = new FileStream(
+ Path.Combine(LocationPath, fwFileName),
+ FileMode.Create, FileAccess.Write))
+ {
+ await readStream.CopyToAsync(fileStream);
+ }
+ }
+ }
+ else
+ {
+ return ExitCodes.E9007;
+ }
+ }
+
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.WriteLine("OK");
+ }
+
+ stepSuccesful = true;
+ }
+ catch
+ {
+ // exception with download, assuming it's something with network connection or Bintray API
+ }
}
else
{
- Console.WriteLine("");
+ // file already exists
+ stepSuccesful = true;
}
-
- if (Verbosity >= VerbosityLevel.Detailed)
- {
- Console.WriteLine($"Download location is {LocationPath}");
- }
-
- // add readme file
- File.WriteAllText(
- Path.Combine(
- LocationPath,
- "README.txt"),
- _readmeContent);
}
- catch
+
+ if (!stepSuccesful)
{
- Console.WriteLine("");
+ // couldn't download the fw file
+ // check if there is one available
+ fwFiles = Directory.EnumerateFiles(LocationPath, $"{_targetName}-*.zip").OrderByDescending(f => f).ToList();
- return ExitCodes.E9006;
- }
+ if (fwFiles.Any())
+ {
+ // take the 1st one
+ fwFileName = fwFiles.First();
- // setup and perform download request
- string fwFileName = $"{_targetName}-{_fwVersion}.zip";
- requestUri = $"https://dl.bintray.com/nfbot/{repoName}/{fwFileName}";
+ // get the version form the file name
+ var pattern = @"(\d+\.\d+\.\d+)(\.\d+|-.+)(?=\.zip)";
+ var match = Regex.Matches(fwFileName, pattern, RegexOptions.IgnoreCase);
- using (var fwFileResponse = await _bintrayClient.GetAsync(requestUri))
- {
- if (fwFileResponse.IsSuccessStatusCode)
- {
- using (var readStream = await fwFileResponse.Content.ReadAsStreamAsync())
+ // set property
+ Version = match[0].Value;
+
+ if (Verbosity >= VerbosityLevel.Normal)
{
- using (var fileStream = new FileStream(
- Path.Combine(LocationPath, fwFileName),
- FileMode.Create, FileAccess.Write))
- {
- await readStream.CopyToAsync(fileStream);
- }
+ Console.WriteLine("Using cached firmware package");
}
}
else
{
+ // no fw file available
+
+ if (Verbosity >= VerbosityLevel.Normal)
+ {
+ Console.WriteLine("Failure to download package and couldn't find one in the cache.");
+ }
+
return ExitCodes.E9007;
}
}
- Console.WriteLine($"Updating to {_fwVersion}");
+ // got here, must have a file!
// unzip the firmware
if (Verbosity >= VerbosityLevel.Detailed)
{
- Console.Write($"Extracting {fwFileName}...");
+ Console.Write($"Extracting {Path.GetFileName(fwFileName)}...");
}
ZipFile.ExtractToDirectory(
@@ -198,9 +311,21 @@ protected async System.Threading.Tasks.Task DownloadAndExtractAsync()
if (Verbosity >= VerbosityLevel.Detailed)
{
- Console.WriteLine("");
+ Console.WriteLine("OK");
}
+ // be nice to the user and delete any fw packages other than the last one
+ var allFwFiles = Directory.EnumerateFiles(LocationPath, "*.zip").OrderByDescending(f => f).ToList();
+ if (allFwFiles.Count > 1)
+ {
+ foreach (var file in allFwFiles.Skip(1))
+ {
+ File.Delete(file);
+ }
+ }
+
+ Console.WriteLine($"Updating to {Version}");
+
return ExitCodes.OK;
}
diff --git a/version.json b/version.json
index cd2bc313..3fa120eb 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "1.16.0-preview.{height}",
+ "version": "1.16.1-preview.{height}",
"assemblyVersion": {
"precision": "revision"
},