diff --git a/docs/content/functions/fileExists.md b/docs/content/functions/fileExists.md new file mode 100644 index 00000000000..3d535aacaf6 --- /dev/null +++ b/docs/content/functions/fileExists.md @@ -0,0 +1,29 @@ +--- +title: "fileExists" +linktitle: "fileExists" +date: 2017-08-31T22:38:22+02:00 +description: Checks whether a file exists under the given path. +godocref: +publishdate: 2017-08-31T22:38:22+02:00 +lastmod: 2017-08-31T22:38:22+02:00 +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["fileExists PATH"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`fileExists` allows you to check if a file exists under a given path, e.g. before inserting code into a template: + +``` +{{ if (fileExists "static/img/banner.jpg") -}} + +{{- end }} +``` + +In the example above, a banner from the `static` folder should be shown if the given path points to an existing file. \ No newline at end of file diff --git a/tpl/os/init.go b/tpl/os/init.go index 3fc3308f2f2..012f43b1f62 100644 --- a/tpl/os/init.go +++ b/tpl/os/init.go @@ -48,6 +48,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.FileExists, + []string{"fileExists"}, + [][2]string{ + {`{{ fileExists "foo.txt" }}`, `false`}, + }, + ) + return ns } diff --git a/tpl/os/os.go b/tpl/os/os.go index c9ffb81cf60..02faa280944 100644 --- a/tpl/os/os.go +++ b/tpl/os/os.go @@ -96,3 +96,22 @@ func (ns *Namespace) ReadDir(i interface{}) ([]_os.FileInfo, error) { return list, nil } + +// FileExists checks whether a file exists under the given path. +func (ns *Namespace) FileExists(i interface{}) (bool, error) { + path, err := cast.ToStringE(i) + if err != nil { + return false, err + } + + if path == "" { + return false, errors.New("fileExists needs a path to a file") + } + + status, err := afero.Exists(ns.deps.Fs.WorkingDir, path) + if err != nil { + return false, err + } + + return status, nil +} diff --git a/tpl/os/os_test.go b/tpl/os/os_test.go index 383eb88c40a..0919f885ab1 100644 --- a/tpl/os/os_test.go +++ b/tpl/os/os_test.go @@ -63,3 +63,39 @@ func TestReadFile(t *testing.T) { assert.Equal(t, test.expect, result, errMsg) } } + +func TestFileExists(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) + afero.WriteFile(ns.deps.Fs.Source, filepath.Join("/home", "f2.txt"), []byte("f2-content"), 0755) + + for i, test := range []struct { + filename string + expect interface{} + }{ + {filepath.FromSlash("/f/f1.txt"), true}, + {filepath.FromSlash("f/f1.txt"), true}, + {filepath.FromSlash("../f2.txt"), false}, + {"b", false}, + {"", nil}, + } { + errMsg := fmt.Sprintf("[%d] %v", i, test) + result, err := ns.FileExists(test.filename) + + if test.expect == nil { + require.Error(t, err, errMsg) + continue + } + + require.NoError(t, err, errMsg) + assert.Equal(t, test.expect, result, errMsg) + } +}