github.com/hairyhenderson/gomplate/v4@v4.0.0-pre-2.0.20240520121557-362f058f0c93/internal/tests/integration/inputdir_test.go (about) 1 package integration 2 3 import ( 4 "os" 5 "testing" 6 7 "github.com/hairyhenderson/gomplate/v4/internal/iohelpers" 8 tassert "github.com/stretchr/testify/assert" 9 "gotest.tools/v3/assert" 10 "gotest.tools/v3/fs" 11 ) 12 13 func setupInputDirTest(t *testing.T) *fs.Dir { 14 tmpDir := fs.NewDir(t, "gomplate-inttests", 15 fs.WithFile("config.yml", "one: eins\ntwo: deux\n"), 16 fs.WithFile("filemap.json", `{"eins.txt":"uno","deux.txt":"dos","drei.sh":"tres","vier.txt":"quatro"}`), 17 fs.WithFile("out.t", `{{- /* .in may contain a directory name - we want to preserve that */ -}} 18 {{ $f := filepath.Base .in -}} 19 out/{{ .in | strings.ReplaceAll $f (index .filemap $f) }}.out 20 `), 21 fs.WithDir("in", 22 fs.WithFile("eins.txt", `{{ (ds "config").one }}`, fs.WithMode(0o644)), 23 fs.WithDir("inner", 24 fs.WithFile("deux.txt", `{{ (ds "config").two }}`, fs.WithMode(0o444)), 25 ), 26 fs.WithFile("drei.sh", `#!/bin/sh\necho "hello world"\n`, fs.WithMode(0o755)), 27 fs.WithFile("vier.txt", `{{ (ds "config").two }} * {{ (ds "config").two }}`, fs.WithMode(0o544)), 28 ), 29 fs.WithDir("out"), 30 fs.WithDir("bad_in", 31 fs.WithFile("bad.tmpl", "{{end}}"), 32 ), 33 ) 34 t.Cleanup(tmpDir.Remove) 35 36 return tmpDir 37 } 38 39 func TestInputDir_InputDir(t *testing.T) { 40 tmpDir := setupInputDirTest(t) 41 42 o, e, err := cmd(t, 43 "--input-dir", tmpDir.Join("in"), 44 "--output-dir", tmpDir.Join("out"), 45 "-d", "config="+tmpDir.Join("config.yml"), 46 ).run() 47 assertSuccess(t, o, e, err, "") 48 49 files, err := os.ReadDir(tmpDir.Join("out")) 50 assert.NilError(t, err) 51 tassert.Len(t, files, 4) 52 53 files, err = os.ReadDir(tmpDir.Join("out", "inner")) 54 assert.NilError(t, err) 55 tassert.Len(t, files, 1) 56 57 testdata := []struct { 58 path string 59 content string 60 mode os.FileMode 61 }{ 62 {tmpDir.Join("out", "eins.txt"), "eins", 0o644}, 63 {tmpDir.Join("out", "inner", "deux.txt"), "deux", 0o444}, 64 {tmpDir.Join("out", "drei.sh"), `#!/bin/sh\necho "hello world"\n`, 0o755}, 65 {tmpDir.Join("out", "vier.txt"), "deux * deux", 0o544}, 66 } 67 for _, v := range testdata { 68 info, err := os.Stat(v.path) 69 assert.NilError(t, err) 70 m := iohelpers.NormalizeFileMode(v.mode) 71 assert.Equal(t, m, info.Mode(), v.path) 72 content, err := os.ReadFile(v.path) 73 assert.NilError(t, err) 74 assert.Equal(t, v.content, string(content)) 75 } 76 } 77 78 func TestInputDir_InputDirWithModeOverride(t *testing.T) { 79 tmpDir := setupInputDirTest(t) 80 o, e, err := cmd(t, 81 "--input-dir", tmpDir.Join("in"), 82 "--output-dir", tmpDir.Join("out"), 83 "--chmod", "0601", 84 "-d", "config="+tmpDir.Join("config.yml"), 85 ).run() 86 assertSuccess(t, o, e, err, "") 87 88 files, err := os.ReadDir(tmpDir.Join("out")) 89 assert.NilError(t, err) 90 tassert.Len(t, files, 4) 91 92 files, err = os.ReadDir(tmpDir.Join("out", "inner")) 93 assert.NilError(t, err) 94 tassert.Len(t, files, 1) 95 96 testdata := []struct { 97 path string 98 content string 99 mode os.FileMode 100 }{ 101 {tmpDir.Join("out", "eins.txt"), "eins", 0o601}, 102 {tmpDir.Join("out", "inner", "deux.txt"), "deux", 0o601}, 103 {tmpDir.Join("out", "drei.sh"), `#!/bin/sh\necho "hello world"\n`, 0o601}, 104 {tmpDir.Join("out", "vier.txt"), "deux * deux", 0o601}, 105 } 106 for _, v := range testdata { 107 info, err := os.Stat(v.path) 108 assert.NilError(t, err) 109 m := iohelpers.NormalizeFileMode(v.mode) 110 assert.Equal(t, m, info.Mode(), v.path) 111 content, err := os.ReadFile(v.path) 112 assert.NilError(t, err) 113 assert.Equal(t, v.content, string(content)) 114 } 115 } 116 117 func TestInputDir_OutputMapInline(t *testing.T) { 118 tmpDir := setupInputDirTest(t) 119 o, e, err := cmd(t, 120 "--input-dir", tmpDir.Join("in"), 121 "--output-map", `OUT/{{ strings.ToUpper .in }}`, 122 "-d", "config.yml", 123 ).withDir(tmpDir.Path()).run() 124 assertSuccess(t, o, e, err, "") 125 126 files, err := os.ReadDir(tmpDir.Join("OUT")) 127 assert.NilError(t, err) 128 tassert.Len(t, files, 4) 129 130 files, err = os.ReadDir(tmpDir.Join("OUT", "INNER")) 131 assert.NilError(t, err) 132 tassert.Len(t, files, 1) 133 134 testdata := []struct { 135 path string 136 content string 137 mode os.FileMode 138 }{ 139 {tmpDir.Join("OUT", "EINS.TXT"), "eins", 0o644}, 140 {tmpDir.Join("OUT", "INNER", "DEUX.TXT"), "deux", 0o444}, 141 {tmpDir.Join("OUT", "DREI.SH"), `#!/bin/sh\necho "hello world"\n`, 0o755}, 142 {tmpDir.Join("OUT", "VIER.TXT"), "deux * deux", 0o544}, 143 } 144 for _, v := range testdata { 145 info, err := os.Stat(v.path) 146 assert.NilError(t, err) 147 m := iohelpers.NormalizeFileMode(v.mode) 148 assert.Equal(t, m, info.Mode(), v.path) 149 content, err := os.ReadFile(v.path) 150 assert.NilError(t, err) 151 assert.Equal(t, v.content, string(content)) 152 } 153 } 154 155 func TestInputDir_OutputMapExternal(t *testing.T) { 156 tmpDir := setupInputDirTest(t) 157 o, e, err := cmd(t, 158 "--input-dir", tmpDir.Join("in"), 159 "--output-map", `{{ template "out" . }}`, 160 "-t", "out=out.t", 161 "-c", "filemap.json", 162 "-d", "config.yml", 163 ).withDir(tmpDir.Path()).run() 164 assertSuccess(t, o, e, err, "") 165 166 files, err := os.ReadDir(tmpDir.Join("out")) 167 assert.NilError(t, err) 168 tassert.Len(t, files, 4) 169 170 files, err = os.ReadDir(tmpDir.Join("out", "inner")) 171 assert.NilError(t, err) 172 tassert.Len(t, files, 1) 173 174 testdata := []struct { 175 path string 176 content string 177 mode os.FileMode 178 }{ 179 {tmpDir.Join("out", "uno.out"), "eins", 0o644}, 180 {tmpDir.Join("out", "inner", "dos.out"), "deux", 0o444}, 181 {tmpDir.Join("out", "tres.out"), `#!/bin/sh\necho "hello world"\n`, 0o755}, 182 {tmpDir.Join("out", "quatro.out"), "deux * deux", 0o544}, 183 } 184 for _, v := range testdata { 185 info, err := os.Stat(v.path) 186 assert.NilError(t, err) 187 m := iohelpers.NormalizeFileMode(v.mode) 188 assert.Equal(t, m, info.Mode(), v.path) 189 content, err := os.ReadFile(v.path) 190 assert.NilError(t, err) 191 assert.Equal(t, v.content, string(content)) 192 } 193 } 194 195 func TestInputDir_DefaultOutputDir(t *testing.T) { 196 tmpDir := setupInputDirTest(t) 197 o, e, err := cmd(t, 198 "--input-dir", tmpDir.Join("in"), 199 "-d", "config="+tmpDir.Join("config.yml"), 200 ).withDir(tmpDir.Join("out")).run() 201 assertSuccess(t, o, e, err, "") 202 203 files, err := os.ReadDir(tmpDir.Join("out")) 204 assert.NilError(t, err) 205 tassert.Len(t, files, 4) 206 207 files, err = os.ReadDir(tmpDir.Join("out", "inner")) 208 assert.NilError(t, err) 209 tassert.Len(t, files, 1) 210 211 content, err := os.ReadFile(tmpDir.Join("out", "eins.txt")) 212 assert.NilError(t, err) 213 assert.Equal(t, "eins", string(content)) 214 215 content, err = os.ReadFile(tmpDir.Join("out", "inner", "deux.txt")) 216 assert.NilError(t, err) 217 assert.Equal(t, "deux", string(content)) 218 219 content, err = os.ReadFile(tmpDir.Join("out", "drei.sh")) 220 assert.NilError(t, err) 221 assert.Equal(t, `#!/bin/sh\necho "hello world"\n`, string(content)) 222 223 content, err = os.ReadFile(tmpDir.Join("out", "vier.txt")) 224 assert.NilError(t, err) 225 assert.Equal(t, `deux * deux`, string(content)) 226 } 227 228 func TestInputDir_ReportsFilenameWithBadInputFile(t *testing.T) { 229 tmpDir := setupInputDirTest(t) 230 o, _, err := cmd(t, 231 "--input-dir", tmpDir.Join("bad_in"), 232 "--output-dir", tmpDir.Join("out"), 233 "-d", "config="+tmpDir.Join("config.yml"), 234 ).run() 235 assert.ErrorContains(t, err, "bad.tmpl:1: unexpected {{end}}") 236 assert.Equal(t, "", o) 237 } 238 239 func TestInputDir_InputDirCwd(t *testing.T) { 240 tmpDir := setupInputDirTest(t) 241 o, e, err := cmd(t, 242 "--input-dir", ".", 243 "--include", "*.txt", 244 "--output-map", `{{ .in | strings.ReplaceAll ".txt" ".out" }}`, 245 "-d", "config="+tmpDir.Join("config.yml"), 246 ).withDir(tmpDir.Path()).run() 247 assertSuccess(t, o, e, err, "") 248 249 testdata := []struct { 250 path string 251 content string 252 mode os.FileMode 253 }{ 254 {tmpDir.Join("in", "eins.out"), "eins", 0o644}, 255 {tmpDir.Join("in", "inner", "deux.out"), "deux", 0o444}, 256 {tmpDir.Join("in", "vier.out"), "deux * deux", 0o544}, 257 } 258 for _, v := range testdata { 259 info, err := os.Stat(v.path) 260 assert.NilError(t, err) 261 m := iohelpers.NormalizeFileMode(v.mode) 262 assert.Equal(t, m, info.Mode(), v.path) 263 content, err := os.ReadFile(v.path) 264 assert.NilError(t, err) 265 assert.Equal(t, v.content, string(content)) 266 } 267 }