add only frontend
This commit is contained in:
@@ -14,6 +14,7 @@ Generate markdown documentation from directory structure. Optimized for LLM inge
|
|||||||
- Configurable depth, file size limits, ignore patterns
|
- Configurable depth, file size limits, ignore patterns
|
||||||
- Optional upload to Proton Drive after generating output
|
- Optional upload to Proton Drive after generating output
|
||||||
- Skip frontend files (`.html`, `.css`, `.js`, etc.)
|
- Skip frontend files (`.html`, `.css`, `.js`, etc.)
|
||||||
|
- Frontend only mode (include only frontend files and `README.md`)
|
||||||
- Omit test files and inline test blocks (Go, Java, Rust)
|
- Omit test files and inline test blocks (Go, Java, Rust)
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
@@ -40,6 +41,9 @@ Generate markdown documentation from directory structure. Optimized for LLM inge
|
|||||||
# Skip frontend files (.html, .css, .js, etc.)
|
# Skip frontend files (.html, .css, .js, etc.)
|
||||||
dirmd -o output.md ~/repos/myproject --skip-frontend
|
dirmd -o output.md ~/repos/myproject --skip-frontend
|
||||||
|
|
||||||
|
# Frontend only (include only frontend files and README.md)
|
||||||
|
dirmd -o output.md ~/repos/myproject --frontend-only
|
||||||
|
|
||||||
# Omit test files and inline test blocks
|
# Omit test files and inline test blocks
|
||||||
# Go: excludes *_test.go
|
# Go: excludes *_test.go
|
||||||
# Java: excludes *Test.java, *Tests.java, src/test/java/*
|
# Java: excludes *Test.java, *Tests.java, src/test/java/*
|
||||||
@@ -47,7 +51,7 @@ Generate markdown documentation from directory structure. Optimized for LLM inge
|
|||||||
dirmd -o output.md ~/repos/myproject --omit-test
|
dirmd -o output.md ~/repos/myproject --omit-test
|
||||||
|
|
||||||
# Combine filters
|
# Combine filters
|
||||||
dirmd -o output.md ~/repos/myproject --skip-frontend --omit-test
|
dirmd -o output.md ~/repos/myproject --frontend-only --omit-test
|
||||||
|
|
||||||
# Generate and upload to Proton Drive (default: /my-files/md/<filename>)
|
# Generate and upload to Proton Drive (default: /my-files/md/<filename>)
|
||||||
dirmd -o output.md ~/repos/myproject --proton-drive
|
dirmd -o output.md ~/repos/myproject --proton-drive
|
||||||
@@ -67,18 +71,26 @@ The `--omit-test` flag removes test files and inline test blocks to reduce token
|
|||||||
|
|
||||||
The Rust stripping works by detecting the `#[cfg(test)]` attribute, then tracking brace depth until the module closes. Nested braces in string literals may occasionally throw off the count, but this is acceptable for RAG use cases.
|
The Rust stripping works by detecting the `#[cfg(test)]` attribute, then tracking brace depth until the module closes. Nested braces in string literals may occasionally throw off the count, but this is acceptable for RAG use cases.
|
||||||
|
|
||||||
Frontend files can be excluded separately with `--skip-frontend`:
|
## Frontend Filtering
|
||||||
|
|
||||||
| Extension Type | Excluded With `--skip-frontend` |
|
Two complementary flags control frontend file inclusion:
|
||||||
|---------------|-------------------------------|
|
|
||||||
|
| Flag | Effect |
|
||||||
|
|------|--------|
|
||||||
|
| `--skip-frontend` | Exclude frontend files, keep everything else |
|
||||||
|
| `--frontend-only` | Include only frontend files and `README.md`, exclude everything else |
|
||||||
|
|
||||||
|
Frontend extensions covered:
|
||||||
|
|
||||||
|
| Type | Extensions |
|
||||||
|
|------|------------|
|
||||||
| Templates | `.html`, `.htm`, `.gohtml`, `.tmpl` |
|
| Templates | `.html`, `.htm`, `.gohtml`, `.tmpl` |
|
||||||
| Stylesheets | `.css`, `.scss`, `.sass`, `.less` |
|
| Stylesheets | `.css`, `.scss`, `.sass`, `.less` |
|
||||||
| Scripts | `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx` |
|
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` |
|
||||||
|
| TypeScript | `.ts`, `.tsx` |
|
||||||
| Frameworks | `.vue`, `.svelte` |
|
| Frameworks | `.vue`, `.svelte` |
|
||||||
|
|
||||||
These flags can be combined freely:
|
`--skip-frontend` and `--frontend-only` are mutually exclusive. Both can be combined with `--omit-test`.
|
||||||
|
|
||||||
dirmd -o docs.md ~/repos/myproject --skip-frontend --omit-test
|
|
||||||
|
|
||||||
## Vertical Slices Mode
|
## Vertical Slices Mode
|
||||||
|
|
||||||
@@ -123,6 +135,7 @@ Output is designed for RAG ingestion and LLM context windows, not human presenta
|
|||||||
| `--proton-drive` | Upload output to Proton Drive after writing locally | false |
|
| `--proton-drive` | Upload output to Proton Drive after writing locally | false |
|
||||||
| `--drive-path` | Full remote path on Proton Drive (e.g. /my-files/md/report.md) | /my-files/md/<filename> |
|
| `--drive-path` | Full remote path on Proton Drive (e.g. /my-files/md/report.md) | /my-files/md/<filename> |
|
||||||
| `--skip-frontend` | Omit frontend file types (.html, .css, .js, .ts, .vue, .svelte, etc.) | false |
|
| `--skip-frontend` | Omit frontend file types (.html, .css, .js, .ts, .vue, .svelte, etc.) | false |
|
||||||
|
| `--frontend-only` | Include only frontend file types and README.md | false |
|
||||||
| `--omit-test` | Exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust | false |
|
| `--omit-test` | Exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust | false |
|
||||||
|
|
||||||
## Proton Drive Integration
|
## Proton Drive Integration
|
||||||
@@ -158,6 +171,9 @@ For full documentation on the Proton Drive CLI, including installation, authenti
|
|||||||
# Skip frontend and omit tests
|
# Skip frontend and omit tests
|
||||||
dirmd -o docs.md ~/repos/project -f --skip-frontend --omit-test
|
dirmd -o docs.md ~/repos/project -f --skip-frontend --omit-test
|
||||||
|
|
||||||
|
# Frontend only with test omission
|
||||||
|
dirmd -o docs.md ~/repos/project -f --frontend-only --omit-test
|
||||||
|
|
||||||
# Generate, then upload to default remote location
|
# Generate, then upload to default remote location
|
||||||
dirmd -o docs.md ~/repos/project --proton-drive
|
dirmd -o docs.md ~/repos/project --proton-drive
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -1,4 +1,3 @@
|
|||||||
// cmd/root.go
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -42,6 +41,9 @@ Examples:
|
|||||||
# Skip frontend files
|
# Skip frontend files
|
||||||
dirmd -o ./docs ~/repos/myproject --skip-frontend
|
dirmd -o ./docs ~/repos/myproject --skip-frontend
|
||||||
|
|
||||||
|
# Frontend only
|
||||||
|
dirmd -o ./docs ~/repos/myproject --frontend-only
|
||||||
|
|
||||||
# Omit test files and test blocks
|
# Omit test files and test blocks
|
||||||
dirmd -o ./docs ~/repos/myproject --omit-test
|
dirmd -o ./docs ~/repos/myproject --omit-test
|
||||||
|
|
||||||
@@ -65,6 +67,7 @@ Examples:
|
|||||||
drivePath string
|
drivePath string
|
||||||
verticalSlices bool
|
verticalSlices bool
|
||||||
skipFrontend bool
|
skipFrontend bool
|
||||||
|
frontendOnly bool
|
||||||
omitTest bool
|
omitTest bool
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,6 +90,7 @@ func init() {
|
|||||||
rootCmd.Flags().StringVar(&drivePath, "drive-path", "", "full remote directory on Proton Drive (e.g. /my-files/docs/api). Requires --proton-drive")
|
rootCmd.Flags().StringVar(&drivePath, "drive-path", "", "full remote directory on Proton Drive (e.g. /my-files/docs/api). Requires --proton-drive")
|
||||||
rootCmd.Flags().BoolVar(&verticalSlices, "vertical-slices", false, "split output into root index.md + one markdown per top-level directory")
|
rootCmd.Flags().BoolVar(&verticalSlices, "vertical-slices", false, "split output into root index.md + one markdown per top-level directory")
|
||||||
rootCmd.Flags().BoolVar(&skipFrontend, "skip-frontend", false, "omit frontend file types (.html, .css, .js, .ts, .vue, .svelte, etc.)")
|
rootCmd.Flags().BoolVar(&skipFrontend, "skip-frontend", false, "omit frontend file types (.html, .css, .js, .ts, .vue, .svelte, etc.)")
|
||||||
|
rootCmd.Flags().BoolVar(&frontendOnly, "frontend-only", false, "include only frontend file types and README.md")
|
||||||
rootCmd.Flags().BoolVar(&omitTest, "omit-test", false, "exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust")
|
rootCmd.Flags().BoolVar(&omitTest, "omit-test", false, "exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust")
|
||||||
|
|
||||||
rootCmd.MarkPersistentFlagRequired("output")
|
rootCmd.MarkPersistentFlagRequired("output")
|
||||||
@@ -105,6 +109,10 @@ func run(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("--vertical-slices cannot be used with --input-file")
|
return fmt.Errorf("--vertical-slices cannot be used with --input-file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skipFrontend && frontendOnly {
|
||||||
|
return fmt.Errorf("--skip-frontend and --frontend-only are mutually exclusive")
|
||||||
|
}
|
||||||
|
|
||||||
excludedExts := append(config.DefaultExts, extensions...)
|
excludedExts := append(config.DefaultExts, extensions...)
|
||||||
if skipFrontend {
|
if skipFrontend {
|
||||||
excludedExts = append(excludedExts, config.FrontendExts...)
|
excludedExts = append(excludedExts, config.FrontendExts...)
|
||||||
@@ -122,6 +130,7 @@ func run(cmd *cobra.Command, args []string) error {
|
|||||||
DrivePath: drivePath,
|
DrivePath: drivePath,
|
||||||
VerticalSlices: verticalSlices,
|
VerticalSlices: verticalSlices,
|
||||||
SkipFrontend: skipFrontend,
|
SkipFrontend: skipFrontend,
|
||||||
|
FrontendOnly: frontendOnly,
|
||||||
OmitTest: omitTest,
|
OmitTest: omitTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// internal/config/config.go
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -80,6 +79,7 @@ type Config struct {
|
|||||||
DrivePath string
|
DrivePath string
|
||||||
VerticalSlices bool
|
VerticalSlices bool
|
||||||
SkipFrontend bool
|
SkipFrontend bool
|
||||||
|
FrontendOnly bool
|
||||||
OmitTest bool
|
OmitTest bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +106,7 @@ func Parse() (*Config, error) {
|
|||||||
drivePath string
|
drivePath string
|
||||||
verticalSlices bool
|
verticalSlices bool
|
||||||
skipFrontend bool
|
skipFrontend bool
|
||||||
|
frontendOnly bool
|
||||||
omitTest bool
|
omitTest bool
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -119,9 +120,10 @@ func Parse() (*Config, error) {
|
|||||||
flag.Var(&exts, "extensions", "additional file extensions to skip (repeatable)")
|
flag.Var(&exts, "extensions", "additional file extensions to skip (repeatable)")
|
||||||
flag.BoolVar(&showVer, "version", false, "print version and exit")
|
flag.BoolVar(&showVer, "version", false, "print version and exit")
|
||||||
flag.BoolVar(&protonDrive, "proton-drive", false, "upload output to Proton Drive after writing locally")
|
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.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(&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 (.html, .css, .js, .ts, .vue, .svelte, etc.)")
|
flag.BoolVar(&skipFrontend, "skip-frontend", false, "omit frontend file types (.html, .css, .js, .ts, .vue, .svelte, etc.)")
|
||||||
|
flag.BoolVar(&frontendOnly, "frontend-only", false, "include only frontend file types and README.md")
|
||||||
flag.BoolVar(&omitTest, "omit-test", false, "exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust")
|
flag.BoolVar(&omitTest, "omit-test", false, "exclude test files (Go *_test.go, Java *Test.java) and strip #[cfg(test)] blocks from Rust")
|
||||||
|
|
||||||
flag.Usage = PrintUsage
|
flag.Usage = PrintUsage
|
||||||
@@ -148,6 +150,10 @@ func Parse() (*Config, error) {
|
|||||||
return nil, fmt.Errorf("--vertical-slices cannot be used with --input-file")
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
excludedExts := append(DefaultExts, exts...)
|
excludedExts := append(DefaultExts, exts...)
|
||||||
if skipFrontend {
|
if skipFrontend {
|
||||||
excludedExts = append(excludedExts, FrontendExts...)
|
excludedExts = append(excludedExts, FrontendExts...)
|
||||||
@@ -165,6 +171,7 @@ func Parse() (*Config, error) {
|
|||||||
DrivePath: drivePath,
|
DrivePath: drivePath,
|
||||||
VerticalSlices: verticalSlices,
|
VerticalSlices: verticalSlices,
|
||||||
SkipFrontend: skipFrontend,
|
SkipFrontend: skipFrontend,
|
||||||
|
FrontendOnly: frontendOnly,
|
||||||
OmitTest: omitTest,
|
OmitTest: omitTest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// internal/filter/filter.go
|
|
||||||
package filter
|
package filter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"dirmd/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
@@ -12,6 +13,7 @@ type Filter struct {
|
|||||||
Extensions []string
|
Extensions []string
|
||||||
Ignores []string
|
Ignores []string
|
||||||
OmitTest bool
|
OmitTest bool
|
||||||
|
FrontendOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Filter) ShouldSkipDir(name string) bool {
|
func (f *Filter) ShouldSkipDir(name string) bool {
|
||||||
@@ -39,14 +41,11 @@ func (f *Filter) ShouldSkipFile(path, name string, info os.FileInfo) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ext := filepath.Ext(path)
|
if info.Size() > f.MaxSize {
|
||||||
for _, bad := range f.Extensions {
|
|
||||||
if strings.EqualFold(ext, bad) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if info.Size() > f.MaxSize {
|
if f.FrontendOnly && !isFrontendOrReadme(path, name) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +53,26 @@ func (f *Filter) ShouldSkipFile(path, name string, info os.FileInfo) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext := filepath.Ext(path)
|
||||||
|
for _, bad := range f.Extensions {
|
||||||
|
if strings.EqualFold(ext, bad) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFrontendOrReadme(path, name string) bool {
|
||||||
|
ext := strings.ToLower(filepath.Ext(path))
|
||||||
|
for _, fe := range config.FrontendExts {
|
||||||
|
if strings.EqualFold(ext, fe) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.EqualFold(name, "README.md")
|
||||||
|
}
|
||||||
|
|
||||||
func isTestFile(path, name string) bool {
|
func isTestFile(path, name string) bool {
|
||||||
ext := strings.ToLower(filepath.Ext(path))
|
ext := strings.ToLower(filepath.Ext(path))
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ func processSingleFile(cfg *config.Config) (*Result, error) {
|
|||||||
Extensions: cfg.Extensions,
|
Extensions: cfg.Extensions,
|
||||||
Ignores: cfg.Ignores,
|
Ignores: cfg.Ignores,
|
||||||
OmitTest: cfg.OmitTest,
|
OmitTest: cfg.OmitTest,
|
||||||
|
FrontendOnly: cfg.FrontendOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
if flt.ShouldSkipFile(cfg.AbsRoot, filepath.Base(cfg.AbsRoot), info) {
|
if flt.ShouldSkipFile(cfg.AbsRoot, filepath.Base(cfg.AbsRoot), info) {
|
||||||
@@ -66,6 +67,7 @@ func walkDirectory(cfg *config.Config) (*Result, error) {
|
|||||||
Extensions: cfg.Extensions,
|
Extensions: cfg.Extensions,
|
||||||
Ignores: cfg.Ignores,
|
Ignores: cfg.Ignores,
|
||||||
OmitTest: cfg.OmitTest,
|
OmitTest: cfg.OmitTest,
|
||||||
|
FrontendOnly: cfg.FrontendOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &Result{AbsRoot: cfg.AbsRoot, OmitTest: cfg.OmitTest}
|
result := &Result{AbsRoot: cfg.AbsRoot, OmitTest: cfg.OmitTest}
|
||||||
|
|||||||
Reference in New Issue
Block a user