-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
150 lines (128 loc) · 3.63 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
)
const VERSION = "1.0.2"
type FileInfo struct {
Name string `json:"name"`
Content string `json:"content"`
Size int64 `json:"size"`
ModTime time.Time `json:"modTime"`
Path string `json:"path"`
}
var (
inputDir string
recursive bool
exclude string
include string
rootCmd = &cobra.Command{
Use: "concatenator",
Short: "A tool to concatenate file information into a JSON file",
Long: `Concatenator is a CLI tool that traverses a directory, collects file information, and outputs it as a structured JSON file.`,
}
concatenateCmd = &cobra.Command{
Use: "concatenate [output_file]",
Short: "Concatenate file information into a JSON file",
Long: `Traverse a directory, collect file information, and output it as a structured JSON file.`,
Args: cobra.MaximumNArgs(1),
Run: run,
}
versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of concatenator",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("concatenator version %s\n", VERSION)
},
}
)
func init() {
concatenateCmd.Flags().StringVarP(&inputDir, "dir", "d", ".", "Input directory")
concatenateCmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "Traverse directory recursively")
concatenateCmd.Flags().StringVarP(&exclude, "exclude", "e", "", "Exclude files matching pattern (comma-separated, supports wildcards)")
concatenateCmd.Flags().StringVarP(&include, "include", "i", "", "Include only files matching pattern (comma-separated, supports wildcards)")
concatenateCmd.Flags().Lookup("recursive").NoOptDefVal = "true"
rootCmd.AddCommand(concatenateCmd, versionCmd)
}
func matchesPattern(path string, patterns []string) bool {
for _, pattern := range patterns {
matched, err := filepath.Match(pattern, filepath.Base(path))
if err == nil && matched {
return true
}
}
return false
}
func run(cmd *cobra.Command, args []string) {
outputFile := "output.json"
if len(args) > 0 {
outputFile = args[0]
}
excludePatterns := strings.Split(exclude, ",")
includePatterns := strings.Split(include, ",")
for i, pattern := range excludePatterns {
excludePatterns[i] = strings.TrimSpace(pattern)
}
for i, pattern := range includePatterns {
includePatterns[i] = strings.TrimSpace(pattern)
}
var files []FileInfo
err := filepath.Walk(inputDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !recursive && info.IsDir() && path != inputDir {
return filepath.SkipDir
}
if info.IsDir() {
return nil
}
if len(includePatterns) > 0 && !matchesPattern(path, includePatterns) {
return nil
}
if matchesPattern(path, excludePatterns) {
return nil
}
content, err := ioutil.ReadFile(path)
if err != nil {
return err
}
relPath, _ := filepath.Rel(inputDir, path)
fileInfo := FileInfo{
Name: info.Name(),
Content: string(content),
Size: info.Size(),
ModTime: info.ModTime(),
Path: relPath,
}
files = append(files, fileInfo)
return nil
})
if err != nil {
fmt.Printf("Error while traversing directory: %v\n", err)
os.Exit(1)
}
jsonData, err := json.MarshalIndent(files, "", " ")
if err != nil {
fmt.Printf("Error while creating JSON: %v\n", err)
os.Exit(1)
}
err = ioutil.WriteFile(outputFile, jsonData, 0644)
if err != nil {
fmt.Printf("Error while writing output file: %v\n", err)
os.Exit(1)
}
fmt.Printf("JSON file created successfully: %s\n", outputFile)
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}