-
Notifications
You must be signed in to change notification settings - Fork 0
/
files.go
152 lines (120 loc) · 3.24 KB
/
files.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
151
152
package cli
import (
"io"
"os"
"github.com/mailund/cli/interfaces"
)
// OutFile represents an open file as an argument
type OutFile struct {
io.Writer
Fname string
}
// Open opens a file given by name
func (o *OutFile) Open(fname string) error {
f, err := os.Create(fname)
if err != nil {
return interfaces.ParseErrorf("couldn't open file %s: %s", fname, err)
}
o.Writer = f
return nil
}
// Set implements the PosValue/FlagValue interface
func (o *OutFile) Set(fname string) error {
return o.Open(fname)
}
// String implements the FlagValue interface
func (o *OutFile) String() string {
switch o.Writer {
case os.Stdout:
return "stdout"
case os.Stderr:
return "stderr"
default:
return `"` + o.Fname + `"`
}
}
// Validate implements the validaator interface. For flags, we either have to
// have a writer or a valid file name.
func (o *OutFile) Validate(flag bool) error {
if !flag || o.Writer != nil || o.Fname != "" {
return nil // we have a valid default, or we will get an argument
}
return interfaces.SpecErrorf("outfile does not have a valid default")
}
// Close implements the io.Closer interface by forwarding to the writer
func (o *OutFile) Close() error {
var err error
if closer, ok := o.Writer.(io.Closer); ok {
err = closer.Close()
}
o.Writer = nil
return err
}
// PrepareValue implements the prepare protocol. It will open
// a file if we don't already have a writer but we have a name.
func (o *OutFile) PrepareValue() error {
if o.Writer != nil {
return nil // we already have a writer
}
return o.Open(o.Fname)
}
// FlagValueDescription implements the value protocol
func (o *OutFile) FlagValueDescription() string {
return "output file"
}
// InFile represents an open file as an argument
type InFile struct {
io.Reader
Fname string
}
// Open opens a file given by name
func (in *InFile) Open(fname string) error {
f, err := os.Open(fname)
if err != nil {
return interfaces.ParseErrorf("couldn't open file %s: %s", fname, err)
}
in.Reader = f
return nil
}
// Set implements the PosValue/FlagValue interface
func (in *InFile) Set(fname string) error {
return in.Open(fname)
}
// String implements the FlagValue interface
func (in *InFile) String() string {
switch in.Reader {
case os.Stdin:
return "stdin"
default:
return `"` + in.Fname + `"`
}
}
// Validate implements the validaator interface. For flags, we either have to
// have a writer or a valid file name.
func (in *InFile) Validate(flag bool) error {
if !flag || in.Reader != nil || in.Fname != "" {
return nil // we have a valid default, or we will get an argument
}
return interfaces.SpecErrorf("infile does not have a valid default")
}
// Close implements the io.Closer interface by forwarding to the writer
func (in *InFile) Close() error {
var err error
if closer, ok := in.Reader.(io.Closer); ok {
err = closer.Close()
}
in.Reader = nil
return err
}
// PrepareValue implements the prepare protocol. It will open
// a file if we don't already have a writer but we have a name.
func (in *InFile) PrepareValue() error {
if in.Reader != nil {
return nil // we already have a reader
}
return in.Open(in.Fname)
}
// FlagValueDescription implements the value protocol
func (in *InFile) FlagValueDescription() string {
return "input file"
}