| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library descriptor.file; | 5 library descriptor.file; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io' as io; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import '../../../../../pkg/pathos/lib/path.dart' as path; | 10 import '../../../../../pkg/pathos/lib/path.dart' as path; |
| 11 | 11 |
| 12 import '../../descriptor.dart' as descriptor; | 12 import '../../descriptor.dart'; |
| 13 import '../../scheduled_test.dart'; | 13 import '../../scheduled_test.dart'; |
| 14 import '../utils.dart'; | 14 import '../utils.dart'; |
| 15 import 'utils.dart'; | |
| 16 | 15 |
| 17 /// A path builder to ensure that [load] uses POSIX paths. | 16 /// A path builder to ensure that [load] uses POSIX paths. |
| 18 final path.Builder _path = new path.Builder(style: path.Style.posix); | 17 final path.Builder _path = new path.Builder(style: path.Style.posix); |
| 19 | 18 |
| 20 /// A descriptor describing a directory containing multiple files. | 19 /// A descriptor describing a directory containing multiple files. |
| 21 class Directory extends descriptor.Entry { | 20 class DirectoryDescriptor extends Descriptor { |
| 22 /// The entries contained within this directory. | 21 /// The entries contained within this directory. |
| 23 final Iterable<descriptor.Entry> contents; | 22 final Iterable<Descriptor> contents; |
| 24 | 23 |
| 25 Directory(Pattern name, this.contents) | 24 DirectoryDescriptor(String name, this.contents) |
| 26 : super(name); | 25 : super(name); |
| 27 | 26 |
| 28 Future create([String parent]) => schedule(() { | 27 Future create([String parent]) => schedule(() { |
| 29 if (parent == null) parent = descriptor.defaultRoot; | 28 if (parent == null) parent = defaultRoot; |
| 30 var fullPath = path.join(parent, stringName); | 29 var fullPath = path.join(parent, name); |
| 31 return new io.Directory(fullPath).create(recursive: true).then((_) { | 30 return new Directory(fullPath).create(recursive: true).then((_) { |
| 32 return Future.wait( | 31 return Future.wait( |
| 33 contents.map((entry) => entry.create(fullPath)).toList()); | 32 contents.map((entry) => entry.create(fullPath)).toList()); |
| 34 }); | 33 }); |
| 35 }, 'creating directory:\n${describe()}'); | 34 }, 'creating directory:\n${describe()}'); |
| 36 | 35 |
| 37 Future validate([String parent]) => schedule(() { | 36 Future validate([String parent]) => schedule(() => validateNow(parent), |
| 38 if (parent == null) parent = descriptor.defaultRoot; | 37 'validating directory:\n${describe()}'); |
| 39 var fullPath = entryMatchingPattern('Directory', parent, name); | 38 |
| 39 Future validateNow([String parent]) { |
| 40 if (parent == null) parent = defaultRoot; |
| 41 var fullPath = path.join(parent, name); |
| 42 if (!new Directory(fullPath).existsSync()) { |
| 43 throw "Directory not found: '$fullPath'."; |
| 44 } |
| 45 |
| 40 return Future.wait( | 46 return Future.wait( |
| 41 contents.map((entry) => entry.validate(fullPath)).toList()); | 47 contents.map((entry) => entry.validateNow(fullPath)).toList()); |
| 42 }, 'validating directory:\n${describe()}'); | 48 } |
| 43 | 49 |
| 44 Stream<List<int>> load(String pathToLoad) { | 50 Stream<List<int>> load(String pathToLoad) { |
| 45 return futureStream(new Future.immediate(null).then((_) { | 51 return futureStream(new Future.immediate(null).then((_) { |
| 46 if (_path.isAbsolute(pathToLoad)) { | 52 if (_path.isAbsolute(pathToLoad)) { |
| 47 throw "Can't load absolute path '$pathToLoad'."; | 53 throw "Can't load absolute path '$pathToLoad'."; |
| 48 } | 54 } |
| 49 | 55 |
| 50 var split = _path.split(_path.normalize(pathToLoad)); | 56 var split = _path.split(_path.normalize(pathToLoad)); |
| 51 if (split.isEmpty || split.first == '.' || split.first == '..') { | 57 if (split.isEmpty || split.first == '.' || split.first == '..') { |
| 52 throw "Can't load '$pathToLoad' from within $nameDescription."; | 58 throw "Can't load '$pathToLoad' from within '$name'."; |
| 53 } | 59 } |
| 54 | 60 |
| 55 var matchingEntries = contents.where((entry) => | 61 var matchingEntries = contents.where((entry) => |
| 56 entry.stringName == split.first).toList(); | 62 entry.name == split.first).toList(); |
| 57 | 63 |
| 58 if (matchingEntries.length == 0) { | 64 if (matchingEntries.length == 0) { |
| 59 throw "Couldn't find an entry named '${split.first}' within " | 65 throw "Couldn't find an entry named '${split.first}' within '$name'."; |
| 60 "$nameDescription."; | |
| 61 } else if (matchingEntries.length > 1) { | 66 } else if (matchingEntries.length > 1) { |
| 62 throw "Found multiple entries named '${split.first}' within " | 67 throw "Found multiple entries named '${split.first}' within '$name'."; |
| 63 "$nameDescription."; | |
| 64 } else { | 68 } else { |
| 65 var remainingPath = split.getRange(1, split.length - 1); | 69 var remainingPath = split.getRange(1, split.length - 1); |
| 66 if (remainingPath.isEmpty) { | 70 if (remainingPath.isEmpty) { |
| 67 return matchingEntries.first.read(); | 71 return matchingEntries.first.read(); |
| 68 } else { | 72 } else { |
| 69 return matchingEntries.first.load(_path.joinAll(remainingPath)); | 73 return matchingEntries.first.load(_path.joinAll(remainingPath)); |
| 70 } | 74 } |
| 71 } | 75 } |
| 72 })); | 76 })); |
| 73 } | 77 } |
| 74 | 78 |
| 75 Stream<List<int>> read() => errorStream("Can't read the contents of " | 79 Stream<List<int>> read() => errorStream("Can't read the contents of '$name': " |
| 76 "$nameDescription: is a directory."); | 80 "is a directory."); |
| 77 | 81 |
| 78 String describe() { | 82 String describe() { |
| 79 var description = name; | 83 if (contents.isEmpty) return name; |
| 80 if (name is! String) description = 'directory matching $nameDescription'; | |
| 81 if (contents.isEmpty) return description; | |
| 82 | 84 |
| 83 var buffer = new StringBuffer(); | 85 var buffer = new StringBuffer(); |
| 84 buffer.writeln(description); | 86 buffer.writeln(name); |
| 85 for (var entry in contents.take(contents.length - 1)) { | 87 for (var entry in contents.take(contents.length - 1)) { |
| 86 var entryString = prefixLines(entry.describe(), prefix: '| ') | 88 var entryString = prefixLines(entry.describe(), prefix: '| ') |
| 87 .replaceFirst('| ', '|-- '); | 89 .replaceFirst('| ', '|-- '); |
| 88 buffer.writeln(entryString); | 90 buffer.writeln(entryString); |
| 89 } | 91 } |
| 90 | 92 |
| 91 var lastEntryString = prefixLines(contents.last.describe(), prefix: ' ') | 93 var lastEntryString = prefixLines(contents.last.describe(), prefix: ' ') |
| 92 .replaceFirst(' ', "'-- "); | 94 .replaceFirst(' ', "'-- "); |
| 93 buffer.write(lastEntryString); | 95 buffer.write(lastEntryString); |
| 94 return buffer.toString(); | 96 return buffer.toString(); |
| 95 } | 97 } |
| 96 } | 98 } |
| OLD | NEW |