torch-it 2.4.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,15 +24,85 @@ It's surprising how often this just fixes things. 🤞
24
24
 
25
25
  ## Features
26
26
 
27
- - **One command** to clear all local caches, delete `node_modules`, and reinstall dependencies
28
- - **Fully customizable** — specify any directories or files to delete
27
+ - **One command** to clean up 50+ build artifacts, cache directories, log files, and reinstall dependencies
28
+ - **Comprehensive framework support** — handles React, Next.js, Vue, Vite, SvelteKit, Remix, Qwik, Nuxt, Astro, Angular, Solid, and 40+ more
29
+ - **Smart file pattern matching** — removes `*.log`, `*.tgz`, `*.tar.gz`, and other temporary files automatically
30
+ - **Fully customizable** — specify any directories or files to delete via `torchrc.json`
29
31
  - **Docker support** — removes containers, images, and volumes and rebuilds from scratch 🐳
30
32
  - **Cross-platform** — works on Windows, Linux, and macOS
31
33
  - **Zero-dependency** — lightweight and no additional packages required
32
34
 
33
35
  ## Supported Frameworks
34
36
 
35
- React, Next.js, Vue, Vite, SvelteKit, React Native, Expo, and more.
37
+ React, Next.js, Vue, Vite, SvelteKit, React Native, Expo, Remix, Qwik, Nuxt, Astro, Angular, Solid, Docusaurus, and 40+ more frameworks and tools.
38
+
39
+ ## Comprehensive Cleanup Targets
40
+
41
+ `torch-it` cleans up 50+ common build artifacts, cache directories, and temporary files:
42
+
43
+ ### Framework Build Outputs
44
+ - `dist`, `build`, `out`, `.output` - Standard build directories
45
+ - `.next` - Next.js build cache
46
+ - `.nuxt` - Nuxt.js build output
47
+ - `.svelte-kit`, `.svelte` - Svelte/SvelteKit builds
48
+ - `.remix` - Remix framework build output
49
+ - `.qwik` - Qwik framework build output
50
+ - `.astro` - Astro framework build output
51
+ - `.angular`, `.angular/cache` - Angular build artifacts
52
+ - `.solid` - Solid.js build output
53
+ - `.docusaurus` - Docusaurus static site output
54
+ - `.nitro` - Nuxt Nitro server output
55
+
56
+ ### Development Tool Caches
57
+ - `.cache`, `.parcel-cache`, `.webpack`, `.rollup.cache` - Build tool caches
58
+ - `.vite` - Vite build tool cache
59
+ - `.swc`, `.rpt2_cache` - JavaScript transpiler caches
60
+ - `.eslintcache`, `.stylelintcache`, `.sass-cache` - Linter/preprocessor caches
61
+ - `.babel-cache`, `.cache-loader` - Babel and webpack loader caches
62
+
63
+ ### Package Manager Caches
64
+ - `node_modules/.cache` - npm package cache
65
+ - `.npm` - npm global cache
66
+ - `.pnpm-store`, `.pnpm-debug.log` - pnpm caches
67
+ - `.yarn/cache`, `.yarn/unplugged`, `.yarn/install-state.gz` - Yarn caches
68
+
69
+ ### Monorepo & Build Tools
70
+ - `.turbo` - Turborepo cache
71
+ - `.nx/cache` - Nx build system cache
72
+ - `.lerna` - Lerna monorepo cache
73
+ - `.rush` - Rush monorepo cache
74
+ - `.yalc` - Yalc local package manager
75
+
76
+ ### Blockchain & Web3 Tools
77
+ - `.hardhat` - Hardhat Ethereum development
78
+ - `.foundry` - Foundry Ethereum development
79
+ - `.anchor` - Anchor Solana development
80
+
81
+ ### Deployment & Platform Files
82
+ - `.vercel` - Vercel deployment cache
83
+ - `.netlify` - Netlify build cache
84
+ - `.wrangler` - Cloudflare Workers
85
+ - `.amplify` - AWS Amplify
86
+ - `.sst` - SST framework
87
+ - `.firebase` - Firebase hosting files
88
+ - `.serverless` - Serverless framework
89
+
90
+ ### Mobile Development
91
+ - `android/.gradle`, `android/build`, `android/app/build` - Android builds
92
+ - `ios/Pods`, `ios/build` - iOS builds
93
+ - `.expo`, `.expo-shared` - Expo React Native
94
+
95
+ ### File Patterns
96
+ - `*.log` - All log files
97
+ - `*.tgz`, `*.tar.gz` - Compressed archives
98
+ - `tsconfig.tsbuildinfo` - TypeScript incremental build info
99
+ - `coverage`, `.nyc_output` - Test coverage reports
100
+ - `storybook-static`, `.storybook-out` - Storybook builds
101
+
102
+ ### Temporary Files
103
+ - `.tmp`, `tmp`, `temp` - Temporary directories
104
+ - `lib`, `es`, `cjs`, `umd` - Compiled JavaScript outputs
105
+ - `jspm_packages`, `.typings` - Package manager files
36
106
 
37
107
  ## Supported Package Managers
38
108
 
@@ -40,18 +110,19 @@ React, Next.js, Vue, Vite, SvelteKit, React Native, Expo, and more.
40
110
 
41
111
  ### Core Operations (Always Performed)
