From ad47699670caaa489c5846824f7fb96aa9d21168 Mon Sep 17 00:00:00 2001 From: leoafarias Date: Sat, 20 Jun 2020 06:30:23 -0400 Subject: [PATCH 1/7] Releases request, and zip download --- lib/constants.dart | 8 ++++++++ lib/utils/releases.dart | 20 ++++++++++++++++++++ pubspec.yaml | 1 + test/utils/releases_test.dart | 31 +++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 lib/utils/releases.dart create mode 100644 test/utils/releases_test.dart diff --git a/lib/constants.dart b/lib/constants.dart index b0cdf170..a920d4ea 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -56,6 +56,14 @@ Directory get kVersionsDir { return Directory(path.join(fvmHome, 'versions')); } +/// Gets Flutter Releases for a platform +String kFlutterReleasesListUrl = + '$kFlutterReleasesUrl/releases_${Platform.operatingSystem}.json'; + +/// Base Url for Flutter Storage +String kFlutterReleasesUrl = + 'https://storage.googleapis.com/flutter_infra/releases'; + /// Where Default Flutter SDK is stored Link get kDefaultFlutterLink => Link(path.join(fvmHome, 'default')); String get kDefaultFlutterPath => path.join(kDefaultFlutterLink.path, 'bin'); diff --git a/lib/utils/releases.dart b/lib/utils/releases.dart new file mode 100644 index 00000000..f7a3c6a6 --- /dev/null +++ b/lib/utils/releases.dart @@ -0,0 +1,20 @@ +import 'package:dio/dio.dart'; +import 'package:fvm/constants.dart'; +// import 'package:path/path.dart' as path; + +Future fetchReleases() async { + try { + final response = await Dio().get(kFlutterReleasesListUrl); + print(response); + } catch (e) { + print(e); + } +} + +Future downloadVersion(String version) async { + // final url = '$kFlutterReleasesUrl/$releasePath'; + // final versionPath = path.join(kVersionsDir.path, version) + // final response = await Dio().download(url,kVersionsDir.path); + + // return response; +} diff --git a/pubspec.yaml b/pubspec.yaml index 70823ce7..9bab60f4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: cli_util: ^0.2.0 console: ^3.1.0 io: ^0.3.3 + dio: ^3.0.9 path: ^1.6.4 dev_dependencies: diff --git a/test/utils/releases_test.dart b/test/utils/releases_test.dart new file mode 100644 index 00000000..f8ce6312 --- /dev/null +++ b/test/utils/releases_test.dart @@ -0,0 +1,31 @@ +@Timeout(Duration(minutes: 5)) +// import 'package:fvm/utils/releases.dart'; +import 'package:test/test.dart'; +import 'package:dio/dio.dart'; +// import 'package:fvm/utils/releases.dart'; + +void main() { + test('Can fetch releases for all platforms', () async { + String getPlatformUrl(String platform) { + return 'https://storage.googleapis.com/flutter_infra/releases/releases_$platform.json'; + } + + try { + await Dio().get(getPlatformUrl('macos')); + await Dio().get(getPlatformUrl('linux')); + await Dio().get(getPlatformUrl('windows')); + expect(true, true); + } on Exception { + fail('Could not resolve all platform releases'); + } + }); + + // test('Can download release', () async { + // try { + // await downloadRelease('beta/macos/flutter_macos_1.19.0-4.1.pre-beta.zip'); + // expect(true, true); + // } on Exception { + // rethrow; + // } + // }); +} From ce1dc628a67d0cc89174b90009b9f08d7fc07240 Mon Sep 17 00:00:00 2001 From: leoafarias Date: Sun, 21 Jun 2020 05:54:54 -0400 Subject: [PATCH 2/7] Small test tweaks --- lib/utils/logger.dart | 5 ----- test/fvm_test.dart | 3 --- test/test_helpers.dart | 6 ++++++ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/utils/logger.dart b/lib/utils/logger.dart index 8cc8c4c6..437c549a 100644 --- a/lib/utils/logger.dart +++ b/lib/utils/logger.dart @@ -2,8 +2,3 @@ import 'package:cli_util/cli_logging.dart'; /// Log Logger logger = Logger.standard(); - -/// Finishes progress -void finishProgress(Progress progress) { - progress.finish(showTiming: true); -} diff --git a/test/fvm_test.dart b/test/fvm_test.dart index b21e6cb8..39f5119f 100644 --- a/test/fvm_test.dart +++ b/test/fvm_test.dart @@ -12,9 +12,6 @@ import 'test_helpers.dart'; final testPath = '$fvmHome/test_path'; -const channel = 'master'; -const release = '1.8.0'; - void main() { setUpAll(fvmSetUpAll); tearDownAll(fvmTearDownAll); diff --git a/test/test_helpers.dart b/test/test_helpers.dart index 3ff7b6ab..6fc61d3c 100644 --- a/test/test_helpers.dart +++ b/test/test_helpers.dart @@ -3,6 +3,12 @@ import 'dart:io'; import 'package:fvm/constants.dart'; import 'package:fvm/utils/config_utils.dart'; +// git clone --mirror https://github.com/flutter/flutter.git ~/gitcaches/flutter.reference +// git clone --reference ~/gitcaches/flutter.reference https://github.com/flutter/flutter.git + +String release = '1.8.0'; +String channel = 'stable'; + void cleanup() { final fvmHomeDir = Directory(fvmHome); if (fvmHomeDir.existsSync()) { From ad9d03e976ca0970e96fdb30b42a04c41699785a Mon Sep 17 00:00:00 2001 From: leoafarias Date: Sun, 21 Jun 2020 07:01:28 -0400 Subject: [PATCH 3/7] Releases helper --- lib/utils/releases_helper.dart | 128 +++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 lib/utils/releases_helper.dart diff --git a/lib/utils/releases_helper.dart b/lib/utils/releases_helper.dart new file mode 100644 index 00000000..8c3cec4b --- /dev/null +++ b/lib/utils/releases_helper.dart @@ -0,0 +1,128 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:fvm/exceptions.dart'; +import 'package:http/http.dart' as http; + +/// Gets platform specific release URL +String getReleasesUrl({String platform}) { + platform ??= Platform.operatingSystem; + return 'https://storage.googleapis.com/flutter_infra/releases/releases_$platform.json'; +} + +/// Fetches Flutter SDK Releases +Future fetchReleases() async { + try { + final response = await http.get(getReleasesUrl()); + return jsonDecode(response.body) as FlutterReleases; + } on Exception { + throw ExceptionCouldNotFetchReleases(); + } +} + +FlutterReleases flutterReleasesFromMap(String str) => + FlutterReleases.fromMap(json.decode(str) as Map); + +String flutterReleasesToMap(FlutterReleases data) => json.encode(data.toMap()); + +class FlutterReleases { + FlutterReleases({ + this.baseUrl, + this.currentRelease, + this.releases, + }); + + final String baseUrl; + final CurrentRelease currentRelease; + final List releases; + + factory FlutterReleases.fromMap(Map json) => FlutterReleases( + baseUrl: json['base_url'] as String, + currentRelease: CurrentRelease.fromMap(json['current_release']), + releases: + List.from(json['releases'].map((x) => Release.fromMap(x))), + ); + + Map toMap() => { + 'base_url': baseUrl, + 'current_release': currentRelease.toMap(), + 'releases': List.from(releases.map((x) => x.toMap())), + }; +} + +class CurrentRelease { + CurrentRelease({ + this.beta, + this.dev, + this.stable, + }); + + final String beta; + final String dev; + final String stable; + + factory CurrentRelease.fromMap(dynamic json) => CurrentRelease( + beta: json['beta'] as String, + dev: json['dev'] as String, + stable: json['stable'] as String, + ); + + Map toMap() => { + 'beta': beta, + 'dev': dev, + 'stable': stable, + }; +} + +class Release { + Release({ + this.hash, + this.channel, + this.version, + this.releaseDate, + this.archive, + this.sha256, + }); + + final String hash; + final Channel channel; + final String version; + final DateTime releaseDate; + final String archive; + final String sha256; + + factory Release.fromMap(Map json) => Release( + hash: json['hash'], + channel: channelValues.map[json['channel']], + version: json['version'], + releaseDate: DateTime.parse(json['release_date']), + archive: json['archive'], + sha256: json['sha256'], + ); + + Map toMap() => { + 'hash': hash, + 'channel': channelValues.reverse[channel], + 'version': version, + 'release_date': releaseDate.toIso8601String(), + 'archive': archive, + 'sha256': sha256, + }; +} + +enum Channel { STABLE, DEV, BETA } + +final channelValues = EnumValues( + {'beta': Channel.BETA, 'dev': Channel.DEV, 'stable': Channel.STABLE}); + +class EnumValues { + Map map; + Map reverseMap; + + EnumValues(this.map); + + Map get reverse { + reverseMap ??= map.map((k, v) => MapEntry(v, k)); + return reverseMap; + } +} From b96c69c1e9b45c59de51132f649fbbee8e4bc5ab Mon Sep 17 00:00:00 2001 From: leoafarias Date: Sun, 21 Jun 2020 09:30:09 -0400 Subject: [PATCH 4/7] Initial release command --- lib/commands/releases.dart | 41 ++++++++++++++++++++++++++++++++++ lib/constants.dart | 8 ------- lib/utils/releases.dart | 20 ----------------- lib/utils/releases_helper.dart | 33 +++++++++++++++------------ test/utils/releases_test.dart | 41 ++++++++++++++++++++-------------- 5 files changed, 84 insertions(+), 59 deletions(-) create mode 100644 lib/commands/releases.dart delete mode 100644 lib/utils/releases.dart diff --git a/lib/commands/releases.dart b/lib/commands/releases.dart new file mode 100644 index 00000000..17b6052e --- /dev/null +++ b/lib/commands/releases.dart @@ -0,0 +1,41 @@ +// import 'dart:io'; + +// import 'package:io/ansi.dart'; +import 'package:args/command_runner.dart'; +import 'package:console/console.dart'; +// import 'package:fvm/utils/print.dart'; + +import 'package:fvm/utils/releases_helper.dart'; +// import 'package:fvm/utils/print.dart'; +// import 'package:fvm/constants.dart'; + +/// List installed SDK Versions +class ReleasesCommand extends Command { + // The [name] and [description] properties must be defined by every + // subclass. + @override + final name = 'releases'; + + @override + final description = 'Lists Flutter SDK releases.'; + + /// Constructor + ReleasesCommand(); + + @override + void run() async { + final flutterReleases = await fetchReleases(); + + final releases = flutterReleases.releases; + final outputReleases = releases.map((release) { + return '${release.version}'; + }).toList(); + var chooser = Chooser( + outputReleases, + message: 'Select a version: ', + ); + + var version = chooser.chooseSync(); + print('You chose $version.'); + } +} diff --git a/lib/constants.dart b/lib/constants.dart index a920d4ea..b0cdf170 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -56,14 +56,6 @@ Directory get kVersionsDir { return Directory(path.join(fvmHome, 'versions')); } -/// Gets Flutter Releases for a platform -String kFlutterReleasesListUrl = - '$kFlutterReleasesUrl/releases_${Platform.operatingSystem}.json'; - -/// Base Url for Flutter Storage -String kFlutterReleasesUrl = - 'https://storage.googleapis.com/flutter_infra/releases'; - /// Where Default Flutter SDK is stored Link get kDefaultFlutterLink => Link(path.join(fvmHome, 'default')); String get kDefaultFlutterPath => path.join(kDefaultFlutterLink.path, 'bin'); diff --git a/lib/utils/releases.dart b/lib/utils/releases.dart deleted file mode 100644 index f7a3c6a6..00000000 --- a/lib/utils/releases.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:fvm/constants.dart'; -// import 'package:path/path.dart' as path; - -Future fetchReleases() async { - try { - final response = await Dio().get(kFlutterReleasesListUrl); - print(response); - } catch (e) { - print(e); - } -} - -Future downloadVersion(String version) async { - // final url = '$kFlutterReleasesUrl/$releasePath'; - // final versionPath = path.join(kVersionsDir.path, version) - // final response = await Dio().download(url,kVersionsDir.path); - - // return response; -} diff --git a/lib/utils/releases_helper.dart b/lib/utils/releases_helper.dart index 8c3cec4b..40a4d555 100644 --- a/lib/utils/releases_helper.dart +++ b/lib/utils/releases_helper.dart @@ -14,14 +14,14 @@ String getReleasesUrl({String platform}) { Future fetchReleases() async { try { final response = await http.get(getReleasesUrl()); - return jsonDecode(response.body) as FlutterReleases; + return flutterReleasesFromMap(response.body); } on Exception { throw ExceptionCouldNotFetchReleases(); } } FlutterReleases flutterReleasesFromMap(String str) => - FlutterReleases.fromMap(json.decode(str) as Map); + FlutterReleases.fromMap(jsonDecode(str) as Map); String flutterReleasesToMap(FlutterReleases data) => json.encode(data.toMap()); @@ -36,12 +36,16 @@ class FlutterReleases { final CurrentRelease currentRelease; final List releases; - factory FlutterReleases.fromMap(Map json) => FlutterReleases( - baseUrl: json['base_url'] as String, - currentRelease: CurrentRelease.fromMap(json['current_release']), - releases: - List.from(json['releases'].map((x) => Release.fromMap(x))), - ); + factory FlutterReleases.fromMap(Map json) { + return FlutterReleases( + baseUrl: json['base_url'] as String, + currentRelease: CurrentRelease.fromMap( + json['current_release'] as Map), + releases: List.from(json['releases'] + .map((x) => Release.fromMap(x as Map)) + as Iterable), + ); + } Map toMap() => { 'base_url': baseUrl, @@ -61,7 +65,7 @@ class CurrentRelease { final String dev; final String stable; - factory CurrentRelease.fromMap(dynamic json) => CurrentRelease( + factory CurrentRelease.fromMap(Map json) => CurrentRelease( beta: json['beta'] as String, dev: json['dev'] as String, stable: json['stable'] as String, @@ -92,12 +96,12 @@ class Release { final String sha256; factory Release.fromMap(Map json) => Release( - hash: json['hash'], + hash: json['hash'] as String, channel: channelValues.map[json['channel']], - version: json['version'], - releaseDate: DateTime.parse(json['release_date']), - archive: json['archive'], - sha256: json['sha256'], + version: json['version'] as String, + releaseDate: DateTime.parse(json['release_date'] as String), + archive: json['archive'] as String, + sha256: json['sha256'] as String, ); Map toMap() => { @@ -123,6 +127,7 @@ class EnumValues { Map get reverse { reverseMap ??= map.map((k, v) => MapEntry(v, k)); + return reverseMap; } } diff --git a/test/utils/releases_test.dart b/test/utils/releases_test.dart index f8ce6312..b9a21cff 100644 --- a/test/utils/releases_test.dart +++ b/test/utils/releases_test.dart @@ -1,31 +1,38 @@ +import 'package:fvm/fvm.dart'; +import 'package:fvm/utils/releases_helper.dart'; @Timeout(Duration(minutes: 5)) -// import 'package:fvm/utils/releases.dart'; import 'package:test/test.dart'; -import 'package:dio/dio.dart'; -// import 'package:fvm/utils/releases.dart'; +import 'package:http/http.dart' as http; void main() { test('Can fetch releases for all platforms', () async { - String getPlatformUrl(String platform) { - return 'https://storage.googleapis.com/flutter_infra/releases/releases_$platform.json'; + try { + await http.get(getReleasesUrl(platform: 'macos')); + await http.get(getReleasesUrl(platform: 'linux')); + await http.get(getReleasesUrl(platform: 'windows')); + expect(true, true); + } on Exception { + fail('Could not resolve all platform releases'); } + }); + test('Can run releases', () async { try { - await Dio().get(getPlatformUrl('macos')); - await Dio().get(getPlatformUrl('linux')); - await Dio().get(getPlatformUrl('windows')); + await fvmRunner(['releases']); + expect(true, true); } on Exception { - fail('Could not resolve all platform releases'); + rethrow; } }); - // test('Can download release', () async { - // try { - // await downloadRelease('beta/macos/flutter_macos_1.19.0-4.1.pre-beta.zip'); - // expect(true, true); - // } on Exception { - // rethrow; - // } - // }); + test('Can download release', () async { + try { + final releases = await fetchReleases(); + print(releases.toString()); + expect(true, true); + } on Exception { + rethrow; + } + }); } From f2fe3ecc92e57073d6c7220187143dd3596795b1 Mon Sep 17 00:00:00 2001 From: leoafarias Date: Sun, 21 Jun 2020 09:30:23 -0400 Subject: [PATCH 5/7] List changes and cleanup --- lib/commands/list.dart | 3 ++- lib/exceptions.dart | 15 ++++++++++++++- lib/fvm.dart | 2 ++ lib/utils/helpers.dart | 22 ++++++++++++++++++---- pubspec.yaml | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/commands/list.dart b/lib/commands/list.dart index 45642a37..110a8abe 100644 --- a/lib/commands/list.dart +++ b/lib/commands/list.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:console/console.dart'; import 'package:fvm/constants.dart'; import 'package:fvm/utils/helpers.dart'; import 'package:fvm/utils/print.dart'; @@ -35,7 +36,7 @@ class ListCommand extends Command { void printVersions(String version) { if (isCurrentVersion(version)) { - version = '$version (current)'; + version = '$version ${Icon.HEAVY_CHECKMARK}'; } Print.info(version); } diff --git a/lib/exceptions.dart b/lib/exceptions.dart index 81f1134b..470d716a 100644 --- a/lib/exceptions.dart +++ b/lib/exceptions.dart @@ -78,7 +78,20 @@ class ExceptionMissingChannelVersion implements Exception { } } -/// Cannot find a config for the projec +/// Could not fetch Flutter releases +class ExceptionCouldNotFetchReleases implements Exception { + final message = 'Could not fetch Flutter releases.'; + + /// Constructor + ExceptionCouldNotFetchReleases(); + + @override + String toString() { + return message; + } +} + +/// Cannot find a config for the project class ExceptionProjectConfigNotFound implements Exception { final message = 'No config found for this project.'; diff --git a/lib/fvm.dart b/lib/fvm.dart index 0181e0a7..5ea433d9 100644 --- a/lib/fvm.dart +++ b/lib/fvm.dart @@ -3,6 +3,7 @@ import 'package:fvm/commands/config.dart'; import 'package:fvm/commands/flutter.dart'; import 'package:fvm/commands/install.dart'; import 'package:fvm/commands/list.dart'; +import 'package:fvm/commands/releases.dart'; import 'package:fvm/commands/remove.dart'; import 'package:fvm/commands/runner.dart'; import 'package:fvm/commands/use.dart'; @@ -22,6 +23,7 @@ Future fvmRunner(List args) async { runner..addCommand(UseCommand()); runner..addCommand(ConfigCommand()); runner..addCommand(VersionCommand()); + runner..addCommand(ReleasesCommand()); return await runner.run(args).catchError((exc, st) { if (exc is String) { diff --git a/lib/utils/helpers.dart b/lib/utils/helpers.dart index 14176a18..ee190b59 100644 --- a/lib/utils/helpers.dart +++ b/lib/utils/helpers.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'dart:io'; import 'package:fvm/constants.dart'; @@ -79,10 +81,7 @@ bool isCurrentVersion(String version) { /// The Flutter SDK Path referenced on FVM String getFlutterSdkPath({String version}) { var sdkVersion = version; - if (version == null) { - final config = readProjectConfig(); - sdkVersion = config.flutterSdkVersion; - } + version ??= readProjectConfig().flutterSdkVersion; return path.join(kVersionsDir.path, sdkVersion); } @@ -90,3 +89,18 @@ String getFlutterSdkExec({String version}) { return path.join(getFlutterSdkPath(version: version), 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter'); } + +String camelCase(String subject) { + final _splittedString = subject.split('_'); + + if (_splittedString.isEmpty) return ''; + + final _firstWord = _splittedString[0].toLowerCase(); + final _restWords = _splittedString.sublist(1).map(capitalize).toList(); + + return _firstWord + _restWords.join(''); +} + +String capitalize(String word) { + return '${word[0].toUpperCase()}${word.substring(1)}'; +} diff --git a/pubspec.yaml b/pubspec.yaml index d0080105..a7d7a9b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,9 +14,9 @@ dependencies: cli_util: ^0.2.0 console: ^3.1.0 io: ^0.3.3 - dio: ^3.0.9 path: ^1.6.4 process_run: ^0.10.10+1 + http: ^0.12.1 dev_dependencies: pedantic: ^1.8.0 From fd86c94414b13636f6a9c7606d8b89539761b7f4 Mon Sep 17 00:00:00 2001 From: leoafarias Date: Mon, 22 Jun 2020 07:06:52 -0400 Subject: [PATCH 6/7] Release command --- lib/commands/releases.dart | 30 +++++++++++++++++------------- lib/utils/releases_helper.dart | 22 ++++++++++++++++++++-- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/commands/releases.dart b/lib/commands/releases.dart index 17b6052e..f6fe7f4a 100644 --- a/lib/commands/releases.dart +++ b/lib/commands/releases.dart @@ -1,13 +1,8 @@ -// import 'dart:io'; - -// import 'package:io/ansi.dart'; import 'package:args/command_runner.dart'; import 'package:console/console.dart'; -// import 'package:fvm/utils/print.dart'; import 'package:fvm/utils/releases_helper.dart'; -// import 'package:fvm/utils/print.dart'; -// import 'package:fvm/constants.dart'; +import 'package:fvm/utils/version_installer.dart'; /// List installed SDK Versions class ReleasesCommand extends Command { @@ -25,17 +20,26 @@ class ReleasesCommand extends Command { @override void run() async { final flutterReleases = await fetchReleases(); + final channels = flutterReleases.currentRelease.toMap(); + + final list = []; + + channels.forEach((key, value) { + list.add('$key: $value'); + }); - final releases = flutterReleases.releases; - final outputReleases = releases.map((release) { - return '${release.version}'; - }).toList(); var chooser = Chooser( - outputReleases, - message: 'Select a version: ', + list, + message: 'Select a release: ', ); var version = chooser.chooseSync(); - print('You chose $version.'); + + channels.forEach((key, value) { + if (version == '$key: $value') { + installFlutterVersion(value as String); + } + }); + print('You chose $version'); } } diff --git a/lib/utils/releases_helper.dart b/lib/utils/releases_helper.dart index 40a4d555..a62ecedc 100644 --- a/lib/utils/releases_helper.dart +++ b/lib/utils/releases_helper.dart @@ -20,6 +20,24 @@ Future fetchReleases() async { } } +Map filterCurrentReleases(Map json) { + final currentRelease = json['current_release'] as Map; + final releases = json['releases'] as List; + // Hashes of current releases + final hashMap = currentRelease.map((key, value) => MapEntry(value, key)); + + // Filter out channel/currentRelease versions + releases.forEach((r) { + // Check if release hash is in hashmap + final channel = hashMap[r['hash']]; + if (channel != null) { + currentRelease[channel] = r['version']; + } + }); + + return currentRelease; +} + FlutterReleases flutterReleasesFromMap(String str) => FlutterReleases.fromMap(jsonDecode(str) as Map); @@ -37,10 +55,10 @@ class FlutterReleases { final List releases; factory FlutterReleases.fromMap(Map json) { + final currentRelease = filterCurrentReleases(json); return FlutterReleases( baseUrl: json['base_url'] as String, - currentRelease: CurrentRelease.fromMap( - json['current_release'] as Map), + currentRelease: CurrentRelease.fromMap(currentRelease), releases: List.from(json['releases'] .map((x) => Release.fromMap(x as Map)) as Iterable), From 408a7cf5d1fc32255d6cdf66ac6372948290bd8a Mon Sep 17 00:00:00 2001 From: leoafarias Date: Mon, 22 Jun 2020 08:19:14 -0400 Subject: [PATCH 7/7] Date formatting and test coverage --- README.md | 16 ++++++++++++--- coverage_badge.svg | 6 +++--- lib/commands/install.dart | 5 +++++ lib/commands/releases.dart | 37 ++++++++++++++++------------------ lib/utils/helpers.dart | 2 +- lib/utils/releases_helper.dart | 6 ++++++ pubspec.yaml | 1 + 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 8c8efa97..52df7180 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,12 @@ Flutter Version Management: A simple cli to manage Flutter SDK versions. **Features:** -- Configure Flutter SDK version per project +- Configure and use Flutter SDK version per project - Ability to install and cache multiple Flutter SDK Versions -- Easily switch between Flutter channels & versions -- Per project Flutter SDK upgrade +- Fast switch between Flutter channels & versions +- Dynamic sdk paths for IDE debugging support. +- Version FVM config with project for consistency across teams and CI environments. +- Set global Flutter version across projects ## Version Management @@ -83,6 +85,14 @@ List all the versions that are installed on your machine. This command will also > fvm list ``` +### List Flutter Releases + +Displays all Flutter releases, including the current version for `dev`, `beta` and `stable` channels. + +```bash +> fvm releases +``` + ### Change FVM Cache Directory There are some configurations that allows for added flexibility on FVM. If no `cache-path` is set, the default fvm path will be used. diff --git a/coverage_badge.svg b/coverage_badge.svg index f6e16c2f..3b4d6cb9 100644 --- a/coverage_badge.svg +++ b/coverage_badge.svg @@ -8,13 +8,13 @@ - + coverage coverage - 74% - 74% + 72% + 72% diff --git a/lib/commands/install.dart b/lib/commands/install.dart index e7085886..67fc6623 100644 --- a/lib/commands/install.dart +++ b/lib/commands/install.dart @@ -30,11 +30,13 @@ class InstallCommand extends Command { Guards.isGitInstalled(); String version; + var hasConfig = false; if (argResults.arguments.isEmpty) { final configVersion = getConfigFlutterVersion(); if (configVersion == null) { throw ExceptionMissingChannelVersion(); } + hasConfig = true; version = configVersion; } else { version = argResults.arguments[0].toLowerCase(); @@ -45,5 +47,8 @@ class InstallCommand extends Command { final flutterVersion = await inferFlutterVersion(version); await installFlutterVersion(flutterVersion, skipSetup: skipSetup); + if (hasConfig) { + setAsProjectVersion(version); + } } } diff --git a/lib/commands/releases.dart b/lib/commands/releases.dart index f6fe7f4a..df873efd 100644 --- a/lib/commands/releases.dart +++ b/lib/commands/releases.dart @@ -1,8 +1,9 @@ import 'package:args/command_runner.dart'; import 'package:console/console.dart'; +import 'package:date_format/date_format.dart'; +import 'package:io/ansi.dart'; import 'package:fvm/utils/releases_helper.dart'; -import 'package:fvm/utils/version_installer.dart'; /// List installed SDK Versions class ReleasesCommand extends Command { @@ -20,26 +21,22 @@ class ReleasesCommand extends Command { @override void run() async { final flutterReleases = await fetchReleases(); - final channels = flutterReleases.currentRelease.toMap(); - - final list = []; - - channels.forEach((key, value) { - list.add('$key: $value'); - }); - - var chooser = Chooser( - list, - message: 'Select a release: ', - ); - - var version = chooser.chooseSync(); - - channels.forEach((key, value) { - if (version == '$key: $value') { - installFlutterVersion(value as String); + final channels = flutterReleases.currentRelease.toHashMap(); + final releases = flutterReleases.releases.reversed; + + releases.forEach((r) { + final channel = channels[r.version]; + final channelOutput = green.wrap('$channel'); + final version = yellow.wrap(r.version.padRight(17)); + final pipe = Icon.PIPE_VERTICAL; + final friendlyDate = + formatDate(r.releaseDate, [M, ' ', d, ' ', yy]).padRight(10); + if (channel != null) { + print('----------$channelOutput----------'); + print('$friendlyDate $pipe $version'); + } else { + print('$friendlyDate $pipe $version'); } }); - print('You chose $version'); } } diff --git a/lib/utils/helpers.dart b/lib/utils/helpers.dart index ee190b59..64840bf7 100644 --- a/lib/utils/helpers.dart +++ b/lib/utils/helpers.dart @@ -81,7 +81,7 @@ bool isCurrentVersion(String version) { /// The Flutter SDK Path referenced on FVM String getFlutterSdkPath({String version}) { var sdkVersion = version; - version ??= readProjectConfig().flutterSdkVersion; + sdkVersion ??= readProjectConfig().flutterSdkVersion; return path.join(kVersionsDir.path, sdkVersion); } diff --git a/lib/utils/releases_helper.dart b/lib/utils/releases_helper.dart index a62ecedc..a30c86ac 100644 --- a/lib/utils/releases_helper.dart +++ b/lib/utils/releases_helper.dart @@ -94,6 +94,12 @@ class CurrentRelease { 'dev': dev, 'stable': stable, }; + + Map toHashMap() => { + '$beta': 'beta', + '$dev': 'dev', + '$stable': 'stable', + }; } class Release { diff --git a/pubspec.yaml b/pubspec.yaml index a7d7a9b1..bf87a401 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: path: ^1.6.4 process_run: ^0.10.10+1 http: ^0.12.1 + date_format: ^1.0.8 dev_dependencies: pedantic: ^1.8.0