diff --git a/tpl/os/init.go b/tpl/os/init.go index 3ef8702d6a2..08a36fe7b6f 100644 --- a/tpl/os/init.go +++ b/tpl/os/init.go @@ -55,6 +55,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.FileStat, + []string{"fileStat"}, + [][2]string{ + {`{{ (fileExists "files/README.txt").Size }}`, `11`}, + }, + ) + return ns } diff --git a/tpl/os/os.go b/tpl/os/os.go index 79d035d7ea7..04f151ec91a 100644 --- a/tpl/os/os.go +++ b/tpl/os/os.go @@ -130,3 +130,22 @@ func (ns *Namespace) FileExists(i interface{}) (bool, error) { return status, nil } + +// FileStat Stat returns the os.FileInfo structure describing file. +func (ns *Namespace) FileStat(i interface{}) (_os.FileInfo, error) { + path, err := cast.ToStringE(i) + if err != nil { + return nil, err + } + + if path == "" { + return nil, errors.New("fileStat needs a path to a file") + } + + r, err := ns.readFileFs.Stat(path) + if err != nil { + return nil, err + } + + return r, nil +} diff --git a/tpl/os/os_test.go b/tpl/os/os_test.go index 0919f885ab1..60e6b1f63fe 100644 --- a/tpl/os/os_test.go +++ b/tpl/os/os_test.go @@ -99,3 +99,37 @@ func TestFileExists(t *testing.T) { assert.Equal(t, test.expect, result, errMsg) } } + +func TestFileStat(t *testing.T) { + t.Parallel() + + workingDir := "/home/hugo" + + v := viper.New() + v.Set("workingDir", workingDir) + + ns := New(&deps.Deps{Fs: hugofs.NewMem(v)}) + + afero.WriteFile(ns.deps.Fs.Source, filepath.Join(workingDir, "/f/f1.txt"), []byte("f1-content"), 0755) + + for i, test := range []struct { + filename string + expect interface{} + }{ + {filepath.FromSlash("/f/f1.txt"), int64(10)}, + {filepath.FromSlash("f/f1.txt"), int64(10)}, + {"b", nil}, + {"", nil}, + } { + errMsg := fmt.Sprintf("[%d] %v", i, test) + result, err := ns.FileStat(test.filename) + + if test.expect == nil { + require.Error(t, err, errMsg) + continue + } + + require.NoError(t, err, errMsg) + assert.Equal(t, test.expect, result.Size(), errMsg) + } +}