blob: cf8b5769532ee31706c428635e1e02896864bf75 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:archive/archive.dart';
import 'package:meta/meta.dart';
import '../base/file_system.dart';
import '../base/version.dart';
import '../convert.dart';
import '../doctor.dart';
/// A parser for the Intellij and Android Studio plugin JAR files.
///
/// This searches on the provided plugin path for a JAR archive, then
/// unzips it to parse the META-INF/plugin.xml for version information.
///
/// See also:
/// * [IntellijValidator], the validator base class that uses this to check
/// plugin versions.
class IntelliJPlugins {
IntelliJPlugins(this.pluginsPath, {
@required FileSystem fileSystem
}) : _fileSystem = fileSystem;
final FileSystem _fileSystem;
final String pluginsPath;
static final Version kMinFlutterPluginVersion = Version(16, 0, 0);
static const String kIntellijDartPluginUrl = 'https://plugins.jetbrains.com/plugin/6351-dart';
static const String kIntellijFlutterPluginUrl = 'https://plugins.jetbrains.com/plugin/9212-flutter';
void validatePackage(
List<ValidationMessage> messages,
List<String> packageNames,
String title,
String url, {
Version minVersion,
}) {
for (final String packageName in packageNames) {
if (!_hasPackage(packageName)) {
continue;
}
final String versionText = _readPackageVersion(packageName);
final Version version = Version.parse(versionText);
if (version != null && minVersion != null && version < minVersion) {
messages.add(ValidationMessage.error(
'$title plugin version $versionText - the recommended minimum version is $minVersion'),
);
} else {
messages.add(ValidationMessage(
'$title plugin ${version != null ? "version $version" : "installed"}'),
);
}
return;
}
messages.add(ValidationMessage(
'$title plugin can be installed from:',
contextUrl: url,
));
}
bool _hasPackage(String packageName) {
final String packagePath = _fileSystem.path.join(pluginsPath, packageName);
if (packageName.endsWith('.jar')) {
return _fileSystem.isFileSync(packagePath);
}
return _fileSystem.isDirectorySync(packagePath);
}
String _readPackageVersion(String packageName) {
final String jarPath = packageName.endsWith('.jar')
? _fileSystem.path.join(pluginsPath, packageName)
: _fileSystem.path.join(pluginsPath, packageName, 'lib', '$packageName.jar');
final File file = _fileSystem.file(jarPath);
if (!file.existsSync()) {
return null;
}
try {
final Archive archive = ZipDecoder().decodeBytes(file.readAsBytesSync());
final ArchiveFile archiveFile = archive.findFile('META-INF/plugin.xml');
final String content = utf8.decode(archiveFile.content as List<int>);
const String versionStartTag = '<version>';
final int start = content.indexOf(versionStartTag);
final int end = content.indexOf('</version>', start);
return content.substring(start + versionStartTag.length, end);
} on ArchiveException {
return null;
}
}
}