Unverified Commit 6b5634fe authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Reduce some direct package:archive usage (#44608)

parent 314eb3ba
...@@ -249,6 +249,7 @@ class _WindowsUtils extends OperatingSystemUtils { ...@@ -249,6 +249,7 @@ class _WindowsUtils extends OperatingSystemUtils {
@override @override
void zip(Directory data, File zipFile) { void zip(Directory data, File zipFile) {
// TODO(jonahwilliams): investigate whether we can remove this dependency with https://github.com/flutter/flutter/issues/45278
final Archive archive = Archive(); final Archive archive = Archive();
for (FileSystemEntity entity in data.listSync(recursive: true)) { for (FileSystemEntity entity in data.listSync(recursive: true)) {
if (entity is! File) { if (entity is! File) {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:archive/archive.dart';
import 'package:build_daemon/client.dart'; import 'package:build_daemon/client.dart';
import 'package:build_daemon/constants.dart' as daemon; import 'package:build_daemon/constants.dart' as daemon;
import 'package:build_daemon/data/build_status.dart'; import 'package:build_daemon/data/build_status.dart';
...@@ -407,33 +406,6 @@ class DebugAssetServer extends AssetServer { ...@@ -407,33 +406,6 @@ class DebugAssetServer extends AssetServer {
return Response.ok(file.readAsBytesSync(), headers: <String, String>{ return Response.ok(file.readAsBytesSync(), headers: <String, String>{
'Content-Type': 'text/javascript', 'Content-Type': 'text/javascript',
}); });
} else if (request.url.path.endsWith('part.js')) {
// Lazily unpack any deferred imports in release/profile mode. These are
// placed into an archive by build_runner, and are named based on the main
// entrypoint + a "part" suffix (Though the actual names are arbitrary).
// To make this easier to deal with they are copied into a temp directory.
if (partFiles == null) {
final File dart2jsArchive = fs.file(fs.path.join(
flutterProject.dartTool.path,
'build',
'flutter_web',
'${flutterProject.manifest.appName}',
'lib',
'${targetBaseName}_web_entrypoint.dart.js.tar.gz',
));
if (dart2jsArchive.existsSync()) {
final Archive archive = TarDecoder().decodeBytes(dart2jsArchive.readAsBytesSync());
partFiles = fs.systemTempDirectory.createTempSync('flutter_tool.')
..createSync();
for (ArchiveFile file in archive) {
partFiles.childFile(file.name).writeAsBytesSync(file.content as List<int>);
}
}
}
final String fileName = fs.path.basename(request.url.path);
return Response.ok(partFiles.childFile(fileName).readAsBytesSync(), headers: <String, String>{
'Content-Type': 'text/javascript',
});
} else if (request.url.path.contains('require.js')) { } else if (request.url.path.contains('require.js')) {
final File file = fs.file(fs.path.join( final File file = fs.file(fs.path.join(
artifacts.getArtifactPath(Artifact.engineDartSdkPath), artifacts.getArtifactPath(Artifact.engineDartSdkPath),
......
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:archive/archive.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/os.dart';
import '../base/version.dart'; import '../base/version.dart';
import '../convert.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../globals.dart';
class IntelliJPlugins { class IntelliJPlugins {
IntelliJPlugins(this.pluginsPath); IntelliJPlugins(this.pluginsPath);
...@@ -56,18 +55,25 @@ class IntelliJPlugins { ...@@ -56,18 +55,25 @@ class IntelliJPlugins {
final String jarPath = packageName.endsWith('.jar') final String jarPath = packageName.endsWith('.jar')
? fs.path.join(pluginsPath, packageName) ? fs.path.join(pluginsPath, packageName)
: fs.path.join(pluginsPath, packageName, 'lib', '$packageName.jar'); : fs.path.join(pluginsPath, packageName, 'lib', '$packageName.jar');
// TODO(danrubel): look for a better way to extract a single 2K file from the zip
// rather than reading the entire file into memory.
try { try {
final Archive archive = final Directory tempDirectory = fs.systemTempDirectory
ZipDecoder().decodeBytes(fs.file(jarPath).readAsBytesSync()); .createTempSync('flutter_tools_intellij.')
final ArchiveFile file = archive.findFile('META-INF/plugin.xml'); ..createSync(recursive: true);
final String content = utf8.decode(file.content as List<int>); os.unzip(fs.file(jarPath), tempDirectory);
final File file = tempDirectory
.childDirectory('META-INF')
.childFile('plugin.xml');
final String content = file.readAsStringSync();
const String versionStartTag = '<version>'; const String versionStartTag = '<version>';
final int start = content.indexOf(versionStartTag); final int start = content.indexOf(versionStartTag);
final int end = content.indexOf('</version>', start); final int end = content.indexOf('</version>', start);
try {
tempDirectory.deleteSync(recursive: true);
} on Exception catch (_) {
printTrace('Failed to delete temp directory: ${tempDirectory?.path}');
}
return content.substring(start + versionStartTag.length, end); return content.substring(start + versionStartTag.length, end);
} catch (_) { } on Exception catch (_) {
return null; return null;
} }
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:convert';
import 'package:archive/archive.dart';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/intellij/intellij.dart'; import 'package:flutter_tools/src/intellij/intellij.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
const String dartPluginContents = '''<idea-plugin version="2">
<name>Dart</name>
<version>162.2485</version>
</idea-plugin>
''';
const String flutterPluginContents = r'''
<idea-plugin version="2">
<name>Flutter</name>
<version>0.1.3</version>
</idea-plugin>
''';
void main() { void main() {
FileSystem fs; testUsingContext('IntelliJ plugins found', () async {
fs.directory(fs.path.join(_kPluginsPath, 'Dart'))
.createSync(recursive: true);
fs.file(fs.path.join(_kPluginsPath, 'flutter-intellij.jar'))
.createSync(recursive: true);
when(os.unzip(any, any)).thenAnswer((Invocation invocation) {
final File file = invocation.positionalArguments.first as File;
final Directory destination = invocation.positionalArguments.last as Directory;
destination
.childDirectory('META-INF')
.childFile('plugin.xml')
..createSync(recursive: true)
..writeAsStringSync(file.path.contains('Dart')
? dartPluginContents
: flutterPluginContents);
});
void writeFileCreatingDirectories(String path, List<int> bytes) { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath);
final File file = fs.file(path);
file.parent.createSync(recursive: true);
file.writeAsBytesSync(bytes);
}
setUp(() { final List<ValidationMessage> messages = <ValidationMessage>[];
fs = MemoryFileSystem(); plugins.validatePackage(messages, <String>['Dart'], 'Dart');
}); plugins.validatePackage(messages,
<String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter',
minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
group('IntelliJ', () { ValidationMessage message = messages
group('plugins', () { .firstWhere((ValidationMessage m) => m.message.startsWith('Dart '));
testUsingContext('found', () async {
final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath);
final Archive dartJarArchive = expect(message.message, 'Dart plugin version 162.2485');
buildSingleFileArchive('META-INF/plugin.xml', r''' message = messages.firstWhere(
<idea-plugin version="2"> (ValidationMessage m) => m.message.startsWith('Flutter '));
<name>Dart</name>
<version>162.2485</version>
</idea-plugin>
''');
writeFileCreatingDirectories(
fs.path.join(_kPluginsPath, 'Dart', 'lib', 'Dart.jar'),
ZipEncoder().encode(dartJarArchive));
final Archive flutterJarArchive = expect(message.message, contains('Flutter plugin version 0.1.3'));
buildSingleFileArchive('META-INF/plugin.xml', r''' expect(message.message, contains('recommended minimum version'));
<idea-plugin version="2"> }, overrides: <Type, Generator>{
<name>Flutter</name> FileSystem: () => MemoryFileSystem(),
<version>0.1.3</version> ProcessManager: () => FakeProcessManager.any(),
</idea-plugin> OperatingSystemUtils: () => MockOperatingSystemUtils(),
''');
writeFileCreatingDirectories(
fs.path.join(_kPluginsPath, 'flutter-intellij.jar'),
ZipEncoder().encode(flutterJarArchive));
final List<ValidationMessage> messages = <ValidationMessage>[];
plugins.validatePackage(messages, <String>['Dart'], 'Dart');
plugins.validatePackage(messages,
<String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter',
minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
ValidationMessage message = messages
.firstWhere((ValidationMessage m) => m.message.startsWith('Dart '));
expect(message.message, 'Dart plugin version 162.2485');
message = messages.firstWhere(
(ValidationMessage m) => m.message.startsWith('Flutter '));
expect(message.message, contains('Flutter plugin version 0.1.3'));
expect(message.message, contains('recommended minimum version'));
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('not found', () async {
final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath);
final List<ValidationMessage> messages = <ValidationMessage>[];
plugins.validatePackage(messages, <String>['Dart'], 'Dart');
plugins.validatePackage(messages,
<String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter',
minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
ValidationMessage message = messages
.firstWhere((ValidationMessage m) => m.message.startsWith('Dart '));
expect(message.message, contains('Dart plugin not installed'));
message = messages.firstWhere(
(ValidationMessage m) => m.message.startsWith('Flutter '));
expect(message.message, contains('Flutter plugin not installed'));
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
});
});
}); });
}
const String _kPluginsPath = '/data/intellij/plugins'; testUsingContext('IntelliJ plugins not found', () async {
final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath);
final List<ValidationMessage> messages = <ValidationMessage>[];
plugins.validatePackage(messages, <String>['Dart'], 'Dart');
plugins.validatePackage(messages,
<String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter',
minVersion: IntelliJPlugins.kMinFlutterPluginVersion);
ValidationMessage message = messages
.firstWhere((ValidationMessage m) => m.message.startsWith('Dart '));
Archive buildSingleFileArchive(String path, String content) { expect(message.message, contains('Dart plugin not installed'));
final Archive archive = Archive();
final List<int> bytes = utf8.encode(content); message = messages.firstWhere(
archive.addFile(ArchiveFile(path, bytes.length, bytes)); (ValidationMessage m) => m.message.startsWith('Flutter '));
return archive; expect(message.message, contains('Flutter plugin not installed'));
}, overrides: <Type, Generator>{
OperatingSystemUtils: () => MockOperatingSystemUtils(),
FileSystem: () => MemoryFileSystem(),
ProcessManager: () => FakeProcessManager.any(),
});
} }
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
const String _kPluginsPath = '/data/intellij/plugins';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment