Skip to content

Commit

Permalink
[flutter_tools] Fix legacy version file not being ensured (#133097)
Browse files Browse the repository at this point in the history
Fixes #133093

When I introduced the new, more robust version file `//flutter/bin/cache/version.json` in #124558, I changed `class FlutterVersion` into an abstract interface, implemented by `_FlutterVersionFromGit` (which is essentially the previous behavior) and `_FlutterVersionFromFile`, which merely reads the data it would have computed via git from `//flutter/bin/cache/version.json`.

While doing this, I made `_FlutterVersionFromGit.ensureVersionFile()` to be a no-op, since I assumed this would not be necessary since we already had a version file in the cache. However, this method was what was previously responsible for ensuring `//flutter/version` existed on disk. This means that if, for whatever reason, the user had `//flutter/bin/cache/flutter.version.json` present but NOT `//flutter/version`, the tool would have never created that file, and they would hit the tool crash seen in #133093.

This fixes the tool by ensuring `//flutter/version` exists regardless of if we're hydrating `FlutterVersion` from `//flutter/bin/cache/flutter.version.json` or not.
  • Loading branch information
christopherfujino committed Aug 23, 2023
1 parent ad78cf3 commit 9e59a68
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
28 changes: 23 additions & 5 deletions packages/flutter_tools/lib/src/version.dart
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,13 @@ class _FlutterVersionFromFile extends FlutterVersion {
final String devToolsVersion;

@override
void ensureVersionFile() {}
void ensureVersionFile() {
_ensureLegacyVersionFile(
fs: fs,
flutterRoot: flutterRoot,
frameworkVersion: frameworkVersion,
);
}
}

class _FlutterVersionGit extends FlutterVersion {
Expand Down Expand Up @@ -599,10 +605,11 @@ class _FlutterVersionGit extends FlutterVersion {

@override
void ensureVersionFile() {
final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
if (!legacyVersionFile.existsSync()) {
legacyVersionFile.writeAsStringSync(frameworkVersion);
}
_ensureLegacyVersionFile(
fs: fs,
flutterRoot: flutterRoot,
frameworkVersion: frameworkVersion,
);

const JsonEncoder encoder = JsonEncoder.withIndent(' ');
final File newVersionFile = FlutterVersion.getVersionFile(fs, flutterRoot);
Expand All @@ -612,6 +619,17 @@ class _FlutterVersionGit extends FlutterVersion {
}
}

void _ensureLegacyVersionFile({
required FileSystem fs,
required String flutterRoot,
required String frameworkVersion,
}) {
final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
if (!legacyVersionFile.existsSync()) {
legacyVersionFile.writeAsStringSync(frameworkVersion);
}
}

/// Checks if the provided [version] is tracking a standard remote.
///
/// A "standard remote" is one having the same url as(in order of precedence):
Expand Down
37 changes: 37 additions & 0 deletions packages/flutter_tools/test/general.shard/version_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,43 @@ void main() {
Cache: () => cache,
});

testUsingContext('_FlutterVersionFromFile.ensureVersionFile ensures legacy version file exists', () async {
final MemoryFileSystem fs = MemoryFileSystem.test();
final Directory flutterRoot = fs.directory('/path/to/flutter');
final Directory cacheDir = flutterRoot
.childDirectory('bin')
.childDirectory('cache')
..createSync(recursive: true);
const String devToolsVersion = '0000000';
final File legacyVersionFile = flutterRoot.childFile('version');
const Map<String, Object> versionJson = <String, Object>{
'channel': 'stable',
'frameworkVersion': '1.2.3',
'repositoryUrl': 'https://github.com/flutter/flutter.git',
'frameworkRevision': '1234abcd',
'frameworkCommitDate': '2023-04-28 12:34:56 -0400',
'engineRevision': 'deadbeef',
'dartSdkVersion': 'deadbeef2',
'devToolsVersion': devToolsVersion,
'flutterVersion': 'foo',
};
cacheDir.childFile('flutter.version.json').writeAsStringSync(
jsonEncode(versionJson),
);
expect(legacyVersionFile.existsSync(), isFalse);
final FlutterVersion flutterVersion = FlutterVersion(
clock: _testClock,
fs: fs,
flutterRoot: flutterRoot.path,
);
flutterVersion.ensureVersionFile();
expect(legacyVersionFile.existsSync(), isTrue);
expect(legacyVersionFile.readAsStringSync(), '1.2.3');
}, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Cache: () => cache,
});

testUsingContext('FlutterVersion() falls back to git if .version.json is malformed', () async {
final MemoryFileSystem fs = MemoryFileSystem.test();
final Directory flutterRoot = fs.directory(fs.path.join('path', 'to', 'flutter'));
Expand Down

0 comments on commit 9e59a68

Please sign in to comment.