os.go - hugo - [fork] hugo port for 9front
HTML git clone https://git.drkhsh.at/hugo.git
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
os.go (4068B)
---
1 // Copyright 2017 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 // Package os provides template functions for interacting with the operating
15 // system.
16 package os
17
18 import (
19 "errors"
20 "fmt"
21 _os "os"
22 "path/filepath"
23
24 "github.com/bep/overlayfs"
25 "github.com/gohugoio/hugo/common/herrors"
26 "github.com/gohugoio/hugo/deps"
27 "github.com/spf13/afero"
28 "github.com/spf13/cast"
29 )
30
31 // New returns a new instance of the os-namespaced template functions.
32 func New(d *deps.Deps) *Namespace {
33 var readFileFs, workFs afero.Fs
34
35 // The docshelper script does not have or need all the dependencies set up.
36 if d.PathSpec != nil {
37 readFileFs = overlayfs.New(overlayfs.Options{
38 Fss: []afero.Fs{
39 d.PathSpec.BaseFs.Work,
40 d.PathSpec.BaseFs.Content.Fs,
41 },
42 })
43 // See #9599
44 workFs = d.PathSpec.BaseFs.WorkDir
45 }
46
47 return &Namespace{
48 readFileFs: readFileFs,
49 workFs: workFs,
50 deps: d,
51 }
52 }
53
54 // Namespace provides template functions for the "os" namespace.
55 type Namespace struct {
56 readFileFs afero.Fs
57 workFs afero.Fs
58 deps *deps.Deps
59 }
60
61 // Getenv retrieves the value of the environment variable named by the key.
62 // It returns the value, which will be empty if the variable is not present.
63 func (ns *Namespace) Getenv(key any) (string, error) {
64 skey, err := cast.ToStringE(key)
65 if err != nil {
66 return "", nil
67 }
68
69 if err = ns.deps.ExecHelper.Sec().CheckAllowedGetEnv(skey); err != nil {
70 return "", err
71 }
72
73 return _os.Getenv(skey), nil
74 }
75
76 // readFile reads the file named by filename in the given filesystem
77 // and returns the contents as a string.
78 func readFile(fs afero.Fs, filename string) (string, error) {
79 filename = filepath.Clean(filename)
80 if filename == "" || filename == "." || filename == string(_os.PathSeparator) {
81 return "", errors.New("invalid filename")
82 }
83
84 b, err := afero.ReadFile(fs, filename)
85 if err != nil {
86 return "", err
87 }
88
89 return string(b), nil
90 }
91
92 // ReadFile reads the file named by filename relative to the configured WorkingDir.
93 // It returns the contents as a string.
94 // There is an upper size limit set at 1 megabytes.
95 func (ns *Namespace) ReadFile(i any) (string, error) {
96 s, err := cast.ToStringE(i)
97 if err != nil {
98 return "", err
99 }
100
101 if ns.deps.PathSpec != nil {
102 s = ns.deps.PathSpec.RelPathify(s)
103 }
104
105 s, err = readFile(ns.readFileFs, s)
106 if err != nil && herrors.IsNotExist(err) {
107 return "", nil
108 }
109 return s, err
110 }
111
112 // ReadDir lists the directory contents relative to the configured WorkingDir.
113 func (ns *Namespace) ReadDir(i any) ([]_os.FileInfo, error) {
114 path, err := cast.ToStringE(i)
115 if err != nil {
116 return nil, err
117 }
118
119 list, err := afero.ReadDir(ns.workFs, path)
120 if err != nil {
121 return nil, fmt.Errorf("failed to read directory %q: %s", path, err)
122 }
123
124 return list, nil
125 }
126
127 // FileExists checks whether a file exists under the given path.
128 func (ns *Namespace) FileExists(i any) (bool, error) {
129 path, err := cast.ToStringE(i)
130 if err != nil {
131 return false, err
132 }
133
134 if path == "" {
135 return false, errors.New("fileExists needs a path to a file")
136 }
137
138 status, err := afero.Exists(ns.readFileFs, path)
139 if err != nil {
140 return false, err
141 }
142
143 return status, nil
144 }
145
146 // Stat returns the os.FileInfo structure describing file.
147 func (ns *Namespace) Stat(i any) (_os.FileInfo, error) {
148 path, err := cast.ToStringE(i)
149 if err != nil {
150 return nil, err
151 }
152
153 if path == "" {
154 return nil, errors.New("fileStat needs a path to a file")
155 }
156
157 r, err := ns.readFileFs.Stat(path)
158 if err != nil {
159 return nil, err
160 }
161
162 return r, nil
163 }