add test suite
This commit is contained in:
+2
-143
@@ -1,19 +1,12 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultMaxSize = 512 * 1024
|
||||
DefaultMaxDepth = 20
|
||||
Version = "0.1.4"
|
||||
)
|
||||
|
||||
var Version = "dev"
|
||||
|
||||
var DefaultIgnores = []string{
|
||||
".git", "node_modules", "vendor", "bin", "go.mod", "go.sum",
|
||||
"target", "build", "dist", "Cargo.lock", ".idea", ".vscode",
|
||||
@@ -41,11 +34,6 @@ var FrontendExts = []string{
|
||||
".vue", ".svelte",
|
||||
}
|
||||
|
||||
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
|
||||
@@ -67,132 +55,3 @@ type Config struct {
|
||||
IncludeInstructions bool
|
||||
PickPaths []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
|
||||
force bool
|
||||
maxSize int64
|
||||
maxDepth int
|
||||
ignores stringSlice
|
||||
exts stringSlice
|
||||
showVer bool
|
||||
protonDrive bool
|
||||
drivePath string
|
||||
verticalSlices bool
|
||||
skipFrontend bool
|
||||
frontendOnly bool
|
||||
omitTest bool
|
||||
omitMd bool
|
||||
includeInstructions bool
|
||||
pickPaths stringSlice
|
||||
)
|
||||
|
||||
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.BoolVar(&force, "f", false, "overwrite existing output file (non-append mode)")
|
||||
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.BoolVar(&protonDrive, "proton-drive", false, "upload output to Proton Drive after writing locally")
|
||||
flag.StringVar(&drivePath, "drive-path", "", "full remote path on Proton Drive (requires --proton-drive")
|
||||
flag.BoolVar(&verticalSlices, "vertical-slices", false, "split output into root file + one markdown per top-level directory")
|
||||
flag.BoolVar(&skipFrontend, "skip-frontend", false, "omit frontend file types")
|
||||
flag.BoolVar(&frontendOnly, "frontend-only", false, "include only frontend file types and README.md")
|
||||
flag.BoolVar(&omitTest, "omit-test", false, "exclude test files and strip #[cfg(test)] blocks")
|
||||
flag.BoolVar(&omitMd, "omit-md", false, "omit all .md files except README.md")
|
||||
flag.BoolVar(&includeInstructions, "instructions", false, "include .dirmd instructions file if present in root")
|
||||
flag.Var(&pickPaths, "pick", "repeatable: relative path to file to include as pick (requires --vertical-slices)")
|
||||
|
||||
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")
|
||||
}
|
||||
if drivePath != "" && !protonDrive {
|
||||
return nil, fmt.Errorf("--drive-path requires --proton-drive")
|
||||
}
|
||||
if verticalSlices && appendMd {
|
||||
return nil, fmt.Errorf("--vertical-slices cannot be used with --append")
|
||||
}
|
||||
if verticalSlices && input != "" {
|
||||
return nil, fmt.Errorf("--vertical-slices cannot be used with --input-file")
|
||||
}
|
||||
if skipFrontend && frontendOnly {
|
||||
return nil, fmt.Errorf("--skip-frontend and --frontend-only are mutually exclusive")
|
||||
}
|
||||
if len(pickPaths) > 0 && !verticalSlices {
|
||||
return nil, fmt.Errorf("--pick requires --vertical-slices")
|
||||
}
|
||||
|
||||
excludedExts := append(DefaultExts, exts...)
|
||||
if skipFrontend {
|
||||
excludedExts = append(excludedExts, FrontendExts...)
|
||||
}
|
||||
|
||||
cfg := &Config{
|
||||
OutputPath: output,
|
||||
AppendMode: appendMd,
|
||||
Force: force,
|
||||
MaxSize: maxSize,
|
||||
MaxDepth: maxDepth,
|
||||
Ignores: append(DefaultIgnores, ignores...),
|
||||
Extensions: excludedExts,
|
||||
ProtonDrive: protonDrive,
|
||||
DrivePath: drivePath,
|
||||
VerticalSlices: verticalSlices,
|
||||
SkipFrontend: skipFrontend,
|
||||
FrontendOnly: frontendOnly,
|
||||
OmitTest: omitTest,
|
||||
OmitMd: omitMd,
|
||||
IncludeInstructions: includeInstructions,
|
||||
PickPaths: pickPaths,
|
||||
}
|
||||
|
||||
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 && !force {
|
||||
return nil, fmt.Errorf("output file %s already exists (use -f to overwrite or -a to append)", output)
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user