Files
2025-11-29 18:47:15 +08:00

173 lines
6.3 KiB
Clojure
Executable File

#!/usr/bin/env bb
;; Comprehensive babashka.fs examples
;; Run with: bb examples.clj
(ns fs-examples
(:require [babashka.fs :as fs]
[clojure.string :as str]))
(println "\n=== BABASHKA.FS EXAMPLES ===\n")
;; Example 1: Basic file operations
(println "1. Basic File Operations")
(fs/with-temp-dir [tmp {}]
(let [test-file (fs/path tmp "test.txt")]
(spit test-file "Hello, babashka.fs!")
(println " Created:" test-file)
(println " Exists?" (fs/exists? test-file))
(println " Is file?" (fs/regular-file? test-file))
(println " Size:" (fs/size test-file) "bytes")
(println " Content:" (slurp test-file))))
;; Example 2: Directory listing and filtering
(println "\n2. Finding Clojure Source Files")
(let [clj-files (->> (fs/glob "." "*.{clj,md}")
(map str)
(take 5))]
(println " Found files:")
(doseq [f clj-files]
(println " -" f)))
;; Example 3: Creating directory structure
(println "\n3. Creating Directory Structure")
(fs/with-temp-dir [tmp {}]
(let [nested-dir (fs/path tmp "a" "b" "c")]
(fs/create-dirs nested-dir)
(println " Created nested directories:" nested-dir)
(println " Directory exists?" (fs/directory? nested-dir))))
;; Example 4: Copying and moving files
(println "\n4. Copy and Move Operations")
(fs/with-temp-dir [tmp {}]
(let [src (fs/path tmp "source.txt")
dest (fs/path tmp "destination.txt")
moved (fs/path tmp "moved.txt")]
(spit src "Original content")
(fs/copy src dest)
(println " Copied:" src "→" dest)
(println " Both exist?" (and (fs/exists? src) (fs/exists? dest)))
(fs/move dest moved)
(println " Moved:" dest "→" moved)
(println " Dest exists?" (fs/exists? dest))
(println " Moved exists?" (fs/exists? moved))))
;; Example 5: Working with paths
(println "\n5. Path Manipulation")
(let [path "src/project/core.clj"]
(println " Original path:" path)
(println " File name:" (fs/file-name path))
(println " Extension:" (fs/extension path))
(println " Parent:" (fs/parent path))
(println " Without ext:" (fs/strip-ext path))
(println " Absolute:" (str (fs/absolutize path))))
;; Example 6: File metadata
(println "\n6. File Metadata")
(let [this-file *file*]
(when (and this-file (fs/exists? this-file))
(println " This script:" this-file)
(println " Size:" (fs/size this-file) "bytes")
(println " Modified:" (fs/last-modified-time this-file))
(println " Readable?" (fs/readable? this-file))
(println " Writable?" (fs/writable? this-file))
(println " Executable?" (fs/executable? this-file))))
;; Example 7: Finding executable in PATH
(println "\n7. Finding Executables")
(when-let [bb-path (fs/which "bb")]
(println " Found bb at:" bb-path))
(when-let [git-path (fs/which "git")]
(println " Found git at:" git-path))
;; Example 8: Glob patterns
(println "\n8. Glob Pattern Matching")
(fs/with-temp-dir [tmp {}]
;; Create some test files
(doseq [file ["data.json" "config.edn" "test.clj"
"README.md" "nested/deep.txt"]]
(let [path (fs/path tmp file)]
(fs/create-dirs (fs/parent path))
(spit path "test")))
(println " All files:")
(doseq [f (fs/glob tmp "**/*")]
(when (fs/regular-file? f)
(println " -" (fs/relativize tmp f))))
(println " Just .clj and .edn files:")
(doseq [f (fs/glob tmp "**/*.{clj,edn}")]
(println " -" (fs/relativize tmp f))))
;; Example 9: Recursive directory walking
(println "\n9. Walking Directory Tree")
(fs/with-temp-dir [tmp {}]
;; Create structure
(doseq [dir ["a" "a/b" "a/b/c"]]
(fs/create-dirs (fs/path tmp dir))
(spit (fs/path tmp dir "file.txt") "test"))
(println " Directory structure:")
(fs/walk-file-tree tmp
{:pre-visit-dir (fn [path _]
(let [depth (count (fs/components
(fs/relativize tmp path)))]
(println (str (apply str (repeat depth " "))
"📁 " (fs/file-name path))))
:continue)
:visit-file (fn [path _]
(let [depth (count (fs/components
(fs/relativize tmp path)))]
(println (str (apply str (repeat depth " "))
"📄 " (fs/file-name path))))
:continue)}))
;; Example 10: File filtering pipeline
(println "\n10. File Filtering Pipeline")
(fs/with-temp-dir [tmp {}]
;; Create test files with different sizes
(doseq [[name content] [["small.txt" "x"]
["medium.txt" (apply str (repeat 100 "x"))]
["large.txt" (apply str (repeat 1000 "x"))]]]
(spit (fs/path tmp name) content))
(let [files (->> (fs/list-dir tmp)
(filter fs/regular-file?)
(map (fn [path]
{:name (fs/file-name path)
:size (fs/size path)}))
(sort-by :size))]
(println " Files by size:")
(doseq [{:keys [name size]} files]
(println (format " - %s: %d bytes" name size)))))
;; Example 11: XDG directories (Unix/Linux)
(println "\n11. XDG Base Directories")
(try
(println " Config home:" (fs/xdg-config-home))
(println " Data home:" (fs/xdg-data-home))
(println " Cache home:" (fs/xdg-cache-home))
(println " App config:" (fs/xdg-config-home "myapp"))
(catch Exception _
(println " (XDG directories not available on this platform)")))
;; Example 12: Temporary files and cleanup
(println "\n12. Temporary File Management")
(let [temp-file (fs/create-temp-file {:prefix "demo-"
:suffix ".txt"})]
(println " Created temp file:" temp-file)
(spit temp-file "Temporary data")
(println " Content:" (slurp temp-file))
(fs/delete temp-file)
(println " Deleted:" (not (fs/exists? temp-file))))
(println "\n13. Working with temp directory context")
(fs/with-temp-dir [tmp-dir {:prefix "work-"}]
(println " Working in:" tmp-dir)
(let [work-file (fs/path tmp-dir "work.txt")]
(spit work-file "work data")
(println " Created file:" work-file)
(println " File exists:" (fs/exists? work-file)))
(println " (Directory will be deleted after this block)"))
(println "\n=== All examples completed! ===\n")