Merge pull request #1 from catseye/develop-1.2
Develop 1.2
Chris Pressey authored 11 months ago
GitHub committed 11 months ago
0 | `tree` | |
1 | ====== | |
2 | ||
3 | _Version 1.1_ | |
4 | ||
5 | This is Cat's Eye Technologies' `tree`, a command-line tool that displays an | |
6 | indented directory tree, similar to "The Tree Command for Linux" except simpler. | |
7 | It: | |
8 | ||
9 | * is written in Python (tested with 2.7.12 and 3.5.2) | |
10 | * is small and has no dependencies besides Python | |
11 | * is in the public domain (see `UNLICENSE`) | |
12 | * is really quite crude | |
13 | * displays a summary of the directory structure by default (because to | |
14 | me, that's the point of this sort of tool: give me a conceptual overview of | |
15 | the directory structure at this point in the filesystem, so I can orient | |
16 | myself) | |
17 | * never follows symbolic links | |
18 | * always outputs a `/` after each directory name | |
19 | * doesn't have any ASCII art (yet; it might someday as the lines do make | |
20 | it a bit easier to "read" the tree) | |
21 | * has no build/install system; either copy it to somewhere on your | |
22 | search path, or alter your search path to include the `script` directory | |
23 | in this repo, or use some system that solves this problem, like | |
24 | [shelf](http://catseye.tc/node/shelf). | |
25 | ||
26 | Usage | |
27 | ----- | |
28 | ||
29 | tree [-f|--full] [-1|--1-line] [-c|--count] | |
30 | [-w|--max-width <int>] [-x|--exclude <list>] [DIRECTORY] | |
31 | ||
32 | If DIRECTORY is not supplied, the current directory is assumed. | |
33 | ||
34 | The `--full` option lists each file in a directory on its own line. | |
35 | ||
36 | The `--1-line` option lists a summary of the files in each directory | |
37 | on one line, truncating the line if it is longer than the max-width. | |
38 | ||
39 | The `--count` option causes a count of files in each directory to | |
40 | be display instead of listing the files themselves. | |
41 | ||
42 | If none of those options are given, all files in a directory are | |
43 | listed compactly over multiple lines, in a "block". | |
44 | ||
45 | The `--max-width` option can be used to set the length of truncation | |
46 | or block-wrapping. It defaults to the width of the terminal window | |
47 | as returned by `stty size`, if that program can be run, otherwise 75. | |
48 | ||
49 | The `--exclude` option sets the list of directory names to not descend | |
50 | into (a comma-separated list). It defaults to `venv`, `node_modules`, | |
51 | and `__pycache__`. | |
52 | ||
53 | Related work | |
54 | ------------ | |
55 | ||
56 | * [The Tree Command for Linux](http://mama.indstate.edu/users/ice/tree/) — | |
57 | GPL'ed and feature-bloated and has no automated build system (you're | |
58 | supposed to edit the Makefile by hand.) | |
59 | * [pyr/tree](https://github.com/pyr/tree) — fine if you're running OpenBSD | |
60 | I suppose, but I gave up on trying to port it to NetBSD and Linux and | |
61 | wrote this instead. |
0 | `tree` | |
1 | ====== | |
2 | ||
3 | _Version 1.2_ | |
4 | ||
5 | This is Cat's Eye Technologies' `tree`, a command-line tool that displays an | |
6 | indented directory tree, similar to "The Tree Command for Linux" except simpler. | |
7 | It: | |
8 | ||
9 | * is written in Python (Python 3 by default; also tested with 2.7) | |
10 | * is small and has no dependencies besides Python | |
11 | * is in the public domain (see `UNLICENSE`) | |
12 | * is really quite crude | |
13 | * displays a summary of the directory structure by default (because to | |
14 | me, that's the point of this sort of tool: give me a conceptual overview of | |
15 | the directory structure at this point in the filesystem, so I can orient | |
16 | myself) | |
17 | * never follows symbolic links | |
18 | * always outputs a `/` after each directory name | |
19 | * doesn't have any ASCII art (yet; it might someday as the lines do make | |
20 | it a bit easier to "read" the tree) | |
21 | * has no build/install system; either copy it to somewhere on your | |
22 | search path, or alter your search path to include the `script` directory | |
23 | in this repo, or use some system that solves this problem, like | |
24 | [shelf](http://catseye.tc/node/shelf). | |
25 | ||
26 | Usage | |
27 | ----- | |
28 | ||
29 | tree [-f|--full] [-a|--all-files] [-1|--1-line] [-c|--count] | |
30 | [-w|--max-width <int>] [-x|--exclude <list>] [DIRECTORY] | |
31 | ||
32 | If DIRECTORY is not supplied, the current directory is assumed. | |
33 | ||
34 | The `--full` option lists each file in a directory on its own line. | |
35 | ||
36 | The `--all-files` option includes files whose names begin with a | |
37 | `.` character, which would otherwise be hidden. | |
38 | ||
39 | The `--1-line` option lists a summary of the files in each directory | |
40 | on one line, truncating the line if it is longer than the max-width. | |
41 | ||
42 | The `--count` option causes a count of files in each directory to | |
43 | be display instead of listing the files themselves. | |
44 | ||
45 | If none of those options are given, all files in a directory are | |
46 | listed compactly over multiple lines, in a "block". | |
47 | ||
48 | The `--max-width` option can be used to set the length of truncation | |
49 | or block-wrapping. It defaults to the width of the terminal window | |
50 | as returned by `stty size`, if that program can be run, otherwise 75. | |
51 | ||
52 | The `--exclude` option sets the list of directory names to not descend | |
53 | into (a comma-separated list). It defaults to `venv`, `node_modules`, | |
54 | `__pycache__`, and `.git`. | |
55 | ||
56 | Related work | |
57 | ------------ | |
58 | ||
59 | * [The Tree Command for Linux](http://mama.indstate.edu/users/ice/tree/) — | |
60 | GPL'ed and feature-bloated and has no automated build system (you're | |
61 | supposed to edit the Makefile by hand.) | |
62 | * [pyr/tree](https://github.com/pyr/tree) — fine if you're running OpenBSD | |
63 | I suppose, but I gave up on trying to port it to NetBSD and Linux and | |
64 | wrote this instead. |
0 | #!/usr/bin/env python | |
0 | #!/usr/bin/env python3 | |
1 | 1 | |
2 | 2 | # Written by Chris Pressey of Cat's Eye Technologies. |
3 | 3 | # This work is in the public domain; see UNLICENSE for more information. |
6 | 6 | import sys |
7 | 7 | |
8 | 8 | |
9 | def print_tree(dirname, indent, filename_format, maxwidth=75, excludes=None): | |
9 | def print_tree(dirname, indent, filename_format, maxwidth=75, excludes=None, all_files=False): | |
10 | 10 | dirnames = [] |
11 | 11 | filenames = [] |
12 | 12 | |
13 | 13 | for filename in sorted(os.listdir(dirname)): |
14 | if filename.startswith('.'): | |
14 | if (not all_files) and filename.startswith('.'): | |
15 | 15 | continue |
16 | 16 | fullname = os.path.join(dirname, filename) |
17 | 17 | if os.path.islink(fullname): |
44 | 44 | |
45 | 45 | for subdirname in dirnames: |
46 | 46 | print(indent + subdirname + '/') |
47 | print_tree(os.path.join(dirname, subdirname), indent + ' ', | |
48 | filename_format, maxwidth=maxwidth, excludes=excludes) | |
47 | print_tree( | |
48 | os.path.join(dirname, subdirname), indent + ' ', | |
49 | filename_format, maxwidth=maxwidth, excludes=excludes, | |
50 | all_files=all_files | |
51 | ) | |
49 | 52 | |
50 | 53 | for file_line in file_lines: |
51 | 54 | if file_line: |
55 | 58 | def main(args): |
56 | 59 | filename_format = 'block' |
57 | 60 | maxwidth = 75 |
58 | excludes = ('venv', 'node_modules', '__pycache__') | |
61 | excludes = ('venv', 'node_modules', '__pycache__', '.git') | |
62 | all_files = False | |
59 | 63 | try: |
60 | 64 | import subprocess |
61 | 65 | with open('/dev/tty') as tty: |
78 | 82 | raise ValueError("Illegal --max-width '%s'" % val) |
79 | 83 | elif opt in ('-x', '--exclude'): |
80 | 84 | excludes = args.pop(0).split(',') |
85 | elif opt in ('-a', '--all-files'): | |
86 | all_files = True | |
81 | 87 | else: |
82 | 88 | raise ValueError("Unknown command-line option '%s'" % opt) |
83 | 89 | if not args: |
84 | 90 | args = ['.'] |
85 | print_tree(args[0], '', filename_format, maxwidth=maxwidth, excludes=excludes) | |
91 | print_tree(args[0], '', filename_format, maxwidth=maxwidth, excludes=excludes, all_files=all_files) | |
86 | 92 | |
87 | 93 | |
88 | 94 | if __name__ == '__main__': |