#!/usr/bin/env runts -- --allow-all import { formatSize2, joinPath, log, parseIntVal, term, } from "https://global.hatter.ink/script/get/@70/deno-commons-mod.ts"; import {parseArgs} from "jsr:@std/cli/parse-args"; const defaultSkipDirs = [ ".git", ".idea", ".gradle", "target", ".DS_Store", ".localized", "node_modules", ]; interface ListDirOptions { maxDepth: number; hideMoreDirs: boolean; hideFileSize: boolean; } async function listDir( dir: string, depth: number, options: ListDirOptions, ): Promise { const tab = " ".repeat(depth * 4); try { for await (const dirEntry of Deno.readDir(dir)) { if (defaultSkipDirs.includes(dirEntry.name)) { continue; } const fullName = joinPath(dir, dirEntry.name); if (dirEntry.isDirectory) { const showNextDepth = (depth + 1) <= options.maxDepth; console.log( `${tab}- [${dirEntry.name}]${ showNextDepth ? "" : (options.hideMoreDirs ? "" : term.auto( "[blue][[[ \t[...more dirs...]]]][/]", )) }`, ); if (showNextDepth) { await listDir(fullName, depth + 1, options); } } else { let fileDesc = ""; if (dirEntry.isSymlink) { fileDesc = " 🔗"; } else if (dirEntry.isFile) { const fileInfo = await Deno.stat(fullName); if (fileInfo.size > 1024 * 1024) { fileDesc = term.auto( `[red][[[ - ${formatSize2(fileInfo.size)}]]]][/]`, ); } else { fileDesc = term.auto( `[yellow][[[ - ${formatSize2(fileInfo.size)}]]][/]`, ); } } let fileLn = `${tab}- ${ term.auto("[green][[[" + dirEntry.name + "]]][/]") }`; if (!options.hideFileSize) { fileLn += ` \t${fileDesc}`; } console.log(fileLn); } } } catch (e) { console.log(term.auto(`[red][[[${tab} ERROR: ${e}]]][/]`)); } } async function main(): Promise { const flags = parseArgs(Deno.args, { boolean: ["help", "hide-more-dirs", "hide-file-size"], number: ["depth"], }); if (flags.help) { console.log(`Help massage for tree.ts tree.ts [parameters] --depth 3 - Directory depth --hide-more-dirs - Hide more dirs - default '.' current dir`); return; } const maxDepth = parseIntVal(flags.depth, 10); const hideMoreDirs = flags["hide-more-dirs"]; const hideFileSize = flags["hide-file-size"]; let baseDir = "."; if (flags._.length > 0) { baseDir = flags._[0]; } await listDir(baseDir, 0, { maxDepth, hideMoreDirs, hideFileSize, }); } main().catch((e) => log.error(e)); // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260411T094252+08:00.MEUCIFfZBs0de3SZZtVCpAZ6 // Kxb5dnBCiwjGOTqydRtCl8CLAiEA/4W5N784C0FkcFpkYUB6vdLecJ7wsFFfNeO95AFiDew=