1// Copyright 2016 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'package:package_config/packages_file.dart' as packages_file; 6 7import '../base/file_system.dart'; 8import '../base/platform.dart'; 9 10const String kPackagesFileName = '.packages'; 11 12Map<String, Uri> _parse(String packagesPath) { 13 final List<int> source = fs.file(packagesPath).readAsBytesSync(); 14 return packages_file.parse(source, 15 Uri.file(packagesPath, windows: platform.isWindows)); 16} 17 18class PackageMap { 19 PackageMap(this.packagesPath); 20 21 static String get globalPackagesPath => _globalPackagesPath ?? kPackagesFileName; 22 23 static String get globalGeneratedPackagesPath => fs.path.setExtension(globalPackagesPath, '.generated'); 24 25 static set globalPackagesPath(String value) { 26 _globalPackagesPath = value; 27 } 28 29 static bool get isUsingCustomPackagesPath => _globalPackagesPath != null; 30 31 static String _globalPackagesPath; 32 33 final String packagesPath; 34 35 /// Load and parses the .packages file. 36 void load() { 37 _map ??= _parse(packagesPath); 38 } 39 40 Map<String, Uri> get map { 41 load(); 42 return _map; 43 } 44 Map<String, Uri> _map; 45 46 /// Returns the path to [packageUri]. 47 String pathForPackage(Uri packageUri) => uriForPackage(packageUri).path; 48 49 /// Returns the path to [packageUri] as Uri. 50 Uri uriForPackage(Uri packageUri) { 51 assert(packageUri.scheme == 'package'); 52 final List<String> pathSegments = packageUri.pathSegments.toList(); 53 final String packageName = pathSegments.removeAt(0); 54 final Uri packageBase = map[packageName]; 55 if (packageBase == null) 56 return null; 57 final String packageRelativePath = fs.path.joinAll(pathSegments); 58 return packageBase.resolveUri(fs.path.toUri(packageRelativePath)); 59 } 60 61 String checkValid() { 62 if (fs.isFileSync(packagesPath)) 63 return null; 64 String message = '$packagesPath does not exist.'; 65 final String pubspecPath = fs.path.absolute(fs.path.dirname(packagesPath), 'pubspec.yaml'); 66 if (fs.isFileSync(pubspecPath)) 67 message += '\nDid you run "flutter pub get" in this directory?'; 68 else 69 message += '\nDid you run this command from the same directory as your pubspec.yaml file?'; 70 return message; 71 } 72} 73