136 lines
3.0 KiB
Go
136 lines
3.0 KiB
Go
package config
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
DefaultMaxSize = 512 * 1024
|
|
DefaultMaxDepth = 20
|
|
Version = "0.1.0"
|
|
)
|
|
|
|
var DefaultIgnores = []string{
|
|
".git",
|
|
"node_modules",
|
|
"vendor",
|
|
"bin",
|
|
}
|
|
|
|
var DefaultExts = []string{
|
|
".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".ico",
|
|
".mp4", ".avi", ".mov", ".mkv", ".webm",
|
|
".mp3", ".wav", ".flac", ".ogg",
|
|
".zip", ".tar", ".gz", ".bz2", ".xz", ".7z", ".rar",
|
|
".exe", ".dll", ".so", ".dylib", ".wasm",
|
|
".pdf", ".doc", ".docx", ".xls", ".xlsx",
|
|
".pem", ".key", ".cert",
|
|
".db", ".sqlite", ".sqlite3",
|
|
}
|
|
|
|
type stringSlice []string
|
|
|
|
func (s *stringSlice) String() string {
|
|
return strings.Join(*s, ", ")
|
|
}
|
|
|
|
func (s *stringSlice) Set(v string) error {
|
|
*s = append(*s, v)
|
|
return nil
|
|
}
|
|
|
|
type Config struct {
|
|
InputPath string
|
|
OutputPath string
|
|
AppendMode bool
|
|
SingleFile bool
|
|
MaxSize int64
|
|
MaxDepth int
|
|
Ignores []string
|
|
Extensions []string
|
|
AbsRoot string
|
|
}
|
|
|
|
func PrintUsage() {
|
|
fmt.Fprintf(os.Stderr, "dirmd v%s\n\n", Version)
|
|
fmt.Fprintf(os.Stderr, "Usage: dirmd [flags] <directory>\n")
|
|
fmt.Fprintf(os.Stderr, " dirmd -a -i <file> -o <output>\n\n")
|
|
fmt.Fprintf(os.Stderr, "Flags:\n")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
func Parse() (*Config, error) {
|
|
var (
|
|
input string
|
|
output string
|
|
appendMd bool
|
|
maxSize int64
|
|
maxDepth int
|
|
ignores stringSlice
|
|
exts stringSlice
|
|
showVer bool
|
|
)
|
|
|
|
flag.StringVar(&input, "i", "", "single file input (append mode only)")
|
|
flag.StringVar(&output, "o", "", "output markdown file path (required)")
|
|
flag.BoolVar(&appendMd, "a", false, "append to existing output file")
|
|
flag.Int64Var(&maxSize, "max-size", DefaultMaxSize, "max file size in bytes")
|
|
flag.IntVar(&maxDepth, "max-depth", DefaultMaxDepth, "max directory recursion depth")
|
|
flag.Var(&ignores, "ignore", "additional ignore patterns (glob, repeatable)")
|
|
flag.Var(&exts, "extensions", "additional file extensions to skip (repeatable)")
|
|
flag.BoolVar(&showVer, "version", false, "print version and exit")
|
|
|
|
flag.Usage = PrintUsage
|
|
flag.Parse()
|
|
|
|
if showVer {
|
|
fmt.Printf("dirmd v%s\n", Version)
|
|
os.Exit(0)
|
|
}
|
|
|
|
if output == "" {
|
|
return nil, fmt.Errorf("-o is required")
|
|
}
|
|
|
|
cfg := &Config{
|
|
OutputPath: output,
|
|
AppendMode: appendMd,
|
|
MaxSize: maxSize,
|
|
MaxDepth: maxDepth,
|
|
Ignores: append(DefaultIgnores, ignores...),
|
|
Extensions: append(DefaultExts, exts...),
|
|
}
|
|
|
|
if input != "" {
|
|
cfg.SingleFile = true
|
|
cfg.InputPath = input
|
|
if !appendMd {
|
|
return nil, fmt.Errorf("single file input (-i) requires append mode (-a)")
|
|
}
|
|
} else {
|
|
args := flag.Args()
|
|
if len(args) < 1 {
|
|
return nil, fmt.Errorf("directory argument is required when -i is not used")
|
|
}
|
|
cfg.InputPath = args[0]
|
|
}
|
|
|
|
abs, err := filepath.Abs(cfg.InputPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to resolve absolute path: %w", err)
|
|
}
|
|
cfg.AbsRoot = abs
|
|
|
|
if !appendMd {
|
|
if _, err := os.Stat(output); err == nil {
|
|
return nil, fmt.Errorf("output file %s already exists (use -a to append)", output)
|
|
}
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|