/
os.go
161 lines (128 loc) · 3.88 KB
/
os.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
153
154
155
156
157
158
159
160
161
/*
Copyright 2018 Turbine Labs, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package os provides an OS interface mirroring a subset of commonly used
// functions and variables from the golang os package.
package os
//go:generate mockgen -source $GOFILE -destination mock_$GOFILE -package $GOPACKAGE --write_package_comment=false
// N.B.: On some platforms this produces what looks like a compilation error because
// mockgen tries to build in go's os package directory before retrying (and succeeding)
// in this directory.
//go:generate mockgen -destination mock_fileinfo.go --write_package_comment=false -package $GOPACKAGE os FileInfo
import (
"io"
"io/ioutil"
"os"
)
// OS is an interface on top of commonly used functions and variables
// from the golang os package, for easier testing. New methods can be
// added as needed.
//
// For undocumented functions, see correspondingly named things at
// https://golang.org/pkg/os.
type OS interface {
Args() []string
Create(name string) (*os.File, error)
Getenv(key string) string
LookupEnv(key string) (value string, found bool)
ExpandEnv(s string) string
Setenv(key, value string) error
Exit(code int)
Stdin() io.Reader
Stdout() io.Writer
Stderr() io.Writer
Stat(name string) (os.FileInfo, error)
IsNotExist(err error) bool
Remove(name string) error
Rename(oldpath, newpath string) error
Open(name string) (*os.File, error)
OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
MkdirAll(path string, perm os.FileMode) error
// Constructs a new DirReader via NewDirReader.
NewDirReader(dir string) DirReader
}
// New produces a new OS backed by the golang os package.
func New() OS {
return goOS{}
}
type goOS struct{}
func (x goOS) Args() []string {
return os.Args
}
func (x goOS) Create(name string) (*os.File, error) {
return os.Create(name)
}
func (x goOS) Getenv(key string) string {
return os.Getenv(key)
}
func (x goOS) LookupEnv(key string) (string, bool) {
return os.LookupEnv(key)
}
func (x goOS) ExpandEnv(s string) string {
return os.ExpandEnv(s)
}
func (x goOS) Setenv(key, value string) error {
return os.Setenv(key, value)
}
func (x goOS) Exit(code int) {
os.Exit(code)
}
func (x goOS) Stdin() io.Reader {
return os.Stdin
}
func (x goOS) Stdout() io.Writer {
return os.Stdout
}
func (x goOS) Stderr() io.Writer {
return os.Stderr
}
func (x goOS) Stat(name string) (os.FileInfo, error) {
return os.Stat(name)
}
func (x goOS) IsNotExist(err error) bool {
return os.IsNotExist(err)
}
func (x goOS) Remove(name string) error {
return os.Remove(name)
}
func (x goOS) Rename(oldpath, newpath string) error {
return os.Rename(oldpath, newpath)
}
func (x goOS) Open(name string) (*os.File, error) {
return os.Open(name)
}
func (x goOS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
return os.OpenFile(name, flag, perm)
}
func (x goOS) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, perm)
}
func (x goOS) NewDirReader(dir string) DirReader {
return NewDirReader(dir)
}
// ReadIfNonEmpty will read from an os.File only if non-empty; otherwise it will
// return an empty string. Useful, particularly, for checking for input on
// os.Stdin.
func ReadIfNonEmpty(f *os.File) (string, error) {
st, err := f.Stat()
if err != nil {
return "", err
}
if st.Size() == 0 {
return "", nil
}
bytes, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
return string(bytes), nil
}