From 7cf3237ccbafcc64fdf2d7b8d40c8ec4ba034d36 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Sun, 7 Jul 2019 22:31:06 +0200 Subject: [PATCH] Add versioning and error handling --- mobile-app/lib/github_reader.dart | 79 ++++++++++++++++++++++------- mobile-app/lib/main.dart | 8 ++- mobile-app/lib/warband_roaster.dart | 19 +++++-- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/mobile-app/lib/github_reader.dart b/mobile-app/lib/github_reader.dart index 5ffa78d..84bd8cd 100644 --- a/mobile-app/lib/github_reader.dart +++ b/mobile-app/lib/github_reader.dart @@ -41,17 +41,37 @@ class GitHubAdapter { "+filename:mordheim.yml+path:\"" + path + "\""); + + // GitHub is not reachable + if (response.statusCode != 200) { + syncErrors.add('Could not find any warband roaster files'); + yield {}; + return; + } + + // No valid response from GitHub + dynamic searchResults; + try { + searchResults = jsonDecode(response.body); + } on FormatException catch (e) { + syncErrors.add('Could not parse GitHub response.'); + yield {}; + return; + } + + // Find suitable files for examination RegExp fileRegex = new RegExp(r"[a-zA-Z]+\.mordheim\.ya?ml"); - var resp = jsonDecode(response.body); - - for (var searchResult in resp['items']) { + for (dynamic searchResult in searchResults['items']) { if (fileRegex.hasMatch(searchResult['name'])) { + // We try to get the name of the player from the name of the folder + // in which the file resists String completePath = searchResult['path']; - String playerName = - completePath.substring(path.length + 1).split('/').first; + List pathParts = + completePath.substring(path.length + 1).split('/'); - if (playerName == '') { - playerName = 'Lonely Recluse'; + String playerName; + if (pathParts.length >= 2) { + playerName = pathParts.first; } // Fetch last change and some metainformation of the file @@ -60,18 +80,34 @@ class GitHubAdapter { repository + "/commits?path=" + completePath); - var resp = jsonDecode(response.body); - var lastCommit = resp.first; - // TODO: Add some error handling + if (response.statusCode != 200) { + syncErrors.add('Could not load the warband metadata from GitHub.'); + continue; + } + // No valid response from GitHub + dynamic commits; + try { + commits = jsonDecode(response.body); + } on FormatException catch (e) { + syncErrors.add('Could not parse GitHub response.'); + continue; + } + + // No commits available + if (commits.length == 0) { + continue; + } + + dynamic latestCommit = commits.first; yield { 'filePath': completePath.toString(), - 'shaHash': lastCommit['sha'], + 'shaHash': latestCommit['sha'], 'player': playerName.toString(), - 'author': lastCommit['commit']['author']['name'], - 'date': lastCommit['commit']['committer']['date'], - 'message': lastCommit['commit']['message'] + 'author': latestCommit['commit']['author']['name'], + 'date': latestCommit['commit']['committer']['date'], + 'message': latestCommit['commit']['message'] }; } } @@ -89,11 +125,16 @@ class GitHubAdapter { try { YamlMap yamlObject = loadYaml(response.body); WarbandRoaster roaster = WarbandRoaster.fromJson(yamlObject); - roaster.playerName = player['player']; - roaster.author = player['author']; - roaster.commitDate = player['date']; - roaster.commitMessage = player['message']; - roaster.commitHash = player['shaHash'] + if (player['player'] != '') { + roaster.playerName = player['player']; + } + + roaster.currentVersion = new Version(player['shaHash'], player['date'], + player['author'], player['message']); + + // On a search, we drop all previous information about the warbands, + // Sp, lastSyncVersion is equal to the currentVersion. + roaster.lastSyncVersion = roaster.currentVersion; roasters.add(roaster); } catch (e) { diff --git a/mobile-app/lib/main.dart b/mobile-app/lib/main.dart index 8b0dcb0..082f9ab 100644 --- a/mobile-app/lib/main.dart +++ b/mobile-app/lib/main.dart @@ -56,8 +56,8 @@ class _RoasterWidgetState extends State { roasters.forEach((roaster) { tiles.add(ListTile( - title: Text(roaster.name + '(' + roaster.playerName + ')'), - subtitle: Text(roaster.commitMessage), + title: Text(roaster.name + ' (' + roaster.playerName + ')'), + subtitle: Text(roaster.currentVersion.message), isThreeLine: true, trailing: Chip( label: Text( @@ -83,6 +83,10 @@ class _RoasterWidgetState extends State { case ConnectionState.done: List roasters = snapshot.data; + if (roasters.length == 0) { + return Text('No warbands found'); + } + // TODO: Replace with router WarbandRoaster warband = roasters.first; diff --git a/mobile-app/lib/warband_roaster.dart b/mobile-app/lib/warband_roaster.dart index 19ade68..341fdb5 100644 --- a/mobile-app/lib/warband_roaster.dart +++ b/mobile-app/lib/warband_roaster.dart @@ -153,6 +153,16 @@ class Stats { this.save); } +class Version { + String gitHash; + String date; + + String author; + String message; + + Version(this.gitHash, this.date, this.author, this.message); +} + @JsonSerializable(nullable: true, anyMap: true, createToJson: false) class WarbandRoaster { /// Store the complete string of name and race. This will split up into the @@ -180,11 +190,10 @@ class WarbandRoaster { /// The players name is not defined in the yml file. This will be added later /// from the GitHubAdapter. - String playerName = ''; - String author = ''; - String commitDate = ''; - String commitMessage = ''; - String commitHash = ''; + String playerName = 'Lonely Recluse'; + + Version lastSyncVersion; + Version currentVersion; WarbandRoaster( this.nameAndRace,