42
112
 
43
- - **Removes build artifacts and cache directories** for common JavaScript/Node.js frameworks (e.g., `node_modules`, `dist`, `.next`, `.cache`, etc.).
113
+ - **Removes build artifacts and cache directories** for 50+ JavaScript/Node.js frameworks and tools (e.g., `node_modules`, `dist`, `.next`, `.cache`, `.vite`, `.remix`, `.qwik`, etc.).
114
+ - **Removes log files and temporary artifacts** including `*.log`, `*.tgz`, `*.tar.gz`, and build info files.
44
115
  - **Removes custom directories/paths** that you define in `torchrc.json`.
45
116
  - **Cleans package manager caches** for npm, yarn, and pnpm.
46
- - **Reinstalls dependencies** using your preferred package manager (npm, yarn, or pnpm) - **skipped when `rebuild=false`**.
117
+ - **Reinstalls dependencies** using your preferred package manager (npm, yarn, or pnpm).
47
118
 
48
119
  ### Docker Operations (Only if Docker is Configured)
49
120
 
50
121
  If your project includes either a `Dockerfile`, `docker-compose.yml`, or `docker-compose.yaml`, `torch-it` will also:
51
122
 
52
123
  - **Stop and clean up Docker resources** (containers, images, volumes) if Docker is running.
53
- - **Rebuild Docker images** from scratch - **skipped when `rebuild=false`**.
54
- - **Restart Docker services** in detached mode - **skipped when `rebuild=false`**.
124
+ - **Rebuild Docker images** from scratch.
125
+ - **Restart Docker services** in detached mode.
55
126
 
56
127
  `torch-it` intelligently detects your project's configuration and only performs Docker operations when appropriate.
57
128
 
@@ -123,14 +194,14 @@ For project-level customization, create a local `torchrc.json` file in your proj
123
194
  "protectedPaths": ["important-data/", "config/production.json"],
124
195
  "dockerMode": true,
125
196
  "rebuild": true,
126
- "logfile": false
197
+ "logfile": true
127
198
  }
