-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
116 lines (91 loc) · 2.55 KB
/
main.go
File metadata and controls
116 lines (91 loc) · 2.55 KB
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
// Package mdextract is a tool for extracting markdown sections from
// files. It can be used to extract documentation from source code
// files, or to extract specific sections from markdown files.
package main
import (
"errors"
"log"
"os"
"github.com/ntnn/mdextract/pkg/mdextract"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
multi := &mdextract.Multi{}
fs := multi.FlagSet()
fOutput := fs.String("output", "", "Output file ('-' for stdout, not compatible with -multi)")
fMulti := fs.Bool("multi", false, "Extract multiple sections based on the file tag (not compatible with -output)")
if err := fs.Parse(os.Args[1:]); err != nil {
return err
}
if *fMulti && *fOutput != "" {
fs.PrintDefaults()
return errors.New("-multi and -output cannot be used together")
}
if !*fMulti && *fOutput == "" {
fs.PrintDefaults()
return errors.New("-multi or -output must be specified")
}
if fs.NArg() == 0 {
fs.PrintDefaults()
return errors.New("no input files specified")
}
if *fMulti {
return doMulti(multi, fs.Args())
}
return doSingle(&multi.Single, *fOutput, multi.FileMode, fs.Args())
}
func doSingle(s *mdextract.Single, outputPath string, fileMode uint32, args []string) error {
f := os.Stdout
closeFn := func() error { return nil }
if outputPath != "-" {
var err error
f, err = os.OpenFile(outputPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.FileMode(fileMode)) //nolint:gosec
if err != nil {
return err
}
closeFn = f.Close
}
for _, input := range args {
out, err := s.ExtractFromFile(input)
if err != nil {
return err
}
if _, err := f.WriteString(out); err != nil {
return err
}
}
return closeFn()
}
// in contrast to Multi.ExtractFromFileAndWrite, this function does not
// truncate files when writing. This allows parsing multiple files in
// one go and accumulating their output in the same files.
func doMulti(m *mdextract.Multi, args []string) error {
for _, input := range args {
out, err := m.ExtractFromFile(input)
if err != nil {
return err
}
for file, content := range out {
if err := writeFileNoTruncate(file, []byte(content), os.FileMode(m.FileMode)); err != nil {
return err
}
}
}
return nil
}
// copied from os.WriteFile but without truncation.
func writeFileNoTruncate(name string, data []byte, perm os.FileMode) error {
f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE, perm) //nolint:gosec
if err != nil {
return err
}
_, err = f.Write(data)
if err1 := f.Close(); err1 != nil && err == nil {
err = err1
}
return err
}