{"id":33174871,"url":"https://github.com/codeinred/untree","last_synced_at":"2025-11-20T20:02:02.116Z","repository":{"id":57671163,"uuid":"454303399","full_name":"codeinred/untree","owner":"codeinred","description":"Untree: Undoing tree for fun and profit","archived":false,"fork":false,"pushed_at":"2025-06-17T03:00:06.000Z","size":564,"stargazers_count":98,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-29T23:45:08.801Z","etag":null,"topics":["directory-tree","filesystem","rust","tree"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/untree","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codeinred.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-01T07:56:06.000Z","updated_at":"2025-09-17T10:51:44.000Z","dependencies_parsed_at":"2023-01-22T02:02:51.262Z","dependency_job_id":null,"html_url":"https://github.com/codeinred/untree","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/codeinred/untree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeinred%2Funtree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeinred%2Funtree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeinred%2Funtree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeinred%2Funtree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codeinred","download_url":"https://codeload.github.com/codeinred/untree/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeinred%2Funtree/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285503668,"owners_count":27182913,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-20T02:00:05.334Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["directory-tree","filesystem","rust","tree"],"created_at":"2025-11-16T02:00:34.329Z","updated_at":"2025-11-20T20:02:02.111Z","avatar_url":"https://github.com/codeinred.png","language":"Rust","readme":"# Untree: Undoing tree for fun and profit\n\nUntree inverts the action of [tree] by converting tree diagrams of directory\nstructures back into directory structures. Given a directory structure, [tree]\nproduces a tree diagram, and given a tree diagram, untree produces a directory\nstructure.\n\nLet's say you have the following directory structure, created by running `tree`\nin the root of this project:\n\n\u003cpre\u003e\u003cfont color=\"#75A1FF\"\u003e\u003cb\u003e.\u003c/b\u003e\u003c/font\u003e\n├── Cargo.lock\n├── Cargo.toml\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003einputs\u003c/b\u003e\u003c/font\u003e\n│   └── test1.tree\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003elib\u003c/b\u003e\u003c/font\u003e\n│   ├── either.rs\n│   ├── errors.rs\n│   ├── functions.rs\n│   ├── mod.rs\n│   ├── more_context.rs\n│   ├── path_action.rs\n│   └── types.rs\n├── LICENSE.txt\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003emedia\u003c/b\u003e\u003c/font\u003e\n│   ├── \u003cfont color=\"#F580FF\"\u003e\u003cb\u003eimage1.png\u003c/b\u003e\u003c/font\u003e\n│   └── \u003cfont color=\"#F580FF\"\u003e\u003cb\u003eimage2.png\u003c/b\u003e\u003c/font\u003e\n├── README.md\n└── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003esrc\u003c/b\u003e\u003c/font\u003e\n    └── main.rs\n\u003c/pre\u003e\n\nuntree can create a mirror that directory structure, just based on that input:\n\n```bash\ntree | untree --dir path/to/output/dir\n```\n\nHere, `test` is the destination directory where `untree` is supposed to create\nfiles. Now, if we `tree` the newly created directory, we can see that it has the\nsame structure as the repository:\n\n\u003cpre\u003e\u003cfont color=\"#75A1FF\"\u003e\u003cb\u003epath/to/output/dir\u003c/b\u003e\u003c/font\u003e\n├── Cargo.lock\n├── Cargo.toml\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003einputs\u003c/b\u003e\u003c/font\u003e\n│   └── test1.tree\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003elib\u003c/b\u003e\u003c/font\u003e\n│   ├── either.rs\n│   ├── errors.rs\n│   ├── functions.rs\n│   ├── mod.rs\n│   ├── more_context.rs\n│   ├── path_action.rs\n│   └── types.rs\n├── LICENSE.txt\n├── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003emedia\u003c/b\u003e\u003c/font\u003e\n│   ├── \u003cfont color=\"#F580FF\"\u003e\u003cb\u003eimage1.png\u003c/b\u003e\u003c/font\u003e\n│   └── \u003cfont color=\"#F580FF\"\u003e\u003cb\u003eimage2.png\u003c/b\u003e\u003c/font\u003e\n├── README.md\n└── \u003cfont color=\"#75A1FF\"\u003e\u003cb\u003esrc\u003c/b\u003e\u003c/font\u003e\n    └── main.rs\n\n4 directories, 15 files\u003c/pre\u003e\n\n`untree` can also read in the tree from an input file, or you can paste it in\ndirectly since it accepts input from standard input:\n\n![Screenshot of untree running on input from stdin. The generated file was placed in path/to/output/dir][image1]\n\n## Motivating untree\n\nI've noticed that in the past I've had to recreate directory structures in order\nto answer questions or run tests on the directory. For example, [this\nquestion][stack-overflow-question] asks about ignoring certain kinds of files,\nand it provides a directory structure as reference.\n\nThe files themselves aren't provided, nor do they need to be, but the directory\nstructure itself _is_ relevant to the question.\n\n`untree` allows you to replicate the structure of a directory printed with tree,\nmaking it easy to answer questions about programs that traverse the directory\ntree. This means that untree is also good for quickly creating directory\nstructures for the purpose of mocking input to other programs.\n\n## Using untree as a library\n\nYou can use untree as a library if you need that functionality included in your\nprogram. In order to create a tree, invoke [`create_tree`] with the given\ndirectory, `Lines` buffer, and options.\n\nThese options are very simple - there's [`UntreeOptions::verbose`], which will\ntell [`create_tree`] and [`create_path`] to print out any directories or files\nthat were created when set, and [`UntreeOptions::dry_run`], which will print out\nany directories or files without actually creating them (`dry_run` implies\n`verbose`).\n\nBelow is an example usage:\n\n```rust\nuse untree::*;\nuse std::io::{BufRead, BufReader, stdin, Lines};\n\nlet options = UntreeOptions::new()\n    .dry_run(true)   // Set dry_run to true\n    .verbose(true);  // Set verbose to true\nlet lines = BufReader::new(stdin()).lines();\n\ncreate_tree(\"path/to/directory\", lines, options)?;\n\n# Ok::\u003c(), Error\u003e(())\n```\n\nAdditional functions include\n\n- [`create_path`], used to create a file or path with the given options,\n- [`get_entry`], used to parse a line in a tree file,\n- [`touch_directory`], used to create a directory,\n- [`touch_file`], used to touch a file (does the same thing as unix touch)\n\nThe primary error type used by untree is [`Error`], which holds information\nabout a path and the action being done on it, in addition to the normal error\ninformation provided by `io::Error`.\n\n## User testimonials\n\nWhen asked about _untree_, my friend said:\n\n\u003e I retroactively want that for my time trying to get Conan to work. It woulda\n\u003e made certain things just a little less painful.\n\n— _some guy_ (He asked to be referred to as \"some guy\")\n\n## Comments, feedback, or contributions are welcome!\n\nI'm in the progress of learning rust, so any feedback you have is greatly\nappreciated! Also, if `untree` is useful to you, please let me know!\n\n[image1]: media/image1.png\n[tree]: https://linux.die.net/man/1/tree\n[stack-overflow-question]:\n  https://stackoverflow.com/questions/70933172/how-to-write-gitignore-so-that-it-only-includes-yaml-files-and-some-specific-fi\n","funding_links":[],"categories":["Other"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeinred%2Funtree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodeinred%2Funtree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeinred%2Funtree/lists"}