Chromium Code Reviews| Index: utils/pub/directory_tree.dart |
| diff --git a/utils/pub/directory_tree.dart b/utils/pub/directory_tree.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f2bfa0cab1dbbac6a08080eb7dca198c7ee268c9 |
| --- /dev/null |
| +++ b/utils/pub/directory_tree.dart |
| @@ -0,0 +1,135 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +/// A simple library for rendering a list of files as a directory tree. |
| +library directory_tree; |
| + |
| +import 'log.dart' as log; |
| +import 'path.dart' as path; |
| + |
| +/// Draws a directory tree for the given list of files. Given a list of files |
| +/// like: |
| +/// |
| +/// TODO |
| +/// example/console_example.dart |
| +/// example/main.dart |
| +/// example/web copy/web_example.dart |
| +/// test/absolute_test.dart |
| +/// test/basename_test.dart |
| +/// test/dirname_test.dart |
| +/// test/extension_test.dart |
| +/// test/is_absolute_test.dart |
| +/// test/is_relative_test.dart |
| +/// test/join_test.dart |
| +/// test/normalize_test.dart |
| +/// test/relative_test.dart |
| +/// test/split_test.dart |
| +/// .gitignore |
| +/// README.md |
| +/// lib/path.dart |
| +/// pubspec.yaml |
| +/// test/all_test.dart |
| +/// test/path_posix_test.dart |
| +/// test/path_windows_test.dart |
| +/// |
| +/// this will render: |
| +/// |
| +/// |-- .gitignore |
| +/// |-- README.md |
| +/// |-- TODO |
| +/// |-- example |
| +/// | |-- console_example.dart |
| +/// | |-- main.dart |
| +/// | '-- web copy |
| +/// | '-- web_example.dart |
| +/// |-- lib |
| +/// | '-- path.dart |
| +/// |-- pubspec.yaml |
| +/// '-- test |
| +/// |-- absolute_test.dart |
| +/// |-- all_test.dart |
| +/// |-- basename_test.dart |
| +/// | (7 more...) |
| +/// |-- path_windows_test.dart |
| +/// |-- relative_test.dart |
| +/// '-- split_test.dart |
|
nweiz
2012/12/12 21:21:21
This is really nice-looking.
Bob Nystrom
2012/12/12 21:45:36
Thanks!
|
| +/// |
| +String generateTree(List<String> files) { |
|
nweiz
2012/12/12 21:21:21
I feel like this should have the same signature as
Bob Nystrom
2012/12/12 21:45:36
So passing in the root directory? Otherwise, how d
nweiz
2012/12/12 21:59:51
Yes. createTarGz takes a list of files and a base
|
| + // Parse out the files into a tree of nested maps. |
| + var root = {}; |
| + for (var file in files) { |
| + var parts = path.split(file); |
| + var directory = root; |
| + for (var part in path.split(file)) { |
| + directory = directory.putIfAbsent(part, () => {}); |
| + } |
| + } |
| + |
| + // Walk the map recursively and render to a string. |
| + var buffer = new StringBuffer(); |
| + _draw(buffer, '', null, null, root); |
| + return buffer.toString(); |
| +} |
| + |
| +void _drawLine(StringBuffer buffer, String prefix, bool isLastChild, |
| + String name) { |
| + // Print lines. |
| + buffer.add(prefix); |
| + if (isLastChild == true) { |
|
nweiz
2012/12/12 21:21:21
if (isLastChild)
Bob Nystrom
2012/12/12 21:45:36
It's nullable. But fixed.
nweiz
2012/12/12 21:59:51
In practice, I don't think null is ever passed in
Bob Nystrom
2012/12/12 22:14:32
The name != null check is new. That's how I avoid
nweiz
2012/12/12 22:19:33
I meant the one in _draw. _drawLine is never calle
|
| + buffer.add("'-- "); |
| + } else if (isLastChild == false) { |
|
nweiz
2012/12/12 21:21:21
if (!isLastChild)
Bob Nystrom
2012/12/12 21:45:36
Done.
|
| + buffer.add("|-- "); |
| + } |
| + |
| + // Print name. |
| + buffer.add(name); |
| + buffer.add('\n'); |
| +} |
| + |
| +String _getPrefix(bool isLast) { |
|
nweiz
2012/12/12 21:21:21
Tri-state booleans are awful. Just pass in two sep
Bob Nystrom
2012/12/12 21:45:36
Done.
|
| + if (isLast == true) { |
| + return " "; |
| + } else if (isLast == false) { |
| + return "| "; |
| + } else { |
| + return ""; |
| + } |
| +} |
| + |
| +void _draw(StringBuffer buffer, String prefix, bool isLast, |
| + String name, Map children) { |
| + // Don't draw a line for the root node. |
| + if (name != null) _drawLine(buffer, prefix, isLast, name); |
| + |
| + // Recurse to the children. |
| + var childNames = new List.from(children.keys); |
| + childNames.sort(); |
| + |
| + _drawChild(bool isLastChild, String child) { |
| + var childPrefix = _getPrefix(isLast); |
| + _draw(buffer, '$prefix$childPrefix', isLastChild, child, children[child]); |
| + } |
| + |
| + if (childNames.length <= 10) { |
| + // Not too many, so show all the children. |
| + for (var i = 0; i < childNames.length; i++) { |
| + _drawChild(i == childNames.length - 1, childNames[i]); |
| + } |
| + } else { |
| + // Show the first few. |
| + _drawChild(false, childNames[0]); |
| + _drawChild(false, childNames[1]); |
| + _drawChild(false, childNames[2]); |
| + |
| + // Elide the middle ones. |
| + buffer.add(prefix); |
| + buffer.add(_getPrefix(isLast)); |
| + buffer.add('| (${childNames.length - 6} more...)\n'); |
| + |
| + // Show the last few. |
| + _drawChild(false, childNames[childNames.length - 3]); |
| + _drawChild(false, childNames[childNames.length - 2]); |
| + _drawChild(true, childNames[childNames.length - 1]); |
| + } |
| +} |