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