128
199
  ```
129
200
 
130
201
  - `customPaths`: Array of additional directories and files to remove during cleanup. Supports both directories and files. torch-it will remove these in the same cleanup pass as the built-in targets.
131
202
  - `protectedPaths`: Array of directories and files to skip during cleanup. These paths will be preserved even if they match built-in or custom cleanup targets.
132
203
  - `dockerMode`: Boolean flag to enable/disable Docker operations. Set to `false` to skip all Docker cleanup, rebuild, and launch steps. Defaults to `true`.
133
- - `rebuild`: Boolean flag to enable/disable rebuild operations. Set to `false` to skip both package manager dependency installation and Docker rebuild/launch while still performing cleanup. Defaults to `true`.
204
+ - `rebuild`: Boolean flag to enable/disable rebuild operations. Set to `false` to skip both **package manager dependency installation** and **Docker rebuild/launch** while still performing cleanup. Defaults to `true`.
134
205
  - `logfile`: Boolean flag to enable or disable writing runtime output to `torch-it.log`. Set to `true` to enable file logging. Defaults to `false`.
135
206
 
136
207
  **Note**: The local `torchrc.json` file is completely optional. torch-it works with sensible defaults out of the box. Only create this file if you need to customize the behavior.
@@ -145,6 +216,8 @@ torch-it --dockerMode=false --rebuild=false --customPaths=["temp/","logs/"]
145
216
 
146
217
  All configuration options can be overridden using `--optionName=value` syntax. For arrays and objects, use JSON syntax:
147
218
 
219
+ - `--help` - Show help message and available options
220
+ - `--test` - Run in dry-run mode (preview changes without executing)
148
221
  - `--customPaths=["path1","path2"]`
149
222
  - `--dockerMode=false`
150
223
  - `--rebuild=false`
package/dist/torch-it.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Z=Object.create;var v=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,se=Object.prototype.hasOwnProperty;var re=(e,o,s,l)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of ne(o))!se.call(e,t)&&t!==s&&v(e,t,{get:()=>o[t],enumerable:!(l=ee(o,t))||l.enumerable});return e};var k=(e,o,s)=>(s=e!=null?Z(oe(e)):{},re(o||!e||!e.__esModule?v(s,"default",{value:e,enumerable:!0}):s,e));var _=k(require("fs"));var g=(e,o)=>s=>`\x1B[${e}m${s}\x1B[${o}m`,i={BOLD:g("1","22"),CYAN:g("36","39"),GREEN:g("32","39"),RED:g("31","39"),YELLOW:g("33","39"),PURPLE:g("35","39"),RESET:e=>`\x1B[0m${e}`},r={INFO:"\u{1F525}",SUCCESS:"\u2705",FAIL:"\u274C",EXCLAMATION:"\u2757",WARN:"\u26A0\uFE0F",ROCKET:"\u{1F525}",CLEAN:"\u{1F525}",PHOENIX:"\u{1F525}",BUILD:"\u{1F528}",TARGET:"\u{1F525}",CELEBRATE:"\u{1F525}",STARS:"\u2728",BOX:"\u{1F4E6}",CLIPBOARD:"\u{1F4CB}",DOCKER:"\u{1F433}"};var T=k(require("fs")),L=!0;function te(e){let o=new RegExp("\x1B\\[[0-9;]*m","g");return e.replace(o,"")}var w=e=>{L=e},P=()=>{L&&T.default.writeFileSync("torch-it.log","")},D=e=>{if(!L)return;let o=te(e).replace(/^\n/,""),s=new Date().toISOString();T.default.appendFileSync("torch-it.log",`[${s}] ${o}
3
- `)};function n(e,o){let s;switch(o){case"info":s=`${i.CYAN(r.INFO)} ${i.BOLD(e)}${i.RESET("")}`;break;case"success":s=`${i.GREEN(r.SUCCESS)} ${e}${i.RESET("")}`;break;case"warn":s=`${i.YELLOW(r.WARN)} ${e}${i.RESET("")}`;break;case"fail":s=`${i.RED(r.FAIL)} ${e}${i.RESET("")}`;break;case"step":s=`
4
- ${i.PURPLE("\u25B6")} ${i.BOLD(e)}${i.RESET("")}`;break;default:s=e}console.log(s),D(s)}function F(){b([` ${r.TARGET} TORCH LIT ${r.ROCKET}`],i.PURPLE);let e=`
2
+ "use strict";var ae=Object.create;var U=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,fe=Object.prototype.hasOwnProperty;var pe=(e,n,s,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of de(n))!fe.call(e,r)&&r!==s&&U(e,r,{get:()=>n[r],enumerable:!(a=le(n,r))||a.enumerable});return e};var C=(e,n,s)=>(s=e!=null?ae(ue(e)):{},pe(n||!e||!e.__esModule?U(s,"default",{value:e,enumerable:!0}):s,e));var O=C(require("fs"));var k=(e,n)=>s=>`\x1B[${e}m${s}\x1B[${n}m`,i={BOLD:k("1","22"),CYAN:k("36","39"),GREEN:k("32","39"),RED:k("31","39"),YELLOW:k("33","39"),PURPLE:k("35","39"),RESET:e=>`\x1B[0m${e}`},t={INFO:"\u{1F525}",SUCCESS:"\u2705",FAIL:"\u274C",EXCLAMATION:"\u2757",WARN:"\u26A0\uFE0F",ROCKET:"\u{1F525}",CLEAN:"\u{1F525}",PHOENIX:"\u{1F525}",BUILD:"\u{1F528}",TARGET:"\u{1F525}",CELEBRATE:"\u{1F525}",STARS:"\u2728",BOX:"\u{1F4E6}",CLIPBOARD:"\u{1F4CB}",DOCKER:"\u{1F433}"};var w=C(require("fs")),v=!0;function me(e){let n=new RegExp("\x1B\\[[0-9;]*m","g");return e.replace(n,"")}var M=e=>{v=e},B=()=>{v&&w.default.writeFileSync("torch-it.log","")},D=e=>{if(!v)return;let n=me(e).replace(/^\n/,""),s=new Date().toISOString();w.default.appendFileSync("torch-it.log",`[${s}] ${n}
3
+ `)};function o(e,n){let s;switch(n){case"info":s=`${i.CYAN(t.INFO)} ${i.BOLD(e)}${i.RESET("")}`;break;case"success":s=`${i.GREEN(t.SUCCESS)} ${e}${i.RESET("")}`;break;case"warn":s=`${i.YELLOW(t.WARN)} ${e}${i.RESET("")}`;break;case"fail":s=`${i.RED(t.FAIL)} ${e}${i.RESET("")}`;break;case"step":s=`
4
+ ${i.PURPLE("\u25B6")} ${i.BOLD(e)}${i.RESET("")}`;break;default:s=e}console.log(s),D(s)}function H(){_([` ${t.TARGET} TORCH LIT ${t.ROCKET}`],i.PURPLE);let e=`
5
5
  ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
6
6
  (( (( (( (( (( (( (( (( (( (( (( (( (( ((
7
7
  ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
@@ -12,4 +12,39 @@ ${i.PURPLE("\u25B6")} ${i.BOLD(e)}${i.RESET("")}`;break;default:s=e}console.log(
12
12
  | _ \\| | | | |_) | \\| || || \\| | | _
13
13
  | |_) | |_| | _ <| |\\ || || |\\ | |_| |
14
14
  |____/ \\___/|_| \\_\\_| \\_|___|_| \\_|\\____|
15
- `;console.log(e),D(e)}function U(){console.log(""),b([` ${r.PHOENIX} RISING FROM THE ASHES ${r.PHOENIX}`],i.PURPLE)}function x(e){let o=new RegExp("\x1B\\[[0-9;]*m","g");return e.replace(o,"").length}function b(e,o=i.GREEN){let s=Math.max(56,...e.map(t=>x(t))),l=o("\u2550".repeat(s));console.log(o("\u2554"+l+"\u2557")),e.forEach(t=>{if(D(t),t.trim()==="")console.log(o("\u2551"+" ".repeat(s)+"\u2551"));else{let f=s-x(t);console.log(o("\u2551"+t+" ".repeat(f)+"\u2551"))}}),console.log(o("\u255A"+l+"\u255D"))}var y=require("child_process"),B=k(require("os"));function c(e,o={}){try{return(0,y.execSync)(e,{stdio:o.silent?"pipe":"inherit"}),!0}catch{return o.silent||n(`Command failed: ${e}`,"fail"),!1}}function a(e){try{return B.platform()==="win32"?(0,y.execSync)(`where ${e}`,{stdio:"ignore"}):(0,y.execSync)(`command -v ${e}`,{stdio:"ignore"}),!0}catch{return!1}}var m=k(require("fs"));var K=["node_modules","dist","build",".svelte-kit",".svelte",".next",".nuxt","out",".output",".vercel",".netlify",".astro",".angular",".angular/cache",".solid",".docusaurus",".vite",".cache",".parcel-cache",".webpack",".rollup.cache",".rpt2_cache",".swc",".eslintcache",".stylelintcache",".sass-cache",".tmp","tmp","temp","coverage",".nyc_output","storybook-static",".storybook-out",".turbo",".rush",".firebase",".serverless","android/.gradle","android/build","android/app/build","ios/Pods","ios/build",".expo",".expo-shared","lib","es","cjs","umd"],M=[".pnpm-store",".pnpm-debug.log",".yarn/cache",".yarn/unplugged",".yarn/install-state.gz",".yarn/build-state.yml",".npm","node_modules/.cache"],H=[];var p={customPaths:[],customDirs:[],customFiles:[],protectedPaths:[],dockerMode:!0,logfile:!1,rebuild:!0};var ie=e=>{let o={};for(let s of e){if(!s.startsWith("--"))continue;let[l,t]=s.slice(2).split("=",2);if(!(!l||!t))try{let f=JSON.parse(t);o[l]=f}catch{t==="true"?o[l]=!0:t==="false"?o[l]=!1:o[l]=t}}return o},ce=()=>{let e="torchrc.json";if(!m.existsSync(e))return{};try{return JSON.parse(m.readFileSync(e,"utf8"))}catch{return n("Invalid torchrc.json (must be valid JSON) - skipping custom config","warn"),{}}},S=()=>{let e=ce();return{customPaths:e.customPaths??p.customPaths,customDirs:e.customDirs??p.customDirs,customFiles:e.customFiles??p.customFiles,protectedPaths:e.protectedPaths??p.protectedPaths,dockerMode:e.dockerMode??p.dockerMode,logfile:e.logfile??p.logfile,rebuild:e.rebuild??p.rebuild}},C=(e=[])=>{let o=S(),s=ie(e);return{...o,...s}},le=()=>{let e=S();return[...e.customPaths,...e.customDirs,...e.customFiles].filter(s=>typeof s=="string").map(s=>s.trim()).filter(s=>s.length>0)},Y=()=>{let e=process.env.TORCH_DRY_RUN==="1",o=0,s=S(),l=le(),t=s.protectedPaths,f=[...new Set([...K,...M,...H])],$=[...new Set(l)],N=f.filter(u=>!t.some(R=>u===R||u.startsWith(R+"/"))),O=$.filter(u=>!t.some(R=>u===R||u.startsWith(R+"/"))),A=u=>{if(m.existsSync(u)){n(`${e?"Would remove":"Removing"} ${u}...`,"step");try{e||m.rmSync(u,{recursive:!0,force:!0}),n(`${u} ${e?"marked for removal (dry-run)":"removed"}`,"success"),o++}catch{n(`Failed to remove ${u}`,"fail")}}};n("Scanning for build artifacts and cache directories...","step"),N.forEach(A),O.length>0&&(n("Deleting user defined custom directories and files","step"),O.forEach(A));let I=f.length-N.length+($.length-O.length);return I>0&&n(`Skipped ${I} protected path(s) from torchrc.json`,"info"),o===0?(n("No build artifacts or cache directories found (project already clean)","info"),!1):(n(`Removed ${o} build/cache directories`,"success"),!0)},j=()=>{let e=process.env.TORCH_DRY_RUN==="1",o=!1;return a("npm")&&(e||c("npm cache clean --force"))&&(n(e?"Dry-run: would clean npm cache":"npm cache cleaned","success"),o=!0),a("yarn")&&(e||c("yarn cache clean"))&&(n(e?"Dry-run: would clean yarn cache":"yarn cache cleaned","success"),o=!0),a("pnpm")&&(e||c("pnpm store prune"))&&(n(e?"Dry-run: would clean pnpm store":"pnpm store cleaned","success"),o=!0),o||n("No package manager caches cleaned (tools not available)","info"),o};function W(){return _.existsSync("Dockerfile")||_.existsSync("docker-compose.yml")||_.existsSync("docker-compose.yaml")}function G(){if(C().dockerMode===!1)return n("Docker mode disabled in torchrc.json - skipping Docker operations","info"),"NO_DOCKER";let o=process.env.TORCH_DRY_RUN==="1";return W()?(n("Stopping Docker services and removing all resources...","info"),a("docker")?c("docker info",{silent:!0})?c("docker compose ps",{silent:!0})?o?(n("Dry-run: would run 'docker compose down --rmi all --volumes'","info"),"OK"):c("docker compose down --rmi all --volumes")?(n("Docker services stopped and resources cleaned","success"),"OK"):(n("Docker cleanup encountered issues","warn"),n("Continuing with the rest of the script...","info"),"DOCKER_FAIL"):(n("No Docker Compose services found - skipping Docker cleanup","warn"),n("This is normal if no services were previously running","info"),"DOCKER_FAIL"):(n("Docker daemon is not running - skipping Docker cleanup","warn"),n("You may need to start Docker manually and run cleanup later","info"),"NO_DOCKER"):(n("Docker is not installed - skipping Docker cleanup","warn"),"NO_DOCKER")):(n("No Docker configuration found - skipping Docker operations","info"),"NO_DOCKER")}function X(){let e=C();if(e.dockerMode===!1)return!1;if(e.rebuild===!1)return n("Rebuild disabled in torchrc.json - skipping Docker rebuild","info"),!1;let o=process.env.TORCH_DRY_RUN==="1";return W()?a("docker")?c("docker info",{silent:!0})?(n("Building Docker resources (this may take a while...)...","step"),console.log(` ${i.YELLOW("\u23F3 Please be patient - pulling fresh images and building...")}`),o?(n("Dry-run: would run 'docker-compose build --pull --no-cache'","info"),!0):c("docker-compose build --pull --no-cache")?!0:(n("Docker build encountered issues - check torch-it.log for details","fail"),!1)):(n("Docker daemon is not running - skipping Docker rebuild","warn"),n("Start Docker manually and run 'docker-compose build --pull --no-cache' later","info"),!1):(n("Docker is not installed - skipping Docker rebuild","warn"),!1):!1}function J(){if(C().dockerMode===!1)return!1;let o=process.env.TORCH_DRY_RUN==="1";return n("Starting Docker services in detached mode...","step"),o?(n("Dry-run: would run 'docker compose up -d'","info"),!0):c("docker compose up -d")?!0:(n("Failed to start Docker services - check torch-it.log for details","fail"),!1)}var E=k(require("fs"));var q=()=>{let e=process.env.TORCH_DRY_RUN==="1",o=!1;return n("Detecting package manager and installing dependencies...","step"),E.existsSync("pnpm-lock.yaml")&&a("pnpm")?(n("Using pnpm (detected pnpm-lock.yaml)...","step"),e||c("pnpm install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with pnpm`,"success"),o=!0):n("pnpm install failed","fail")):E.existsSync("yarn.lock")&&a("yarn")?(n("Using yarn (detected yarn.lock)...","step"),e||c("yarn install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with yarn`,"success"),o=!0):n("yarn install failed","fail")):E.existsSync("package-lock.json")&&a("npm")?(n("Using npm (detected package-lock.json)...","step"),e||c("npm install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with npm`,"success"),o=!0):n("npm install failed","fail")):a("npm")?(n("Using npm (fallback)...","info"),e||c("npm install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with npm`,"success"),o=!0):n("npm install failed","fail")):a("yarn")?(n("Using yarn (fallback)...","info"),e||c("yarn install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with yarn`,"success"),o=!0):n("yarn install failed","")):a("pnpm")?(n("Using pnpm (fallback)...","info"),e||c("pnpm install")?(n(`Dependencies ${e?"would be installed":"installed successfully"} with pnpm`,"success"),o=!0):n("pnpm install failed","fail")):n("No package manager found (npm/yarn/pnpm). Please install dependencies manually.","fail"),o};var V=e=>{let o="",s="",l="";e.dockerClean==="NO_DOCKER"?o=`${r.DOCKER} No Docker containers found`:e.dockerClean==="DOCKER_FAIL"&&(o=`${r.FAIL} Failed to remove Docker containers`),e.dockerClean==="OK"&&(e.dockerRebuild?s=`${r.DOCKER} Docker containers rebuilt from scratch`:s=`${r.FAIL} Failed to rebuild Docker containers`,e.dockerLaunch&&e.dockerRebuild?l=`${r.ROCKET} Services running in detached mode`:l=`${r.FAIL} Failed to start Docker containers`);let t=e.buildAndCacheClean&&e.packageManagerClean?`${r.CLEAN} All build artifacts & caches removed`:`${r.FAIL} Build artifacts or cache directories not found`,f=e.dependencyInstall?`${r.BOX} Dependencies freshly installed`:`${r.FAIL} Failed to install dependencies`;console.log(""),b(["\u{1F525} PROJECT SUCCESSFULLY TORCHED! \u{1F525}","",`${t}`,`${f}`,`${o}`,`${s}`,`${l}`,"",e.logfile===!1?`${r.CLIPBOARD} Logging to torch-it.log is disabled; set "logfile": true in torchrc.json to enable it`:`${r.CLIPBOARD} Check torch-it.log for detailed logs`])};var z=process.argv.slice(2),Q=z.includes("--test");Q&&(process.env.TORCH_DRY_RUN="1");var h=C(z.filter(e=>e!=="--test"));w(h.logfile);h.logfile&&P();F();Q&&n("Running in --test dry-run mode (no files or services will be changed)","warn");var d={dockerClean:"NO_DOCKER",buildAndCacheClean:!1,packageManagerClean:!1,dependencyInstall:!1,dockerRebuild:!1,dockerLaunch:!1,logfile:h.logfile};n(`${r.CLEAN} DOCKER CLEANUP`,"step");d.dockerClean=G();n(`${r.CLEAN} BUILD ARTIFACTS & CACHE CLEANUP`,"step");d.buildAndCacheClean=Y();n("Cleaning package manager caches...","step");d.packageManagerClean=j();h.rebuild!==!1?(U(),n(`${r.BUILD} DEPENDENCY INSTALLATION`,"step"),d.dependencyInstall=q()):(n("Rebuild disabled - skipping dependency installation","info"),d.dependencyInstall=!1);d.dockerClean!=="NO_DOCKER"&&h.rebuild!==!1?(n(`${r.BUILD} DOCKER REBUILD`,"step"),d.dockerRebuild=X()):d.dockerClean!=="NO_DOCKER"&&h.rebuild===!1&&(n("Rebuild disabled - skipping Docker rebuild","info"),d.dockerRebuild=!1);d.dockerRebuild&&(d.dockerLaunch=J(),n(`${r.ROCKET} LAUNCH`,"step"));V(d);
15
+ `;console.log(e),D(e)}function j(){console.log(""),_([` ${t.PHOENIX} RISING FROM THE ASHES ${t.PHOENIX}`],i.PURPLE)}function K(e){let n=new RegExp("\x1B\\[[0-9;]*m","g");return e.replace(n,"").length}function _(e,n=i.GREEN){let s=Math.max(56,...e.map(r=>K(r))),a=n("\u2550".repeat(s));console.log(n("\u2554"+a+"\u2557")),e.forEach(r=>{if(D(r),r.trim()==="")console.log(n("\u2551"+" ".repeat(s)+"\u2551"));else{let m=s-K(r);console.log(n("\u2551"+r+" ".repeat(m)+"\u2551"))}}),console.log(n("\u255A"+a+"\u255D"))}var E=require("child_process"),Y=C(require("os"));function c(e,n={}){try{return(0,E.execSync)(e,{stdio:n.silent?"pipe":"inherit"}),!0}catch{return n.silent||o(`Command failed: ${e}`,"fail"),!1}}function u(e){try{return Y.platform()==="win32"?(0,E.execSync)(`where ${e}`,{stdio:"ignore"}):(0,E.execSync)(`command -v ${e}`,{stdio:"ignore"}),!0}catch{return!1}}var d=C(require("fs")),J=C(require("path"));var G=["node_modules","dist","build",".svelte-kit",".svelte",".next",".nuxt","out",".output",".vercel",".netlify",".astro",".angular",".angular/cache",".solid",".docusaurus",".vite",".cache",".parcel-cache",".webpack",".rollup.cache",".rpt2_cache",".swc",".eslintcache",".stylelintcache",".sass-cache",".tmp","tmp","temp","coverage",".nyc_output","storybook-static",".storybook-out",".turbo",".rush",".firebase",".serverless","android/.gradle","android/build","android/app/build","ios/Pods","ios/build",".expo",".expo-shared","lib","es","cjs","umd",".remix",".qwik",".nitro",".wrangler",".amplify",".sst",".babel-cache",".cache-loader","jspm_packages",".typings"],W=["*.log","*.tgz","*.tar.gz","tsconfig.tsbuildinfo"],X=[".pnpm-store",".pnpm-debug.log",".yarn/cache",".yarn/unplugged",".yarn/install-state.gz",".yarn/build-state.yml",".npm","node_modules/.cache",".yalc",".lerna",".nx/cache",".vite/deps",".turbo","tsconfig.tsbuildinfo",".hardhat",".foundry",".anchor"],q=[];var g={customPaths:[],customDirs:[],customFiles:[],protectedPaths:[],dockerMode:!0,logfile:!1,rebuild:!0};var ge=e=>{let n={};for(let s of e){if(!s.startsWith("--"))continue;let[a,r]=s.slice(2).split("=",2);if(!(!a||!r))try{let m=JSON.parse(r);n[a]=m}catch{r==="true"?n[a]=!0:r==="false"?n[a]=!1:n[a]=r}}return n},he=()=>{let e="torchrc.json";if(!d.existsSync(e))return{};try{return JSON.parse(d.readFileSync(e,"utf8"))}catch{return o("Invalid torchrc.json (must be valid JSON) - skipping custom config","warn"),{}}},N=()=>{let e=he();return{customPaths:e.customPaths??g.customPaths,customDirs:e.customDirs??g.customDirs,customFiles:e.customFiles??g.customFiles,protectedPaths:e.protectedPaths??g.protectedPaths,dockerMode:e.dockerMode??g.dockerMode,logfile:e.logfile??g.logfile,rebuild:e.rebuild??g.rebuild}},R=(e=[])=>{let n=N(),s=ge(e);return{...n,...s}},Ce=()=>{let e=N();return[...e.customPaths,...e.customDirs,...e.customFiles].filter(s=>typeof s=="string").map(s=>s.trim()).filter(s=>s.length>0)},z=()=>{let e=process.env.TORCH_DRY_RUN==="1",n=0,s=N(),a=Ce(),r=s.protectedPaths,m=[...new Set([...G,...X,...q])],I=[...new Set(a)],ie=[...W],P=m.filter(l=>!r.some(h=>l===h||l.startsWith(h+"/"))),S=I.filter(l=>!r.some(h=>l===h||l.startsWith(h+"/"))),$=l=>{if(d.existsSync(l)){o(`${e?"Would remove":"Removing"} ${l}...`,"step");try{e||d.rmSync(l,{recursive:!0,force:!0}),o(`${l} ${e?"marked for removal (dry-run)":"removed"}`,"success"),n++}catch{o(`Failed to remove ${l}`,"fail")}}},ce=()=>{for(let l of ie)if(l.includes("*"))try{let L=d.readdirSync(".",{withFileTypes:!0}).filter(y=>y.name.match(l.replace("*",".*"))).map(y=>y.name);for(let y of L){let p=J.join(".",y);if(d.existsSync(p)&&d.statSync(p).isFile()&&!r.some(F=>p===F||p.startsWith(F+"/"))){o(`${e?"Would remove":"Removing"} ${p}...`,"step");try{e||d.unlinkSync(p),o(`${p} ${e?"marked for removal (dry-run)":"removed"}`,"success"),n++}catch{o(`Failed to remove ${p}`,"fail")}}}}catch(L){o(`Failed to process pattern ${l}: ${L}`,"warn")}else d.existsSync(l)&&$(l)};o("Scanning for build artifacts and cache directories...","step"),P.forEach($),o("Scanning for log files and temporary files...","step"),ce(),S.length>0&&(o("Deleting user defined custom directories and files","step"),S.forEach($));let x=m.length-P.length+(I.length-S.length);return x>0&&o(`Skipped ${x} protected path(s) from torchrc.json`,"info"),n===0?(o("No build artifacts or cache directories found (project already clean)","info"),!1):(o(`Removed ${n} build/cache directories`,"success"),!0)},V=()=>{let e=process.env.TORCH_DRY_RUN==="1",n=!1;return u("npm")&&(e||c("npm cache clean --force"))&&(o(e?"Dry-run: would clean npm cache":"npm cache cleaned","success"),n=!0),u("yarn")&&(e||c("yarn cache clean"))&&(o(e?"Dry-run: would clean yarn cache":"yarn cache cleaned","success"),n=!0),u("pnpm")&&(e||c("pnpm store prune"))&&(o(e?"Dry-run: would clean pnpm store":"pnpm store cleaned","success"),n=!0),n||o("No package manager caches cleaned (tools not available)","info"),n};function Q(){return O.existsSync("Dockerfile")||O.existsSync("docker-compose.yml")||O.existsSync("docker-compose.yaml")}function Z(){if(R().dockerMode===!1)return o("Docker mode disabled in torchrc.json - skipping Docker operations","info"),"NO_DOCKER";let n=process.env.TORCH_DRY_RUN==="1";return Q()?(o("Stopping Docker services and removing all resources...","info"),u("docker")?c("docker info",{silent:!0})?c("docker compose ps",{silent:!0})?n?(o("Dry-run: would run 'docker compose down --rmi all --volumes'","info"),"OK"):c("docker compose down --rmi all --volumes")?(o("Docker services stopped and resources cleaned","success"),"OK"):(o("Docker cleanup encountered issues","warn"),o("Continuing with the rest of the script...","info"),"DOCKER_FAIL"):(o("No Docker Compose services found - skipping Docker cleanup","warn"),o("This is normal if no services were previously running","info"),"DOCKER_FAIL"):(o("Docker daemon is not running - skipping Docker cleanup","warn"),o("You may need to start Docker manually and run cleanup later","info"),"NO_DOCKER"):(o("Docker is not installed - skipping Docker cleanup","warn"),"NO_DOCKER")):(o("No Docker configuration found - skipping Docker operations","info"),"NO_DOCKER")}function ee(){let e=R();if(e.dockerMode===!1)return!1;if(e.rebuild===!1)return o("Rebuild disabled in torchrc.json - skipping Docker rebuild","info"),!1;let n=process.env.TORCH_DRY_RUN==="1";return Q()?u("docker")?c("docker info",{silent:!0})?(o("Building Docker resources (this may take a while...)...","step"),console.log(` ${i.YELLOW("\u23F3 Please be patient - pulling fresh images and building...")}`),n?(o("Dry-run: would run 'docker-compose build --pull --no-cache'","info"),!0):c("docker-compose build --pull --no-cache")?!0:(o("Docker build encountered issues - check torch-it.log for details","fail"),!1)):(o("Docker daemon is not running - skipping Docker rebuild","warn"),o("Start Docker manually and run 'docker-compose build --pull --no-cache' later","info"),!1):(o("Docker is not installed - skipping Docker rebuild","warn"),!1):!1}function oe(){if(R().dockerMode===!1)return!1;let n=process.env.TORCH_DRY_RUN==="1";return o("Starting Docker services in detached mode...","step"),n?(o("Dry-run: would run 'docker compose up -d'","info"),!0):c("docker compose up -d")?!0:(o("Failed to start Docker services - check torch-it.log for details","fail"),!1)}var T=C(require("fs"));var ne=()=>{let e=process.env.TORCH_DRY_RUN==="1",n=!1;return o("Detecting package manager and installing dependencies...","step"),T.existsSync("pnpm-lock.yaml")&&u("pnpm")?(o("Using pnpm (detected pnpm-lock.yaml)...","step"),e||c("pnpm install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with pnpm`,"success"),n=!0):o("pnpm install failed","fail")):T.existsSync("yarn.lock")&&u("yarn")?(o("Using yarn (detected yarn.lock)...","step"),e||c("yarn install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with yarn`,"success"),n=!0):o("yarn install failed","fail")):T.existsSync("package-lock.json")&&u("npm")?(o("Using npm (detected package-lock.json)...","step"),e||c("npm install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with npm`,"success"),n=!0):o("npm install failed","fail")):u("npm")?(o("Using npm (fallback)...","info"),e||c("npm install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with npm`,"success"),n=!0):o("npm install failed","fail")):u("yarn")?(o("Using yarn (fallback)...","info"),e||c("yarn install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with yarn`,"success"),n=!0):o("yarn install failed","")):u("pnpm")?(o("Using pnpm (fallback)...","info"),e||c("pnpm install")?(o(`Dependencies ${e?"would be installed":"installed successfully"} with pnpm`,"success"),n=!0):o("pnpm install failed","fail")):o("No package manager found (npm/yarn/pnpm). Please install dependencies manually.","fail"),n};var se=e=>{let n="",s="",a="";e.dockerClean==="NO_DOCKER"?n=`${t.DOCKER} No Docker containers found`:e.dockerClean==="DOCKER_FAIL"&&(n=`${t.FAIL} Failed to remove Docker containers`),e.dockerClean==="OK"&&(e.dockerRebuild?s=`${t.DOCKER} Docker containers rebuilt from scratch`:s=`${t.FAIL} Failed to rebuild Docker containers`,e.dockerLaunch&&e.dockerRebuild?a=`${t.ROCKET} Services running in detached mode`:a=`${t.FAIL} Failed to start Docker containers`);let r=e.buildAndCacheClean&&e.packageManagerClean?`${t.CLEAN} All build artifacts & caches removed`:`${t.FAIL} Build artifacts or cache directories not found`,m=e.dependencyInstall?`${t.BOX} Dependencies freshly installed`:`${t.FAIL} Failed to install dependencies`;console.log(""),_(["\u{1F525} PROJECT SUCCESSFULLY TORCHED! \u{1F525}","",`${r}`,`${m}`,`${n}`,`${s}`,`${a}`,"",e.logfile===!1?`${t.CLIPBOARD} Logging to torch-it.log is disabled; set "logfile": true in torchrc.json to enable it`:`${t.CLIPBOARD} Check torch-it.log for detailed logs`])};var te=()=>{o(`
16
+ \u{1F525} Torch It - Project Environment Reset Tool
17
+
18
+ USAGE:
19
+ torch-it [options]
20
+
21
+ OPTIONS:
22
+ --help Show this help message and exit
23
+ --test Run in dry-run mode (preview changes without executing)
24
+ --dockerMode=<bool> Enable/disable Docker operations (default: true)
25
+ --rebuild=<bool> Enable/disable rebuild operations (default: true)
26
+ --logfile=<bool> Enable/disable file logging (default: false)
27
+ --customPaths=<array> Additional paths to remove during cleanup
28
+ --protectedPaths=<array> Paths to skip during cleanup
29
+
30
+ EXAMPLES:
31
+ torch-it # Run with default settings
32
+ torch-it --test # Preview what would be done
33
+ torch-it --rebuild=false # Clean only, don't rebuild
34
+ torch-it --dockerMode=false # Skip Docker operations
35
+ torch-it --logfile=true # Enable file logging
36
+ torch-it --customPaths=["temp/","logs/"] # Clean additional paths
37
+
38
+ CONFIGURATION:
39
+ Create a torchrc.json file in your project root for persistent settings:
40
+
41
+ {
42
+ "customPaths": ["apps/web/.next", "coverage-final.json"],
43
+ "protectedPaths": ["important-data/"],
44
+ "dockerMode": true,
45
+ "rebuild": true,
46
+ "logfile": false
47
+ }
48
+
49
+ For more information, visit: https://github.com/piyook/torch-it
50
+ `.trim(),"info")};var A=process.argv.slice(2);A.includes("--help")&&(te(),process.exit(0));var re=A.includes("--test");re&&(process.env.TORCH_DRY_RUN="1");var b=R(A.filter(e=>e!=="--test"&&e!=="--help"));M(b.logfile);b.logfile&&B();H();re&&o("Running in --test dry-run mode (no files or services will be changed)","warn");var f={dockerClean:"NO_DOCKER",buildAndCacheClean:!1,packageManagerClean:!1,dependencyInstall:!1,dockerRebuild:!1,dockerLaunch:!1,logfile:b.logfile};o(`${t.CLEAN} DOCKER CLEANUP`,"step");f.dockerClean=Z();o(`${t.CLEAN} BUILD ARTIFACTS & CACHE CLEANUP`,"step");f.buildAndCacheClean=z();o("Cleaning package manager caches...","step");f.packageManagerClean=V();b.rebuild!==!1?(j(),o(`${t.BUILD} DEPENDENCY INSTALLATION`,"step"),f.dependencyInstall=ne()):(o("Rebuild disabled - skipping dependency installation","info"),f.dependencyInstall=!1);f.dockerClean!=="NO_DOCKER"&&b.rebuild!==!1?(o(`${t.BUILD} DOCKER REBUILD`,"step"),f.dockerRebuild=ee()):f.dockerClean!=="NO_DOCKER"&&b.rebuild===!1&&(o("Rebuild disabled - skipping Docker rebuild","info"),f.dockerRebuild=!1);f.dockerRebuild&&(f.dockerLaunch=oe(),o(`${t.ROCKET} LAUNCH`,"step"));se(f);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torch-it",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "CLI to reset, clean, and rebuild Node.js project environments.",
5
5
  "keywords": [
6
6
  "cleanup",